mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Make timeouts for async XHR post a runnable.
This commit is contained in:
parent
5c7be5c9c3
commit
17a88f1f81
1 changed files with 40 additions and 25 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue