Create resource timing entry for sync network fetch

This commit is contained in:
pylbrecht 2019-05-04 17:01:41 +02:00
parent ea71b35220
commit e5217eed0e
7 changed files with 131 additions and 90 deletions

View file

@ -20,7 +20,9 @@ use crate::dom::promise::Promise;
use crate::dom::request::Request;
use crate::dom::response::Response;
use crate::dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
use crate::network_listener::{
self, submit_timing_data, NetworkListener, PreInvoke, ResourceTimingListener,
};
use crate::task_source::TaskSourceName;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
@ -28,6 +30,7 @@ use js::jsapi::JSAutoCompartment;
use net_traits::request::RequestBuilder;
use net_traits::request::{Request as NetTraitsRequest, ServiceWorkersMode};
use net_traits::CoreResourceMsg::Fetch as NetTraitsFetch;
use net_traits::{CoreResourceMsg, CoreResourceThread, FetchResponseMsg};
use net_traits::{FetchChannels, FetchResponseListener, NetworkError};
use net_traits::{FetchMetadata, FilteredMetadata, Metadata};
use net_traits::{ResourceFetchTiming, ResourceTimingType};
@ -301,3 +304,43 @@ fn fill_headers_with_metadata(r: DomRoot<Response>, m: Metadata) {
r.set_raw_status(m.status);
r.set_final_url(m.final_url);
}
/// Convenience function for synchronously loading a whole resource.
pub fn load_whole_resource(
request: RequestBuilder,
core_resource_thread: &CoreResourceThread,
global: &GlobalScope,
) -> Result<(Metadata, Vec<u8>), NetworkError> {
let (action_sender, action_receiver) = ipc::channel().unwrap();
let url = request.url.clone();
core_resource_thread
.send(CoreResourceMsg::Fetch(
request,
FetchChannels::ResponseMsg(action_sender, None),
))
.unwrap();
let mut buf = vec![];
let mut metadata = None;
loop {
match action_receiver.recv().unwrap() {
FetchResponseMsg::ProcessRequestBody | FetchResponseMsg::ProcessRequestEOF => (),
FetchResponseMsg::ProcessResponse(Ok(m)) => {
metadata = Some(match m {
FetchMetadata::Unfiltered(m) => m,
FetchMetadata::Filtered { unsafe_, .. } => unsafe_,
})
},
FetchResponseMsg::ProcessResponseChunk(data) => buf.extend_from_slice(&data),
FetchResponseMsg::ProcessResponseEOF(Ok(_)) => {
let metadata = metadata.unwrap();
if let Some(timing) = &metadata.timing {
submit_timing_data(global, url, InitiatorType::Other, &timing);
}
return Ok((metadata, buf));
},
FetchResponseMsg::ProcessResponse(Err(e)) |
FetchResponseMsg::ProcessResponseEOF(Err(e)) => return Err(e),
}
}
}