Make the fetch target non-optional.

This commit is contained in:
Ms2ger 2016-12-02 15:49:41 +01:00
parent 6f2606cdee
commit 217f44b67a
4 changed files with 32 additions and 49 deletions

View file

@ -25,7 +25,7 @@ use std::mem;
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc::{Sender, Receiver};
pub type Target = Option<Box<FetchTaskTarget + Send>>; pub type Target<'a> = &'a mut (FetchTaskTarget + Send);
pub enum Data { pub enum Data {
Payload(Vec<u8>), Payload(Vec<u8>),
@ -43,7 +43,7 @@ pub type DoneChannel = Option<(Sender<Data>, Receiver<Data>)>;
/// [Fetch](https://fetch.spec.whatwg.org#concept-fetch) /// [Fetch](https://fetch.spec.whatwg.org#concept-fetch)
pub fn fetch(request: Rc<Request>, pub fn fetch(request: Rc<Request>,
target: &mut Target, target: Target,
context: &FetchContext) context: &FetchContext)
-> Response { -> Response {
fetch_with_cors_cache(request, &mut CorsCache::new(), target, context) fetch_with_cors_cache(request, &mut CorsCache::new(), target, context)
@ -51,7 +51,7 @@ pub fn fetch(request: Rc<Request>,
pub fn fetch_with_cors_cache(request: Rc<Request>, pub fn fetch_with_cors_cache(request: Rc<Request>,
cache: &mut CorsCache, cache: &mut CorsCache,
target: &mut Target, target: Target,
context: &FetchContext) context: &FetchContext)
-> Response { -> Response {
// Step 1 // Step 1
@ -120,7 +120,7 @@ pub fn main_fetch(request: Rc<Request>,
cache: &mut CorsCache, cache: &mut CorsCache,
cors_flag: bool, cors_flag: bool,
recursive_flag: bool, recursive_flag: bool,
target: &mut Target, target: Target,
done_chan: &mut DoneChannel, done_chan: &mut DoneChannel,
context: &FetchContext) context: &FetchContext)
-> Response { -> Response {
@ -297,20 +297,16 @@ pub fn main_fetch(request: Rc<Request>,
// Step 19 // Step 19
if request.synchronous { if request.synchronous {
if let Some(ref mut target) = *target { // process_response is not supposed to be used
// process_response is not supposed to be used // by sync fetch, but we overload it here for simplicity
// by sync fetch, but we overload it here for simplicity target.process_response(&response);
target.process_response(&response);
}
if let Some(ref ch) = *done_chan { if let Some(ref ch) = *done_chan {
loop { loop {
match ch.1.recv() match ch.1.recv()
.expect("fetch worker should always send Done before terminating") { .expect("fetch worker should always send Done before terminating") {
Data::Payload(vec) => { Data::Payload(vec) => {
if let Some(ref mut target) = *target { target.process_response_chunk(vec);
target.process_response_chunk(vec);
}
} }
Data::Done => break, Data::Done => break,
} }
@ -321,37 +317,29 @@ pub fn main_fetch(request: Rc<Request>,
// in case there was no channel to wait for, the body was // in case there was no channel to wait for, the body was
// obtained synchronously via basic_fetch for data/file/about/etc // obtained synchronously via basic_fetch for data/file/about/etc
// We should still send the body across as a chunk // We should still send the body across as a chunk
if let Some(ref mut target) = *target { target.process_response_chunk(vec.clone());
target.process_response_chunk(vec.clone());
}
} else { } else {
assert!(*body == ResponseBody::Empty) assert!(*body == ResponseBody::Empty)
} }
} }
// overloaded similarly to process_response // overloaded similarly to process_response
if let Some(ref mut target) = *target { target.process_response_eof(&response);
target.process_response_eof(&response);
}
return response; return response;
} }
// Step 20 // Step 20
if request.body.borrow().is_some() && matches!(request.current_url().scheme(), "http" | "https") { if request.body.borrow().is_some() && matches!(request.current_url().scheme(), "http" | "https") {
if let Some(ref mut target) = *target { // XXXManishearth: We actually should be calling process_request
// XXXManishearth: We actually should be calling process_request // in http_network_fetch. However, we can't yet follow the request
// in http_network_fetch. However, we can't yet follow the request // upload progress, so I'm keeping it here for now and pretending
// upload progress, so I'm keeping it here for now and pretending // the body got sent in one chunk
// the body got sent in one chunk target.process_request_body(&request);
target.process_request_body(&request); target.process_request_eof(&request);
target.process_request_eof(&request);
}
} }
// Step 21 // Step 21
if let Some(ref mut target) = *target { target.process_response(&response);
target.process_response(&response);
}
// Step 22 // Step 22
if let Some(ref ch) = *done_chan { if let Some(ref ch) = *done_chan {
@ -359,14 +347,12 @@ pub fn main_fetch(request: Rc<Request>,
match ch.1.recv() match ch.1.recv()
.expect("fetch worker should always send Done before terminating") { .expect("fetch worker should always send Done before terminating") {
Data::Payload(vec) => { Data::Payload(vec) => {
if let Some(ref mut target) = *target { target.process_response_chunk(vec);
target.process_response_chunk(vec);
}
} }
Data::Done => break, Data::Done => break,
} }
} }
} else if let Some(ref mut target) = *target { } else {
let body = response.body.lock().unwrap(); let body = response.body.lock().unwrap();
if let ResponseBody::Done(ref vec) = *body { if let ResponseBody::Done(ref vec) = *body {
// in case there was no channel to wait for, the body was // in case there was no channel to wait for, the body was
@ -379,9 +365,7 @@ pub fn main_fetch(request: Rc<Request>,
} }
// Step 24 // Step 24
if let Some(ref mut target) = *target { target.process_response_eof(&response);
target.process_response_eof(&response);
}
// TODO remove this line when only asynchronous fetches are used // TODO remove this line when only asynchronous fetches are used
return response; return response;
@ -390,7 +374,7 @@ pub fn main_fetch(request: Rc<Request>,
/// [Basic fetch](https://fetch.spec.whatwg.org#basic-fetch) /// [Basic fetch](https://fetch.spec.whatwg.org#basic-fetch)
fn basic_fetch(request: Rc<Request>, fn basic_fetch(request: Rc<Request>,
cache: &mut CorsCache, cache: &mut CorsCache,
target: &mut Target, target: Target,
done_chan: &mut DoneChannel, done_chan: &mut DoneChannel,
context: &FetchContext) context: &FetchContext)
-> Response { -> Response {

View file

@ -533,7 +533,7 @@ pub fn http_fetch(request: Rc<Request>,
cors_flag: bool, cors_flag: bool,
cors_preflight_flag: bool, cors_preflight_flag: bool,
authentication_fetch_flag: bool, authentication_fetch_flag: bool,
target: &mut Target, target: Target,
done_chan: &mut DoneChannel, done_chan: &mut DoneChannel,
context: &FetchContext) context: &FetchContext)
-> Response { -> Response {
@ -707,7 +707,7 @@ fn http_redirect_fetch(request: Rc<Request>,
cache: &mut CorsCache, cache: &mut CorsCache,
response: Response, response: Response,
cors_flag: bool, cors_flag: bool,
target: &mut Target, target: Target,
done_chan: &mut DoneChannel, done_chan: &mut DoneChannel,
context: &FetchContext) context: &FetchContext)
-> Response { -> Response {

View file

@ -18,7 +18,7 @@ use hyper::header::{Header, SetCookie};
use hyper_serde::Serde; use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender}; use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender};
use net_traits::{CookieSource, CoreResourceThread}; use net_traits::{CookieSource, CoreResourceThread};
use net_traits::{CoreResourceMsg, FetchResponseMsg, FetchTaskTarget}; use net_traits::{CoreResourceMsg, FetchResponseMsg};
use net_traits::{CustomResponseMediator, ResourceId}; use net_traits::{CustomResponseMediator, ResourceId};
use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData}; use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData};
use net_traits::request::{Request, RequestInit}; use net_traits::request::{Request, RequestInit};
@ -332,7 +332,7 @@ impl CoreResourceManager {
fn fetch(&self, fn fetch(&self,
init: RequestInit, init: RequestInit,
sender: IpcSender<FetchResponseMsg>, mut sender: IpcSender<FetchResponseMsg>,
group: &ResourceGroup) { group: &ResourceGroup) {
let http_state = HttpState { let http_state = HttpState {
hsts_list: group.hsts_list.clone(), hsts_list: group.hsts_list.clone(),
@ -349,14 +349,13 @@ impl CoreResourceManager {
// todo load context / mimesniff in fetch // todo load context / mimesniff in fetch
// todo referrer policy? // todo referrer policy?
// todo service worker stuff // todo service worker stuff
let mut target = Some(Box::new(sender) as Box<FetchTaskTarget + Send + 'static>);
let context = FetchContext { let context = FetchContext {
state: http_state, state: http_state,
user_agent: ua, user_agent: ua,
devtools_chan: dc, devtools_chan: dc,
filemanager: filemanager, filemanager: filemanager,
}; };
fetch(Rc::new(request), &mut target, &context); fetch(Rc::new(request), &mut sender, &context);
}).expect("Thread spawning failed"); }).expect("Thread spawning failed");
} }

View file

@ -78,22 +78,22 @@ fn fetch(request: Request, dc: Option<Sender<DevtoolsControlMsg>>) -> Response {
fn fetch_with_context(request: Request, context: &FetchContext) -> Response { fn fetch_with_context(request: Request, context: &FetchContext) -> Response {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let target = Box::new(FetchResponseCollector { let mut target = FetchResponseCollector {
sender: sender, sender: sender,
}); };
methods::fetch(Rc::new(request), &mut Some(target), context); methods::fetch(Rc::new(request), &mut target, context);
receiver.recv().unwrap() receiver.recv().unwrap()
} }
fn fetch_with_cors_cache(request: Rc<Request>, cache: &mut CorsCache) -> Response { fn fetch_with_cors_cache(request: Rc<Request>, cache: &mut CorsCache) -> Response {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let target = Box::new(FetchResponseCollector { let mut target = FetchResponseCollector {
sender: sender, sender: sender,
}); };
methods::fetch_with_cors_cache(request, cache, &mut Some(target), &new_fetch_context(None)); methods::fetch_with_cors_cache(request, cache, &mut target, &new_fetch_context(None));
receiver.recv().unwrap() receiver.recv().unwrap()
} }