mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #19274 - Manishearth:xhr-cancel, r=jdm
Fetch cancellation This PR implements cancellation for fetch, and uses it for XHR. This means that fetch clients can now send a message to the fetch task asking for the network request to be aborted. Previously, clients like XHR had abort functionality but would implement it by simply ignoring future messages from the network task; and would not actually cancel the network fetch. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19274) <!-- Reviewable:end -->
This commit is contained in:
commit
00b3612fe9
12 changed files with 98 additions and 31 deletions
|
@ -126,7 +126,7 @@ impl DocumentLoader {
|
|||
request: RequestInit,
|
||||
fetch_target: IpcSender<FetchResponseMsg>) {
|
||||
self.resource_threads.sender().send(
|
||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(fetch_target))).unwrap();
|
||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(fetch_target, None))).unwrap();
|
||||
}
|
||||
|
||||
/// Mark an in-progress network request complete.
|
||||
|
|
|
@ -491,7 +491,7 @@ impl EventSource {
|
|||
listener.notify_fetch(message.to().unwrap());
|
||||
}));
|
||||
global.core_resource_thread().send(
|
||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(action_sender))).unwrap();
|
||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(action_sender, None))).unwrap();
|
||||
// Step 13
|
||||
Ok(ev)
|
||||
}
|
||||
|
@ -555,6 +555,6 @@ impl EventSourceTimeoutCallback {
|
|||
}
|
||||
// Step 5.4
|
||||
global.core_resource_thread().send(
|
||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(self.action_sender))).unwrap();
|
||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(self.action_sender, None))).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,8 @@ pub struct XMLHttpRequest {
|
|||
response_status: Cell<Result<(), ()>>,
|
||||
referrer_url: Option<ServoUrl>,
|
||||
referrer_policy: Option<ReferrerPolicy>,
|
||||
#[ignore_malloc_size_of = "channels are hard"]
|
||||
cancellation_chan: DomRefCell<Option<ipc::IpcSender<()>>>,
|
||||
}
|
||||
|
||||
impl XMLHttpRequest {
|
||||
|
@ -198,6 +200,7 @@ impl XMLHttpRequest {
|
|||
response_status: Cell::new(Ok(())),
|
||||
referrer_url: referrer_url,
|
||||
referrer_policy: referrer_policy,
|
||||
cancellation_chan: DomRefCell::new(None),
|
||||
}
|
||||
}
|
||||
pub fn new(global: &GlobalScope) -> DomRoot<XMLHttpRequest> {
|
||||
|
@ -218,7 +221,8 @@ impl XMLHttpRequest {
|
|||
fn initiate_async_xhr(context: Arc<Mutex<XHRContext>>,
|
||||
task_source: NetworkingTaskSource,
|
||||
global: &GlobalScope,
|
||||
init: RequestInit) {
|
||||
init: RequestInit,
|
||||
cancellation_chan: ipc::IpcReceiver<()>) {
|
||||
impl FetchResponseListener for XHRContext {
|
||||
fn process_request_body(&mut self) {
|
||||
// todo
|
||||
|
@ -255,6 +259,7 @@ impl XMLHttpRequest {
|
|||
}
|
||||
|
||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||
|
||||
let listener = NetworkListener {
|
||||
context: context,
|
||||
task_source: task_source,
|
||||
|
@ -264,7 +269,7 @@ impl XMLHttpRequest {
|
|||
listener.notify_fetch(message.to().unwrap());
|
||||
}));
|
||||
global.core_resource_thread().send(
|
||||
Fetch(init, FetchChannels::ResponseMsg(action_sender))).unwrap();
|
||||
Fetch(init, FetchChannels::ResponseMsg(action_sender, Some(cancellation_chan)))).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1018,6 +1023,12 @@ impl XMLHttpRequest {
|
|||
}
|
||||
|
||||
fn terminate_ongoing_fetch(&self) {
|
||||
if let Some(ref cancel_chan) = *self.cancellation_chan.borrow() {
|
||||
// The receiver will be destroyed if the request has already completed;
|
||||
// so we throw away the error. Cancellation is a courtesy call,
|
||||
// we don't actually care if the other side heard.
|
||||
let _ = cancel_chan.send(());
|
||||
}
|
||||
let GenerationId(prev_id) = self.generation_id.get();
|
||||
self.generation_id.set(GenerationId(prev_id + 1));
|
||||
self.response_status.set(Ok(()));
|
||||
|
@ -1311,8 +1322,11 @@ impl XMLHttpRequest {
|
|||
(global.networking_task_source(), None)
|
||||
};
|
||||
|
||||
let (cancel_sender, cancel_receiver) = ipc::channel().unwrap();
|
||||
*self.cancellation_chan.borrow_mut() = Some(cancel_sender);
|
||||
|
||||
XMLHttpRequest::initiate_async_xhr(context.clone(), task_source,
|
||||
global, init);
|
||||
global, init, cancel_receiver);
|
||||
|
||||
if let Some(script_port) = script_port {
|
||||
loop {
|
||||
|
|
|
@ -109,7 +109,7 @@ pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: RootedTraceableBox<
|
|||
listener.notify_fetch(message.to().unwrap());
|
||||
}));
|
||||
core_resource_thread.send(
|
||||
NetTraitsFetch(request_init, FetchChannels::ResponseMsg(action_sender))).unwrap();
|
||||
NetTraitsFetch(request_init, FetchChannels::ResponseMsg(action_sender, None))).unwrap();
|
||||
|
||||
promise
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue