diff options
Diffstat (limited to 'components/script/cors.rs')
-rw-r--r-- | components/script/cors.rs | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/components/script/cors.rs b/components/script/cors.rs index 0b669ab8bf8..235ec43f779 100644 --- a/components/script/cors.rs +++ b/components/script/cors.rs @@ -9,8 +9,14 @@ //! This library will eventually become the core of the Fetch crate //! with CORSRequest being expanded into FetchRequest (etc) +use network_listener::{NetworkListener, PreInvoke}; +use script_task::ScriptChan; +use net_traits::{AsyncResponseTarget, AsyncResponseListener, ResponseAction, Metadata}; + use std::ascii::AsciiExt; use std::borrow::ToOwned; +use std::cell::RefCell; +use std::sync::{Arc, Mutex}; use time; use time::{now, Timespec}; @@ -27,14 +33,12 @@ use hyper::status::StatusClass::Success; use url::{SchemeData, Url}; use util::task::spawn_named; +/// Interface for network listeners concerned with CORS checks. Proper network requests +/// should be initiated from this method, based on the response provided. pub trait AsyncCORSResponseListener { fn response_available(&self, response: CORSResponse); } -pub trait AsyncCORSResponseTarget { - fn invoke_with_listener(&self, response: CORSResponse); -} - #[derive(Clone)] pub struct CORSRequest { pub origin: Url, @@ -98,13 +102,48 @@ impl CORSRequest { } } - pub fn http_fetch_async(&self, listener: Box<AsyncCORSResponseTarget + Send>) { + pub fn http_fetch_async(&self, + listener: Box<AsyncCORSResponseListener+Send>, + script_chan: Box<ScriptChan+Send>) { + struct CORSContext { + listener: Box<AsyncCORSResponseListener+Send>, + response: RefCell<Option<CORSResponse>>, + } + + // This is shoe-horning the CORSReponse stuff into the rest of the async network + // framework right now. It would be worth redesigning http_fetch to do this properly. + impl AsyncResponseListener for CORSContext { + fn headers_available(&self, _metadata: Metadata) { + } + + fn data_available(&self, _payload: Vec<u8>) { + } + + fn response_complete(&self, _status: Result<(), String>) { + let response = self.response.borrow_mut().take().unwrap(); + self.listener.response_available(response); + } + } + impl PreInvoke for CORSContext {} + + let context = CORSContext { + listener: listener, + response: RefCell::new(None), + }; + let listener = NetworkListener { + context: Arc::new(Mutex::new(context)), + script_chan: script_chan, + }; + // TODO: this exists only to make preflight check non-blocking // perhaps should be handled by the resource task? let req = self.clone(); spawn_named("cors".to_owned(), move || { let response = req.http_fetch(); - listener.invoke_with_listener(response); + let mut context = listener.context.lock(); + let context = context.as_mut().unwrap(); + *context.response.borrow_mut() = Some(response); + listener.invoke_with_listener(ResponseAction::ResponseComplete(Ok(()))); }); } |