mirror of
https://github.com/servo/servo.git
synced 2025-09-10 15:08:21 +01:00
Hookup mime classifier to main document loader (#39109)
While we don't perform any sniffing yet, it does now check all relevant mime types. Before, we would only check specific versions of specific mime types. However, the specification is more elaborate, which MimeClassifier already handles. There are two new test failures, but they actually fail in the same way in other browsers. These tests are still being discussed what the correct behavior should be [1] Part of #14024 [1]: https://github.com/whatwg/mimesniff/issues/189#issuecomment-2081559661 --------- Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
a44b98c358
commit
dab195ca80
23 changed files with 284 additions and 619 deletions
|
@ -22,10 +22,11 @@ use html5ever::{Attribute, ExpandedName, LocalName, QualName, local_name, ns};
|
|||
use hyper_serde::Serde;
|
||||
use markup5ever::TokenizerResult;
|
||||
use mime::{self, Mime};
|
||||
use net_traits::mime_classifier::{ApacheBugFlag, MediaType, MimeClassifier, NoSniffFlag};
|
||||
use net_traits::policy_container::PolicyContainer;
|
||||
use net_traits::request::RequestId;
|
||||
use net_traits::{
|
||||
FetchMetadata, FetchResponseListener, Metadata, NetworkError, ResourceFetchTiming,
|
||||
FetchMetadata, FetchResponseListener, LoadContext, Metadata, NetworkError, ResourceFetchTiming,
|
||||
ResourceTimingType,
|
||||
};
|
||||
use profile_traits::time::{
|
||||
|
@ -44,6 +45,7 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
|
|||
DocumentMethods, DocumentReadyState,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
|
||||
|
@ -75,6 +77,7 @@ use crate::dom::processinginstruction::ProcessingInstruction;
|
|||
use crate::dom::reportingendpoint::ReportingEndpoint;
|
||||
use crate::dom::shadowroot::IsUserAgentWidget;
|
||||
use crate::dom::text::Text;
|
||||
use crate::dom::types::{HTMLAudioElement, HTMLMediaElement, HTMLVideoElement};
|
||||
use crate::dom::virtualmethods::vtable_for;
|
||||
use crate::network_listener::PreInvoke;
|
||||
use crate::realms::enter_realm;
|
||||
|
@ -943,21 +946,24 @@ impl FetchResponseListener for ParserContext {
|
|||
self.parser = Some(Trusted::new(&*parser));
|
||||
self.submit_resource_timing();
|
||||
|
||||
let content_type = match content_type {
|
||||
Some(ref content_type) => content_type,
|
||||
None => {
|
||||
// No content-type header.
|
||||
// Merge with #4212 when fixed.
|
||||
// Steps for https://html.spec.whatwg.org/multipage/#loading-a-document
|
||||
//
|
||||
// Step 1. Let type be the computed type of navigationParams's response.
|
||||
let mime_type = MimeClassifier::default().classify(
|
||||
LoadContext::Browsing,
|
||||
NoSniffFlag::Off,
|
||||
ApacheBugFlag::from_content_type(content_type.as_ref()),
|
||||
&content_type,
|
||||
// TODO(14024): Figure out how to pass the response data here for sniffing
|
||||
// Requires implementation of https://mimesniff.spec.whatwg.org/#read-the-resource-header
|
||||
&[],
|
||||
);
|
||||
let Some(media_type) = MimeClassifier::get_media_type(&mime_type) else {
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
match (
|
||||
content_type.type_(),
|
||||
content_type.subtype(),
|
||||
content_type.suffix(),
|
||||
) {
|
||||
(mime::IMAGE, _, _) => {
|
||||
match media_type {
|
||||
// Return the result of loading a media document given navigationParams and type.
|
||||
MediaType::Image | MediaType::AudioVideo => {
|
||||
self.is_synthesized_document = true;
|
||||
let page = "<html><body></body></html>".into();
|
||||
parser.push_string_input_chunk(page);
|
||||
|
@ -965,6 +971,7 @@ impl FetchResponseListener for ParserContext {
|
|||
|
||||
let doc = &parser.document;
|
||||
let doc_body = DomRoot::upcast::<Node>(doc.GetBody().unwrap());
|
||||
let node = if media_type == MediaType::Image {
|
||||
let img = HTMLImageElement::new(
|
||||
local_name!("img"),
|
||||
None,
|
||||
|
@ -974,18 +981,35 @@ impl FetchResponseListener for ParserContext {
|
|||
CanGc::note(),
|
||||
);
|
||||
img.SetSrc(USVString(self.url.to_string()));
|
||||
DomRoot::upcast::<Node>(img)
|
||||
} else if mime_type.type_() == mime::AUDIO {
|
||||
let audio =
|
||||
HTMLAudioElement::new(local_name!("audio"), None, doc, None, CanGc::note());
|
||||
audio
|
||||
.upcast::<HTMLMediaElement>()
|
||||
.SetSrc(USVString(self.url.to_string()));
|
||||
DomRoot::upcast::<Node>(audio)
|
||||
} else {
|
||||
let video =
|
||||
HTMLVideoElement::new(local_name!("video"), None, doc, None, CanGc::note());
|
||||
video
|
||||
.upcast::<HTMLMediaElement>()
|
||||
.SetSrc(USVString(self.url.to_string()));
|
||||
DomRoot::upcast::<Node>(video)
|
||||
};
|
||||
doc_body
|
||||
.AppendChild(&DomRoot::upcast::<Node>(img), CanGc::note())
|
||||
.AppendChild(&node, CanGc::note())
|
||||
.expect("Appending failed");
|
||||
},
|
||||
(mime::TEXT, mime::PLAIN, _) => {
|
||||
// Return the result of loading a text document given navigationParams and type.
|
||||
MediaType::JavaScript | MediaType::Json | MediaType::Text | MediaType::Css => {
|
||||
// https://html.spec.whatwg.org/multipage/#read-text
|
||||
let page = "<pre>\n".into();
|
||||
parser.push_string_input_chunk(page);
|
||||
parser.parse_sync(CanGc::note());
|
||||
parser.tokenizer.set_plaintext_state();
|
||||
},
|
||||
(mime::TEXT, mime::HTML, _) => match error {
|
||||
MediaType::Html => match error {
|
||||
Some(NetworkError::SslValidation(reason, bytes)) => {
|
||||
self.is_synthesized_document = true;
|
||||
let page = resources::read_string(Resource::BadCertHTML);
|
||||
|
@ -1012,20 +1036,17 @@ impl FetchResponseListener for ParserContext {
|
|||
parser.parse_sync(CanGc::note());
|
||||
},
|
||||
Some(_) => {},
|
||||
// Return the result of loading an HTML document, given navigationParams.
|
||||
None => parser.document.set_csp_list(csp_list),
|
||||
},
|
||||
(mime::TEXT, mime::XML, _) |
|
||||
(mime::APPLICATION, mime::XML, _) |
|
||||
(mime::APPLICATION, mime::JSON, _) => parser.document.set_csp_list(csp_list),
|
||||
(mime::APPLICATION, subtype, Some(mime::XML)) if subtype == "xhtml" => {
|
||||
parser.document.set_csp_list(csp_list)
|
||||
},
|
||||
(mime_type, subtype, _) => {
|
||||
// Return the result of loading an XML document given navigationParams and type.
|
||||
MediaType::Xml => parser.document.set_csp_list(csp_list),
|
||||
_ => {
|
||||
// Show warning page for unknown mime types.
|
||||
let page = format!(
|
||||
"<html><body><p>Unknown content type ({}/{}).</p></body></html>",
|
||||
mime_type.as_str(),
|
||||
subtype.as_str()
|
||||
mime_type.type_().as_str(),
|
||||
mime_type.subtype().as_str()
|
||||
);
|
||||
self.is_synthesized_document = true;
|
||||
parser.push_string_input_chunk(page);
|
||||
|
|
|
@ -13,7 +13,6 @@ pub struct MimeClassifier {
|
|||
plaintext_classifier: GroupedClassifier,
|
||||
archive_classifier: GroupedClassifier,
|
||||
binary_or_plaintext: BinaryOrPlaintextClassifier,
|
||||
feeds_classifier: FeedsClassifier,
|
||||
font_classifier: GroupedClassifier,
|
||||
}
|
||||
|
||||
|
@ -26,8 +25,11 @@ pub enum MediaType {
|
|||
JavaScript,
|
||||
Json,
|
||||
Font,
|
||||
Text,
|
||||
Css,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum ApacheBugFlag {
|
||||
On,
|
||||
Off,
|
||||
|
@ -35,12 +37,11 @@ pub enum ApacheBugFlag {
|
|||
|
||||
impl ApacheBugFlag {
|
||||
/// <https://mimesniff.spec.whatwg.org/#supplied-mime-type-detection-algorithm>
|
||||
pub fn from_content_type(last_raw_content_type: &[u8]) -> ApacheBugFlag {
|
||||
if last_raw_content_type == b"text/plain" ||
|
||||
last_raw_content_type == b"text/plain; charset=ISO-8859-1" ||
|
||||
last_raw_content_type == b"text/plain; charset=iso-8859-1" ||
|
||||
last_raw_content_type == b"text/plain; charset=UTF-8"
|
||||
{
|
||||
pub fn from_content_type(mime_type: Option<&Mime>) -> ApacheBugFlag {
|
||||
// TODO(36801): also handle charset ISO-8859-1
|
||||
if mime_type.is_some_and(|mime_type| {
|
||||
*mime_type == mime::TEXT_PLAIN || *mime_type == mime::TEXT_PLAIN_UTF_8
|
||||
}) {
|
||||
ApacheBugFlag::On
|
||||
} else {
|
||||
ApacheBugFlag::Off
|
||||
|
@ -63,14 +64,13 @@ impl Default for MimeClassifier {
|
|||
plaintext_classifier: GroupedClassifier::plaintext_classifier(),
|
||||
archive_classifier: GroupedClassifier::archive_classifier(),
|
||||
binary_or_plaintext: BinaryOrPlaintextClassifier,
|
||||
feeds_classifier: FeedsClassifier,
|
||||
font_classifier: GroupedClassifier::font_classifier(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MimeClassifier {
|
||||
// Performs MIME Type Sniffing Algorithm (sections 7 and 8)
|
||||
/// <https://mimesniff.spec.whatwg.org/#mime-type-sniffing-algorithm>
|
||||
pub fn classify<'a>(
|
||||
&'a self,
|
||||
context: LoadContext,
|
||||
|
@ -82,41 +82,55 @@ impl MimeClassifier {
|
|||
let supplied_type_or_octet_stream = supplied_type
|
||||
.clone()
|
||||
.unwrap_or(mime::APPLICATION_OCTET_STREAM);
|
||||
// Step 1. If the supplied MIME type is an XML MIME type or HTML MIME type,
|
||||
// the computed MIME type is the supplied MIME type.
|
||||
if Self::is_xml(&supplied_type_or_octet_stream) ||
|
||||
Self::is_html(&supplied_type_or_octet_stream)
|
||||
{
|
||||
return supplied_type_or_octet_stream;
|
||||
}
|
||||
match context {
|
||||
LoadContext::Browsing => match *supplied_type {
|
||||
// Step 2. If the supplied MIME type is undefined or if the supplied MIME type’s essence is "unknown/unknown",
|
||||
// "application/unknown", or "*/*", execute the rules for identifying
|
||||
// an unknown MIME type with the sniff-scriptable flag equal to the inverse of the no-sniff flag and abort these steps.
|
||||
None => self.sniff_unknown_type(no_sniff_flag, data),
|
||||
Some(ref supplied_type) => {
|
||||
if MimeClassifier::is_explicit_unknown(supplied_type) {
|
||||
self.sniff_unknown_type(no_sniff_flag, data)
|
||||
} else {
|
||||
match no_sniff_flag {
|
||||
NoSniffFlag::On => supplied_type.clone(),
|
||||
NoSniffFlag::Off => match apache_bug_flag {
|
||||
ApacheBugFlag::On => self.sniff_text_or_data(data),
|
||||
ApacheBugFlag::Off => {
|
||||
return self.sniff_unknown_type(no_sniff_flag, data);
|
||||
}
|
||||
// Step 3. If the no-sniff flag is set, the computed MIME type is the supplied MIME type.
|
||||
// Abort these steps.
|
||||
if no_sniff_flag == NoSniffFlag::On {
|
||||
return supplied_type.clone();
|
||||
}
|
||||
// Step 4. If the check-for-apache-bug flag is set,
|
||||
// execute the rules for distinguishing if a resource is text or binary and abort these steps.
|
||||
if apache_bug_flag == ApacheBugFlag::On {
|
||||
return self.sniff_text_or_data(data);
|
||||
}
|
||||
match MimeClassifier::get_media_type(supplied_type) {
|
||||
Some(MediaType::Html) => {
|
||||
self.feeds_classifier.classify(data)
|
||||
},
|
||||
// Step 5. If the supplied MIME type is an image MIME type supported by the user agent,
|
||||
// let matched-type be the result of executing the image type pattern matching algorithm with
|
||||
// the resource header as the byte sequence to be matched.
|
||||
Some(MediaType::Image) => {
|
||||
// Step 6. If matched-type is not undefined, the computed MIME type is matched-type.
|
||||
self.image_classifier.classify(data)
|
||||
},
|
||||
// Step 7. If the supplied MIME type is an audio or video MIME type supported by the user agent,
|
||||
// let matched-type be the result of executing the audio or video type pattern matching algorithm
|
||||
// with the resource header as the byte sequence to be matched.
|
||||
Some(MediaType::AudioVideo) => {
|
||||
// Step 8. If matched-type is not undefined, the computed MIME type is matched-type.
|
||||
self.audio_video_classifier.classify(data)
|
||||
},
|
||||
Some(MediaType::JavaScript) |
|
||||
Some(MediaType::Font) |
|
||||
Some(MediaType::Json) |
|
||||
Some(MediaType::Xml) |
|
||||
None => None,
|
||||
Some(MediaType::Html) | Some(MediaType::Xml) => unreachable!(),
|
||||
_ => None,
|
||||
}
|
||||
// Step 9. The computed MIME type is the supplied MIME type.
|
||||
.unwrap_or(supplied_type.clone())
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
LoadContext::Image => {
|
||||
// Section 8.2 Sniffing an image context
|
||||
match MimeClassifier::maybe_get_media_type(supplied_type) {
|
||||
|
@ -195,7 +209,6 @@ impl MimeClassifier {
|
|||
self.plaintext_classifier.validate()?;
|
||||
self.archive_classifier.validate()?;
|
||||
self.binary_or_plaintext.validate()?;
|
||||
self.feeds_classifier.validate()?;
|
||||
self.font_classifier.validate()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -300,6 +313,14 @@ impl MimeClassifier {
|
|||
.contains(&mt.subtype().as_str())))
|
||||
}
|
||||
|
||||
fn is_text(mt: &Mime) -> bool {
|
||||
*mt == mime::TEXT_PLAIN || mt.essence_str() == "text/vtt"
|
||||
}
|
||||
|
||||
fn is_css(mt: &Mime) -> bool {
|
||||
*mt == mime::TEXT_CSS
|
||||
}
|
||||
|
||||
pub fn get_media_type(mime: &Mime) -> Option<MediaType> {
|
||||
if MimeClassifier::is_xml(mime) {
|
||||
Some(MediaType::Xml)
|
||||
|
@ -315,6 +336,10 @@ impl MimeClassifier {
|
|||
Some(MediaType::Font)
|
||||
} else if MimeClassifier::is_json(mime) {
|
||||
Some(MediaType::Json)
|
||||
} else if MimeClassifier::is_text(mime) {
|
||||
Some(MediaType::Text)
|
||||
} else if MimeClassifier::is_css(mime) {
|
||||
Some(MediaType::Css)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -334,38 +359,6 @@ trait MIMEChecker {
|
|||
fn validate(&self) -> Result<(), String>;
|
||||
}
|
||||
|
||||
trait Matches {
|
||||
fn matches(&mut self, matches: &[u8]) -> bool;
|
||||
}
|
||||
|
||||
impl<'a, T: Iterator<Item = &'a u8> + Clone> Matches for T {
|
||||
// Matching function that works on an iterator.
|
||||
// see if the next matches.len() bytes in data_iterator equal matches
|
||||
// move iterator and return true or just return false
|
||||
//
|
||||
// Params
|
||||
// self: an iterator
|
||||
// matches: a vector of bytes to match
|
||||
//
|
||||
// Return
|
||||
// true if the next n elements of self match n elements of matches
|
||||
// false otherwise
|
||||
//
|
||||
// Side effects
|
||||
// moves the iterator when match is found
|
||||
fn matches(&mut self, matches: &[u8]) -> bool {
|
||||
if self.clone().nth(matches.len()).is_none() {
|
||||
// there are less than matches.len() elements in self
|
||||
return false;
|
||||
}
|
||||
let result = self.clone().zip(matches).all(|(s, m)| *s == *m);
|
||||
if result {
|
||||
self.nth(matches.len());
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
struct ByteMatcher {
|
||||
pattern: &'static [u8],
|
||||
mask: &'static [u8],
|
||||
|
@ -452,29 +445,45 @@ impl MIMEChecker for TagTerminatedByteMatcher {
|
|||
pub struct Mp4Matcher;
|
||||
|
||||
impl Mp4Matcher {
|
||||
/// <https://mimesniff.spec.whatwg.org/#matches-the-signature-for-mp4>
|
||||
pub fn matches(&self, data: &[u8]) -> bool {
|
||||
// Step 1. Let sequence be the byte sequence to be matched,
|
||||
// where sequence[s] is byte s in sequence and sequence[0] is the first byte in sequence.
|
||||
// Step 2. Let length be the number of bytes in sequence.
|
||||
// Step 3. If length is less than 12, return false.
|
||||
if data.len() < 12 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 4. Let box-size be the four bytes from sequence[0] to sequence[3],
|
||||
// interpreted as a 32-bit unsigned big-endian integer.
|
||||
let box_size = (((data[0] as u32) << 24) |
|
||||
((data[1] as u32) << 16) |
|
||||
((data[2] as u32) << 8) |
|
||||
(data[3] as u32)) as usize;
|
||||
// Step 5. If length is less than box-size or if box-size modulo 4 is not equal to 0, return false.
|
||||
if (data.len() < box_size) || (box_size % 4 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 6. If the four bytes from sequence[4] to sequence[7] are not equal to 0x66 0x74 0x79 0x70 ("ftyp"), return false.
|
||||
let ftyp = [0x66, 0x74, 0x79, 0x70];
|
||||
if !data[4..].starts_with(&ftyp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 7. If the three bytes from sequence[8] to sequence[10] are equal to 0x6D 0x70 0x34 ("mp4"), return true.
|
||||
let mp4 = [0x6D, 0x70, 0x34];
|
||||
data[8..].starts_with(&mp4) ||
|
||||
// Step 8. Let bytes-read be 16.
|
||||
// Step 9. While bytes-read is less than box-size, continuously loop through these steps:
|
||||
data[16..box_size]
|
||||
// Step 11. Increment bytes-read by 4.
|
||||
.chunks(4)
|
||||
// Step 10. If the three bytes from sequence[bytes-read] to sequence[bytes-read + 2]
|
||||
// are equal to 0x6D 0x70 0x34 ("mp4"), return true.
|
||||
.any(|chunk| chunk.starts_with(&mp4))
|
||||
// Step 12. Return false.
|
||||
}
|
||||
}
|
||||
impl MIMEChecker for Mp4Matcher {
|
||||
|
@ -494,7 +503,15 @@ impl MIMEChecker for Mp4Matcher {
|
|||
struct BinaryOrPlaintextClassifier;
|
||||
|
||||
impl BinaryOrPlaintextClassifier {
|
||||
/// <https://mimesniff.spec.whatwg.org/#rules-for-text-or-binary>
|
||||
fn classify_impl(&self, data: &[u8]) -> Mime {
|
||||
// Step 1. Let length be the number of bytes in the resource header.
|
||||
// Step 2. If length is greater than or equal to 2 and
|
||||
// the first 2 bytes of the resource header are equal to 0xFE 0xFF (UTF-16BE BOM)
|
||||
// or 0xFF 0xFE (UTF-16LE BOM), the computed MIME type is "text/plain".
|
||||
// Step 3. If length is greater than or equal to 3
|
||||
// and the first 3 bytes of the resource header are equal to
|
||||
// 0xEF 0xBB 0xBF (UTF-8 BOM), the computed MIME type is "text/plain".
|
||||
if data.starts_with(&[0xFFu8, 0xFEu8]) ||
|
||||
data.starts_with(&[0xFEu8, 0xFFu8]) ||
|
||||
data.starts_with(&[0xEFu8, 0xBBu8, 0xBFu8])
|
||||
|
@ -506,8 +523,11 @@ impl BinaryOrPlaintextClassifier {
|
|||
(0x0Eu8..=0x1Au8).contains(&x) ||
|
||||
(0x1Cu8..=0x1Fu8).contains(&x)
|
||||
}) {
|
||||
// Step 5. The computed MIME type is "application/octet-stream".
|
||||
mime::APPLICATION_OCTET_STREAM
|
||||
} else {
|
||||
// Step 4. If the resource header contains no binary data bytes,
|
||||
// the computed MIME type is "text/plain".
|
||||
mime::TEXT_PLAIN
|
||||
}
|
||||
}
|
||||
|
@ -629,120 +649,6 @@ impl MIMEChecker for GroupedClassifier {
|
|||
}
|
||||
}
|
||||
|
||||
enum Match {
|
||||
None,
|
||||
Start,
|
||||
StartAndEnd,
|
||||
}
|
||||
|
||||
impl Match {
|
||||
fn chain<F: FnOnce() -> Match>(self, f: F) -> Match {
|
||||
if let Match::None = self {
|
||||
return f();
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn eats_until<'a, T>(matcher: &mut T, start: &[u8], end: &[u8]) -> Match
|
||||
where
|
||||
T: Iterator<Item = &'a u8> + Clone,
|
||||
{
|
||||
if !matcher.matches(start) {
|
||||
Match::None
|
||||
} else if end.len() == 1 {
|
||||
if matcher.any(|&x| x == end[0]) {
|
||||
Match::StartAndEnd
|
||||
} else {
|
||||
Match::Start
|
||||
}
|
||||
} else {
|
||||
while !matcher.matches(end) {
|
||||
if matcher.next().is_none() {
|
||||
return Match::Start;
|
||||
}
|
||||
}
|
||||
Match::StartAndEnd
|
||||
}
|
||||
}
|
||||
|
||||
struct FeedsClassifier;
|
||||
impl FeedsClassifier {
|
||||
// Implements sniffing for mislabeled feeds (https://mimesniff.spec.whatwg.org/#sniffing-a-mislabeled-feed)
|
||||
fn classify_impl(&self, data: &[u8]) -> Option<Mime> {
|
||||
// Step 4: can not be feed unless length is > 3
|
||||
if data.len() < 3 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut matcher = data.iter();
|
||||
|
||||
// eat the first three acceptable byte sequences if they are equal to UTF-8 BOM
|
||||
let utf8_bom = &[0xEFu8, 0xBBu8, 0xBFu8];
|
||||
matcher.matches(utf8_bom);
|
||||
|
||||
// continuously search for next "<" until end of matcher
|
||||
// TODO: need max_bytes to prevent inadvertently examining html document
|
||||
// eg. an html page with a feed example
|
||||
loop {
|
||||
if !matcher.any(|x| *x == b'<') {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Steps 5.2.1 to 5.2.4
|
||||
match eats_until(&mut matcher, b"?", b"?>")
|
||||
.chain(|| eats_until(&mut matcher, b"!--", b"-->"))
|
||||
.chain(|| eats_until(&mut matcher, b"!", b">"))
|
||||
{
|
||||
Match::StartAndEnd => continue,
|
||||
Match::None => {},
|
||||
Match::Start => return None,
|
||||
}
|
||||
|
||||
// Step 5.2.5
|
||||
if matcher.matches(b"rss") {
|
||||
return Some("application/rss+xml".parse().unwrap());
|
||||
}
|
||||
// Step 5.2.6
|
||||
if matcher.matches(b"feed") {
|
||||
return Some("application/atom+xml".parse().unwrap());
|
||||
}
|
||||
// Step 5.2.7
|
||||
if matcher.matches(b"rdf:RDF") {
|
||||
while matcher.next().is_some() {
|
||||
match eats_until(
|
||||
&mut matcher,
|
||||
b"http://purl.org/rss/1.0/",
|
||||
b"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
||||
)
|
||||
.chain(|| {
|
||||
eats_until(
|
||||
&mut matcher,
|
||||
b"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
||||
b"http://purl.org/rss/1.0/",
|
||||
)
|
||||
}) {
|
||||
Match::StartAndEnd => return Some("application/rss+xml".parse().unwrap()),
|
||||
Match::None => {},
|
||||
Match::Start => return None,
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MIMEChecker for FeedsClassifier {
|
||||
fn classify(&self, data: &[u8]) -> Option<Mime> {
|
||||
self.classify_impl(data)
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Contains hard coded byte matchers
|
||||
// TODO: These should be configured and not hard coded
|
||||
impl ByteMatcher {
|
||||
|
|
|
@ -496,51 +496,6 @@ fn test_sniff_utf_8_bom() {
|
|||
test_sniff_classification("utf8bom.txt", mime::TEXT_PLAIN, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sniff_rss_feed() {
|
||||
// RSS feeds
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/feed.rss"),
|
||||
"application/rss+xml".parse().unwrap(),
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/rdf_rss.xml"),
|
||||
"application/rss+xml".parse().unwrap(),
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
// Not RSS feeds
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/rdf_rss_ko_1.xml"),
|
||||
mime::TEXT_HTML,
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/rdf_rss_ko_2.xml"),
|
||||
mime::TEXT_HTML,
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/rdf_rss_ko_3.xml"),
|
||||
mime::TEXT_HTML,
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/rdf_rss_ko_4.xml"),
|
||||
mime::TEXT_HTML,
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sniff_atom_feed() {
|
||||
test_sniff_full(
|
||||
&PathBuf::from("text/xml/feed.atom"),
|
||||
"application/atom+xml".parse().unwrap(),
|
||||
Some(mime::TEXT_HTML),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sniff_binary_file() {
|
||||
test_sniff_full(
|
||||
|
@ -550,28 +505,6 @@ fn test_sniff_binary_file() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sniff_atom_feed_with_no_sniff_flag_on() {
|
||||
test_sniff_with_flags(
|
||||
&PathBuf::from("text/xml/feed.atom"),
|
||||
mime::TEXT_HTML,
|
||||
Some(mime::TEXT_HTML),
|
||||
NoSniffFlag::On,
|
||||
ApacheBugFlag::Off,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sniff_with_no_sniff_flag_on_and_apache_flag_on() {
|
||||
test_sniff_with_flags(
|
||||
&PathBuf::from("text/xml/feed.atom"),
|
||||
mime::TEXT_HTML,
|
||||
Some(mime::TEXT_HTML),
|
||||
NoSniffFlag::On,
|
||||
ApacheBugFlag::On,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sniff_utf_8_bom_with_apache_flag_on() {
|
||||
test_sniff_with_flags(
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<feed>
|
|
@ -1,151 +0,0 @@
|
|||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>FeedForAll Sample Feed</title>
|
||||
<description>RSS is a fascinating technology. The uses for RSS are expanding daily. Take a closer look at how various industries are using the benefits of RSS in their businesses.</description>
|
||||
<link>http://www.feedforall.com/industry-solutions.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<copyright>Copyright 2004 NotePage, Inc.</copyright>
|
||||
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate>Tue, 19 Oct 2004 13:39:14 -0400</lastBuildDate>
|
||||
<managingEditor>marketing@feedforall.com</managingEditor>
|
||||
<pubDate>Tue, 19 Oct 2004 13:38:55 -0400</pubDate>
|
||||
<webMaster>webmaster@feedforall.com</webMaster>
|
||||
<generator>FeedForAll Beta1 (0.0.1.8)</generator>
|
||||
<image>
|
||||
<url>http://www.feedforall.com/ffalogo48x48.gif</url>
|
||||
<title>FeedForAll Sample Feed</title>
|
||||
<link>http://www.feedforall.com/industry-solutions.htm</link>
|
||||
<description>FeedForAll Sample Feed</description>
|
||||
<width>48</width>
|
||||
<height>48</height>
|
||||
</image>
|
||||
<item>
|
||||
<title>RSS Solutions for Restaurants</title>
|
||||
<description><b>FeedForAll </b>helps Restaurant's communicate with customers. Let your customers know the latest specials or events.<br>
|
||||
<br>
|
||||
RSS feed uses include:<br>
|
||||
<i><font color="#FF0000">Daily Specials <br>
|
||||
Entertainment <br>
|
||||
Calendar of Events </i></font></description>
|
||||
<link>http://www.feedforall.com/restaurant.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:09:11 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Schools and Colleges</title>
|
||||
<description>FeedForAll helps Educational Institutions communicate with students about school wide activities, events, and schedules.<br>
|
||||
<br>
|
||||
RSS feed uses include:<br>
|
||||
<i><font color="#0000FF">Homework Assignments <br>
|
||||
School Cancellations <br>
|
||||
Calendar of Events <br>
|
||||
Sports Scores <br>
|
||||
Clubs/Organization Meetings <br>
|
||||
Lunches Menus </i></font></description>
|
||||
<link>http://www.feedforall.com/schools.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:09:09 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Computer Service Companies</title>
|
||||
<description>FeedForAll helps Computer Service Companies communicate with clients about cyber security and related issues. <br>
|
||||
<br>
|
||||
Uses include:<br>
|
||||
<i><font color="#0000FF">Cyber Security Alerts <br>
|
||||
Specials<br>
|
||||
Job Postings </i></font></description>
|
||||
<link>http://www.feedforall.com/computer-service.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:09:07 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Governments</title>
|
||||
<description>FeedForAll helps Governments communicate with the general public about positions on various issues, and keep the community aware of changes in important legislative issues. <b><i><br>
|
||||
</b></i><br>
|
||||
RSS uses Include:<br>
|
||||
<i><font color="#00FF00">Legislative Calendar<br>
|
||||
Votes<br>
|
||||
Bulletins</i></font></description>
|
||||
<link>http://www.feedforall.com/government.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:09:05 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Politicians</title>
|
||||
<description>FeedForAll helps Politicians communicate with the general public about positions on various issues, and keep the community notified of their schedule. <br>
|
||||
<br>
|
||||
Uses Include:<br>
|
||||
<i><font color="#FF0000">Blogs<br>
|
||||
Speaking Engagements <br>
|
||||
Statements<br>
|
||||
</i></font></description>
|
||||
<link>http://www.feedforall.com/politics.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:09:03 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Meteorologists</title>
|
||||
<description>FeedForAll helps Meteorologists communicate with the general public about storm warnings and weather alerts, in specific regions. Using RSS meteorologists are able to quickly disseminate urgent and life threatening weather warnings. <br>
|
||||
<br>
|
||||
Uses Include:<br>
|
||||
<i><font color="#0000FF">Weather Alerts<br>
|
||||
Plotting Storms<br>
|
||||
School Cancellations </i></font></description>
|
||||
<link>http://www.feedforall.com/weather.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:09:01 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Realtors & Real Estate Firms</title>
|
||||
<description>FeedForAll helps Realtors and Real Estate companies communicate with clients informing them of newly available properties, and open house announcements. RSS helps to reach a targeted audience and spread the word in an inexpensive, professional manner. <font color="#0000FF"><br>
|
||||
</font><br>
|
||||
Feeds can be used for:<br>
|
||||
<i><font color="#FF0000">Open House Dates<br>
|
||||
New Properties For Sale<br>
|
||||
Mortgage Rates</i></font></description>
|
||||
<link>http://www.feedforall.com/real-estate.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:08:59 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Banks / Mortgage Companies</title>
|
||||
<description>FeedForAll helps <b>Banks, Credit Unions and Mortgage companies</b> communicate with the general public about rate changes in a prompt and professional manner. <br>
|
||||
<br>
|
||||
Uses include:<br>
|
||||
<i><font color="#0000FF">Mortgage Rates<br>
|
||||
Foreign Exchange Rates <br>
|
||||
Bank Rates<br>
|
||||
Specials</i></font></description>
|
||||
<link>http://www.feedforall.com/banks.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:08:57 -0400</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>RSS Solutions for Law Enforcement</title>
|
||||
<description><b>FeedForAll</b> helps Law Enforcement Professionals communicate with the general public and other agencies in a prompt and efficient manner. Using RSS police are able to quickly disseminate urgent and life threatening information. <br>
|
||||
<br>
|
||||
Uses include:<br>
|
||||
<i><font color="#0000FF">Amber Alerts<br>
|
||||
Sex Offender Community Notification <br>
|
||||
Weather Alerts <br>
|
||||
Scheduling <br>
|
||||
Security Alerts <br>
|
||||
Police Report <br>
|
||||
Meetings</i></font></description>
|
||||
<link>http://www.feedforall.com/law-enforcement.htm</link>
|
||||
<category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
|
||||
<comments>http://www.feedforall.com/forum</comments>
|
||||
<pubDate>Tue, 19 Oct 2004 11:08:56 -0400</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
|
@ -1,7 +0,0 @@
|
|||
<!-- Good format for a "RDF feed" -->
|
||||
<?xml version="1.0"?>
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
>
|
||||
</rdf:RDF>
|
|
@ -1,7 +0,0 @@
|
|||
<!-- Bad format for a "RDF feed" (space between "rdf:" and "RDF") -->
|
||||
<?xml version="1.0"?>
|
||||
<rdf: RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
>
|
||||
</rdf:RDF>
|
|
@ -1,3 +0,0 @@
|
|||
<!-- Bad format for a "RDF feed" (2 missing URLs) -->
|
||||
<?xml version="1.0"?>
|
||||
<rdf:RDF/>
|
|
@ -1,6 +0,0 @@
|
|||
<!-- Bad format for a "RDF feed" (one missing URL) -->
|
||||
<?xml version="1.0"?>
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
>
|
||||
</rdf:RDF>
|
|
@ -1,7 +0,0 @@
|
|||
<!-- Bad format for a "RDF feed" (unexpected space in first URL) -->
|
||||
<?xml version="1.0"?>
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http: //www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
>
|
||||
</rdf:RDF>
|
|
@ -1,2 +1,2 @@
|
|||
[Document-createElement-svg.svg]
|
||||
expected: TIMEOUT
|
||||
expected: ERROR
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[parser-uses-create-an-element-for-a-token-svg.svg]
|
||||
expected: TIMEOUT
|
||||
expected: ERROR
|
||||
|
|
|
@ -49,3 +49,9 @@
|
|||
|
||||
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,51 +1,21 @@
|
|||
[anchor.tentative.https.window.html?include=from-treat-as-public]
|
||||
[treat-as-public-address to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local (same-origin): no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[anchor.tentative.https.window.html?include=from-public]
|
||||
[public to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -55,18 +25,27 @@
|
|||
[public to public to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[anchor.tentative.https.window.html?include=from-local]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[anchor.tentative.https.window.html?include=from-private]
|
||||
[private to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
[anchor.tentative.window.html]
|
||||
[private to local: failure.]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: failure.]
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failure.]
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: failure.]
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failure.]
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,54 +1,39 @@
|
|||
[iframe.tentative.https.window.html?include=from-treat-as-public]
|
||||
[treat-as-public-address to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: missing CORS headers.]
|
||||
[treat-as-public-address to local (same-origin): no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: missing PNA header.]
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: missing PNA header.]
|
||||
[treat-as-public-address to local: optional preflight]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[iframe.tentative.https.window.html?include=from-local]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[iframe.tentative.https.window.html?include=from-public]
|
||||
[public to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: missing PNA header.]
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
|
@ -59,16 +44,19 @@
|
|||
[public to local, grandparent navigates: success.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[iframe.tentative.https.window.html?include=from-private]
|
||||
[private to local: failed preflight.]
|
||||
[local to local, grandparent navigates: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to local (same-origin), grandparent navigates: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[iframe.tentative.https.window.html?include=from-private]
|
||||
[private to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: missing CORS headers.]
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: missing PNA header.]
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
[iframe.tentative.window.html]
|
||||
[private to local: failure.]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: failure.]
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failure.]
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: failure.]
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failure.]
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to local, grandparent navigates: success.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
[window-open-existing.tentative.window.html]
|
||||
[private to local: failure.]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: failure.]
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failure.]
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: failure.]
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failure.]
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -46,69 +46,54 @@
|
|||
|
||||
|
||||
[window-open.tentative.https.window.html?include=from-local]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: optional preflight]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[window-open.tentative.https.window.html?include=from-treat-as-public]
|
||||
[treat-as-public-address to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local (same-origin): no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: optional preflight]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[window-open.tentative.https.window.html?include=from-private]
|
||||
[private to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[private to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: optional preflight]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[window-open.tentative.https.window.html?include=from-public]
|
||||
[public to local: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: success.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failed preflight.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: missing CORS headers.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: missing PNA header.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -117,3 +102,9 @@
|
|||
|
||||
[public to public to private: success.]
|
||||
expected: FAIL
|
||||
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: optional preflight]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
[window-open.tentative.window.html]
|
||||
[private to local: failure.]
|
||||
[local to local: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to local: failure.]
|
||||
[local to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to private: failure.]
|
||||
[local to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to local: failure.]
|
||||
[private to private: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to private: failure.]
|
||||
[private to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[public to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
||||
[treat-as-public-address to public: no preflight required.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[user-interaction-editing-designMode-svg.svg]
|
||||
expected: TIMEOUT
|
||||
expected: ERROR
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
[navigation-type-post-backforward.html]
|
||||
expected: TIMEOUT
|
||||
[Navigation type after posting and navigating away and back should be back_forward.]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
[preload-type-match.html]
|
||||
[Preload with {as=track; type=text/vtt} should load when retrieved resource is a track]
|
||||
expected: FAIL
|
||||
|
||||
[Preload with {as=image; type=image/unknown} should timeout when retrieved resource is a png]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue