Skip to content

Commit

Permalink
minimal implementation of http_network_fetch for testing purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
nikkisquared committed Jan 5, 2016
1 parent e94a530 commit af310f7
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 24 deletions.
98 changes: 92 additions & 6 deletions components/net/fetch/request.rs
Expand Up @@ -4,16 +4,20 @@

use fetch::cors_cache::{BasicCORSCache, CORSCache, CacheRequestDetails};
use fetch::response::ResponseMethods;
use http_loader::{NetworkHttpRequestFactory, WrappedHttpResponse};
use http_loader::{create_http_connector, obtain_response};
use hyper::client::response::Response as HyperResponse;
use hyper::header::{Accept, IfMatch, IfRange, IfUnmodifiedSince, Location};
use hyper::header::{AcceptLanguage, ContentLength, ContentLanguage, HeaderView};
use hyper::header::{Authorization, Basic};
use hyper::header::{Authorization, Basic, ContentEncoding, Encoding};
use hyper::header::{ContentType, Header, Headers, IfModifiedSince, IfNoneMatch};
use hyper::header::{QualityItem, q, qitem, Referer as RefererHeader, UserAgent};
use hyper::method::Method;
use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value};
use hyper::status::StatusCode;
use net_traits::{AsyncFetchListener, CacheState, Response};
use net_traits::{ResponseType, Metadata};
use net_traits::{AsyncFetchListener, CacheState, HttpsState, Response};
use net_traits::{ResponseType, Metadata, TerminationReason};
use resource_task::CancellationListener;
use std::ascii::AsciiExt;
use std::cell::RefCell;
use std::rc::Rc;
Expand Down Expand Up @@ -121,7 +125,7 @@ pub struct Request {
pub use_url_credentials: bool,
pub cache_mode: CacheMode,
pub redirect_mode: RedirectMode,
pub redirect_count: usize,
pub redirect_count: u32,
pub response_tainting: ResponseTainting
}

Expand Down Expand Up @@ -543,7 +547,6 @@ fn http_fetch(request: Rc<RefCell<Request>>,
fn http_network_or_cache_fetch(request: Rc<RefCell<Request>>,
credentials_flag: bool,
authentication_fetch_flag: bool) -> Response {
// TODO: Implement HTTP network or cache fetch spec

// TODO: Implement Window enum for Request
let request_has_no_window = true;
Expand Down Expand Up @@ -728,7 +731,90 @@ fn http_network_fetch(request: Rc<RefCell<Request>>,
http_request: Rc<RefCell<Request>>,
credentials_flag: bool) -> Response {
// TODO: Implement HTTP network fetch spec
Response::network_error()

// Step 1
// nothing to do here, since credentials_flag is already a boolean

// Step 2
// TODO be able to create connection using current url's origin and credentials
let connection = create_http_connector();

// Step 3
// TODO be able to tell if the connection is a failure

// Step 4
let factory = NetworkHttpRequestFactory {
connector: connection,
};
let req = request.borrow();
let url = req.current_url();
let cancellation_listener = CancellationListener::new(None);

let wrapped_response = obtain_response(&factory, &url, &req.method, &mut request.borrow_mut().headers,
&cancellation_listener, &None, &req.method,
&None, req.redirect_count, &None, "");

let mut response = Response::new();
match wrapped_response {
Ok(res) => {
// is it okay for res.version to be unused?
response.url = Some(res.response.url.clone());
response.status = Some(res.response.status);
response.headers = res.response.headers.clone();
},
Err(e) =>
response.termination_reason = Some(TerminationReason::Fatal)
};

// TODO these substeps aren't possible yet
// Substep 1

// Substep 2

// TODO how can I tell if response was retrieved over HTTPS?
// TODO: Servo needs to decide what ciphers are to be treated as "deprecated"
response.https_state = HttpsState::None;

// TODO how do I read request?

// Step 5
// TODO when https://bugzilla.mozilla.org/show_bug.cgi?id=1030660
// is resolved, this step will become uneccesary
// TODO this step
if let Some(encoding) = response.headers.get::<ContentEncoding>() {
if encoding.contains(&Encoding::Gzip) {

}

else if encoding.contains(&Encoding::Compress) {

}
};

// Step 6
response.url_list = request.borrow().url_list.clone();

// Step 7

// Step 8

// Step 9
// Substep 1
// Substep 2
// Substep 3
// Substep 4

// Step 10
// Substep 1
// Substep 2
// Sub-substep 1
// Sub-substep 2
// Sub-substep 3
// Sub-substep 4
// Substep 3

// Step 11
response
}

/// [CORS preflight fetch](https://fetch.spec.whatwg.org#cors-preflight-fetch)
Expand Down
3 changes: 2 additions & 1 deletion components/net/fetch/response.rs
Expand Up @@ -4,7 +4,7 @@

use hyper::header::Headers;
use hyper::status::StatusCode;
use net_traits::{CacheState, Response, ResponseBody, ResponseType};
use net_traits::{CacheState, HttpsState, Response, ResponseBody, ResponseType};
use std::ascii::AsciiExt;
use std::cell::RefCell;
use std::rc::Rc;
Expand All @@ -27,6 +27,7 @@ impl ResponseMethods for Response {
headers: Headers::new(),
body: ResponseBody::Empty,
cache_state: CacheState::None,
https_state: HttpsState::None,
internal_response: None
}
}
Expand Down
35 changes: 19 additions & 16 deletions components/net/http_loader.rs
Expand Up @@ -198,8 +198,8 @@ pub trait HttpResponse: Read {
}


struct WrappedHttpResponse {
response: Response
pub struct WrappedHttpResponse {
pub response: Response
}

impl Read for WrappedHttpResponse {
Expand Down Expand Up @@ -235,8 +235,8 @@ pub trait HttpRequestFactory {
fn create(&self, url: Url, method: Method) -> Result<Self::R, LoadError>;
}

struct NetworkHttpRequestFactory {
connector: Arc<Pool<Connector>>,
pub struct NetworkHttpRequestFactory {
pub connector: Arc<Pool<Connector>>,
}

impl HttpRequestFactory for NetworkHttpRequestFactory {
Expand Down Expand Up @@ -276,7 +276,7 @@ pub trait HttpRequest {
fn send(self, body: &Option<Vec<u8>>) -> Result<Self::R, LoadError>;
}

struct WrappedHttpRequest {
pub struct WrappedHttpRequest {
request: Request<Fresh>
}

Expand Down Expand Up @@ -556,7 +556,9 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
method: &Method,
request_headers: &mut Headers,
cancel_listener: &CancellationListener,
load_data: &LoadData,
data: &Option<Vec<u8>>,
load_data_method: &Method,
pipeline_id: &Option<PipelineId>,
iters: u32,
devtools_chan: &Option<Sender<DevtoolsControlMsg>>,
request_id: &str)
Expand All @@ -581,7 +583,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
for header in req.headers_mut().iter() {
info!(" - {}", header);
}
info!("{:?}", load_data.data);
info!("{:?}", data);
}

// Avoid automatically sending request body if a redirect has occurred.
Expand All @@ -592,21 +594,21 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
// https://tools.ietf.org/html/rfc7231#section-6.4
let is_redirected_request = iters != 1;
let cloned_data;
let maybe_response = match load_data.data {
Some(ref data) if !is_redirected_request => {
req.headers_mut().set(ContentLength(data.len() as u64));
cloned_data = load_data.data.clone();
req.send(&load_data.data)
}
let maybe_response = match data {
&Some(ref d) if !is_redirected_request => {
req.headers_mut().set(ContentLength(d.len() as u64));
cloned_data = data.clone();
req.send(data)
},
_ => {
if load_data.method != Method::Get && load_data.method != Method::Head {
if *load_data_method != Method::Get && *load_data_method != Method::Head {
req.headers_mut().set(ContentLength(0))
}
cloned_data = None;
req.send(&None)
}
};
if let Some(pipeline_id) = load_data.pipeline_id {
if let Some(pipeline_id) = *pipeline_id {
send_request_to_devtools(
devtools_chan.clone(), request_id.clone().into(),
url.clone(), method.clone(), request_headers.clone(),
Expand Down Expand Up @@ -705,7 +707,8 @@ pub fn load<A>(load_data: LoadData,
modify_request_headers(&mut request_headers, &doc_url, &user_agent, &cookie_jar, &load_data);

let response = try!(obtain_response(request_factory, &url, &method, &mut request_headers,
&cancel_listener, &load_data, iters, &devtools_chan, &request_id));
&cancel_listener, &load_data.data, &load_data.method,
&load_data.pipeline_id, iters, &devtools_chan, &request_id));

process_response_headers(&response, &url, &doc_url, &cookie_jar, &hsts_list, &load_data);

Expand Down
12 changes: 11 additions & 1 deletion components/net_traits/lib.rs
Expand Up @@ -72,7 +72,7 @@ pub enum ResponseBody {
Done(Vec<u8>),
}

// [Cache state](https://fetch.spec.whatwg.org/#concept-response-cache-state)
/// [Cache state](https://fetch.spec.whatwg.org/#concept-response-cache-state)
#[derive(Clone)]
pub enum CacheState {
None,
Expand All @@ -81,6 +81,14 @@ pub enum CacheState {
Partial
}

/// [Https state](https://fetch.spec.whatwg.org/#concept-response-https-state)
#[derive(Clone)]
pub enum HttpsState {
None,
Deprecated,
Modern
}

pub enum ResponseMsg {
Chunk(Vec<u8>),
Finished,
Expand All @@ -99,6 +107,7 @@ pub struct Response {
pub headers: Headers,
pub body: ResponseBody,
pub cache_state: CacheState,
pub https_state: HttpsState,
/// [Internal response](https://fetch.spec.whatwg.org/#concept-internal-response), only used if the Response
/// is a filtered response
pub internal_response: Option<Rc<RefCell<Response>>>,
Expand All @@ -115,6 +124,7 @@ impl Response {
headers: Headers::new(),
body: ResponseBody::Empty,
cache_state: CacheState::None,
https_state: HttpsState::None,
internal_response: None
}
}
Expand Down

0 comments on commit af310f7

Please sign in to comment.