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

Implement MIME sniffing #5005

Merged
merged 6 commits into from Apr 7, 2015
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Remove the sniffer task.

  • Loading branch information
jdm committed Apr 6, 2015
commit 2d730f2ae947a369e6f82869dd4e6f3604b40709
@@ -4,7 +4,7 @@

use net_traits::{LoadData, Metadata};
use net_traits::ProgressMsg::Done;
use resource_task::{TargetedLoadResponse, start_sending, ResponseSenders};
use resource_task::start_sending;
use file_loader;

use url::Url;
@@ -13,16 +13,12 @@ use util::resource_files::resources_dir_path;

use std::borrow::IntoCow;
use std::fs::PathExt;
use std::sync::mpsc::Sender;

pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
let senders = ResponseSenders {
immediate_consumer: start_chan.clone(),
eventual_consumer: load_data.consumer.clone(),
};
pub fn factory(mut load_data: LoadData) {
match load_data.url.non_relative_scheme_data().unwrap() {
"blank" => {
let chan = start_sending(senders, Metadata {
let start_chan = load_data.consumer;
let chan = start_sending(start_chan, Metadata {
final_url: load_data.url,
content_type: Some(("text".to_string(), "html".to_string())),
charset: Some("utf-8".to_string()),
@@ -40,10 +36,11 @@ pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>
load_data.url = Url::from_file_path(&*path).unwrap();
}
_ => {
start_sending(senders, Metadata::default(load_data.url))
let start_chan = load_data.consumer;
start_sending(start_chan, Metadata::default(load_data.url))
.send(Done(Err("Unknown about: URL.".to_string()))).unwrap();
return
}
};
file_loader::factory(load_data, start_chan)
file_loader::factory(load_data)
}
@@ -4,34 +4,28 @@

use net_traits::{LoadData, Metadata};
use net_traits::ProgressMsg::{Payload, Done};
use resource_task::{TargetedLoadResponse, start_sending, ResponseSenders};
use resource_task::start_sending;

use rustc_serialize::base64::FromBase64;

use hyper::mime::Mime;
use url::{percent_decode, SchemeData};

use std::sync::mpsc::Sender;

pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
pub fn factory(load_data: LoadData) {
// NB: we don't spawn a new task.
// Hypothesis: data URLs are too small for parallel base64 etc. to be worth it.
// Should be tested at some point.
// Left in separate function to allow easy moving to a task, if desired.
load(load_data, start_chan)
load(load_data)
}

fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
fn load(load_data: LoadData) {
let start_chan = load_data.consumer;
let url = load_data.url;
assert!(&*url.scheme == "data");

let mut metadata = Metadata::default(url.clone());

let senders = ResponseSenders {
immediate_consumer: start_chan,
eventual_consumer: load_data.consumer,
};

// Split out content type and data.
let mut scheme_data = match url.scheme_data {
SchemeData::NonRelative(scheme_data) => scheme_data,
@@ -46,7 +40,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
}
let parts: Vec<&str> = scheme_data.splitn(1, ',').collect();
if parts.len() != 2 {
start_sending(senders, metadata).send(Done(Err("invalid data uri".to_string()))).unwrap();
start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string()))).unwrap();
return;
}

@@ -64,7 +58,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
let content_type: Option<Mime> = ct_str.parse().ok();
metadata.set_content_type(content_type.as_ref());

let progress_chan = start_sending(senders, metadata);
let progress_chan = start_sending(start_chan, metadata);
let bytes = percent_decode(parts[1].as_bytes());

if is_base64 {
@@ -93,11 +87,9 @@ fn assert_parse(url: &'static str,
data: Option<Vec<u8>>) {
use std::sync::mpsc::channel;
use url::Url;
use sniffer_task;

let (start_chan, start_port) = channel();
let sniffer_task = sniffer_task::new_mock_sniffer_task();
load(LoadData::new(Url::parse(url).unwrap(), start_chan), sniffer_task);
load(LoadData::new(Url::parse(url).unwrap(), start_chan));

let response = start_port.recv().unwrap();
assert_eq!(&response.metadata.content_type, &content_type);
@@ -4,7 +4,7 @@

use net_traits::{LoadData, Metadata, ProgressMsg};
use net_traits::ProgressMsg::{Payload, Done};
use resource_task::{start_sending, TargetedLoadResponse, ResponseSenders};
use resource_task::start_sending;

use std::borrow::ToOwned;
use std::io;
@@ -30,14 +30,11 @@ fn read_all(reader: &mut io::Read, progress_chan: &Sender<ProgressMsg>)
}
}

pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
pub fn factory(load_data: LoadData) {
let url = load_data.url;
let start_chan = load_data.consumer;
assert!(&*url.scheme == "file");
let senders = ResponseSenders {
immediate_consumer: start_chan,
eventual_consumer: load_data.consumer,
};
let progress_chan = start_sending(senders, Metadata::default(url.clone()));
let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
spawn_named("file_loader".to_owned(), move || {
let file_path: Result<PathBuf, ()> = url.to_file_path();
match file_path {
@@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use net_traits::{ControlMsg, CookieSource, LoadData, Metadata};
use net_traits::{ControlMsg, CookieSource, LoadData, LoadResponse, Metadata};
use net_traits::ProgressMsg;
use net_traits::ProgressMsg::{Payload, Done};
use resource_task::{TargetedLoadResponse, start_sending_opt, ResponseSenders};
use resource_task::start_sending_opt;

use log;
use std::collections::HashSet;
@@ -31,36 +31,32 @@ use url::{Url, UrlParser};
use std::borrow::ToOwned;

pub fn factory(cookies_chan: Sender<ControlMsg>)
-> Box<Invoke<(LoadData, Sender<TargetedLoadResponse>)> + Send> {
box move |(load_data, start_chan)| {
spawn_named("http_loader".to_owned(), move || load(load_data, start_chan, cookies_chan))
-> Box<Invoke<(LoadData,)> + Send> {
box move |(load_data,)| {
spawn_named("http_loader".to_owned(), move || load(load_data, cookies_chan))
}
}

fn send_error(url: Url, err: String, senders: ResponseSenders) {
fn send_error(url: Url, err: String, start_chan: Sender<LoadResponse>) {
let mut metadata: Metadata = Metadata::default(url);
metadata.status = None;

match start_sending_opt(senders, metadata) {
match start_sending_opt(start_chan, metadata) {
Ok(p) => p.send(Done(Err(err))).unwrap(),
_ => {}
};
}

fn load(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>, cookies_chan: Sender<ControlMsg>) {
fn load(mut load_data: LoadData, cookies_chan: Sender<ControlMsg>) {
// FIXME: At the time of writing this FIXME, servo didn't have any central
// location for configuration. If you're reading this and such a
// repository DOES exist, please update this constant to use it.
let max_redirects = 50u;
let mut iters = 0u;
let start_chan = load_data.consumer;
let mut url = load_data.url.clone();
let mut redirected_to = HashSet::new();

let senders = ResponseSenders {
immediate_consumer: start_chan,
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
@@ -73,7 +69,7 @@ fn load(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>, cooki
"http" | "https" => {}
_ => {
let s = format!("The {} scheme with view-source is not supported", url.scheme);
send_error(url, s, senders);
send_error(url, s, start_chan);
return;
}
};
@@ -84,15 +80,15 @@ fn load(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>, cooki
iters = iters + 1;

if iters > max_redirects {
send_error(url, "too many redirects".to_string(), senders);
send_error(url, "too many redirects".to_string(), start_chan);
return;
}

match &*url.scheme {
"http" | "https" => {}
_ => {
let s = format!("{} request, but we don't support that scheme", url.scheme);
send_error(url, s, senders);
send_error(url, s, start_chan);
return;
}
}
@@ -125,13 +121,13 @@ reason: \"certificate verify failed\" }]";
) => {
let mut image = resources_dir_path();
image.push("badcert.html");
let load_data = LoadData::new(Url::from_file_path(&*image).unwrap(), senders.eventual_consumer);
file_loader::factory(load_data, senders.immediate_consumer);
let load_data = LoadData::new(Url::from_file_path(&*image).unwrap(), start_chan);
file_loader::factory(load_data);
return;
},
Err(e) => {
println!("{:?}", e);
send_error(url, e.description().to_string(), senders);
send_error(url, e.description().to_string(), start_chan);
return;
}
};
@@ -179,13 +175,13 @@ reason: \"certificate verify failed\" }]";
let mut writer = match req.start() {
Ok(w) => w,
Err(e) => {
send_error(url, e.description().to_string(), senders);
send_error(url, e.description().to_string(), start_chan);
return;
}
};
match writer.write_all(&*data) {
Err(e) => {
send_error(url, e.description().to_string(), senders);
send_error(url, e.description().to_string(), start_chan);
return;
}
_ => {}
@@ -200,7 +196,7 @@ reason: \"certificate verify failed\" }]";
match req.start() {
Ok(w) => w,
Err(e) => {
send_error(url, e.description().to_string(), senders);
send_error(url, e.description().to_string(), start_chan);
return;
}
}
@@ -209,7 +205,7 @@ reason: \"certificate verify failed\" }]";
let mut response = match writer.send() {
Ok(r) => r,
Err(e) => {
send_error(url, e.description().to_string(), senders);
send_error(url, e.description().to_string(), start_chan);
return;
}
};
@@ -240,7 +236,7 @@ reason: \"certificate verify failed\" }]";
Some(ref c) => {
if c.preflight {
// The preflight lied
send_error(url, "Preflight fetch inconsistent with main fetch".to_string(), senders);
send_error(url, "Preflight fetch inconsistent with main fetch".to_string(), start_chan);
return;
} else {
// XXXManishearth There are some CORS-related steps here,
@@ -252,7 +248,7 @@ reason: \"certificate verify failed\" }]";
let new_url = match UrlParser::new().base_url(&url).parse(&new_url) {
Ok(u) => u,
Err(e) => {
send_error(url, e.to_string(), senders);
send_error(url, e.to_string(), start_chan);
return;
}
};
@@ -268,7 +264,7 @@ reason: \"certificate verify failed\" }]";
}

if redirected_to.contains(&url) {
send_error(url, "redirect loop".to_string(), senders);
send_error(url, "redirect loop".to_string(), start_chan);
return;
}

@@ -291,7 +287,7 @@ reason: \"certificate verify failed\" }]";
metadata.headers = Some(adjusted_headers);
metadata.status = Some(response.status_raw().clone());

let progress_chan = match start_sending_opt(senders, metadata) {
let progress_chan = match start_sending_opt(start_chan, metadata) {
Ok(p) => p,
_ => return
};
@@ -46,7 +46,6 @@ pub mod image_cache_task;
pub mod pub_domains;
pub mod resource_task;
pub mod storage_task;
mod sniffer_task;
mod mime_classifier;

/// An implementation of the [Fetch spec](http://fetch.spec.whatwg.org/)
@@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![allow(dead_code)]

use std::borrow::ToOwned;
use std::cmp::max;

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