mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Add FetchMetadata and update corresponding methods
This commit is contained in:
parent
4dcf693a75
commit
07c9cfecec
5 changed files with 75 additions and 29 deletions
|
@ -22,7 +22,7 @@ use hyper::status::StatusCode;
|
||||||
use hyper_serde::Serde;
|
use hyper_serde::Serde;
|
||||||
use mime_guess::guess_mime_type;
|
use mime_guess::guess_mime_type;
|
||||||
use msg::constellation_msg::ReferrerPolicy;
|
use msg::constellation_msg::ReferrerPolicy;
|
||||||
use net_traits::FetchTaskTarget;
|
use net_traits::{FetchTaskTarget, FetchMetadata};
|
||||||
use net_traits::request::{CacheMode, CredentialsMode, Destination};
|
use net_traits::request::{CacheMode, CredentialsMode, Destination};
|
||||||
use net_traits::request::{RedirectMode, Referrer, Request, RequestMode, ResponseTainting};
|
use net_traits::request::{RedirectMode, Referrer, Request, RequestMode, ResponseTainting};
|
||||||
use net_traits::request::{Type, Origin, Window};
|
use net_traits::request::{Type, Origin, Window};
|
||||||
|
@ -981,7 +981,10 @@ fn http_network_fetch(request: Rc<Request>,
|
||||||
|
|
||||||
// We're about to spawn a thread to be waited on here
|
// We're about to spawn a thread to be waited on here
|
||||||
*done_chan = Some(channel());
|
*done_chan = Some(channel());
|
||||||
let meta = response.metadata().expect("Response metadata should exist at this stage");
|
let meta = match response.metadata().expect("Response metadata should exist at this stage") {
|
||||||
|
FetchMetadata::Unfiltered(m) => m,
|
||||||
|
FetchMetadata::Filtered { unsafe_, .. } => unsafe_
|
||||||
|
};
|
||||||
let done_sender = done_chan.as_ref().map(|ch| ch.0.clone());
|
let done_sender = done_chan.as_ref().map(|ch| ch.0.clone());
|
||||||
let devtools_sender = devtools_chan.clone();
|
let devtools_sender = devtools_chan.clone();
|
||||||
let meta_status = meta.status.clone();
|
let meta_status = meta.status.clone();
|
||||||
|
|
|
@ -170,7 +170,7 @@ pub enum FetchResponseMsg {
|
||||||
ProcessRequestBody,
|
ProcessRequestBody,
|
||||||
ProcessRequestEOF,
|
ProcessRequestEOF,
|
||||||
// todo: send more info about the response (or perhaps the entire Response)
|
// todo: send more info about the response (or perhaps the entire Response)
|
||||||
ProcessResponse(Result<Metadata, NetworkError>),
|
ProcessResponse(Result<FetchMetadata, NetworkError>),
|
||||||
ProcessResponseChunk(Vec<u8>),
|
ProcessResponseChunk(Vec<u8>),
|
||||||
ProcessResponseEOF(Result<(), NetworkError>),
|
ProcessResponseEOF(Result<(), NetworkError>),
|
||||||
}
|
}
|
||||||
|
@ -200,10 +200,25 @@ pub trait FetchTaskTarget {
|
||||||
fn process_response_eof(&mut self, response: &Response);
|
fn process_response_eof(&mut self, response: &Response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum FilteredMetadata {
|
||||||
|
Opaque,
|
||||||
|
Transparent(Metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum FetchMetadata {
|
||||||
|
Unfiltered(Metadata),
|
||||||
|
Filtered {
|
||||||
|
filtered: FilteredMetadata,
|
||||||
|
unsafe_: Metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait FetchResponseListener {
|
pub trait FetchResponseListener {
|
||||||
fn process_request_body(&mut self);
|
fn process_request_body(&mut self);
|
||||||
fn process_request_eof(&mut self);
|
fn process_request_eof(&mut self);
|
||||||
fn process_response(&mut self, metadata: Result<Metadata, NetworkError>);
|
fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>);
|
||||||
fn process_response_chunk(&mut self, chunk: Vec<u8>);
|
fn process_response_chunk(&mut self, chunk: Vec<u8>);
|
||||||
fn process_response_eof(&mut self, response: Result<(), NetworkError>);
|
fn process_response_eof(&mut self, response: Result<(), NetworkError>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! The [Response](https://fetch.spec.whatwg.org/#responses) object
|
//! The [Response](https://fetch.spec.whatwg.org/#responses) object
|
||||||
//! resulting from a [fetch operation](https://fetch.spec.whatwg.org/#concept-fetch)
|
//! resulting from a [fetch operation](https://fetch.spec.whatwg.org/#concept-fetch)
|
||||||
use {Metadata, NetworkError};
|
use {FetchMetadata, FilteredMetadata, Metadata, NetworkError};
|
||||||
use hyper::header::{AccessControlExposeHeaders, ContentType, Headers};
|
use hyper::header::{AccessControlExposeHeaders, ContentType, Headers};
|
||||||
use hyper::status::StatusCode;
|
use hyper::status::StatusCode;
|
||||||
use hyper_serde::Serde;
|
use hyper_serde::Serde;
|
||||||
|
@ -225,24 +225,42 @@ impl Response {
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata(&self) -> Result<Metadata, NetworkError> {
|
pub fn metadata(&self) -> Result<FetchMetadata, NetworkError> {
|
||||||
let mut metadata = if let Some(ref url) = self.url {
|
fn init_metadata(response: &Response, url: &Url) -> Metadata {
|
||||||
Metadata::default(url.clone())
|
let mut metadata = Metadata::default(url.clone());
|
||||||
} else {
|
metadata.set_content_type(match response.headers.get() {
|
||||||
return Err(NetworkError::Internal("No url found in response".to_string()));
|
Some(&ContentType(ref mime)) => Some(mime),
|
||||||
|
None => None
|
||||||
|
});
|
||||||
|
metadata.headers = Some(Serde(response.headers.clone()));
|
||||||
|
metadata.status = response.raw_status.clone();
|
||||||
|
metadata.https_state = response.https_state;
|
||||||
|
metadata
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.is_network_error() {
|
if self.is_network_error() {
|
||||||
return Err(NetworkError::Internal("Cannot extract metadata from network error".to_string()));
|
return Err(NetworkError::Internal("Cannot extract metadata from network error".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.set_content_type(match self.headers.get() {
|
let metadata = self.url.as_ref().map(|url| init_metadata(self, url));
|
||||||
Some(&ContentType(ref mime)) => Some(mime),
|
|
||||||
None => None
|
if let Some(ref response) = self.internal_response {
|
||||||
});
|
match response.url {
|
||||||
metadata.headers = Some(Serde(self.headers.clone()));
|
Some(ref url) => {
|
||||||
metadata.status = self.raw_status.clone();
|
let unsafe_metadata = init_metadata(response, url);
|
||||||
metadata.https_state = self.https_state;
|
|
||||||
return Ok(metadata);
|
Ok(FetchMetadata::Filtered {
|
||||||
|
filtered: match metadata {
|
||||||
|
Some(m) => FilteredMetadata::Transparent(m),
|
||||||
|
None => FilteredMetadata::Opaque
|
||||||
|
},
|
||||||
|
unsafe_: unsafe_metadata
|
||||||
|
})
|
||||||
|
}
|
||||||
|
None => Err(NetworkError::Internal("No url found in unsafe response".to_owned()))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(FetchMetadata::Unfiltered(metadata.unwrap()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use html5ever::tree_builder::NextParserState;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use net_traits::{FetchResponseListener, Metadata, NetworkError};
|
use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError};
|
||||||
use net_traits::request::{CORSSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
|
use net_traits::request::{CORSSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
|
||||||
use network_listener::{NetworkListener, PreInvoke};
|
use network_listener::{NetworkListener, PreInvoke};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
@ -159,8 +159,12 @@ impl FetchResponseListener for ScriptContext {
|
||||||
|
|
||||||
fn process_request_eof(&mut self) {} // TODO(KiChjang): Perhaps add custom steps to perform fetch here?
|
fn process_request_eof(&mut self) {} // TODO(KiChjang): Perhaps add custom steps to perform fetch here?
|
||||||
|
|
||||||
fn process_response(&mut self, metadata: Result<Metadata, NetworkError>) {
|
fn process_response(&mut self,
|
||||||
self.metadata = metadata.ok();
|
metadata: Result<FetchMetadata, NetworkError>) {
|
||||||
|
self.metadata = metadata.ok().map(|meta| match meta {
|
||||||
|
FetchMetadata::Unfiltered(m) => m,
|
||||||
|
FetchMetadata::Filtered { unsafe_, .. } => unsafe_
|
||||||
|
});
|
||||||
|
|
||||||
let status_code = self.metadata.as_ref().and_then(|m| {
|
let status_code = self.metadata.as_ref().and_then(|m| {
|
||||||
match m.status {
|
match m.status {
|
||||||
|
|
|
@ -45,8 +45,8 @@ use js::jsapi::{JSContext, JS_ParseJSON};
|
||||||
use js::jsapi::JS_ClearPendingException;
|
use js::jsapi::JS_ClearPendingException;
|
||||||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use net_traits::{CoreResourceThread, LoadOrigin};
|
use net_traits::{CoreResourceThread, FetchMetadata, FilteredMetadata};
|
||||||
use net_traits::{FetchResponseListener, Metadata, NetworkError};
|
use net_traits::{FetchResponseListener, LoadOrigin, NetworkError};
|
||||||
use net_traits::CoreResourceMsg::Fetch;
|
use net_traits::CoreResourceMsg::Fetch;
|
||||||
use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode};
|
use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode};
|
||||||
use net_traits::trim_http_whitespace;
|
use net_traits::trim_http_whitespace;
|
||||||
|
@ -227,10 +227,10 @@ impl XMLHttpRequest {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_response(&mut self, metadata: Result<Metadata, NetworkError>) {
|
fn process_response(&mut self,
|
||||||
|
metadata: Result<FetchMetadata, NetworkError>) {
|
||||||
let xhr = self.xhr.root();
|
let xhr = self.xhr.root();
|
||||||
let rv = xhr.process_headers_available(self.gen_id,
|
let rv = xhr.process_headers_available(self.gen_id, metadata);
|
||||||
metadata);
|
|
||||||
if rv.is_err() {
|
if rv.is_err() {
|
||||||
*self.sync_status.borrow_mut() = Some(rv);
|
*self.sync_status.borrow_mut() = Some(rv);
|
||||||
}
|
}
|
||||||
|
@ -869,10 +869,16 @@ impl XMLHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_headers_available(&self,
|
fn process_headers_available(&self,
|
||||||
gen_id: GenerationId, metadata: Result<Metadata, NetworkError>)
|
gen_id: GenerationId, metadata: Result<FetchMetadata, NetworkError>)
|
||||||
-> Result<(), Error> {
|
-> Result<(), Error> {
|
||||||
let metadata = match metadata {
|
let metadata = match metadata {
|
||||||
Ok(meta) => meta,
|
Ok(meta) => match meta {
|
||||||
|
FetchMetadata::Unfiltered(m) => m,
|
||||||
|
FetchMetadata::Filtered { filtered, .. } => match filtered {
|
||||||
|
FilteredMetadata::Opaque => return Err(Error::Network),
|
||||||
|
FilteredMetadata::Transparent(m) => m
|
||||||
|
}
|
||||||
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
|
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
|
||||||
return Err(Error::Network);
|
return Err(Error::Network);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue