Add aborted flag to response, set when fetch is aborted

This commit is contained in:
Manish Goregaokar 2017-11-20 17:02:31 -08:00
parent 7249fd6bd8
commit 6f59b152f1
3 changed files with 21 additions and 8 deletions

View file

@ -37,6 +37,7 @@ pub type Target<'a> = &'a mut (FetchTaskTarget + Send);
pub enum Data { pub enum Data {
Payload(Vec<u8>), Payload(Vec<u8>),
Done, Done,
Cancelled,
} }
pub struct FetchContext { pub struct FetchContext {
@ -347,7 +348,7 @@ pub fn main_fetch(request: &mut Request,
}; };
// Execute deferred rebinding of response. // Execute deferred rebinding of response.
let response = if let Some(error) = internal_error { let mut response = if let Some(error) = internal_error {
Response::network_error(error) Response::network_error(error)
} else { } else {
response response
@ -355,9 +356,9 @@ pub fn main_fetch(request: &mut Request,
// Step 19. // Step 19.
let mut response_loaded = false; let mut response_loaded = false;
let response = if !response.is_network_error() && !request.integrity_metadata.is_empty() { let mut response = if !response.is_network_error() && !request.integrity_metadata.is_empty() {
// Step 19.1. // Step 19.1.
wait_for_response(&response, target, done_chan); wait_for_response(&mut response, target, done_chan);
response_loaded = true; response_loaded = true;
// Step 19.2. // Step 19.2.
@ -376,9 +377,9 @@ pub fn main_fetch(request: &mut Request,
if request.synchronous { if request.synchronous {
// 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(&mut response);
if !response_loaded { if !response_loaded {
wait_for_response(&response, target, done_chan); wait_for_response(&mut response, target, done_chan);
} }
// overloaded similarly to process_response // overloaded similarly to process_response
target.process_response_eof(&response); target.process_response_eof(&response);
@ -400,7 +401,7 @@ pub fn main_fetch(request: &mut Request,
// Step 23. // Step 23.
if !response_loaded { if !response_loaded {
wait_for_response(&response, target, done_chan); wait_for_response(&mut response, target, done_chan);
} }
// Step 24. // Step 24.
@ -411,7 +412,7 @@ pub fn main_fetch(request: &mut Request,
response response
} }
fn wait_for_response(response: &Response, target: Target, done_chan: &mut DoneChannel) { fn wait_for_response(response: &mut Response, target: Target, done_chan: &mut DoneChannel) {
if let Some(ref ch) = *done_chan { if let Some(ref ch) = *done_chan {
loop { loop {
match ch.1.recv() match ch.1.recv()
@ -420,6 +421,10 @@ fn wait_for_response(response: &Response, target: Target, done_chan: &mut DoneCh
target.process_response_chunk(vec); target.process_response_chunk(vec);
}, },
Data::Done => break, Data::Done => break,
Data::Cancelled => {
response.aborted = true;
break;
}
} }
} }
} else { } else {

View file

@ -1088,6 +1088,9 @@ fn http_network_fetch(request: &Request,
let meta_status = meta.status.clone(); let meta_status = meta.status.clone();
let meta_headers = meta.headers.clone(); let meta_headers = meta.headers.clone();
let cancellation_listener = context.cancellation_listener.clone(); let cancellation_listener = context.cancellation_listener.clone();
if cancellation_listener.lock().unwrap().cancelled() {
return Response::network_error(NetworkError::Internal("Fetch aborted".into()))
}
thread::Builder::new().name(format!("fetch worker thread")).spawn(move || { thread::Builder::new().name(format!("fetch worker thread")).spawn(move || {
match StreamedResponse::from_http_response(res) { match StreamedResponse::from_http_response(res) {
Ok(mut res) => { Ok(mut res) => {
@ -1112,7 +1115,7 @@ fn http_network_fetch(request: &Request,
loop { loop {
if cancellation_listener.lock().unwrap().cancelled() { if cancellation_listener.lock().unwrap().cancelled() {
*res_body.lock().unwrap() = ResponseBody::Done(vec![]); *res_body.lock().unwrap() = ResponseBody::Done(vec![]);
let _ = done_sender.send(Data::Done); let _ = done_sender.send(Data::Cancelled);
return; return;
} }
match read_block(&mut res) { match read_block(&mut res) {
@ -1134,6 +1137,7 @@ fn http_network_fetch(request: &Request,
let _ = done_sender.send(Data::Done); let _ = done_sender.send(Data::Done);
break; break;
} }
Ok(Data::Cancelled) => unreachable!() // read_block doesn't return Data::Cancelled
} }
} }
} }

View file

@ -112,6 +112,8 @@ pub struct Response {
pub internal_response: Option<Box<Response>>, pub internal_response: Option<Box<Response>>,
/// whether or not to try to return the internal_response when asked for actual_response /// whether or not to try to return the internal_response when asked for actual_response
pub return_internal: bool, pub return_internal: bool,
/// https://fetch.spec.whatwg.org/#concept-response-aborted
pub aborted: bool,
} }
impl Response { impl Response {
@ -133,6 +135,7 @@ impl Response {
location_url: None, location_url: None,
internal_response: None, internal_response: None,
return_internal: true, return_internal: true,
aborted: false,
} }
} }
@ -162,6 +165,7 @@ impl Response {
location_url: None, location_url: None,
internal_response: None, internal_response: None,
return_internal: true, return_internal: true,
aborted: false,
} }
} }