aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2017-11-20 17:02:31 -0800
committerManish Goregaokar <manishsmail@gmail.com>2017-11-20 17:04:55 -0800
commit6f59b152f1738ddecfbc1891bafd6f55c34992bc (patch)
tree1ffacc1e0e5413bc30b528debe4582dfc4261926
parent7249fd6bd82b70fa097ce2c66dc8bdb4bf023da8 (diff)
downloadservo-6f59b152f1738ddecfbc1891bafd6f55c34992bc.tar.gz
servo-6f59b152f1738ddecfbc1891bafd6f55c34992bc.zip
Add aborted flag to response, set when fetch is aborted
-rw-r--r--components/net/fetch/methods.rs19
-rw-r--r--components/net/http_loader.rs6
-rw-r--r--components/net_traits/response.rs4
3 files changed, 21 insertions, 8 deletions
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index f65c6c196f2..729435020a3 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -37,6 +37,7 @@ pub type Target<'a> = &'a mut (FetchTaskTarget + Send);
pub enum Data {
Payload(Vec<u8>),
Done,
+ Cancelled,
}
pub struct FetchContext {
@@ -347,7 +348,7 @@ pub fn main_fetch(request: &mut Request,
};
// 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)
} else {
response
@@ -355,9 +356,9 @@ pub fn main_fetch(request: &mut Request,
// Step 19.
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.
- wait_for_response(&response, target, done_chan);
+ wait_for_response(&mut response, target, done_chan);
response_loaded = true;
// Step 19.2.
@@ -376,9 +377,9 @@ pub fn main_fetch(request: &mut Request,
if request.synchronous {
// process_response is not supposed to be used
// by sync fetch, but we overload it here for simplicity
- target.process_response(&response);
+ target.process_response(&mut response);
if !response_loaded {
- wait_for_response(&response, target, done_chan);
+ wait_for_response(&mut response, target, done_chan);
}
// overloaded similarly to process_response
target.process_response_eof(&response);
@@ -400,7 +401,7 @@ pub fn main_fetch(request: &mut Request,
// Step 23.
if !response_loaded {
- wait_for_response(&response, target, done_chan);
+ wait_for_response(&mut response, target, done_chan);
}
// Step 24.
@@ -411,7 +412,7 @@ pub fn main_fetch(request: &mut Request,
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 {
loop {
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);
},
Data::Done => break,
+ Data::Cancelled => {
+ response.aborted = true;
+ break;
+ }
}
}
} else {
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs
index 8eb1a901203..318e57e1030 100644
--- a/components/net/http_loader.rs
+++ b/components/net/http_loader.rs
@@ -1088,6 +1088,9 @@ fn http_network_fetch(request: &Request,
let meta_status = meta.status.clone();
let meta_headers = meta.headers.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 || {
match StreamedResponse::from_http_response(res) {
Ok(mut res) => {
@@ -1112,7 +1115,7 @@ fn http_network_fetch(request: &Request,
loop {
if cancellation_listener.lock().unwrap().cancelled() {
*res_body.lock().unwrap() = ResponseBody::Done(vec![]);
- let _ = done_sender.send(Data::Done);
+ let _ = done_sender.send(Data::Cancelled);
return;
}
match read_block(&mut res) {
@@ -1134,6 +1137,7 @@ fn http_network_fetch(request: &Request,
let _ = done_sender.send(Data::Done);
break;
}
+ Ok(Data::Cancelled) => unreachable!() // read_block doesn't return Data::Cancelled
}
}
}
diff --git a/components/net_traits/response.rs b/components/net_traits/response.rs
index 8eecd3d4ee6..0425b039517 100644
--- a/components/net_traits/response.rs
+++ b/components/net_traits/response.rs
@@ -112,6 +112,8 @@ pub struct Response {
pub internal_response: Option<Box<Response>>,
/// whether or not to try to return the internal_response when asked for actual_response
pub return_internal: bool,
+ /// https://fetch.spec.whatwg.org/#concept-response-aborted
+ pub aborted: bool,
}
impl Response {
@@ -133,6 +135,7 @@ impl Response {
location_url: None,
internal_response: None,
return_internal: true,
+ aborted: false,
}
}
@@ -162,6 +165,7 @@ impl Response {
location_url: None,
internal_response: None,
return_internal: true,
+ aborted: false,
}
}