mirror of
https://github.com/servo/servo.git
synced 2025-09-19 03:18:20 +01:00
script: Do not start Fetch
operations if they have been aborted by the AbortController
(#39295)
The first step for aborting fetch calls. It only has the case where the signal was already aborted prior to fetch starting. Part of #34866 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
6deb42dbd5
commit
6cba44e0e3
2 changed files with 49 additions and 92 deletions
|
@ -7,6 +7,8 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use base::id::WebViewId;
|
use base::id::WebViewId;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
|
use js::rust::HandleValue;
|
||||||
use net_traits::policy_container::{PolicyContainer, RequestPolicyContainer};
|
use net_traits::policy_container::{PolicyContainer, RequestPolicyContainer};
|
||||||
use net_traits::request::{
|
use net_traits::request::{
|
||||||
CorsSettings, CredentialsMode, Destination, InsecureRequestsPolicy, Referrer,
|
CorsSettings, CredentialsMode, Destination, InsecureRequestsPolicy, Referrer,
|
||||||
|
@ -19,12 +21,14 @@ use net_traits::{
|
||||||
};
|
};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
|
||||||
|
use crate::dom::bindings::codegen::Bindings::AbortSignalBinding::AbortSignalMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::RequestBinding::{
|
use crate::dom::bindings::codegen::Bindings::RequestBinding::{
|
||||||
RequestInfo, RequestInit, RequestMethods,
|
RequestInfo, RequestInit, RequestMethods,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::codegen::Bindings::ResponseBinding::Response_Binding::ResponseMethods;
|
use crate::dom::bindings::codegen::Bindings::ResponseBinding::Response_Binding::ResponseMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::ResponseBinding::ResponseType as DOMResponseType;
|
use crate::dom::bindings::codegen::Bindings::ResponseBinding::ResponseType as DOMResponseType;
|
||||||
use crate::dom::bindings::error::Error;
|
use crate::dom::bindings::error::Error;
|
||||||
|
use crate::dom::bindings::import::module::SafeJSContext;
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::DomGlobal;
|
use crate::dom::bindings::reflector::DomGlobal;
|
||||||
|
@ -139,6 +143,27 @@ fn request_init_from_request(request: NetTraitsRequest) -> RequestBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://fetch.spec.whatwg.org/#abort-fetch>
|
||||||
|
fn abort_fetch_call(
|
||||||
|
promise: Rc<Promise>,
|
||||||
|
_request: &NetTraitsRequest,
|
||||||
|
_response_object: Option<&Response>,
|
||||||
|
abort_reason: HandleValue,
|
||||||
|
cx: SafeJSContext,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
|
// Step 1. Reject promise with error.
|
||||||
|
promise.reject(cx, abort_reason, can_gc);
|
||||||
|
// Step 2. If request’s body is non-null and is readable, then cancel request’s body with error.
|
||||||
|
// TODO
|
||||||
|
// Step 3. If responseObject is null, then return.
|
||||||
|
// TODO
|
||||||
|
// Step 4. Let response be responseObject’s response.
|
||||||
|
// TODO
|
||||||
|
// Step 5. If response’s body is non-null and is readable, then error response’s body with error.
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
/// <https://fetch.spec.whatwg.org/#dom-global-fetch>
|
/// <https://fetch.spec.whatwg.org/#dom-global-fetch>
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||||
|
@ -151,6 +176,7 @@ pub(crate) fn Fetch(
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
// Step 1. Let p be a new promise.
|
// Step 1. Let p be a new promise.
|
||||||
let promise = Promise::new_in_current_realm(comp, can_gc);
|
let promise = Promise::new_in_current_realm(comp, can_gc);
|
||||||
|
let cx = GlobalScope::get_cx();
|
||||||
|
|
||||||
// Step 7. Let responseObject be null.
|
// Step 7. Let responseObject be null.
|
||||||
// NOTE: We do initialize the object earlier earlier so we can use it to track errors
|
// NOTE: We do initialize the object earlier earlier so we can use it to track errors
|
||||||
|
@ -159,32 +185,41 @@ pub(crate) fn Fetch(
|
||||||
|
|
||||||
// Step 2. Let requestObject be the result of invoking the initial value of Request as constructor
|
// Step 2. Let requestObject be the result of invoking the initial value of Request as constructor
|
||||||
// with input and init as arguments. If this throws an exception, reject p with it and return p.
|
// with input and init as arguments. If this throws an exception, reject p with it and return p.
|
||||||
let request = match Request::Constructor(global, None, can_gc, input, init) {
|
let request_object = match Request::Constructor(global, None, can_gc, input, init) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
response.error_stream(e.clone(), can_gc);
|
response.error_stream(e.clone(), can_gc);
|
||||||
promise.reject_error(e, can_gc);
|
promise.reject_error(e, can_gc);
|
||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
Ok(r) => {
|
Ok(r) => r,
|
||||||
// Step 3. Let request be requestObject’s request.
|
|
||||||
r.get_request()
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
// Step 3. Let request be requestObject’s request.
|
||||||
|
let request = request_object.get_request();
|
||||||
let timing_type = request.timing_type();
|
let timing_type = request.timing_type();
|
||||||
|
|
||||||
let mut request_init = request_init_from_request(request);
|
|
||||||
request_init.policy_container =
|
|
||||||
RequestPolicyContainer::PolicyContainer(global.policy_container());
|
|
||||||
|
|
||||||
// Step 4. If requestObject’s signal is aborted, then:
|
// Step 4. If requestObject’s signal is aborted, then:
|
||||||
// TODO
|
let signal = request_object.Signal();
|
||||||
|
if signal.aborted() {
|
||||||
// Step 4.1. Abort the fetch() call with p, request, null, and requestObject’s signal’s abort reason.
|
// Step 4.1. Abort the fetch() call with p, request, null, and requestObject’s signal’s abort reason.
|
||||||
// TODO
|
rooted!(in(*cx) let mut abort_reason = UndefinedValue());
|
||||||
|
signal.Reason(cx, abort_reason.handle_mut());
|
||||||
|
abort_fetch_call(
|
||||||
|
promise.clone(),
|
||||||
|
&request,
|
||||||
|
None,
|
||||||
|
abort_reason.handle(),
|
||||||
|
cx,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
// Step 4.2. Return p.
|
// Step 4.2. Return p.
|
||||||
// TODO
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
// Step 5. Let globalObject be request’s client’s global object.
|
// Step 5. Let globalObject be request’s client’s global object.
|
||||||
// NOTE: We already get the global object as an argument
|
// NOTE: We already get the global object as an argument
|
||||||
|
let mut request_init = request_init_from_request(request);
|
||||||
|
request_init.policy_container =
|
||||||
|
RequestPolicyContainer::PolicyContainer(global.policy_container());
|
||||||
|
|
||||||
// Step 6. If globalObject is a ServiceWorkerGlobalScope object, then set request’s
|
// Step 6. If globalObject is a ServiceWorkerGlobalScope object, then set request’s
|
||||||
// service-workers mode to "none".
|
// service-workers mode to "none".
|
||||||
|
|
|
@ -6,30 +6,6 @@
|
||||||
|
|
||||||
[general.any.html]
|
[general.any.html]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
[Aborting rejects with AbortError]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Aborting rejects with AbortError - no-cors]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object created from request object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object created from request object, with signal on second request]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object created from request object, with signal on second request overriding another]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal retained after unrelated properties are overridden by fetch]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Already aborted signal rejects immediately]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Request is still 'used' if signal is aborted before fetching]
|
[Request is still 'used' if signal is aborted before fetching]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -51,15 +27,6 @@
|
||||||
[Call text() twice on aborted response]
|
[Call text() twice on aborted response]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Already aborted signal does not make request]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Already aborted signal can be used for many fetches]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal can be used to abort other fetches, even if another fetch succeeded before aborting]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Underlying connection is closed when aborting after receiving response]
|
[Underlying connection is closed when aborting after receiving response]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -93,12 +60,6 @@
|
||||||
[Readable stream synchronously cancels with AbortError if aborted before reading]
|
[Readable stream synchronously cancels with AbortError if aborted before reading]
|
||||||
expected: NOTRUN
|
expected: NOTRUN
|
||||||
|
|
||||||
[Aborting rejects with abort reason]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object should also have abort reason]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[response.bytes() rejects if already aborted]
|
[response.bytes() rejects if already aborted]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -108,30 +69,6 @@
|
||||||
|
|
||||||
[general.any.worker.html]
|
[general.any.worker.html]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
[Aborting rejects with AbortError]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Aborting rejects with AbortError - no-cors]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object created from request object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object created from request object, with signal on second request]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object created from request object, with signal on second request overriding another]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal retained after unrelated properties are overridden by fetch]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Already aborted signal rejects immediately]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Request is still 'used' if signal is aborted before fetching]
|
[Request is still 'used' if signal is aborted before fetching]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -153,15 +90,6 @@
|
||||||
[Call text() twice on aborted response]
|
[Call text() twice on aborted response]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Already aborted signal does not make request]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Already aborted signal can be used for many fetches]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal can be used to abort other fetches, even if another fetch succeeded before aborting]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Underlying connection is closed when aborting after receiving response]
|
[Underlying connection is closed when aborting after receiving response]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -195,12 +123,6 @@
|
||||||
[Readable stream synchronously cancels with AbortError if aborted before reading]
|
[Readable stream synchronously cancels with AbortError if aborted before reading]
|
||||||
expected: NOTRUN
|
expected: NOTRUN
|
||||||
|
|
||||||
[Aborting rejects with abort reason]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Signal on request object should also have abort reason]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[response.bytes() rejects if already aborted]
|
[response.bytes() rejects if already aborted]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue