diff --git a/components/devtools/actors/network_event.rs b/components/devtools/actors/network_event.rs index cd0ccc7cbf5..262e1e4696b 100644 --- a/components/devtools/actors/network_event.rs +++ b/components/devtools/actors/network_event.rs @@ -9,13 +9,14 @@ extern crate hyper; use actor::{Actor, ActorMessageStatus, ActorRegistry}; +use devtools_traits::HttpRequest as DevtoolsHttpRequest; +use devtools_traits::HttpResponse as DevtoolsHttpResponse; use hyper::header::Headers; use hyper::http::RawStatus; use hyper::method::Method; use protocol::JsonPacketStream; use rustc_serialize::json; use std::net::TcpStream; -use url::Url; struct HttpRequest { url: String, @@ -125,18 +126,18 @@ impl NetworkEventActor { } } - pub fn add_request(&mut self, url: Url, method: Method, headers: Headers, body: Option>) { - self.request.url = url.serialize(); - self.request.method = method.clone(); - self.request.headers = headers.clone(); - self.request.body = body; + pub fn add_request(&mut self, request: DevtoolsHttpRequest) { + self.request.url = request.url.serialize(); + self.request.method = request.method.clone(); + self.request.headers = request.headers.clone(); + self.request.body = request.body; } - pub fn add_response(&mut self, headers: Option, status: Option, body: Option>) { - self.response.headers = headers.clone(); - self.response.status = status.clone(); - self.response.body = body.clone(); - } + pub fn add_response(&mut self, response: DevtoolsHttpResponse) { + self.response.headers = response.headers.clone(); + self.response.status = response.status.clone(); + self.response.body = response.body.clone(); + } pub fn event_actor(&self) -> EventActor { // TODO: Send the correct values for startedDateTime, isXHR, private diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 3b89e5193f3..c0049b31ad3 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -335,9 +335,9 @@ fn run_server(sender: Sender, let actor = actors.find_mut::(&netevent_actor_name); match network_event { - NetworkEvent::HttpRequest(url, method, headers, body) => { + NetworkEvent::HttpRequest(httprequest) => { //Store the request information in the actor - actor.add_request(url, method, headers, body); + actor.add_request(httprequest); //Send a networkEvent message to the client let msg = NetworkEventMsg { @@ -349,9 +349,9 @@ fn run_server(sender: Sender, stream.write_json_packet(&msg); } } - NetworkEvent::HttpResponse(headers, status, body) => { + NetworkEvent::HttpResponse(httpresponse) => { //Store the response information in the actor - actor.add_response(headers, status, body); + actor.add_response(httpresponse); //Send a networkEventUpdate (responseStart) to the client let msg = NetworkEventUpdateMsg { diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index b5f956efef5..4cb0a688211 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -258,10 +258,24 @@ pub enum CachedConsoleMessage { ConsoleAPI(ConsoleAPI), } -#[derive(Clone)] +#[derive(Debug, PartialEq)] +pub struct HttpRequest { + pub url: Url, + pub method: Method, + pub headers: Headers, + pub body: Option>, +} + +#[derive(Debug, PartialEq)] +pub struct HttpResponse { + pub headers: Option, + pub status: Option, + pub body: Option>, +} + pub enum NetworkEvent { - HttpRequest(Url, Method, Headers, Option>), - HttpResponse(Option, Option, Option>) + HttpRequest(HttpRequest), + HttpResponse(HttpResponse), } impl TimelineMarker { diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 8d0f4613f08..1d44e1664a1 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -5,7 +5,8 @@ use cookie; use cookie_storage::CookieStorage; -use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent}; +use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, HttpRequest as DevtoolsHttpRequest}; +use devtools_traits::{HttpResponse as DevtoolsHttpResponse, NetworkEvent}; use file_loader; use flate2::read::{DeflateDecoder, GzDecoder}; use hsts::{HSTSEntry, HSTSList, secure_url}; @@ -447,7 +448,8 @@ fn send_request_to_devtools(devtools_chan: Option>, body: Option>) { if let Some(ref chan) = devtools_chan { - let net_event = NetworkEvent::HttpRequest(url, method, headers, body); + let request = DevtoolsHttpRequest { url: url, method: method, headers: headers, body: body }; + let net_event = NetworkEvent::HttpRequest(request); let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event); chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap(); @@ -459,7 +461,8 @@ fn send_response_to_devtools(devtools_chan: Option>, headers: Option, status: Option) { if let Some(ref chan) = devtools_chan { - let net_event_response = NetworkEvent::HttpResponse(headers, status, None); + let response = DevtoolsHttpResponse { headers: headers, status: status, body: None }; + let net_event_response = NetworkEvent::HttpResponse(response); let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event_response); chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap(); diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 5caf483d592..f248ac4f1e5 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1130,6 +1130,7 @@ name = "net_tests" version = "0.0.1" dependencies = [ "cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "devtools_traits 0.0.1", "flate2 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", diff --git a/tests/unit/net/Cargo.toml b/tests/unit/net/Cargo.toml index fdd82f7fb6d..efa1601296c 100644 --- a/tests/unit/net/Cargo.toml +++ b/tests/unit/net/Cargo.toml @@ -17,6 +17,9 @@ path = "../../../components/net_traits" [dependencies.util] path = "../../../components/util" +[dependencies.devtools_traits] +path = "../../../components/devtools_traits" + [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs index 97b9a34e1ae..5a24eda16ae 100644 --- a/tests/unit/net/http_loader.rs +++ b/tests/unit/net/http_loader.rs @@ -3,9 +3,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cookie_rs; +use devtools_traits::HttpRequest as DevtoolsHttpRequest; +use devtools_traits::HttpResponse as DevtoolsHttpResponse; +use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent}; use flate2::Compression; use flate2::write::{GzEncoder, DeflateEncoder}; -use hyper::header::{Headers, Location, ContentLength}; +use hyper::header::{Headers, Location, ContentLength, Host}; use hyper::http::RawStatus; use hyper::method::Method; use hyper::status::StatusCode; @@ -16,7 +19,8 @@ use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, HttpRes use net_traits::{LoadData, CookieSource}; use std::borrow::Cow; use std::io::{self, Write, Read, Cursor}; -use std::sync::{Arc, RwLock}; +use std::sync::mpsc::Receiver; +use std::sync::{Arc, mpsc, RwLock}; use url::Url; const DEFAULT_USER_AGENT: &'static str = "Test-agent"; @@ -212,6 +216,38 @@ impl HttpRequest for AssertMustHaveBodyRequest { } } +fn expect_devtools_http_request(devtools_port: &Receiver) -> DevtoolsHttpRequest { + match devtools_port.recv().unwrap() { + DevtoolsControlMsg::FromChrome( + ChromeToDevtoolsControlMsg::NetworkEvent(_, net_event)) => { + match net_event { + NetworkEvent::HttpRequest(httprequest) => { + httprequest + }, + + _ => panic!("No HttpRequest Received"), + } + }, + _ => panic!("No HttpRequest Received"), + } +} + +fn expect_devtools_http_response(devtools_port: &Receiver) -> DevtoolsHttpResponse { + match devtools_port.recv().unwrap() { + DevtoolsControlMsg::FromChrome( + ChromeToDevtoolsControlMsg::NetworkEvent(_, net_event_response)) => { + match net_event_response { + NetworkEvent::HttpResponse(httpresponse) => { + httpresponse + }, + + _ => panic!("No HttpResponse Received"), + } + }, + _ => panic!("No HttpResponse Received"), + } +} + #[test] fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length_should_be_set_to_0() { let url = Url::parse("http://mozilla.com").unwrap(); @@ -234,6 +270,60 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length }, DEFAULT_USER_AGENT.to_string()); } +#[test] +fn test_request_and_response_data_with_network_messages() { + struct Factory; + + impl HttpRequestFactory for Factory { + type R = MockRequest; + + fn create(&self, _: Url, _: Method) -> Result { + let mut headers = Headers::new(); + headers.set(Host { hostname: "foo.bar".to_owned(), port: None }); + Ok(MockRequest::new( + ResponseType::WithHeaders(<[_]>::to_vec("Yay!".as_bytes()), headers)) + ) + } + } + + let hsts_list = Arc::new(RwLock::new(HSTSList::new())); + let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + + let url = Url::parse("https://mozilla.com").unwrap(); + let (devtools_chan, devtools_port) = mpsc::channel::(); + let mut load_data = LoadData::new(url.clone(), None); + let mut request_headers = Headers::new(); + request_headers.set(Host { hostname: "bar.foo".to_owned(), port: None }); + load_data.headers = request_headers.clone(); + let _ = load::(load_data, hsts_list, cookie_jar, Some(devtools_chan), &Factory, + DEFAULT_USER_AGENT.to_string()); + + // notification received from devtools + let devhttprequest = expect_devtools_http_request(&devtools_port); + let devhttpresponse = expect_devtools_http_response(&devtools_port); + + let httprequest = DevtoolsHttpRequest { + url: url, + method: Method::Get, + headers: request_headers, + body: None, + }; + + let content = "Yay!"; + let mut response_headers = Headers::new(); + response_headers.set(ContentLength(content.len() as u64)); + response_headers.set(Host { hostname: "foo.bar".to_owned(), port: None }); + + let httpresponse = DevtoolsHttpResponse { + headers: Some(response_headers), + status: Some(RawStatus(200, Cow::Borrowed("Ok"))), + body: None + }; + + assert_eq!(devhttprequest, httprequest); + assert_eq!(devhttpresponse, httpresponse); +} + #[test] fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() { struct Factory; diff --git a/tests/unit/net/lib.rs b/tests/unit/net/lib.rs index d1af6130123..eb93f284df0 100644 --- a/tests/unit/net/lib.rs +++ b/tests/unit/net/lib.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate cookie as cookie_rs; +extern crate devtools_traits; extern crate flate2; extern crate hyper; extern crate ipc_channel;