diff options
author | Josh Matthews <josh@joshmatthews.net> | 2015-03-04 15:20:31 -0500 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2015-04-16 11:46:40 -0400 |
commit | 17a88f1f815ad54364f3a86a9d23050312f35da7 (patch) | |
tree | 7de2e1a67344bd68705a6c92eed9ef9ad4bc31fd /components/script/dom/xmlhttprequest.rs | |
parent | 5c7be5c9c3f593fac14b9eec85b9d697528c78f4 (diff) | |
download | servo-17a88f1f815ad54364f3a86a9d23050312f35da7.tar.gz servo-17a88f1f815ad54364f3a86a9d23050312f35da7.zip |
Make timeouts for async XHR post a runnable.
Diffstat (limited to 'components/script/dom/xmlhttprequest.rs')
-rw-r--r-- | components/script/dom/xmlhttprequest.rs | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index ecc4c99c5d0..f757775ed44 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -218,7 +218,6 @@ impl XMLHttpRequest { #[allow(unsafe_code)] fn fetch2(xhr: TrustedXHRAddress, script_chan: Box<ScriptChan+Send>, resource_task: ResourceTask, load_data: LoadData, sync: bool, - terminate_receiver: Receiver<TerminateReason>, cors_request: Result<Option<CORSRequest>,()>, gen_id: GenerationId) { let cors_request = match cors_request { Err(_) => { @@ -229,13 +228,11 @@ impl XMLHttpRequest { Ok(req) => req, }; - #[derive(Clone)] struct XHRContext { xhr: TrustedXHRAddress, gen_id: GenerationId, cors_request: Option<CORSRequest>, buf: DOMRefCell<Vec<u8>>, - terminate_receiver: Arc<Mutex<Receiver<TerminateReason>>>, got_response_complete: Cell<bool>, } @@ -243,7 +240,6 @@ impl XMLHttpRequest { xhr: xhr, cors_request: cors_request.clone(), gen_id: gen_id, - terminate_receiver: Arc::new(Mutex::new(terminate_receiver)), buf: DOMRefCell::new(vec!()), got_response_complete: Cell::new(false), })); @@ -260,8 +256,10 @@ impl XMLHttpRequest { impl AsyncCORSResponseListener for CORSContext { fn response_available(&self, response: CORSResponse) { if response.network_error { - //notify_error_and_return!(Network); - return; //XXXjdm + let context = self.xhr.lock().unwrap(); + let xhr = context.xhr.to_temporary().root(); + xhr.r().process_partial_response(XHRProgress::Errored(context.gen_id, Network)); + return; //XXXjdm Err(Network) } let mut load_data = self.load_data.borrow_mut().take().unwrap(); @@ -348,27 +346,12 @@ impl XMLHttpRequest { fn handler(self: Box<XHRRunnable>) { let this = *self; - let context = this.context.lock(); - let context = context.unwrap(); + let context = this.context.lock().unwrap(); let xhr = context.xhr.to_temporary().root(); if xhr.r().generation_id.get() != context.gen_id { return; } - { - let terminate_receiver = context.terminate_receiver.lock().unwrap(); - if let Ok(reason) = terminate_receiver.try_recv() { - match reason { - TerminateReason::AbortedOrReopened => return, //Err(Abort) - TerminateReason::TimedOut => { - xhr.r().process_partial_response( - XHRProgress::Errored(context.gen_id, Network)); - return; //Err(Network) - } - } - } - } - this.action.process(&*context); } } @@ -856,7 +839,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { let addr = Trusted::new(self.global.root().r().get_cx(), self, script_chan.clone()); XMLHttpRequest::fetch2(addr, script_chan, resource_task, load_data, self.sync.get(), - terminate_receiver, cors_request, gen_id); + cors_request, gen_id); let timeout = self.timeout.get(); if timeout > 0 { self.set_timeout(timeout); @@ -1015,6 +998,7 @@ trait PrivateXMLHttpRequestHelpers { fn set_timeout(self, timeout:u32); fn cancel_timeout(self); fn filter_response_headers(self) -> Headers; + fn discard_subsequent_responses(self); } impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { @@ -1078,7 +1062,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { // Ignore message if it belongs to a terminated fetch return_if_fetch_was_terminated!(); - // Ignore messages coming from previously-errored responses + // Ignore messages coming from previously-errored responses or requests that have timed out if self.response_status.get().is_err() { return; } @@ -1134,6 +1118,8 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { self.ready_state.get() == XMLHttpRequestState::Loading || self.sync.get()); + self.cancel_timeout(); + // Part of step 11, send() (processing response end of file) // XXXManishearth handle errors, if any (substep 2) @@ -1149,7 +1135,9 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { self.dispatch_response_progress_event("loadend".to_owned()); }, XHRProgress::Errored(_, e) => { - self.response_status.set(Err(())); + self.cancel_timeout(); + + self.discard_subsequent_responses(); self.send_flag.set(false); // XXXManishearth set response to NetworkError self.change_ready_state(XMLHttpRequestState::Done); @@ -1222,14 +1210,37 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { self.dispatch_progress_event(false, type_, len, total); } fn set_timeout(self, timeout: u32) { + struct XHRTimeout { + xhr: TrustedXHRAddress, + gen_id: GenerationId, + } + + impl Runnable for XHRTimeout { + fn handler(self: Box<XHRTimeout>) { + let this = *self; + let xhr = this.xhr.to_temporary().root(); + if xhr.r().ready_state.get() != XMLHttpRequestState::Done { + xhr.r().process_partial_response(XHRProgress::Errored(this.gen_id, Timeout)); + } + } + } + // Sets up the object to timeout in a given number of milliseconds // This will cancel all previous timeouts let oneshot = self.timer.borrow_mut() .oneshot(Duration::milliseconds(timeout as i64)); let terminate_sender = (*self.terminate_sender.borrow()).clone(); + let global = self.global.root(); + let script_chan = global.r().script_chan(); + let xhr = Trusted::new(global.r().get_cx(), self, global.r().script_chan()); + let gen_id = self.generation_id.get(); spawn_named("XHR:Timer".to_owned(), move || { match oneshot.recv() { Ok(_) => { + script_chan.send(ScriptMsg::RunnableMsg(box XHRTimeout { + xhr: xhr, + gen_id: gen_id, + })).unwrap(); terminate_sender.map(|s| s.send(TerminateReason::TimedOut)); }, Err(_) => { @@ -1297,6 +1308,10 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { // XXXManishearth additional CORS filtering goes here headers } + + fn discard_subsequent_responses(self) { + self.response_status.set(Err(())); + } } trait Extractable { |