aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/cors.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2015-03-05 10:34:30 -0500
committerJosh Matthews <josh@joshmatthews.net>2015-04-16 11:46:41 -0400
commit1ca9ff56c8de01056ffaf31d6173e893b6567d46 (patch)
treebde7c854431467097df623e6a86f05576524b8b7 /components/script/cors.rs
parentf7ac1f1876bbf139bcf7a32ba6d8a602a8269345 (diff)
downloadservo-1ca9ff56c8de01056ffaf31d6173e893b6567d46.tar.gz
servo-1ca9ff56c8de01056ffaf31d6173e893b6567d46.zip
Create easy common interface for off-thread network listeners, and remove the CORS-specific reimplementation of async networking.
Diffstat (limited to 'components/script/cors.rs')
-rw-r--r--components/script/cors.rs51
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(())));
});
}