mirror of
https://github.com/servo/servo.git
synced 2025-08-02 12:10:29 +01:00
tests for devtools integration with network requests/responses
This commit is contained in:
parent
e04c2c78ee
commit
920bb5e4b8
8 changed files with 136 additions and 23 deletions
|
@ -9,13 +9,14 @@
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
|
||||||
use actor::{Actor, ActorMessageStatus, ActorRegistry};
|
use actor::{Actor, ActorMessageStatus, ActorRegistry};
|
||||||
|
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
|
||||||
|
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
|
||||||
use hyper::header::Headers;
|
use hyper::header::Headers;
|
||||||
use hyper::http::RawStatus;
|
use hyper::http::RawStatus;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use protocol::JsonPacketStream;
|
use protocol::JsonPacketStream;
|
||||||
use rustc_serialize::json;
|
use rustc_serialize::json;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
struct HttpRequest {
|
struct HttpRequest {
|
||||||
url: String,
|
url: String,
|
||||||
|
@ -125,18 +126,18 @@ impl NetworkEventActor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_request(&mut self, url: Url, method: Method, headers: Headers, body: Option<Vec<u8>>) {
|
pub fn add_request(&mut self, request: DevtoolsHttpRequest) {
|
||||||
self.request.url = url.serialize();
|
self.request.url = request.url.serialize();
|
||||||
self.request.method = method.clone();
|
self.request.method = request.method.clone();
|
||||||
self.request.headers = headers.clone();
|
self.request.headers = request.headers.clone();
|
||||||
self.request.body = body;
|
self.request.body = request.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_response(&mut self, headers: Option<Headers>, status: Option<RawStatus>, body: Option<Vec<u8>>) {
|
pub fn add_response(&mut self, response: DevtoolsHttpResponse) {
|
||||||
self.response.headers = headers.clone();
|
self.response.headers = response.headers.clone();
|
||||||
self.response.status = status.clone();
|
self.response.status = response.status.clone();
|
||||||
self.response.body = body.clone();
|
self.response.body = response.body.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event_actor(&self) -> EventActor {
|
pub fn event_actor(&self) -> EventActor {
|
||||||
// TODO: Send the correct values for startedDateTime, isXHR, private
|
// TODO: Send the correct values for startedDateTime, isXHR, private
|
||||||
|
|
|
@ -335,9 +335,9 @@ fn run_server(sender: Sender<DevtoolsControlMsg>,
|
||||||
let actor = actors.find_mut::<NetworkEventActor>(&netevent_actor_name);
|
let actor = actors.find_mut::<NetworkEventActor>(&netevent_actor_name);
|
||||||
|
|
||||||
match network_event {
|
match network_event {
|
||||||
NetworkEvent::HttpRequest(url, method, headers, body) => {
|
NetworkEvent::HttpRequest(httprequest) => {
|
||||||
//Store the request information in the actor
|
//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
|
//Send a networkEvent message to the client
|
||||||
let msg = NetworkEventMsg {
|
let msg = NetworkEventMsg {
|
||||||
|
@ -349,9 +349,9 @@ fn run_server(sender: Sender<DevtoolsControlMsg>,
|
||||||
stream.write_json_packet(&msg);
|
stream.write_json_packet(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NetworkEvent::HttpResponse(headers, status, body) => {
|
NetworkEvent::HttpResponse(httpresponse) => {
|
||||||
//Store the response information in the actor
|
//Store the response information in the actor
|
||||||
actor.add_response(headers, status, body);
|
actor.add_response(httpresponse);
|
||||||
|
|
||||||
//Send a networkEventUpdate (responseStart) to the client
|
//Send a networkEventUpdate (responseStart) to the client
|
||||||
let msg = NetworkEventUpdateMsg {
|
let msg = NetworkEventUpdateMsg {
|
||||||
|
|
|
@ -258,10 +258,24 @@ pub enum CachedConsoleMessage {
|
||||||
ConsoleAPI(ConsoleAPI),
|
ConsoleAPI(ConsoleAPI),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct HttpRequest {
|
||||||
|
pub url: Url,
|
||||||
|
pub method: Method,
|
||||||
|
pub headers: Headers,
|
||||||
|
pub body: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct HttpResponse {
|
||||||
|
pub headers: Option<Headers>,
|
||||||
|
pub status: Option<RawStatus>,
|
||||||
|
pub body: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum NetworkEvent {
|
pub enum NetworkEvent {
|
||||||
HttpRequest(Url, Method, Headers, Option<Vec<u8>>),
|
HttpRequest(HttpRequest),
|
||||||
HttpResponse(Option<Headers>, Option<RawStatus>, Option<Vec<u8>>)
|
HttpResponse(HttpResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimelineMarker {
|
impl TimelineMarker {
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
use cookie;
|
use cookie;
|
||||||
use cookie_storage::CookieStorage;
|
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 file_loader;
|
||||||
use flate2::read::{DeflateDecoder, GzDecoder};
|
use flate2::read::{DeflateDecoder, GzDecoder};
|
||||||
use hsts::{HSTSEntry, HSTSList, secure_url};
|
use hsts::{HSTSEntry, HSTSList, secure_url};
|
||||||
|
@ -447,7 +448,8 @@ fn send_request_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
body: Option<Vec<u8>>) {
|
body: Option<Vec<u8>>) {
|
||||||
|
|
||||||
if let Some(ref chan) = devtools_chan {
|
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);
|
let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event);
|
||||||
chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
|
chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
|
||||||
|
@ -459,7 +461,8 @@ fn send_response_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
headers: Option<Headers>,
|
headers: Option<Headers>,
|
||||||
status: Option<RawStatus>) {
|
status: Option<RawStatus>) {
|
||||||
if let Some(ref chan) = devtools_chan {
|
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);
|
let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event_response);
|
||||||
chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
|
chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -1130,6 +1130,7 @@ name = "net_tests"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
|
|
|
@ -17,6 +17,9 @@ path = "../../../components/net_traits"
|
||||||
[dependencies.util]
|
[dependencies.util]
|
||||||
path = "../../../components/util"
|
path = "../../../components/util"
|
||||||
|
|
||||||
|
[dependencies.devtools_traits]
|
||||||
|
path = "../../../components/devtools_traits"
|
||||||
|
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use cookie_rs;
|
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::Compression;
|
||||||
use flate2::write::{GzEncoder, DeflateEncoder};
|
use flate2::write::{GzEncoder, DeflateEncoder};
|
||||||
use hyper::header::{Headers, Location, ContentLength};
|
use hyper::header::{Headers, Location, ContentLength, Host};
|
||||||
use hyper::http::RawStatus;
|
use hyper::http::RawStatus;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use hyper::status::StatusCode;
|
use hyper::status::StatusCode;
|
||||||
|
@ -16,7 +19,8 @@ use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, HttpRes
|
||||||
use net_traits::{LoadData, CookieSource};
|
use net_traits::{LoadData, CookieSource};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::io::{self, Write, Read, Cursor};
|
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;
|
use url::Url;
|
||||||
|
|
||||||
const DEFAULT_USER_AGENT: &'static str = "Test-agent";
|
const DEFAULT_USER_AGENT: &'static str = "Test-agent";
|
||||||
|
@ -212,6 +216,38 @@ impl HttpRequest for AssertMustHaveBodyRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expect_devtools_http_request(devtools_port: &Receiver<DevtoolsControlMsg>) -> 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<DevtoolsControlMsg>) -> 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]
|
#[test]
|
||||||
fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length_should_be_set_to_0() {
|
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();
|
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());
|
}, 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<MockRequest, LoadError> {
|
||||||
|
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::<DevtoolsControlMsg>();
|
||||||
|
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::<MockRequest>(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]
|
#[test]
|
||||||
fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() {
|
fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() {
|
||||||
struct Factory;
|
struct Factory;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
|
extern crate devtools_traits;
|
||||||
extern crate flate2;
|
extern crate flate2;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate ipc_channel;
|
extern crate ipc_channel;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue