aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-06-01 17:18:11 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-06-10 20:53:23 +0530
commit5e49873af7bfe7190afa98a8d6bee08582213fb1 (patch)
tree9a2b2e8da9dbf650baa62aa16a647cadc11c08f8 /components/script/dom
parentd4f428ad9559f7d5f338e565e7f5d5efab70f67f (diff)
downloadservo-5e49873af7bfe7190afa98a8d6bee08582213fb1.tar.gz
servo-5e49873af7bfe7190afa98a8d6bee08582213fb1.zip
Hook XHR up to fetch
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/xmlhttprequest.rs189
1 files changed, 42 insertions, 147 deletions
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 3cb74ec282c..400549dc714 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use cors::CORSResponse;
-use cors::{AsyncCORSResponseListener, CORSRequest, RequestMode, allow_cross_origin_request};
use document_loader::DocumentLoader;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
@@ -45,17 +43,17 @@ use js::jsapi::JS_ClearPendingException;
use js::jsapi::{JSContext, JS_ParseJSON, RootedValue};
use js::jsval::{JSVal, NullValue, UndefinedValue};
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
-use net_traits::CoreResourceMsg::Load;
+use net_traits::CoreResourceMsg::Fetch;
use net_traits::trim_http_whitespace;
-use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError, RequestSource};
-use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread, LoadOrigin};
+use net_traits::{FetchResponseListener, Metadata, NetworkError, RequestSource};
+use net_traits::{LoadContext, LoadData, CoreResourceThread, LoadOrigin};
use network_listener::{NetworkListener, PreInvoke};
use parse::html::{ParseContext, parse_html};
use parse::xml::{self, parse_xml};
use script_runtime::ScriptChan;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
use std::default::Default;
use std::str;
use std::sync::{Arc, Mutex};
@@ -63,7 +61,6 @@ use string_cache::Atom;
use time;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::{Url, Position};
-use util::prefs::mozbrowser_enabled;
#[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)]
enum XMLHttpRequestState {
@@ -82,7 +79,6 @@ pub struct GenerationId(u32);
struct XHRContext {
xhr: TrustedXHRAddress,
gen_id: GenerationId,
- cors_request: Option<CORSRequest>,
buf: DOMRefCell<Vec<u8>>,
sync_status: DOMRefCell<Option<ErrorResult>>,
}
@@ -216,75 +212,42 @@ impl XMLHttpRequest {
}
}
- fn check_cors(context: Arc<Mutex<XHRContext>>,
- load_data: LoadData,
- req: CORSRequest,
- script_chan: Box<ScriptChan + Send>,
- core_resource_thread: CoreResourceThread) {
- struct CORSContext {
- xhr: Arc<Mutex<XHRContext>>,
- load_data: RefCell<Option<LoadData>>,
- req: CORSRequest,
- script_chan: Box<ScriptChan + Send>,
- core_resource_thread: CoreResourceThread,
- }
-
- impl AsyncCORSResponseListener for CORSContext {
- fn response_available(&self, response: CORSResponse) {
- if response.network_error {
- let mut context = self.xhr.lock().unwrap();
- let xhr = context.xhr.root();
- xhr.process_partial_response(XHRProgress::Errored(context.gen_id, Error::Network));
- *context.sync_status.borrow_mut() = Some(Err(Error::Network));
- return;
- }
-
- let mut load_data = self.load_data.borrow_mut().take().unwrap();
- load_data.cors = Some(ResourceCORSData {
- preflight: self.req.preflight_flag,
- origin: self.req.origin.clone()
- });
-
- XMLHttpRequest::initiate_async_xhr(self.xhr.clone(), self.script_chan.clone(),
- self.core_resource_thread.clone(), load_data);
- }
- }
-
- let cors_context = CORSContext {
- xhr: context,
- load_data: RefCell::new(Some(load_data)),
- req: req.clone(),
- script_chan: script_chan.clone(),
- core_resource_thread: core_resource_thread,
- };
-
- req.http_fetch_async(box cors_context, script_chan);
- }
-
fn initiate_async_xhr(context: Arc<Mutex<XHRContext>>,
script_chan: Box<ScriptChan + Send>,
core_resource_thread: CoreResourceThread,
load_data: LoadData) {
- impl AsyncResponseListener for XHRContext {
- fn headers_available(&mut self, metadata: Result<Metadata, NetworkError>) {
- let xhr = self.xhr.root();
- let rv = xhr.process_headers_available(self.cors_request.clone(),
- self.gen_id,
- metadata);
- if rv.is_err() {
- *self.sync_status.borrow_mut() = Some(rv);
+ impl FetchResponseListener for XHRContext {
+ fn process_request_body(&mut self) {
+ // todo
+ }
+ fn process_request_eof(&mut self) {
+ // todo
+ }
+ fn process_response(&mut self, metadata: Result<Metadata, NetworkError>) {
+ let xhr = self.xhr.root();
+ let rv = xhr.process_headers_available(self.gen_id,
+ metadata);
+ if rv.is_err() {
+ *self.sync_status.borrow_mut() = Some(rv);
+ }
+ }
+ fn process_response_eof(&mut self, response: Result<Vec<u8>, NetworkError>) {
+ match response {
+ Ok(buf) => {
+ *self.buf.borrow_mut() = buf;
+ // todo move to a process_chunk
+ self.xhr.root().process_data_available(self.gen_id, self.buf.borrow().clone());
+ let rv = self.xhr.root().process_response_complete(self.gen_id, Ok(()));
+ *self.sync_status.borrow_mut() = Some(rv);
+ }
+ Err(e) => {
+ let rv = self.xhr.root().process_response_complete(self.gen_id, Err(e));
+ *self.sync_status.borrow_mut() = Some(rv);
+ }
+ }
+
+
}
- }
-
- fn data_available(&mut self, payload: Vec<u8>) {
- self.buf.borrow_mut().extend_from_slice(&payload);
- self.xhr.root().process_data_available(self.gen_id, self.buf.borrow().clone());
- }
-
- fn response_complete(&mut self, status: Result<(), NetworkError>) {
- let rv = self.xhr.root().process_response_complete(self.gen_id, status);
- *self.sync_status.borrow_mut() = Some(rv);
- }
}
impl PreInvoke for XHRContext {
@@ -298,13 +261,10 @@ impl XMLHttpRequest {
context: context,
script_chan: script_chan,
};
- let response_target = AsyncResponseTarget {
- sender: action_sender,
- };
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
- listener.notify_action(message.to().unwrap());
+ listener.notify_fetch(message.to().unwrap());
});
- core_resource_thread.send(Load(load_data, LoadConsumer::Listener(response_target), None)).unwrap();
+ core_resource_thread.send(Fetch(load_data, action_sender)).unwrap();
}
}
@@ -637,34 +597,13 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// CORS stuff
let global = self.global();
- let referer_url = self.global().r().get_url();
- let mode = if self.upload_events.get() {
- RequestMode::ForcedPreflight
- } else {
- RequestMode::CORS
- };
let mut combined_headers = load_data.headers.clone();
combined_headers.extend(load_data.preserved_headers.iter());
- let cors_request = CORSRequest::maybe_new(referer_url.clone(),
- load_data.url.clone(),
- mode,
- load_data.method.clone(),
- combined_headers,
- true);
- match cors_request {
- Ok(None) => {
- let bytes = referer_url[..Position::AfterPath].as_bytes().to_vec();
- self.request_headers.borrow_mut().set_raw("Referer".to_owned(), vec![bytes]);
- },
- Ok(Some(ref req)) => self.insert_trusted_header("origin".to_owned(),
- req.origin.to_string()),
- _ => {}
- }
debug!("request_headers = {:?}", *self.request_headers.borrow());
self.fetch_time.set(time::now().to_timespec().sec);
- let rv = self.fetch(load_data, cors_request, global.r());
+ let rv = self.fetch(load_data, global.r());
// Step 10
if self.sync.get() {
return rv;
@@ -879,7 +818,7 @@ impl XMLHttpRequest {
event.fire(self.upcast());
}
- fn process_headers_available(&self, cors_request: Option<CORSRequest>,
+ fn process_headers_available(&self,
gen_id: GenerationId, metadata: Result<Metadata, NetworkError>)
-> Result<(), Error> {
let metadata = match metadata {
@@ -890,34 +829,7 @@ impl XMLHttpRequest {
},
};
- let bypass_cross_origin_check = {
- // We want to be able to do cross-origin requests in browser.html.
- // If the XHR happens in a top level window and the mozbrowser
- // preference is enabled, we allow bypassing the CORS check.
- // This is a temporary measure until we figure out Servo privilege
- // story. See https://github.com/servo/servo/issues/9582
- if let GlobalRoot::Window(win) = self.global() {
- let is_root_pipeline = win.parent_info().is_none();
- let is_mozbrowser_enabled = mozbrowser_enabled();
- is_root_pipeline && is_mozbrowser_enabled
- } else {
- false
- }
- };
-
- if !bypass_cross_origin_check {
- if let Some(ref req) = cors_request {
- match metadata.headers {
- Some(ref h) if allow_cross_origin_request(req, h) => {},
- _ => {
- self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
- return Err(Error::Network);
- }
- }
- }
- } else {
- debug!("Bypassing cross origin check");
- }
+ // todo allow cors in mozbrowser
*self.response_url.borrow_mut() = metadata.final_url[..Position::AfterQuery].to_owned();
@@ -1319,24 +1231,12 @@ impl XMLHttpRequest {
fn fetch(&self,
load_data: LoadData,
- cors_request: Result<Option<CORSRequest>, ()>,
global: GlobalRef) -> ErrorResult {
- let cors_request = match cors_request {
- Err(_) => {
- // Happens in case of unsupported cross-origin URI schemes.
- // Supported schemes are http, https, data, and about.
- self.process_partial_response(XHRProgress::Errored(
- self.generation_id.get(), Error::Network));
- return Err(Error::Network);
- }
- Ok(req) => req,
- };
let xhr = Trusted::new(self);
let context = Arc::new(Mutex::new(XHRContext {
xhr: xhr,
- cors_request: cors_request.clone(),
gen_id: self.generation_id.get(),
buf: DOMRefCell::new(vec!()),
sync_status: DOMRefCell::new(None),
@@ -1350,13 +1250,8 @@ impl XMLHttpRequest {
};
let core_resource_thread = global.core_resource_thread();
- if let Some(req) = cors_request {
- XMLHttpRequest::check_cors(context.clone(), load_data, req.clone(),
- script_chan.clone(), core_resource_thread);
- } else {
- XMLHttpRequest::initiate_async_xhr(context.clone(), script_chan,
- core_resource_thread, load_data);
- }
+ XMLHttpRequest::initiate_async_xhr(context.clone(), script_chan,
+ core_resource_thread, load_data);
if let Some(script_port) = script_port {
loop {