diff options
author | Josh Matthews <josh@joshmatthews.net> | 2016-06-03 13:39:38 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2016-06-06 00:51:36 +0100 |
commit | 7bf2e19437ad954bd1d03bb52b86551546ae8ba5 (patch) | |
tree | 96d085e4a406776ce766e10b4c236be831e4cf65 /components/net | |
parent | 1f5b0008ac763bbb2209a70afddb6434d18cff9d (diff) | |
download | servo-7bf2e19437ad954bd1d03bb52b86551546ae8ba5.tar.gz servo-7bf2e19437ad954bd1d03bb52b86551546ae8ba5.zip |
Make the net monitor panel in FF's devtools show meaningful output.
0) Advertise support for the network monitor in the initial protocol communication.
1) Only notify the developer tools server about the final request in an HTTP transaction.
2) Add timing information for connecting to the HTTP server and sending the HTTP request.
3) Reduce duplication between various networkEventUpdate structures by creating a helper function
that merges two JSON structures together. This also corrects the JSON structure so the devtools
client interprets the output correctly.
4) Calculate various header size fields correctly.
5) Remove unnecessary usize->u32 casts by making the appropriate fields usize.
6) Add header values to request and response header messages.
7) Support triggering page reloads via the devtools client.
Diffstat (limited to 'components/net')
-rw-r--r-- | components/net/fetch/methods.rs | 2 | ||||
-rw-r--r-- | components/net/http_loader.rs | 83 |
2 files changed, 62 insertions, 23 deletions
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 45ecbd1e603..16d64a86a7c 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -816,7 +816,7 @@ fn http_network_fetch(request: Rc<Request>, let mut response = Response::new(); match wrapped_response { - Ok(mut res) => { + Ok((mut res, _)) => { response.url = Some(res.response.url.clone()); response.status = Some(res.response.status); response.headers = res.response.headers.clone(); diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index a6b810cc18a..f9fc6224d36 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -119,6 +119,10 @@ impl HttpState { } } +fn precise_time_ms() -> u64 { + time::precise_time_ns() / (1000 * 1000) +} + fn load_for_consumer(load_data: LoadData, start_chan: LoadConsumer, classifier: Arc<MIMEClassifier>, @@ -552,21 +556,34 @@ enum Decoder { Plain(Box<HttpResponse>) } -fn send_request_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>, - request_id: String, +fn prepare_devtools_request(request_id: String, url: Url, method: Method, headers: Headers, body: Option<Vec<u8>>, - pipeline_id: PipelineId, now: Tm) { - if let Some(ref chan) = devtools_chan { - let request = DevtoolsHttpRequest { - url: url, method: method, headers: headers, body: body, pipeline_id: pipeline_id, startedDateTime: now }; - let net_event = NetworkEvent::HttpRequest(request); + pipeline_id: PipelineId, + now: Tm, + connect_time: u64, + send_time: u64) -> ChromeToDevtoolsControlMsg { + let request = DevtoolsHttpRequest { + url: url, + method: method, + headers: headers, + body: body, + pipeline_id: pipeline_id, + startedDateTime: now, + timeStamp: now.to_timespec().sec, + connect_time: connect_time, + send_time: send_time, + }; + let net_event = NetworkEvent::HttpRequest(request); - let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event); - chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap(); - } + ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event) +} + +fn send_request_to_devtools(msg: ChromeToDevtoolsControlMsg, + devtools_chan: &Sender<DevtoolsControlMsg>) { + devtools_chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap(); } fn send_response_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>, @@ -701,10 +718,12 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>, iters: u32, devtools_chan: &Option<Sender<DevtoolsControlMsg>>, request_id: &str) - -> Result<A::R, LoadError> where A: HttpRequest + 'static { + -> Result<(A::R, Option<ChromeToDevtoolsControlMsg>), LoadError> + where A: HttpRequest + 'static { let null_data = None; let response; let connection_url = replace_hosts(&url); + let mut msg; // loop trying connections in connection pool // they may have grown stale (disconnected), in which case we'll get @@ -742,22 +761,36 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>, info!("{:?}", data); } + let connect_start = precise_time_ms(); + let req = try!(request_factory.create(connection_url.clone(), method.clone(), headers.clone())); + let connect_end = precise_time_ms(); + if cancel_listener.is_cancelled() { return Err(LoadError::new(connection_url.clone(), LoadErrorType::Cancelled)); } + let send_start = precise_time_ms(); + let maybe_response = req.send(request_body); - if let Some(pipeline_id) = *pipeline_id { - send_request_to_devtools( - devtools_chan.clone(), request_id.clone().into(), - url.clone(), method.clone(), headers, - request_body.clone(), pipeline_id, time::now() - ); - } + let send_end = precise_time_ms(); + + msg = if devtools_chan.is_some() { + if let Some(pipeline_id) = *pipeline_id { + Some(prepare_devtools_request( + request_id.clone().into(), + url.clone(), method.clone(), headers, + request_body.clone(), pipeline_id, time::now(), + connect_end - connect_start, send_end - send_start)) + } else { + None + } + } else { + None + }; response = match maybe_response { Ok(r) => r, @@ -775,7 +808,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>, break; } - Ok(response) + Ok((response, msg)) } pub trait UIProvider { @@ -914,9 +947,10 @@ pub fn load<A, B>(load_data: &LoadData, request_headers.set(auth_header.clone()); } - let response = try!(obtain_response(request_factory, &doc_url, &method, &request_headers, - &cancel_listener, &load_data.data, &load_data.method, - &load_data.pipeline_id, iters, &devtools_chan, &request_id)); + let (response, msg) = + try!(obtain_response(request_factory, &doc_url, &method, &request_headers, + &cancel_listener, &load_data.data, &load_data.method, + &load_data.pipeline_id, iters, &devtools_chan, &request_id)); process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data); @@ -1006,6 +1040,11 @@ pub fn load<A, B>(load_data: &LoadData, HttpsState::None }; + // Only notify the devtools about the final request that received a response. + if let Some(msg) = msg { + send_request_to_devtools(msg, devtools_chan.as_ref().unwrap()); + } + // --- Tell devtools that we got a response // Send an HttpResponse message to devtools with the corresponding request_id // TODO: Send this message even when the load fails? |