Skip to content

Commit

Permalink
Auto merge of #10555 - jdm:http_response_refactor, r=ms2ger
Browse files Browse the repository at this point in the history
Remove unnecessary indirection in HTTP unit tests

Many of the HTTP unit tests use a custom request factory as well as a custom request that contained test logic. This is unnecessarily convoluted, and exists solely because the complete set of headers was unavailable until the request body was sent. These patches restructure the header manipulations so that the headers are available when the request object is created, allowing the test logic to move into the test factories, and enabling the deletion of almost all of the test request types.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10555)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Apr 15, 2016
2 parents 7faa3ed + 43369fa commit eb78e21
Show file tree
Hide file tree
Showing 2 changed files with 247 additions and 375 deletions.
75 changes: 38 additions & 37 deletions components/net/http_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ fn load_for_consumer(load_data: LoadData,

let ui_provider = TFDProvider;
let context = load_data.context.clone();
match load::<WrappedHttpRequest, TFDProvider>(load_data, &ui_provider, &http_state,
devtools_chan, &factory,
user_agent, &cancel_listener) {
match load(load_data, &ui_provider, &http_state,
devtools_chan, &factory,
user_agent, &cancel_listener) {
Err(LoadError::UnsupportedScheme(url)) => {
let s = format!("{} request, but we don't support that scheme", &*url.scheme);
send_error(url, s, start_chan)
Expand Down Expand Up @@ -249,7 +249,7 @@ impl HttpResponse for WrappedHttpResponse {
pub trait HttpRequestFactory {
type R: HttpRequest;

fn create(&self, url: Url, method: Method) -> Result<Self::R, LoadError>;
fn create(&self, url: Url, method: Method, headers: Headers) -> Result<Self::R, LoadError>;
}

pub struct NetworkHttpRequestFactory {
Expand All @@ -259,7 +259,8 @@ pub struct NetworkHttpRequestFactory {
impl HttpRequestFactory for NetworkHttpRequestFactory {
type R = WrappedHttpRequest;

fn create(&self, url: Url, method: Method) -> Result<WrappedHttpRequest, LoadError> {
fn create(&self, url: Url, method: Method, headers: Headers)
-> Result<WrappedHttpRequest, LoadError> {
let connection = Request::with_connector(method, url.clone(), &*self.connector);

if let Err(HttpError::Ssl(ref error)) = connection {
Expand All @@ -274,13 +275,14 @@ impl HttpRequestFactory for NetworkHttpRequestFactory {
}
}

let request = match connection {
let mut request = match connection {
Ok(req) => req,

Err(e) => {
return Err(LoadError::Connection(url, e.description().to_owned()))
}
};
*request.headers_mut() = headers;

Ok(WrappedHttpRequest { request: request })
}
Expand All @@ -289,7 +291,6 @@ impl HttpRequestFactory for NetworkHttpRequestFactory {
pub trait HttpRequest {
type R: HttpResponse + 'static;

fn headers_mut(&mut self) -> &mut Headers;
fn send(self, body: &Option<Vec<u8>>) -> Result<Self::R, LoadError>;
}

Expand All @@ -300,10 +301,6 @@ pub struct WrappedHttpRequest {
impl HttpRequest for WrappedHttpRequest {
type R = WrappedHttpResponse;

fn headers_mut(&mut self) -> &mut Headers {
self.request.headers_mut()
}

fn send(self, body: &Option<Vec<u8>>) -> Result<WrappedHttpResponse, LoadError> {
let url = self.request.url.clone();
let mut request_writer = match self.request.start() {
Expand Down Expand Up @@ -628,6 +625,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
request_id: &str)
-> Result<A::R, LoadError> where A: HttpRequest + 'static {

let null_data = None;
let response;
let connection_url = replace_hosts(&url);

Expand All @@ -636,20 +634,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
// a ConnectionAborted error. this loop tries again with a new
// connection.
loop {
let mut req = try!(request_factory.create(connection_url.clone(), method.clone()));
*req.headers_mut() = request_headers.clone();

if cancel_listener.is_cancelled() {
return Err(LoadError::Cancelled(connection_url.clone(), "load cancelled".to_owned()));
}

if log_enabled!(log::LogLevel::Info) {
info!("{}", method);
for header in req.headers_mut().iter() {
info!(" - {}", header);
}
info!("{:?}", data);
}
let mut headers = request_headers.clone();

// Avoid automatically sending request body if a redirect has occurred.
//
Expand All @@ -658,26 +643,42 @@ 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 data {
let request_body;
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)
},
headers.set(ContentLength(d.len() as u64));
request_body = data;
}
_ => {
if *load_data_method != Method::Get && *load_data_method != Method::Head {
req.headers_mut().set(ContentLength(0))
headers.set(ContentLength(0))
}
cloned_data = None;
req.send(&None)
request_body = &null_data;
}
};
}

if log_enabled!(log::LogLevel::Info) {
info!("{}", method);
for header in headers.iter() {
info!(" - {}", header);
}
info!("{:?}", data);
}

let req = try!(request_factory.create(connection_url.clone(), method.clone(),
headers.clone()));

if cancel_listener.is_cancelled() {
return Err(LoadError::Cancelled(connection_url.clone(), "load cancelled".to_owned()));
}

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(), request_headers.clone(),
cloned_data, pipeline_id, time::now()
url.clone(), method.clone(), headers,
request_body.clone(), pipeline_id, time::now()
);
}

Expand Down
Loading

0 comments on commit eb78e21

Please sign in to comment.