Skip to content

Instantly share code, notes, and snippets.

@Manishearth
Created May 19, 2014 21:12
Show Gist options
  • Save Manishearth/ae1c1b5014e9d8e38d49 to your computer and use it in GitHub Desktop.
Save Manishearth/ae1c1b5014e9d8e38d49 to your computer and use it in GitHub Desktop.
enum SyncOrAsync<'a> {
Sync(&'a mut JSRef<'a, XMLHttpRequest>),
Async(TrustedXHRAddress)
}
...
impl XMLHttpRequest {
...
fn progress_syncorasync(sync: SyncOrAsync, msg: XHRProgress, script_chan: &ScriptChan) {
match sync {
Sync(ref mut xhr) => {
xhr.process_partial_response(msg);
},
Async(addr) => {
let ScriptChan(ref chan) = *script_chan;
chan.send(XHRProgressMsg(addr, msg));
}
}
}
fn fetch(sync: SyncOrAsync, resource_task: ResourceTask, url: Url, script_chan: ScriptChan) -> ErrorResult {
// Step 10, 13
let (start_chan, start_port) = channel();
resource_task.send(Load(url, start_chan));
let response = start_port.recv();
XMLHttpRequest::progress_syncorasync(sync, HeadersReceivedMsg(response.metadata.headers.clone()), &script_chan);
let mut buf = vec!();
loop {
match response.progress_port.recv() {
Payload(data) => {
buf.push_all(data.as_slice());
XMLHttpRequest::progress_syncorasync(sync, LoadingMsg(ByteString::new(buf.clone())), &script_chan);
},
Done(Ok(())) => {
XMLHttpRequest::progress_syncorasync(sync, DoneMsg, &script_chan);
match sync {
Async(_) => XMLHttpRequest::progress_syncorasync(sync, ReleaseMsg, &script_chan),
_ => {}
}
return Ok(());
},
Done(Err(_)) => {
XMLHttpRequest::progress_syncorasync(sync, ErroredMsg, &script_chan);
match sync {
Async(_) => XMLHttpRequest::progress_syncorasync(sync, ReleaseMsg, &script_chan),
_ => {}
}
return Err(Network)
}
}
}
}
...
impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
...
fn Send(&mut self, data: Option<DOMString>) -> ErrorResult {
// XXXManishearth handle POSTdata, and headers
if self.ready_state != Opened || self.send_flag {
return Err(InvalidState); // Step 1, 2
}
let data = match self.request_method.to_lower().as_str() {
Some("get") | Some("head") => None, // Step 3
_ => data
};
// Step 6
self.upload_complete = false;
self.upload_events = false;
// XXXManishearth handle upload events
// Step 9
self.send_flag = true;
let resource_task = self.global.root().page().resource_task.deref().clone();
let url = self.request_url.clone();
let script_chan = (&*self.global.root()).script_chan.clone();
if self.sync {
return XMLHttpRequest::fetch(Sync(self), resource_task, url, script_chan);
} else {
let mut builder = task::task().named("XHRTask");
unsafe {
let addr = self.to_trusted();
builder.spawn(proc() {
XMLHttpRequest::fetch(Async(addr), resource_task, url, script_chan);
})
}
}
Ok(())
}
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment