diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-02-05 20:30:45 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-02-05 20:30:45 -0700 |
commit | 237cdee9e462bc7b070d9fe1a7722ad961ff25c2 (patch) | |
tree | fcc4e97a0bc2920d86aa589c6c821ddd4fdec873 | |
parent | 6d1c13ea1bc94fe9383da684c6ee0e22851750ec (diff) | |
parent | c17f04771e56eeb6e813ecfa8857fbe8f4a3ff10 (diff) | |
download | servo-237cdee9e462bc7b070d9fe1a7722ad961ff25c2.tar.gz servo-237cdee9e462bc7b070d9fe1a7722ad961ff25c2.zip |
auto merge of #4702 : shinglyu/servo/bug3219, r=jdm
This is a fix for bug #3219 . This patch allows the user to specify a disposiable hostfile using the `HOST_FILE` environment variable. Therefore, we can run tests on test servers without actually changing the system hostfile.
-rw-r--r-- | components/net/resource_task.rs | 99 | ||||
-rw-r--r-- | components/servo/main.rs | 5 |
2 files changed, 102 insertions, 2 deletions
diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs index 14aacc5d451..70d871eebe6 100644 --- a/components/net/resource_task.rs +++ b/components/net/resource_task.rs @@ -25,6 +25,31 @@ use url::Url; use std::borrow::ToOwned; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thunk::Invoke; +use std::collections::HashMap; +use std::io::{BufferedReader, File}; +use std::mem; +use std::os; + +#[cfg(test)] +use std::io::{Listener, Acceptor, TimedOut}; +#[cfg(test)] +use std::io::net::tcp::TcpListener; + +static mut HOST_TABLE: Option<*mut HashMap<String, String>> = None; + +pub fn global_init() { + if let Some(host_file_path) = os::getenv("HOST_FILE") { + //TODO: handle bad file path and corrupted file + let path = Path::new(host_file_path); + let mut file = BufferedReader::new(File::open(&path)); + if let Ok(lines) = file.read_to_string(){ + unsafe { + let host_table: *mut HashMap<String, String> = mem::transmute(parse_hostfile(lines.as_slice())); + HOST_TABLE = Some(host_table); + } + } + } +} pub enum ControlMsg { /// Request the data associated with a particular URL @@ -203,6 +228,29 @@ pub fn new_resource_task(user_agent: Option<String>) -> ResourceTask { setup_chan } +pub fn parse_hostfile(hostfile_content: &str) -> Box<HashMap<String, String>> { + let mut host_table = HashMap::new(); + let lines: Vec<&str> = hostfile_content.split('\n').collect(); + for line in lines.iter() { + let ip_host: Vec<&str> = line.split(' ').collect(); + if ip_host.len() == 2 { + host_table.insert(ip_host[1].to_owned(), ip_host[0].to_owned()); + } + } + box host_table +} + +pub fn replace_hosts(mut load_data: LoadData, host_table: *mut HashMap<String, String>) -> LoadData { + if let Some(h) = load_data.url.domain_mut() { + unsafe { + if let Some(ip) = (*host_table).get(h) { + *h = ip.clone(); + } + } + } + return load_data; +} + struct ResourceManager { from_client: Receiver<ControlMsg>, user_agent: Option<String>, @@ -252,8 +300,13 @@ impl ResourceManager { } } - fn load(&mut self, load_data: LoadData) { - let mut load_data = load_data; + fn load(&mut self, mut load_data: LoadData) { + unsafe { + if let Some(host_table) = HOST_TABLE { + load_data = replace_hosts(load_data, host_table); + } + } + self.user_agent.as_ref().map(|ua| load_data.headers.set(UserAgent(ua.clone()))); let senders = ResponseSenders { immediate_consumer: self.sniffer_task.clone(), @@ -334,3 +387,45 @@ fn test_bad_scheme() { } resource_task.send(ControlMsg::Exit); } + +#[test] +fn test_parse_hostfile() { + let mock_host_file_content = "127.0.0.1 foo.bar.com\n127.0.0.2 servo.test.server"; + let host_table = parse_hostfile(mock_host_file_content); + assert_eq!(2, (*host_table).len()); + assert_eq!("127.0.0.1".to_owned(), *host_table.get(&"foo.bar.com".to_owned()).unwrap()); + assert_eq!("127.0.0.2".to_owned(), *host_table.get(&"servo.test.server".to_owned()).unwrap()); +} + +//TODO: test mal-formed file content + +#[test] +fn test_replace_hosts() { + let mut host_table_box = box HashMap::new(); + host_table_box.insert("foo.bar.com".to_owned(), "127.0.0.1".to_owned()); + host_table_box.insert("servo.test.server".to_owned(), "127.0.0.2".to_owned()); + + let host_table: *mut HashMap<String, String> = unsafe {mem::transmute(host_table_box)}; + + //Start the TCP server + let mut listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let port = listener.socket_name().unwrap().port; + let mut acceptor = listener.listen().unwrap(); + + //Start the resource task and make a request to our TCP server + let resource_task = new_resource_task(None); + let (start_chan, _) = channel(); + let mut raw_url: String = "http://foo.bar.com:".to_string(); + raw_url = raw_url + port.to_string().as_slice(); + let url = Url::parse(raw_url.as_slice()).unwrap(); + resource_task.send(ControlMsg::Load(replace_hosts(LoadData::new(url, start_chan), host_table))); + + match acceptor.accept() { + Ok(..) => assert!(true, "received request"), + Err(ref e) if e.kind == TimedOut => { assert!(false, "timed out!"); }, + Err(_) => assert!(false, "error") + } + + resource_task.send(ControlMsg::Exit); + drop(acceptor); +} diff --git a/components/servo/main.rs b/components/servo/main.rs index 5d9231e8b38..fa508400dd1 100644 --- a/components/servo/main.rs +++ b/components/servo/main.rs @@ -12,6 +12,7 @@ extern crate libc; extern crate servo; extern crate time; extern crate util; +extern crate "net" as servo_net; #[cfg(not(test))] extern crate "glutin_app" as app; @@ -30,6 +31,9 @@ use libc::c_int; use util::opts; #[cfg(not(test))] +use servo_net::resource_task; + +#[cfg(not(test))] use servo::Browser; #[cfg(not(test))] use compositing::windowing::WindowEvent; @@ -113,6 +117,7 @@ fn setup_logging() { fn main() { if opts::from_cmdline_args(get_args().as_slice()) { setup_logging(); + resource_task::global_init(); let window = if opts::get().headless { None |