Implement MIME sniffing.

This commit is contained in:
Nathan Climer 2014-11-14 08:45:32 -05:00 committed by Josh Matthews
parent a277036dd9
commit 44930b0fb0
105 changed files with 2021 additions and 2 deletions

View file

@ -96,7 +96,7 @@ fn assert_parse(url: &'static str,
use sniffer_task;
let (start_chan, start_port) = channel();
let sniffer_task = sniffer_task::new_sniffer_task();
let sniffer_task = sniffer_task::new_mock_sniffer_task();
load(LoadData::new(Url::parse(url).unwrap(), start_chan), sniffer_task);
let response = start_port.recv().unwrap();

View file

@ -47,6 +47,7 @@ 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/)
pub mod fetch {

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,8 @@
//! A task that sniffs data
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread::Builder;
use resource_task::{TargetedLoadResponse};
use mime_classifier::MIMEClassifier;
use resource_task::{TargetedLoadResponse, LoadResponse, ProgressMsg};
pub type SnifferTask = Sender<TargetedLoadResponse>;
@ -20,17 +21,89 @@ pub fn new_sniffer_task() -> SnifferTask {
struct SnifferManager {
data_receiver: Receiver<TargetedLoadResponse>,
mime_classifier: MIMEClassifier
}
impl SnifferManager {
fn new(data_receiver: Receiver <TargetedLoadResponse>) -> SnifferManager {
SnifferManager {
data_receiver: data_receiver,
mime_classifier: MIMEClassifier::new()
}
}
}
impl SnifferManager {
fn start(self) {
for mut snif_data in self.data_receiver.iter() {
// Read all the data
let mut resource_data = vec!();
loop {
match snif_data.load_response.progress_port.recv().unwrap() {
ProgressMsg::Payload(data) => {
resource_data.push_all(data.as_slice());
}
ProgressMsg::Done(res) => {
let (new_progress_chan, new_progress_port) = channel();
// TODO: should be calculated in the resource loader, from pull requeset #4094
let nosniff = false;
let check_for_apache_bug = false;
// We have all the data, go ahead and sniff it and replace the Content-Type
if res.is_ok() {
snif_data.load_response.metadata.content_type = self.mime_classifier.classify(
nosniff,check_for_apache_bug,&snif_data.load_response.metadata.content_type,
&resource_data
);
}
let load_response = LoadResponse {
progress_port: new_progress_port,
metadata: snif_data.load_response.metadata,
};
if snif_data.consumer.send(load_response).is_err() {
break;
}
if resource_data.len() > 0 {
new_progress_chan.send(ProgressMsg::Payload(resource_data)).unwrap();
}
new_progress_chan.send(ProgressMsg::Done(res)).unwrap();
return;
}
}
}
} // end for
}
}
#[cfg(test)]
pub fn new_mock_sniffer_task() -> SnifferTask {
let(sen, rec) = channel();
let builder = TaskBuilder::new().named("SnifferManager");
builder.spawn(move || {
MockSnifferManager::new(rec).start();
});
sen
}
#[cfg(test)]
struct MockSnifferManager {
data_receiver: Receiver<TargetedLoadResponse>,
}
#[cfg(test)]
impl MockSnifferManager {
fn new(data_receiver: Receiver <TargetedLoadResponse>) -> MockSnifferManager {
MockSnifferManager {
data_receiver: data_receiver,
}
}
}
#[cfg(test)]
impl MockSnifferManager {
fn start(self) {
loop {
match self.data_receiver.recv() {