Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Response API #13058

Merged
merged 1 commit into from Sep 9, 2016
Merged

Response API #13058

Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

dom::Response implementation

  • Loading branch information
malisas committed Sep 7, 2016
commit faf32a7cfbaf568bbfeb4f2572ea96b6a30d231e
@@ -11,6 +11,7 @@ path = "lib.rs"

[dependencies]
devtools_traits = {path = "../devtools_traits"}
encoding = "0.2"
hyper = "0.9.9"
hyper_serde = "0.1.4"
ipc-channel = "0.5"
@@ -11,12 +11,15 @@ extern crate hyper;
use actor::{Actor, ActorMessageStatus, ActorRegistry};
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
use encoding::all::UTF_8;
use encoding::types::{DecoderTrap, Encoding};
use hyper::header::Headers;
use hyper::header::{ContentType, Cookie};
use hyper::http::RawStatus;
use hyper::method::Method;
use protocol::JsonPacketStream;
use serde_json::Value;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::net::TcpStream;
use time;
@@ -360,7 +363,10 @@ impl NetworkEventActor {

pub fn add_response(&mut self, response: DevtoolsHttpResponse) {
self.response.headers = response.headers.clone();
self.response.status = response.status.clone();
self.response.status = response.status.as_ref().map(|&(s, ref st)| {
let status_text = UTF_8.decode(st, DecoderTrap::Replace).unwrap();
RawStatus(s, Cow::from(status_text))
});
self.response.body = response.body.clone();
}

@@ -21,6 +21,7 @@
#![deny(unsafe_code)]

extern crate devtools_traits;
extern crate encoding;
extern crate hyper;
extern crate ipc_channel;
#[macro_use]
@@ -27,7 +27,6 @@ extern crate time;
extern crate url;

use hyper::header::Headers;
use hyper::http::RawStatus;
use hyper::method::Method;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
@@ -304,7 +303,7 @@ pub struct HttpRequest {
#[derive(Debug, PartialEq)]
pub struct HttpResponse {
pub headers: Option<Headers>,
pub status: Option<RawStatus>,
pub status: Option<(u16, Vec<u8>)>,
pub body: Option<Vec<u8>>,
pub pipeline_id: PipelineId,
}
@@ -4,7 +4,6 @@

use file_loader;
use hyper::header::ContentType;
use hyper::http::RawStatus;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper_serde::Serde;
use mime_classifier::MimeClassifier;
@@ -38,7 +37,7 @@ pub fn factory(mut load_data: LoadData,
Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![])))),
charset: Some("utf-8".to_owned()),
headers: None,
status: Some(Serde(RawStatus(200, "OK".into()))),
status: Some((200, b"OK".to_vec())),
https_state: HttpsState::None,
referrer: None,
};
@@ -5,7 +5,6 @@
use filemanager_thread::{FileManager, UIProvider};
use hyper::header::{DispositionType, ContentDisposition, DispositionParam};
use hyper::header::{Headers, ContentType, ContentLength, Charset};
use hyper::http::RawStatus;
use hyper_serde::Serde;
use ipc_channel::ipc;
use mime::{Mime, Attr};
@@ -72,7 +71,7 @@ fn load_blob<UI: 'static + UIProvider>
charset: charset.map(|c| c.as_str().to_string()),
headers: Some(Serde(headers)),
// https://w3c.github.io/FileAPI/#TwoHundredOK
status: Some(Serde(RawStatus(200, "OK".into()))),
status: Some((200, b"OK".to_vec())),
https_state: HttpsState::None,
referrer: None,
};
@@ -973,8 +973,9 @@ fn http_network_fetch(request: Rc<Request>,
Ok((res, msg)) => {
response.url = Some(url.clone());
response.status = Some(res.response.status);
response.raw_status = Some(res.response.status_raw().clone());
response.headers = res.response.headers.clone();
response.raw_status = Some((res.response.status_raw().0,
res.response.status_raw().1.as_bytes().to_vec()));
response.headers = res.response.headers.clone();

let res_body = response.body.clone();

@@ -1001,7 +1002,7 @@ fn http_network_fetch(request: Rc<Request>,
send_response_to_devtools(
&sender, request_id.unwrap(),
meta_headers.map(Serde::into_inner),
meta_status.map(Serde::into_inner),
meta_status,
pipeline_id);
}
}
@@ -629,7 +629,7 @@ pub fn send_request_to_devtools(msg: ChromeToDevtoolsControlMsg,
pub fn send_response_to_devtools(devtools_chan: &Sender<DevtoolsControlMsg>,
request_id: String,
headers: Option<Headers>,
status: Option<RawStatus>,
status: Option<(u16, Vec<u8>)>,
pipeline_id: PipelineId) {
let response = DevtoolsHttpResponse { headers: headers, status: status, body: None, pipeline_id: pipeline_id };
let net_event_response = NetworkEvent::HttpResponse(response);
@@ -1081,7 +1081,8 @@ pub fn load<A, B>(load_data: &LoadData,
None => None
});
metadata.headers = Some(Serde(adjusted_headers));
metadata.status = Some(Serde(response.status_raw().clone()));
metadata.status = Some((response.status_raw().0,
response.status_raw().1.as_bytes().to_vec()));
metadata.https_state = if doc_url.scheme() == "https" {
HttpsState::Modern
} else {
@@ -1097,7 +1098,7 @@ pub fn load<A, B>(load_data: &LoadData,
send_response_to_devtools(
&chan, request_id.unwrap(),
metadata.headers.clone().map(Serde::into_inner),
metadata.status.clone().map(Serde::into_inner),
metadata.status.clone(),
pipeline_id);
}
}
@@ -560,9 +560,8 @@ pub struct Metadata {
/// Headers
pub headers: Option<Serde<Headers>>,

#[ignore_heap_size_of = "Defined in hyper"]
/// HTTP Status
pub status: Option<Serde<RawStatus>>,
pub status: Option<(u16, Vec<u8>)>,

/// Is successful HTTPS connection
pub https_state: HttpsState,
@@ -580,7 +579,7 @@ impl Metadata {
charset: None,
headers: None,
// https://fetch.spec.whatwg.org/#concept-response-status-message
status: Some(Serde(RawStatus(200, "OK".into()))),
status: Some((200, b"OK".to_vec())),
https_state: HttpsState::None,
referrer: None,
}
@@ -5,7 +5,6 @@
//! The [Response](https://fetch.spec.whatwg.org/#responses) object
//! resulting from a [fetch operation](https://fetch.spec.whatwg.org/#concept-fetch)
use hyper::header::{AccessControlExposeHeaders, ContentType, Headers};
use hyper::http::RawStatus;
use hyper::status::StatusCode;
use hyper_serde::Serde;
use std::ascii::AsciiExt;
@@ -15,7 +14,7 @@ use url::Url;
use {Metadata, NetworkError};

/// [Response type](https://fetch.spec.whatwg.org/#concept-response-type)
#[derive(Clone, PartialEq, Copy, Debug, Deserialize, Serialize)]
#[derive(Clone, PartialEq, Copy, Debug, Deserialize, Serialize, HeapSizeOf)]
pub enum ResponseType {
Basic,
CORS,
@@ -26,7 +25,7 @@ pub enum ResponseType {
}

/// [Response termination reason](https://fetch.spec.whatwg.org/#concept-response-termination-reason)
#[derive(Clone, Copy, Deserialize, Serialize)]
#[derive(Clone, Copy, Deserialize, Serialize, HeapSizeOf)]
pub enum TerminationReason {
EndUserAbort,
Fatal,
@@ -35,7 +34,7 @@ pub enum TerminationReason {

/// The response body can still be pushed to after fetch
/// This provides a way to store unfinished response bodies
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, HeapSizeOf)]
pub enum ResponseBody {
Empty, // XXXManishearth is this necessary, or is Done(vec![]) enough?
Receiving(Vec<u8>),
@@ -53,7 +52,7 @@ impl ResponseBody {


/// [Cache state](https://fetch.spec.whatwg.org/#concept-response-cache-state)
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, HeapSizeOf)]
pub enum CacheState {
None,
Local,
@@ -76,16 +75,19 @@ pub enum ResponseMsg {
}

/// A [Response](https://fetch.spec.whatwg.org/#concept-response) as defined by the Fetch spec
#[derive(Clone)]
#[derive(Clone, HeapSizeOf)]
pub struct Response {
pub response_type: ResponseType,
pub termination_reason: Option<TerminationReason>,
pub url: Option<Url>,
pub url_list: RefCell<Vec<Url>>,
/// `None` can be considered a StatusCode of `0`.
#[ignore_heap_size_of = "Defined in hyper"]
pub status: Option<StatusCode>,
pub raw_status: Option<RawStatus>,
pub raw_status: Option<(u16, Vec<u8>)>,
#[ignore_heap_size_of = "Defined in hyper"]
pub headers: Headers,
#[ignore_heap_size_of = "Mutex heap size undefined"]
pub body: Arc<Mutex<ResponseBody>>,
pub cache_state: CacheState,
pub https_state: HttpsState,
@@ -104,7 +106,7 @@ impl Response {
url: None,
url_list: RefCell::new(Vec::new()),
status: Some(StatusCode::Ok),
raw_status: Some(RawStatus(200, "OK".into())),
raw_status: Some((200, b"OK".to_vec())),
headers: Headers::new(),
body: Arc::new(Mutex::new(ResponseBody::Empty)),
cache_state: CacheState::None,
@@ -239,7 +241,7 @@ impl Response {
None => None
});
metadata.headers = Some(Serde(self.headers.clone()));
metadata.status = self.raw_status.clone().map(Serde);
metadata.status = self.raw_status.clone();
metadata.https_state = self.https_state;
return Ok(metadata);
}
@@ -50,6 +50,7 @@ use html5ever::tree_builder::QuirksMode;
use hyper::header::Headers;
use hyper::method::Method;
use hyper::mime::Mime;
use hyper::status::StatusCode;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use js::glue::{CallObjectTracer, CallUnbarrieredObjectTracer, CallValueTracer};
use js::jsapi::{GCTraceKindToAscii, Heap, TraceKind, JSObject, JSTracer};
@@ -62,6 +63,7 @@ use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::request::Request;
use net_traits::response::HttpsState;
use net_traits::response::{Response, ResponseBody};
use net_traits::storage_thread::StorageType;
use net_traits::{Metadata, NetworkError, ResourceThreads};
use offscreen_gl_context::GLLimits;
@@ -339,7 +341,10 @@ no_jsmanaged_fields!(SharedRt);
no_jsmanaged_fields!(TouchpadPressurePhase);
no_jsmanaged_fields!(USVString);
no_jsmanaged_fields!(ReferrerPolicy);
no_jsmanaged_fields!(Response);
no_jsmanaged_fields!(ResponseBody);
no_jsmanaged_fields!(ResourceThreads);
no_jsmanaged_fields!(StatusCode);
no_jsmanaged_fields!(SystemTime);
no_jsmanaged_fields!(RelativePos);
no_jsmanaged_fields!(OpaqueStyleAndLayoutData);
@@ -209,7 +209,13 @@ impl Headers {
headers_for_request
}

pub fn set_guard(&self, new_guard: Guard) {
pub fn for_response(global: GlobalRef) -> Root<Headers> {
let headers_for_response = Headers::new(global);
headers_for_response.guard.set(Guard::Response);
headers_for_response
}

pub fn set_guard(&self, new_guard: Guard) {
self.guard.set(new_guard)
}

@@ -346,15 +352,15 @@ pub fn is_forbidden_header_name(name: &str) -> bool {
// [3] https://tools.ietf.org/html/rfc7230#section-3.2.6
// [4] https://www.rfc-editor.org/errata_search.php?rfc=7230
fn validate_name_and_value(name: ByteString, value: ByteString)
-> Result<(String, Vec<u8>), Error> {
-> Fallible<(String, Vec<u8>)> {
let valid_name = try!(validate_name(name));
if !is_field_content(&value) {
return Err(Error::Type("Value is not valid".to_string()));
}
Ok((valid_name, value.into()))
}

fn validate_name(name: ByteString) -> Result<String, Error> {
fn validate_name(name: ByteString) -> Fallible<String> {
if !is_field_name(&name) {
return Err(Error::Type("Name is not valid".to_string()));
}
@@ -444,15 +450,15 @@ fn is_field_vchar(x: u8) -> bool {
}

// https://tools.ietf.org/html/rfc5234#appendix-B.1
fn is_vchar(x: u8) -> bool {
pub fn is_vchar(x: u8) -> bool {
match x {
0x21...0x7E => true,
_ => false,
}
}

// http://tools.ietf.org/html/rfc7230#section-3.2.6
fn is_obs_text(x: u8) -> bool {
pub fn is_obs_text(x: u8) -> bool {
match x {
0x80...0xFF => true,
_ => false,
@@ -22,7 +22,6 @@ use dom::virtualmethods::VirtualMethods;
use encoding::EncodingRef;
use encoding::all::UTF_8;
use hyper::header::ContentType;
use hyper::http::RawStatus;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper_serde::Serde;
use ipc_channel::ipc;
@@ -335,7 +334,7 @@ impl AsyncResponseListener for StylesheetContext {
document.invalidate_stylesheets();

// FIXME: Revisit once consensus is reached at: https://github.com/whatwg/html/issues/1142
successful = metadata.status.map_or(false, |Serde(RawStatus(code, _))| code == 200);
successful = metadata.status.map_or(false, |(code, _)| code == 200);
}

if elem.parser_inserted.get() {
@@ -24,7 +24,6 @@ use dom::htmlsourceelement::HTMLSourceElement;
use dom::mediaerror::MediaError;
use dom::node::{window_from_node, document_from_node, Node, UnbindContext};
use dom::virtualmethods::VirtualMethods;
use hyper_serde::Serde;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError};
@@ -66,7 +65,7 @@ impl AsyncResponseListener for HTMLMediaElementContext {
.as_ref()
.and_then(|m| m.status
.as_ref()
.map(|&Serde(ref s)| s.0 < 200 || s.0 >= 300))
.map(|&(s, _)| s < 200 || s >= 300))
.unwrap_or(false);
if is_failure {
// Ensure that the element doesn't receive any further notifications
@@ -26,8 +26,6 @@ use dom::window::ScriptHelpers;
use encoding::label::encoding_from_whatwg_label;
use encoding::types::{DecoderTrap, EncodingRef};
use html5ever::tree_builder::NextParserState;
use hyper::http::RawStatus;
use hyper_serde::Serde;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::jsval::UndefinedValue;
@@ -159,7 +157,7 @@ impl AsyncResponseListener for ScriptContext {

let status_code = self.metadata.as_ref().and_then(|m| {
match m.status {
Some(Serde(RawStatus(c, _))) => Some(c),
Some((c, _)) => Some(c),
_ => None,
}
}).unwrap_or(0);
@@ -372,6 +372,7 @@ pub mod progressevent;
pub mod radionodelist;
pub mod range;
pub mod request;
pub mod response;
pub mod screen;
pub mod serviceworker;
pub mod serviceworkercontainer;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.