Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

view-source protocol and text/plain handling #5219

Closed
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -14,6 +14,7 @@ use hyper::client::Request;
use hyper::header::{ContentLength, ContentType, Host, Location};
use hyper::HttpError;
use hyper::method::Method;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::net::HttpConnector;
use hyper::status::{StatusCode, StatusClass};
use std::error::Error;
@@ -59,6 +60,26 @@ fn load(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>, cooki
eventual_consumer: load_data.consumer
};

// If the URL is a view-source scheme then the scheme data contains the
// real URL that should be used for which the source is to be viewed.
// Change our existing URL to that and keep note that we are viewing
// the source rather than rendering the contents of the URL.
let viewing_source = if url.scheme == "view-source" {
let inner_url = load_data.url.non_relative_scheme_data().unwrap();
url = Url::parse(inner_url).unwrap();
match url.scheme.as_slice() {
"http" | "https" => {}
_ => {
let s = format!("The {} scheme with view-source is not supported", url.scheme);
send_error(url, s, senders);
return;
}
};
true
} else {
false
};

// Loop to handle redirects.
loop {
iters = iters + 1;
@@ -259,12 +280,16 @@ reason: \"certificate verify failed\" }]";
}
}

let mut adjusted_headers = response.headers.clone();
if viewing_source {
adjusted_headers.set(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![])));
}
let mut metadata = Metadata::default(url);
metadata.set_content_type(match response.headers.get() {
metadata.set_content_type(match adjusted_headers.get() {
Some(&ContentType(ref mime)) => Some(mime),
None => None
});
metadata.headers = Some(response.headers.clone());
metadata.headers = Some(adjusted_headers);
metadata.status = Some(response.status_raw().clone());

let progress_chan = match start_sending_opt(senders, metadata) {
@@ -333,7 +333,7 @@ impl ResourceManager {

let loader = match load_data.url.scheme.as_slice() {
"file" => from_factory(file_loader::factory),
"http" | "https" => http_loader::factory(self.resource_task.clone()),
"http" | "https" | "view-source" => http_loader::factory(self.resource_task.clone()),
"data" => from_factory(data_loader::factory),
"about" => from_factory(about_loader::factory),
_ => {
@@ -180,6 +180,22 @@ pub fn parse_html(document: JSRef<Document>,
task_state::enter(IN_HTML_PARSER);
}

fn parse_progress(parser: &JSRef<ServoHTMLParser>, url: &Url, load_response: &LoadResponse) {
for msg in load_response.progress_port.iter() {
match msg {
ProgressMsg::Payload(data) => {
// FIXME: use Vec<u8> (html5ever #34)
let data = UTF_8.decode(data.as_slice(), DecoderTrap::Replace).unwrap();
parser.parse_chunk(data);
}
ProgressMsg::Done(Err(err)) => {
panic!("Failed to load page URL {}, error: {}", url.serialize(), err);
}
ProgressMsg::Done(Ok(())) => break,
}
}
};

match input {
HTMLInput::InputString(s) => {
parser.parse_chunk(s);
@@ -190,20 +206,22 @@ pub fn parse_html(document: JSRef<Document>,
let page = format!("<html><body><img src='{}' /></body></html>", url.serialize());
parser.parse_chunk(page);
},
Some((ref t, ref st)) if t.as_slice().eq_ignore_ascii_case("text") &&
st.as_slice().eq_ignore_ascii_case("plain") => {
// FIXME: When servo/html5ever#109 is fixed remove <plaintext> usage and
// replace with fix from that issue.

// text/plain documents require setting the tokenizer into PLAINTEXT mode.
// This is done by using a <plaintext> element as the html5ever tokenizer
// provides no other way to change to that state.
// Spec for text/plain handling is:
// https://html.spec.whatwg.org/multipage/browsers.html#read-text
let page = format!("<pre>\u{000A}<plaintext>");
parser.parse_chunk(page);
parse_progress(&parser, url, &load_response);
},
_ => {
for msg in load_response.progress_port.iter() {
match msg {
ProgressMsg::Payload(data) => {
// FIXME: use Vec<u8> (html5ever #34)
let data = UTF_8.decode(data.as_slice(), DecoderTrap::Replace).unwrap();
parser.parse_chunk(data);
}
ProgressMsg::Done(Err(err)) => {
panic!("Failed to load page URL {}, error: {}", url.serialize(), err);
}
ProgressMsg::Done(Ok(())) => break,
}
}
parse_progress(&parser, url, &load_response);
}
}
}
@@ -82,6 +82,7 @@ use js;
use url::Url;

use libc;
use std::ascii::AsciiExt;
use std::any::Any;
use std::borrow::ToOwned;
use std::cell::{Cell, RefCell};
@@ -984,10 +985,18 @@ impl ScriptTask {
headers.get().map(|&LastModified(ref tm)| dom_last_modified(tm))
});

let content_type = match response.metadata.content_type {
Some((ref t, ref st)) if t.as_slice().eq_ignore_ascii_case("text") &&
st.as_slice().eq_ignore_ascii_case("plain") => {
Some("text/plain".to_owned())
}
_ => None
};

let document = Document::new(window.r(),
Some(final_url.clone()),
IsHTMLDocument::HTMLDocument,
None,
content_type,
last_modified,
DocumentSource::FromParser).root();

@@ -1,11 +1,5 @@
[load-text-plain.html]
type: testharness
[Checking document metadata for text file]
expected: FAIL

[Checking DOM for text file]
expected: FAIL

[Checking contents for text file]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.