mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Make the service worker send custom response
This commit is contained in:
parent
81a1e28da1
commit
36dbd27ba5
4 changed files with 52 additions and 29 deletions
|
@ -15,7 +15,7 @@ pub enum WorkerScriptMsg {
|
||||||
/// Common variants associated with the script messages
|
/// Common variants associated with the script messages
|
||||||
Common(CommonScriptMsg),
|
Common(CommonScriptMsg),
|
||||||
/// Message sent through Worker.postMessage
|
/// Message sent through Worker.postMessage
|
||||||
DOMMessage(StructuredCloneData),
|
DOMMessage(StructuredCloneData)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SimpleWorkerErrorHandler<T: Reflectable> {
|
pub struct SimpleWorkerErrorHandler<T: Reflectable> {
|
||||||
|
|
|
@ -307,7 +307,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
let path_seg = format!("url({})", scope.get_url());
|
let path_seg = format!("url({})", scope.get_url());
|
||||||
let reports = get_reports(cx, path_seg);
|
let reports = get_reports(cx, path_seg);
|
||||||
reports_chan.send(reports);
|
reports_chan.send(reports);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::{LoadContext, load_whole_resource, IpcSend};
|
use net_traits::{LoadContext, load_whole_resource, IpcSend, CustomResponseMediator};
|
||||||
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx};
|
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx};
|
||||||
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg};
|
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg};
|
||||||
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
|
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
|
||||||
|
@ -36,8 +36,16 @@ use util::thread::spawn_named;
|
||||||
use util::thread_state;
|
use util::thread_state;
|
||||||
use util::thread_state::{IN_WORKER, SCRIPT};
|
use util::thread_state::{IN_WORKER, SCRIPT};
|
||||||
|
|
||||||
|
/// Messages used to control service worker event loop
|
||||||
|
pub enum ServiceWorkerScriptMsg {
|
||||||
|
/// Message common to all workers
|
||||||
|
CommonWorker(WorkerScriptMsg),
|
||||||
|
// Message to request a custom response by the service worker
|
||||||
|
Response(CustomResponseMediator)
|
||||||
|
}
|
||||||
|
|
||||||
pub enum MixedMessage {
|
pub enum MixedMessage {
|
||||||
FromServiceWorker((TrustedServiceWorkerAddress, WorkerScriptMsg)),
|
FromServiceWorker(ServiceWorkerScriptMsg),
|
||||||
FromDevtools(DevtoolScriptControlMsg),
|
FromDevtools(DevtoolScriptControlMsg),
|
||||||
FromTimeoutThread(()),
|
FromTimeoutThread(()),
|
||||||
}
|
}
|
||||||
|
@ -47,9 +55,9 @@ pub struct ServiceWorkerGlobalScope {
|
||||||
workerglobalscope: WorkerGlobalScope,
|
workerglobalscope: WorkerGlobalScope,
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
#[ignore_heap_size_of = "Defined in std"]
|
#[ignore_heap_size_of = "Defined in std"]
|
||||||
receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
receiver: Receiver<ServiceWorkerScriptMsg>,
|
||||||
#[ignore_heap_size_of = "Defined in std"]
|
#[ignore_heap_size_of = "Defined in std"]
|
||||||
own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
own_sender: Sender<ServiceWorkerScriptMsg>,
|
||||||
#[ignore_heap_size_of = "Defined in std"]
|
#[ignore_heap_size_of = "Defined in std"]
|
||||||
timer_event_port: Receiver<()>,
|
timer_event_port: Receiver<()>,
|
||||||
#[ignore_heap_size_of = "Trusted<T> has unclear ownership like JS<T>"]
|
#[ignore_heap_size_of = "Trusted<T> has unclear ownership like JS<T>"]
|
||||||
|
@ -66,8 +74,8 @@ impl ServiceWorkerGlobalScope {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
own_sender: Sender<ServiceWorkerScriptMsg>,
|
||||||
receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
receiver: Receiver<ServiceWorkerScriptMsg>,
|
||||||
timer_event_chan: IpcSender<TimerEvent>,
|
timer_event_chan: IpcSender<TimerEvent>,
|
||||||
timer_event_port: Receiver<()>,
|
timer_event_port: Receiver<()>,
|
||||||
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
||||||
|
@ -95,8 +103,8 @@ impl ServiceWorkerGlobalScope {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
own_sender: Sender<ServiceWorkerScriptMsg>,
|
||||||
receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
receiver: Receiver<ServiceWorkerScriptMsg>,
|
||||||
timer_event_chan: IpcSender<TimerEvent>,
|
timer_event_chan: IpcSender<TimerEvent>,
|
||||||
timer_event_port: Receiver<()>,
|
timer_event_port: Receiver<()>,
|
||||||
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
||||||
|
@ -119,8 +127,8 @@ impl ServiceWorkerGlobalScope {
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn run_serviceworker_scope(scope_things: ScopeThings,
|
pub fn run_serviceworker_scope(scope_things: ScopeThings,
|
||||||
own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
own_sender: Sender<ServiceWorkerScriptMsg>,
|
||||||
receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
|
receiver: Receiver<ServiceWorkerScriptMsg>,
|
||||||
devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
|
devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
|
||||||
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
||||||
scope_url: Url) {
|
scope_url: Url) {
|
||||||
|
@ -201,7 +209,7 @@ impl ServiceWorkerGlobalScope {
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
MixedMessage::FromServiceWorker((_, msg)) => {
|
MixedMessage::FromServiceWorker(msg) => {
|
||||||
self.handle_script_event(msg);
|
self.handle_script_event(msg);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -212,9 +220,11 @@ impl ServiceWorkerGlobalScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_script_event(&self, msg: WorkerScriptMsg) {
|
fn handle_script_event(&self, msg: ServiceWorkerScriptMsg) {
|
||||||
|
use self::ServiceWorkerScriptMsg::*;
|
||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
WorkerScriptMsg::DOMMessage(data) => {
|
CommonWorker(WorkerScriptMsg::DOMMessage(data)) => {
|
||||||
let scope = self.upcast::<WorkerGlobalScope>();
|
let scope = self.upcast::<WorkerGlobalScope>();
|
||||||
let target = self.upcast();
|
let target = self.upcast();
|
||||||
let _ac = JSAutoCompartment::new(scope.get_cx(),
|
let _ac = JSAutoCompartment::new(scope.get_cx(),
|
||||||
|
@ -223,19 +233,22 @@ impl ServiceWorkerGlobalScope {
|
||||||
data.read(GlobalRef::Worker(scope), message.handle_mut());
|
data.read(GlobalRef::Worker(scope), message.handle_mut());
|
||||||
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
|
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
|
||||||
},
|
},
|
||||||
WorkerScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable)) => {
|
CommonWorker(WorkerScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable))) => {
|
||||||
runnable.handler()
|
runnable.handler()
|
||||||
},
|
},
|
||||||
WorkerScriptMsg::Common(CommonScriptMsg::RefcountCleanup(addr)) => {
|
CommonWorker(WorkerScriptMsg::Common(CommonScriptMsg::RefcountCleanup(addr))) => {
|
||||||
LiveDOMReferences::cleanup(addr);
|
LiveDOMReferences::cleanup(addr);
|
||||||
},
|
},
|
||||||
WorkerScriptMsg::Common(CommonScriptMsg::CollectReports(reports_chan)) => {
|
CommonWorker(WorkerScriptMsg::Common(CommonScriptMsg::CollectReports(reports_chan))) => {
|
||||||
let scope = self.upcast::<WorkerGlobalScope>();
|
let scope = self.upcast::<WorkerGlobalScope>();
|
||||||
let cx = scope.get_cx();
|
let cx = scope.get_cx();
|
||||||
let path_seg = format!("url({})", scope.get_url());
|
let path_seg = format!("url({})", scope.get_url());
|
||||||
let reports = get_reports(cx, path_seg);
|
let reports = get_reports(cx, path_seg);
|
||||||
reports_chan.send(reports);
|
reports_chan.send(reports);
|
||||||
},
|
},
|
||||||
|
Response(mediator) => {
|
||||||
|
let _ = mediator.response_chan.send(None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +288,7 @@ impl ServiceWorkerGlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_event(&self, msg: CommonScriptMsg) {
|
pub fn process_event(&self, msg: CommonScriptMsg) {
|
||||||
self.handle_script_event(WorkerScriptMsg::Common(msg));
|
self.handle_script_event(ServiceWorkerScriptMsg::CommonWorker(WorkerScriptMsg::Common(msg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,16 @@
|
||||||
//! active_workers map
|
//! active_workers map
|
||||||
|
|
||||||
use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
|
use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
|
||||||
use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
|
use dom::serviceworkerglobalscope::{ServiceWorkerGlobalScope, ServiceWorkerScriptMsg};
|
||||||
use dom::serviceworkerregistration::longest_prefix_match;
|
use dom::serviceworkerregistration::longest_prefix_match;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use net_traits::{CustomResponseMediator, CoreResourceMsg};
|
use net_traits::{CustomResponseMediator, CoreResourceMsg};
|
||||||
use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders};
|
use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::mpsc::{channel, Receiver, RecvError};
|
use std::sync::mpsc::{channel, Sender, Receiver, RecvError};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use util::prefs::PREFS;
|
||||||
use util::thread::spawn_named;
|
use util::thread::spawn_named;
|
||||||
|
|
||||||
enum Message {
|
enum Message {
|
||||||
|
@ -62,7 +63,7 @@ impl ServiceWorkerManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_activation(&mut self, load_url: &Url) {
|
pub fn prepare_activation(&mut self, load_url: &Url) -> Option<Sender<ServiceWorkerScriptMsg>> {
|
||||||
let mut scope_url = None;
|
let mut scope_url = None;
|
||||||
for scope in self.registered_workers.keys() {
|
for scope in self.registered_workers.keys() {
|
||||||
if longest_prefix_match(&scope, load_url) {
|
if longest_prefix_match(&scope, load_url) {
|
||||||
|
@ -75,7 +76,7 @@ impl ServiceWorkerManager {
|
||||||
if self.active_workers.contains_key(&scope_url) {
|
if self.active_workers.contains_key(&scope_url) {
|
||||||
// do not run the same worker if already active.
|
// do not run the same worker if already active.
|
||||||
warn!("Service worker for {:?} already active", scope_url);
|
warn!("Service worker for {:?} already active", scope_url);
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
let scope_things = self.registered_workers.get(&scope_url);
|
let scope_things = self.registered_workers.get(&scope_url);
|
||||||
if let Some(scope_things) = scope_things {
|
if let Some(scope_things) = scope_things {
|
||||||
|
@ -93,17 +94,19 @@ impl ServiceWorkerManager {
|
||||||
page_info));
|
page_info));
|
||||||
};
|
};
|
||||||
ServiceWorkerGlobalScope::run_serviceworker_scope(scope_things.clone(),
|
ServiceWorkerGlobalScope::run_serviceworker_scope(scope_things.clone(),
|
||||||
sender,
|
sender.clone(),
|
||||||
receiver,
|
receiver,
|
||||||
devtools_receiver,
|
devtools_receiver,
|
||||||
self.own_sender.clone(),
|
self.own_sender.clone(),
|
||||||
scope_url.clone());
|
scope_url.clone());
|
||||||
// We store the activated worker
|
// We store the activated worker
|
||||||
self.active_workers.insert(scope_url.clone(), scope_things.clone());
|
self.active_workers.insert(scope_url.clone(), scope_things.clone());
|
||||||
|
return Some(sender);
|
||||||
} else {
|
} else {
|
||||||
warn!("Unable to activate service worker");
|
warn!("Unable to activate service worker");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_message(&mut self) {
|
fn handle_message(&mut self) {
|
||||||
|
@ -146,11 +149,14 @@ impl ServiceWorkerManager {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn handle_message_from_resource(&mut self, mediator: CustomResponseMediator) -> bool {
|
fn handle_message_from_resource(&mut self, mediator: CustomResponseMediator) -> bool {
|
||||||
self.prepare_activation(&mediator.load_url);
|
if serviceworker_enabled() {
|
||||||
// TODO XXXcreativcoder This mediator will need to be send to the appropriate service worker
|
let worker_sender = self.prepare_activation(&mediator.load_url);
|
||||||
// so that it may do the sending of custom responses.
|
if let Some(ref sender) = worker_sender {
|
||||||
// For now we just send a None from here itself
|
let _ = sender.send(ServiceWorkerScriptMsg::Response(mediator));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let _ = mediator.response_chan.send(None);
|
let _ = mediator.response_chan.send(None);
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,3 +170,7 @@ impl ServiceWorkerManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn serviceworker_enabled() -> bool {
|
||||||
|
PREFS.get("dom.serviceworker.enabled").as_boolean().unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue