mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Implement initial version of navigator.sendBeacon
(#38301)
Gated behind the feature flag `dom_navigator_sendbeacon_enabled` as the `keep-alive` fetch parameter is crucial for real-life use cases such as analytics requests. Part of #4577 Part of #38302 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
181f97879d
commit
dbb886fad2
22 changed files with 237 additions and 29 deletions
|
@ -99,6 +99,7 @@ pub struct Preferences {
|
||||||
pub dom_microdata_testing_enabled: bool,
|
pub dom_microdata_testing_enabled: bool,
|
||||||
pub dom_mouse_event_which_enabled: bool,
|
pub dom_mouse_event_which_enabled: bool,
|
||||||
pub dom_mutation_observer_enabled: bool,
|
pub dom_mutation_observer_enabled: bool,
|
||||||
|
pub dom_navigator_sendbeacon_enabled: bool,
|
||||||
pub dom_notification_enabled: bool,
|
pub dom_notification_enabled: bool,
|
||||||
pub dom_offscreen_canvas_enabled: bool,
|
pub dom_offscreen_canvas_enabled: bool,
|
||||||
pub dom_permissions_enabled: bool,
|
pub dom_permissions_enabled: bool,
|
||||||
|
@ -279,6 +280,7 @@ impl Preferences {
|
||||||
dom_microdata_testing_enabled: false,
|
dom_microdata_testing_enabled: false,
|
||||||
dom_mouse_event_which_enabled: false,
|
dom_mouse_event_which_enabled: false,
|
||||||
dom_mutation_observer_enabled: true,
|
dom_mutation_observer_enabled: true,
|
||||||
|
dom_navigator_sendbeacon_enabled: false,
|
||||||
dom_notification_enabled: false,
|
dom_notification_enabled: false,
|
||||||
dom_offscreen_canvas_enabled: false,
|
dom_offscreen_canvas_enabled: false,
|
||||||
dom_permissions_enabled: false,
|
dom_permissions_enabled: false,
|
||||||
|
|
|
@ -4,28 +4,45 @@
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::sync::LazyLock;
|
use std::sync::{Arc, LazyLock, Mutex};
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use headers::HeaderMap;
|
||||||
|
use http::header::{self, HeaderValue};
|
||||||
use js::rust::MutableHandleValue;
|
use js::rust::MutableHandleValue;
|
||||||
|
use net_traits::request::{
|
||||||
|
CredentialsMode, Destination, RequestBuilder, RequestId, RequestMode,
|
||||||
|
is_cors_safelisted_request_content_type,
|
||||||
|
};
|
||||||
|
use net_traits::{
|
||||||
|
FetchMetadata, FetchResponseListener, NetworkError, ResourceFetchTiming, ResourceTimingType,
|
||||||
|
};
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
|
||||||
|
use crate::body::Extractable;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
|
use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
|
use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XMLHttpRequestBinding::BodyInit;
|
||||||
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
|
use crate::dom::bindings::refcounted::Trusted;
|
||||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::{DOMString, USVString};
|
||||||
use crate::dom::bindings::utils::to_frozen_array;
|
use crate::dom::bindings::utils::to_frozen_array;
|
||||||
#[cfg(feature = "bluetooth")]
|
#[cfg(feature = "bluetooth")]
|
||||||
use crate::dom::bluetooth::Bluetooth;
|
use crate::dom::bluetooth::Bluetooth;
|
||||||
use crate::dom::clipboard::Clipboard;
|
use crate::dom::clipboard::Clipboard;
|
||||||
|
use crate::dom::csp::{GlobalCspReporting, Violation};
|
||||||
use crate::dom::gamepad::Gamepad;
|
use crate::dom::gamepad::Gamepad;
|
||||||
use crate::dom::gamepadevent::GamepadEventType;
|
use crate::dom::gamepadevent::GamepadEventType;
|
||||||
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::mediadevices::MediaDevices;
|
use crate::dom::mediadevices::MediaDevices;
|
||||||
use crate::dom::mediasession::MediaSession;
|
use crate::dom::mediasession::MediaSession;
|
||||||
use crate::dom::mimetypearray::MimeTypeArray;
|
use crate::dom::mimetypearray::MimeTypeArray;
|
||||||
use crate::dom::navigatorinfo;
|
use crate::dom::navigatorinfo;
|
||||||
|
use crate::dom::performanceresourcetiming::InitiatorType;
|
||||||
use crate::dom::permissions::Permissions;
|
use crate::dom::permissions::Permissions;
|
||||||
use crate::dom::pluginarray::PluginArray;
|
use crate::dom::pluginarray::PluginArray;
|
||||||
use crate::dom::serviceworkercontainer::ServiceWorkerContainer;
|
use crate::dom::serviceworkercontainer::ServiceWorkerContainer;
|
||||||
|
@ -35,6 +52,7 @@ use crate::dom::webgpu::gpu::GPU;
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
use crate::dom::xrsystem::XRSystem;
|
use crate::dom::xrsystem::XRSystem;
|
||||||
|
use crate::network_listener::{PreInvoke, ResourceTimingListener, submit_timing};
|
||||||
use crate::script_runtime::{CanGc, JSContext};
|
use crate::script_runtime::{CanGc, JSContext};
|
||||||
|
|
||||||
pub(super) fn hardware_concurrency() -> u64 {
|
pub(super) fn hardware_concurrency() -> u64 {
|
||||||
|
@ -320,9 +338,159 @@ impl NavigatorMethods<crate::DomTypeHolder> for Navigator {
|
||||||
.or_init(|| Clipboard::new(&self.global(), CanGc::note()))
|
.or_init(|| Clipboard::new(&self.global(), CanGc::note()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://w3c.github.io/beacon/#sec-processing-model>
|
||||||
|
fn SendBeacon(&self, url: USVString, data: Option<BodyInit>, can_gc: CanGc) -> Fallible<bool> {
|
||||||
|
let global = self.global();
|
||||||
|
// Step 1. Set base to this's relevant settings object's API base URL.
|
||||||
|
let base = global.api_base_url();
|
||||||
|
// Step 2. Set origin to this's relevant settings object's origin.
|
||||||
|
let origin = global.origin().immutable().clone();
|
||||||
|
// Step 3. Set parsedUrl to the result of the URL parser steps with url and base.
|
||||||
|
// If the algorithm returns an error, or if parsedUrl's scheme is not "http" or "https",
|
||||||
|
// throw a "TypeError" exception and terminate these steps.
|
||||||
|
let Ok(url) = ServoUrl::parse_with_base(Some(&base), &url) else {
|
||||||
|
return Err(Error::Type("Cannot parse URL".to_owned()));
|
||||||
|
};
|
||||||
|
if !matches!(url.scheme(), "http" | "https") {
|
||||||
|
return Err(Error::Type("URL is not http(s)".to_owned()));
|
||||||
|
}
|
||||||
|
let mut request_body = None;
|
||||||
|
// Step 4. Let headerList be an empty list.
|
||||||
|
let mut headers = HeaderMap::with_capacity(1);
|
||||||
|
// Step 5. Let corsMode be "no-cors".
|
||||||
|
let mut cors_mode = RequestMode::NoCors;
|
||||||
|
// Step 6. If data is not null:
|
||||||
|
if let Some(data) = data {
|
||||||
|
// Step 6.1. Set transmittedData and contentType to the result of extracting data's byte stream
|
||||||
|
// with the keepalive flag set.
|
||||||
|
let extracted_body = data.extract(&global, can_gc)?;
|
||||||
|
// Step 6.2. If the amount of data that can be queued to be sent by keepalive enabled requests
|
||||||
|
// is exceeded by the size of transmittedData (as defined in HTTP-network-or-cache fetch),
|
||||||
|
// set the return value to false and terminate these steps.
|
||||||
|
if let Some(total_bytes) = extracted_body.total_bytes {
|
||||||
|
if total_bytes > 64 * 1024 {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 6.3. If contentType is not null:
|
||||||
|
if let Some(content_type) = extracted_body.content_type.as_ref() {
|
||||||
|
// Set corsMode to "cors".
|
||||||
|
cors_mode = RequestMode::CorsMode;
|
||||||
|
// If contentType value is a CORS-safelisted request-header value for the Content-Type header,
|
||||||
|
// set corsMode to "no-cors".
|
||||||
|
if is_cors_safelisted_request_content_type(content_type.as_bytes()) {
|
||||||
|
cors_mode = RequestMode::NoCors;
|
||||||
|
}
|
||||||
|
// Append a Content-Type header with value contentType to headerList.
|
||||||
|
//
|
||||||
|
// We cannot use typed header insertion with `mime::Mime` parsing here,
|
||||||
|
// since it lowercases `charset=UTF-8`: https://github.com/hyperium/mime/issues/116
|
||||||
|
headers.insert(
|
||||||
|
header::CONTENT_TYPE,
|
||||||
|
HeaderValue::from_str(content_type).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
request_body = Some(extracted_body.into_net_request_body().0);
|
||||||
|
}
|
||||||
|
// Step 7.1. Let req be a new request, initialized as follows:
|
||||||
|
let request = RequestBuilder::new(None, url.clone(), global.get_referrer())
|
||||||
|
.mode(cors_mode)
|
||||||
|
.destination(Destination::None)
|
||||||
|
.policy_container(global.policy_container())
|
||||||
|
.insecure_requests_policy(global.insecure_requests_policy())
|
||||||
|
.has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_or_current_origin())
|
||||||
|
.method(http::Method::POST)
|
||||||
|
.body(request_body)
|
||||||
|
.origin(origin)
|
||||||
|
// TODO: Set keep-alive flag
|
||||||
|
.credentials_mode(CredentialsMode::Include)
|
||||||
|
.headers(headers);
|
||||||
|
// Step 7.2. Fetch req.
|
||||||
|
global.fetch(
|
||||||
|
request,
|
||||||
|
Arc::new(Mutex::new(BeaconFetchListener {
|
||||||
|
url,
|
||||||
|
global: Trusted::new(&global),
|
||||||
|
resource_timing: ResourceFetchTiming::new(ResourceTimingType::None),
|
||||||
|
})),
|
||||||
|
global.task_manager().networking_task_source().into(),
|
||||||
|
);
|
||||||
|
// Step 7. Set the return value to true, return the sendBeacon() call,
|
||||||
|
// and continue to run the following steps in parallel:
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
/// <https://servo.org/internal-no-spec>
|
/// <https://servo.org/internal-no-spec>
|
||||||
fn Servo(&self) -> DomRoot<ServoInternals> {
|
fn Servo(&self) -> DomRoot<ServoInternals> {
|
||||||
self.servo_internals
|
self.servo_internals
|
||||||
.or_init(|| ServoInternals::new(&self.global(), CanGc::note()))
|
.or_init(|| ServoInternals::new(&self.global(), CanGc::note()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BeaconFetchListener {
|
||||||
|
/// URL of this request.
|
||||||
|
url: ServoUrl,
|
||||||
|
/// Timing data for this resource.
|
||||||
|
resource_timing: ResourceFetchTiming,
|
||||||
|
/// The global object fetching the report uri violation
|
||||||
|
global: Trusted<GlobalScope>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FetchResponseListener for BeaconFetchListener {
|
||||||
|
fn process_request_body(&mut self, _: RequestId) {}
|
||||||
|
|
||||||
|
fn process_request_eof(&mut self, _: RequestId) {}
|
||||||
|
|
||||||
|
fn process_response(
|
||||||
|
&mut self,
|
||||||
|
_: RequestId,
|
||||||
|
fetch_metadata: Result<FetchMetadata, NetworkError>,
|
||||||
|
) {
|
||||||
|
_ = fetch_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_response_chunk(&mut self, _: RequestId, chunk: Vec<u8>) {
|
||||||
|
_ = chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_response_eof(
|
||||||
|
&mut self,
|
||||||
|
_: RequestId,
|
||||||
|
response: Result<ResourceFetchTiming, NetworkError>,
|
||||||
|
) {
|
||||||
|
_ = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resource_timing_mut(&mut self) -> &mut ResourceFetchTiming {
|
||||||
|
&mut self.resource_timing
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resource_timing(&self) -> &ResourceFetchTiming {
|
||||||
|
&self.resource_timing
|
||||||
|
}
|
||||||
|
|
||||||
|
fn submit_resource_timing(&mut self) {
|
||||||
|
submit_timing(self, CanGc::note())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<Violation>) {
|
||||||
|
let global = self.resource_timing_global();
|
||||||
|
global.report_csp_violations(violations, None, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResourceTimingListener for BeaconFetchListener {
|
||||||
|
fn resource_timing_information(&self) -> (InitiatorType, ServoUrl) {
|
||||||
|
(InitiatorType::Beacon, self.url.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resource_timing_global(&self) -> DomRoot<GlobalScope> {
|
||||||
|
self.global.root()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PreInvoke for BeaconFetchListener {
|
||||||
|
fn should_invoke(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,9 +23,10 @@ use crate::script_runtime::CanGc;
|
||||||
// TODO Cross origin resources MUST BE INCLUDED as PerformanceResourceTiming objects
|
// TODO Cross origin resources MUST BE INCLUDED as PerformanceResourceTiming objects
|
||||||
// https://w3c.github.io/resource-timing/#sec-cross-origin-resources
|
// https://w3c.github.io/resource-timing/#sec-cross-origin-resources
|
||||||
|
|
||||||
// TODO CSS, Beacon
|
// TODO CSS
|
||||||
#[derive(Debug, JSTraceable, MallocSizeOf, PartialEq)]
|
#[derive(Debug, JSTraceable, MallocSizeOf, PartialEq)]
|
||||||
pub(crate) enum InitiatorType {
|
pub(crate) enum InitiatorType {
|
||||||
|
Beacon,
|
||||||
LocalName(String),
|
LocalName(String),
|
||||||
Navigation,
|
Navigation,
|
||||||
XMLHttpRequest,
|
XMLHttpRequest,
|
||||||
|
@ -191,6 +192,7 @@ impl PerformanceResourceTimingMethods<crate::DomTypeHolder> for PerformanceResou
|
||||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-initiatortype
|
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-initiatortype
|
||||||
fn InitiatorType(&self) -> DOMString {
|
fn InitiatorType(&self) -> DOMString {
|
||||||
match self.initiator_type {
|
match self.initiator_type {
|
||||||
|
InitiatorType::Beacon => DOMString::from("beacon"),
|
||||||
InitiatorType::LocalName(ref n) => DOMString::from(n.clone()),
|
InitiatorType::LocalName(ref n) => DOMString::from(n.clone()),
|
||||||
InitiatorType::Navigation => DOMString::from("navigation"),
|
InitiatorType::Navigation => DOMString::from("navigation"),
|
||||||
InitiatorType::XMLHttpRequest => DOMString::from("xmlhttprequest"),
|
InitiatorType::XMLHttpRequest => DOMString::from("xmlhttprequest"),
|
||||||
|
|
|
@ -503,7 +503,7 @@ DOMInterfaces = {
|
||||||
|
|
||||||
'Navigator': {
|
'Navigator': {
|
||||||
'inRealms': ['GetVRDisplays'],
|
'inRealms': ['GetVRDisplays'],
|
||||||
'canGc': ['Languages'],
|
'canGc': ['Languages', 'SendBeacon'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'Node': {
|
'Node': {
|
||||||
|
|
|
@ -81,3 +81,9 @@ interface mixin NavigatorConcurrentHardware {
|
||||||
partial interface Navigator {
|
partial interface Navigator {
|
||||||
[SecureContext, SameObject, Pref="dom_async_clipboard_enabled"] readonly attribute Clipboard clipboard;
|
[SecureContext, SameObject, Pref="dom_async_clipboard_enabled"] readonly attribute Clipboard clipboard;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://w3c.github.io/beacon/#sendbeacon-method
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Pref="dom_navigator_sendbeacon_enabled"]
|
||||||
|
boolean sendBeacon(USVString url, optional BodyInit? data = null);
|
||||||
|
};
|
||||||
|
|
|
@ -801,7 +801,7 @@ fn is_cors_safelisted_language(value: &[u8]) -> bool {
|
||||||
|
|
||||||
// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
|
// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
|
||||||
// subclause `content-type`
|
// subclause `content-type`
|
||||||
fn is_cors_safelisted_request_content_type(value: &[u8]) -> bool {
|
pub fn is_cors_safelisted_request_content_type(value: &[u8]) -> bool {
|
||||||
// step 1
|
// step 1
|
||||||
if value.iter().any(is_cors_unsafe_request_header_byte) {
|
if value.iter().any(is_cors_unsafe_request_header_byte) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -591,6 +591,7 @@ pub(crate) fn parse_command_line_arguments(args: Vec<String>) -> ArgumentParsing
|
||||||
"dom_fontface_enabled",
|
"dom_fontface_enabled",
|
||||||
"dom_intersection_observer_enabled",
|
"dom_intersection_observer_enabled",
|
||||||
"dom_mouse_event_which_enabled",
|
"dom_mouse_event_which_enabled",
|
||||||
|
"dom_navigator_sendbeacon_enabled",
|
||||||
"dom_notification_enabled",
|
"dom_notification_enabled",
|
||||||
"dom_offscreen_canvas_enabled",
|
"dom_offscreen_canvas_enabled",
|
||||||
"dom_permissions_enabled",
|
"dom_permissions_enabled",
|
||||||
|
|
2
tests/wpt/include.ini
vendored
2
tests/wpt/include.ini
vendored
|
@ -3,6 +3,8 @@ skip: true
|
||||||
skip: false
|
skip: false
|
||||||
[_webgl]
|
[_webgl]
|
||||||
skip: false
|
skip: false
|
||||||
|
[beacon]
|
||||||
|
skip: false
|
||||||
[clipboard-apis]
|
[clipboard-apis]
|
||||||
skip: false
|
skip: false
|
||||||
[console]
|
[console]
|
||||||
|
|
12
tests/wpt/meta/beacon/beacon-basic.https.window.js.ini
vendored
Normal file
12
tests/wpt/meta/beacon/beacon-basic.https.window.js.ini
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[beacon-basic.https.window.html]
|
||||||
|
[Payload size restriction should be accumulated: type = string]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Payload size restriction should be accumulated: type = arraybuffer]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Payload size restriction should be accumulated: type = blob]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[sendBeacon() with a stream does not work due to the keepalive flag being set]
|
||||||
|
expected: FAIL
|
6
tests/wpt/meta/beacon/beacon-cors.https.window.js.ini
vendored
Normal file
6
tests/wpt/meta/beacon/beacon-cors.https.window.js.ini
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[beacon-cors.https.window.html]
|
||||||
|
[cross-origin, non-CORS-safelisted: failure case (without redirect)]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[cross-origin, non-CORS-safelisted[credentials=false\]]
|
||||||
|
expected: FAIL
|
4
tests/wpt/meta/beacon/headers/header-referrer-no-referrer-when-downgrade.https.html.ini
vendored
Normal file
4
tests/wpt/meta/beacon/headers/header-referrer-no-referrer-when-downgrade.https.html.ini
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[header-referrer-no-referrer-when-downgrade.https.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Test referer header http://web-platform.test:8000/beacon/resources/]
|
||||||
|
expected: TIMEOUT
|
4
tests/wpt/meta/beacon/headers/header-referrer-strict-origin-when-cross-origin.https.html.ini
vendored
Normal file
4
tests/wpt/meta/beacon/headers/header-referrer-strict-origin-when-cross-origin.https.html.ini
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[header-referrer-strict-origin-when-cross-origin.https.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Test referer header http://www1.web-platform.test:8000/beacon/resources/]
|
||||||
|
expected: TIMEOUT
|
4
tests/wpt/meta/beacon/headers/header-referrer-strict-origin.https.html.ini
vendored
Normal file
4
tests/wpt/meta/beacon/headers/header-referrer-strict-origin.https.html.ini
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[header-referrer-strict-origin.https.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Test referer header http://web-platform.test:8000/beacon/resources/]
|
||||||
|
expected: TIMEOUT
|
4
tests/wpt/meta/beacon/headers/header-referrer-unsafe-url.https.html.ini
vendored
Normal file
4
tests/wpt/meta/beacon/headers/header-referrer-unsafe-url.https.html.ini
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[header-referrer-unsafe-url.https.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Test referer header http://web-platform.test:8000/beacon/resources/]
|
||||||
|
expected: TIMEOUT
|
|
@ -1,3 +0,0 @@
|
||||||
[connect-src-beacon-allowed.sub.html]
|
|
||||||
[Expecting logs: ["Pass"\]]
|
|
||||||
expected: NOTRUN
|
|
|
@ -1,3 +0,0 @@
|
||||||
[connect-src-beacon-blocked.sub.html]
|
|
||||||
[Expecting logs: ["Pass", "violated-directive=connect-src"\]]
|
|
||||||
expected: NOTRUN
|
|
|
@ -1,3 +0,0 @@
|
||||||
[connect-src-beacon-redirect-to-blocked.sub.html]
|
|
||||||
[Expecting logs: ["violated-directive=connect-src"\]]
|
|
||||||
expected: NOTRUN
|
|
|
@ -14,9 +14,6 @@
|
||||||
[source : unpaired surrogate codepoint should be replaced with U+FFFD]
|
[source : unpaired surrogate codepoint should be replaced with U+FFFD]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[sendBeacon URL: unpaired surrogate codepoint should not make any exceptions.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[RegisterProtocolHandler URL: unpaired surrogate codepoint should not make any exceptions.]
|
[RegisterProtocolHandler URL: unpaired surrogate codepoint should not make any exceptions.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[beacon.https.html]
|
[beacon.https.html]
|
||||||
[Mixed-Content: Expects allowed for beacon to same-https origin and keep-scheme redirection from https context.]
|
[Mixed-Content: Expects blocked for beacon to cross-https origin and swap-scheme redirection from https context.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Mixed-Content: Expects allowed for beacon to same-https origin and no-redirect redirection from https context.]
|
[Mixed-Content: Expects blocked for beacon to same-https origin and swap-scheme redirection from https context.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[beacon.https.html]
|
|
||||||
[Mixed-Content: Expects allowed for beacon to same-https origin and no-redirect redirection from https context.]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[beacon.https.html]
|
|
||||||
[Mixed-Content: Expects allowed for beacon to same-https origin and keep-scheme redirection from https context.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Mixed-Content: Expects allowed for beacon to same-https origin and no-redirect redirection from https context.]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +1,16 @@
|
||||||
[misc.html]
|
[misc.html]
|
||||||
expected: ERROR
|
expected: TIMEOUT
|
||||||
|
[The initiator type for <body background> must be 'body']
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[The initiator type for <input type='image'> must be 'input']
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[The initiator type for <object type='image/png'> must be 'object']
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[The initiator type for for fetch() must be 'fetch']
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[The initiator type for new EventSource() must be 'other']
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue