aboutsummaryrefslogtreecommitdiffstats
path: root/components/net
diff options
context:
space:
mode:
authorSean McArthur <sean.monstar@gmail.com>2014-11-14 11:57:32 -0800
committerManish Goregaokar <manishsmail@gmail.com>2014-12-04 10:06:39 -0800
commit12727d4dd0a93c7ab8139c8ae6893a1ec3b5edaf (patch)
tree31cbc8e8cfbbf7e95b6c9878f9589eaf63add8d1 /components/net
parent92a8c7a80ccd5721884da96dbd28c6c40ba32b70 (diff)
downloadservo-12727d4dd0a93c7ab8139c8ae6893a1ec3b5edaf.tar.gz
servo-12727d4dd0a93c7ab8139c8ae6893a1ec3b5edaf.zip
convert net crate to use hyper
Diffstat (limited to 'components/net')
-rw-r--r--components/net/Cargo.toml4
-rw-r--r--components/net/about_loader.rs4
-rw-r--r--components/net/data_loader.rs7
-rw-r--r--components/net/fetch/cors_cache.rs2
-rw-r--r--components/net/fetch/request.rs12
-rw-r--r--components/net/fetch/response.rs48
-rw-r--r--components/net/http_loader.rs92
-rw-r--r--components/net/lib.rs2
-rw-r--r--components/net/resource_task.rs39
9 files changed, 119 insertions, 91 deletions
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index 17560f4aa5c..60903838269 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -13,8 +13,8 @@ path = "../util"
[dependencies.geom]
git = "https://github.com/servo/rust-geom"
-[dependencies.http]
-git = "https://github.com/servo/rust-http"
+[dependencies.hyper]
+git = "https://github.com/hyperium/hyper"
branch = "servo"
[dependencies.png]
diff --git a/components/net/about_loader.rs b/components/net/about_loader.rs
index eebdcfd4237..f8867cd5479 100644
--- a/components/net/about_loader.rs
+++ b/components/net/about_loader.rs
@@ -7,7 +7,7 @@ use file_loader;
use std::io::fs::PathExtensions;
use url::Url;
-use http::status::Ok as StatusOk;
+use hyper::http::RawStatus;
use servo_util::resource_files::resources_dir_path;
@@ -23,7 +23,7 @@ pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>
content_type: Some(("text".to_string(), "html".to_string())),
charset: Some("utf-8".to_string()),
headers: None,
- status: Some(StatusOk),
+ status: Some(RawStatus(200, "OK".into_string()))
});
chan.send(Done(Ok(())));
return
diff --git a/components/net/data_loader.rs b/components/net/data_loader.rs
index 33e2651512b..8f9f551f5dc 100644
--- a/components/net/data_loader.rs
+++ b/components/net/data_loader.rs
@@ -6,8 +6,7 @@ use resource_task::{Done, Payload, Metadata, LoadData, TargetedLoadResponse, sta
use serialize::base64::FromBase64;
-use http::headers::test_utils::from_stream_with_str;
-use http::headers::content_type::MediaType;
+use hyper::mime::Mime;
use url::{percent_decode, NonRelativeSchemeData};
@@ -59,8 +58,8 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
// Parse the content type using rust-http.
// FIXME: this can go into an infinite loop! (rust-http #25)
- let content_type: Option<MediaType> = from_stream_with_str(ct_str);
- metadata.set_content_type(&content_type);
+ let content_type: Option<Mime> = from_str(ct_str);
+ metadata.set_content_type(content_type.as_ref());
let progress_chan = start_sending(senders, metadata);
let bytes = percent_decode(parts[1].as_bytes());
diff --git a/components/net/fetch/cors_cache.rs b/components/net/fetch/cors_cache.rs
index f7b63b3b339..b287e7999fe 100644
--- a/components/net/fetch/cors_cache.rs
+++ b/components/net/fetch/cors_cache.rs
@@ -9,7 +9,7 @@
//! This library will eventually become the core of the Fetch crate
//! with CORSRequest being expanded into FetchRequest (etc)
-use http::method::Method;
+use hyper::method::Method;
use std::ascii::AsciiExt;
use std::comm::{Sender, Receiver, channel};
use time;
diff --git a/components/net/fetch/request.rs b/components/net/fetch/request.rs
index 95bdc76ca35..aa53337516b 100644
--- a/components/net/fetch/request.rs
+++ b/components/net/fetch/request.rs
@@ -3,8 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use url::Url;
-use http::method::{Get, Method};
-use http::headers::request::HeaderCollection;
+use hyper::method::{Get, Method};
+use hyper::mime::{Mime, Text, Html, Charset, Utf8};
+use hyper::header::Headers;
+use hyper::header::common::ContentType;
use fetch::cors_cache::CORSCache;
use fetch::response::Response;
@@ -58,7 +60,7 @@ pub enum ResponseTainting {
pub struct Request {
pub method: Method,
pub url: Url,
- pub headers: HeaderCollection,
+ pub headers: Headers,
pub unsafe_request: bool,
pub body: Option<Vec<u8>>,
pub preserve_content_codings: bool,
@@ -87,7 +89,7 @@ impl Request {
Request {
method: Get,
url: url,
- headers: HeaderCollection::new(),
+ headers: Headers::new(),
unsafe_request: false,
body: None,
preserve_content_codings: false,
@@ -116,7 +118,7 @@ impl Request {
"about" => match self.url.non_relative_scheme_data() {
Some(s) if s.as_slice() == "blank" => {
let mut response = Response::new();
- let _ = response.headers.insert_raw("Content-Type".to_string(), b"text/html;charset=utf-8");
+ response.headers.set(ContentType(Mime(Text, Html, vec![(Charset, Utf8)])));
response
},
_ => Response::network_error()
diff --git a/components/net/fetch/response.rs b/components/net/fetch/response.rs
index 7b9034166ee..48a2794aed3 100644
--- a/components/net/fetch/response.rs
+++ b/components/net/fetch/response.rs
@@ -3,11 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use url::Url;
-use http::status::{Status, UnregisteredStatus};
-use http::status::Ok as StatusOk;
-use http::headers::HeaderEnum;
-use http::headers::response::HeaderCollection;
-use std::ascii::OwnedAsciiExt;
+use hyper::status::StatusCode;
+use hyper::status::Ok as StatusOk;
+use hyper::header::Headers;
+use std::ascii::AsciiExt;
use std::comm::Receiver;
/// [Response type](http://fetch.spec.whatwg.org/#concept-response-type)
@@ -57,8 +56,9 @@ pub struct Response {
pub response_type: ResponseType,
pub termination_reason: Option<TerminationReason>,
pub url: Option<Url>,
- pub status: Status,
- pub headers: HeaderCollection,
+ /// `None` can be considered a StatusCode of `0`.
+ pub status: Option<StatusCode>,
+ pub headers: Headers,
pub body: ResponseBody,
/// [Internal response](http://fetch.spec.whatwg.org/#concept-internal-response), only used if the Response is a filtered response
pub internal_response: Option<Box<Response>>,
@@ -70,8 +70,8 @@ impl Response {
response_type: Default,
termination_reason: None,
url: None,
- status: StatusOk,
- headers: HeaderCollection::new(),
+ status: Some(StatusOk),
+ headers: Headers::new(),
body: Empty,
internal_response: None
}
@@ -82,8 +82,8 @@ impl Response {
response_type: Error,
termination_reason: None,
url: None,
- status: UnregisteredStatus(0, "".to_string()),
- headers: HeaderCollection::new(),
+ status: None,
+ headers: Headers::new(),
body: Empty,
internal_response: None
}
@@ -110,32 +110,30 @@ impl Response {
match filter_type {
Default | Error => unreachable!(),
Basic => {
- let mut headers = HeaderCollection::new();
- for h in old_headers.iter() {
- match h.header_name().into_ascii_lower().as_slice() {
- "set-cookie" | "set-cookie2" => {},
- _ => headers.insert(h)
+ let headers = old_headers.iter().filter(|header| {
+ match header.name().to_ascii_lower().as_slice() {
+ "set-cookie" | "set-cookie2" => false,
+ _ => true
}
- }
+ }).collect();
response.headers = headers;
response.response_type = filter_type;
},
CORS => {
- let mut headers = HeaderCollection::new();
- for h in old_headers.iter() {
- match h.header_name().into_ascii_lower().as_slice() {
+ let headers = old_headers.iter().filter(|header| {
+ match header.name().to_ascii_lower().as_slice() {
"cache-control" | "content-language" |
- "content-type" | "expires" | "last-modified" | "Pragma" => {},
+ "content-type" | "expires" | "last-modified" | "Pragma" => false,
// XXXManishearth handle Access-Control-Expose-Headers
- _ => headers.insert(h)
+ _ => true
}
- }
+ }).collect();
response.headers = headers;
response.response_type = filter_type;
},
Opaque => {
- response.headers = HeaderCollection::new();
- response.status = UnregisteredStatus(0, "".to_string());
+ response.headers = Headers::new();
+ response.status = None;
response.body = Empty;
}
}
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs
index ca3226191ea..79a7dca25a1 100644
--- a/components/net/http_loader.rs
+++ b/components/net/http_loader.rs
@@ -6,11 +6,13 @@ use resource_task::{Metadata, Payload, Done, TargetedLoadResponse, LoadData, sta
use log;
use std::collections::HashSet;
-use http::client::{RequestWriter, NetworkStream};
-use http::headers::HeaderEnum;
+use hyper::client::Request;
+use hyper::header::common::{ContentLength, ContentType, Host, Location};
+use hyper::method::{Get, Head};
+use hyper::status::Redirection;
use std::io::Reader;
use servo_util::task::spawn_named;
-use url::Url;
+use url::{Url, UrlParser};
pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
spawn_named("http_loader", proc() load(load_data, start_chan))
@@ -67,55 +69,75 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
info!("requesting {:s}", url.serialize());
- let request = RequestWriter::<NetworkStream>::new(load_data.method.clone(), url.clone());
- let mut writer = match request {
- Ok(w) => box w,
+ let mut req = match Request::new(load_data.method.clone(), url.clone()) {
+ Ok(req) => req,
Err(e) => {
- send_error(url, e.desc.to_string(), senders);
+ send_error(url, e.to_string(), senders);
return;
}
};
- // Preserve the `host` header set automatically by RequestWriter.
- let host = writer.headers.host.clone();
- writer.headers = load_data.headers.clone();
- writer.headers.host = host;
- if writer.headers.accept_encoding.is_none() {
+ // Preserve the `host` header set automatically by Request.
+ let host = req.headers().get::<Host>().unwrap().clone();
+ *req.headers_mut() = load_data.headers.clone();
+ req.headers_mut().set(host);
+ // FIXME(seanmonstar): use AcceptEncoding from Hyper once available
+ //if !req.headers.has::<AcceptEncoding>() {
// We currently don't support HTTP Compression (FIXME #2587)
- writer.headers.accept_encoding = Some(String::from_str("identity".as_slice()))
- }
- match load_data.data {
+ req.headers_mut().set_raw("Accept-Encoding", vec![b"identity".to_vec()]);
+ //}
+ let writer = match load_data.data {
Some(ref data) => {
- writer.headers.content_length = Some(data.len());
+ req.headers_mut().set(ContentLength(data.len()));
+ let mut writer = match req.start() {
+ Ok(w) => w,
+ Err(e) => {
+ send_error(url, e.to_string(), senders);
+ return;
+ }
+ };
match writer.write(data.as_slice()) {
Err(e) => {
send_error(url, e.desc.to_string(), senders);
return;
}
_ => {}
- }
+ };
+ writer
},
- _ => {}
- }
- let mut response = match writer.read_response() {
+ None => {
+ match load_data.method {
+ Get | Head => (),
+ _ => req.headers_mut().set(ContentLength(0))
+ }
+ match req.start() {
+ Ok(w) => w,
+ Err(e) => {
+ send_error(url, e.to_string(), senders);
+ return;
+ }
+ }
+ }
+ };
+ let mut response = match writer.send() {
Ok(r) => r,
- Err((_, e)) => {
- send_error(url, e.desc.to_string(), senders);
+ Err(e) => {
+ send_error(url, e.to_string(), senders);
return;
}
};
// Dump headers, but only do the iteration if info!() is enabled.
- info!("got HTTP response {:s}, headers:", response.status.to_string());
+ info!("got HTTP response {}, headers:", response.status);
if log_enabled!(log::INFO) {
for header in response.headers.iter() {
- info!(" - {:s}: {:s}", header.header_name(), header.header_value());
+ info!(" - {}", header);
}
}
- if 3 == (response.status.code() / 100) {
- match response.headers.location {
- Some(new_url) => {
+ if response.status.class() == Redirection {
+ match response.headers.get::<Location>() {
+ Some(&Location(ref new_url)) => {
// CORS (http://fetch.spec.whatwg.org/#http-fetch, status section, point 9, 10)
match load_data.cors {
Some(ref c) => {
@@ -130,7 +152,14 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
}
_ => {}
}
- info!("redirecting to {:s}", new_url.serialize());
+ let new_url = match UrlParser::new().base_url(&url).parse(new_url.as_slice()) {
+ Ok(u) => u,
+ Err(e) => {
+ send_error(url, e.to_string(), senders);
+ return;
+ }
+ };
+ info!("redirecting to {}", new_url);
url = new_url;
continue;
}
@@ -139,9 +168,12 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
}
let mut metadata = Metadata::default(url);
- metadata.set_content_type(&response.headers.content_type);
+ metadata.set_content_type(match response.headers.get() {
+ Some(&ContentType(ref mime)) => Some(mime),
+ None => None
+ });
metadata.headers = Some(response.headers.clone());
- metadata.status = Some(response.status.clone());
+ metadata.status = Some(response.status_raw().clone());
let progress_chan = match start_sending_opt(senders, metadata) {
Ok(p) => p,
diff --git a/components/net/lib.rs b/components/net/lib.rs
index d3b1d5bfd95..1954802b2aa 100644
--- a/components/net/lib.rs
+++ b/components/net/lib.rs
@@ -9,7 +9,7 @@
extern crate collections;
extern crate geom;
-extern crate http;
+extern crate hyper;
extern crate png;
#[phase(plugin, link)]
extern crate log;
diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs
index 7cd5d6a8310..60ad9c8578b 100644
--- a/components/net/resource_task.rs
+++ b/components/net/resource_task.rs
@@ -12,14 +12,13 @@ use sniffer_task;
use sniffer_task::SnifferTask;
use std::comm::{channel, Receiver, Sender};
-use http::headers::content_type::MediaType;
-use http::headers::response::HeaderCollection as ResponseHeaderCollection;
-use http::headers::request::HeaderCollection as RequestHeaderCollection;
-use http::method::{Method, Get};
+use hyper::mime::{Mime, Charset};
+use hyper::header::Headers;
+use hyper::header::common::UserAgent;
+use hyper::method::{Method, Get};
use url::Url;
-use http::status::Ok as StatusOk;
-use http::status::Status;
+use hyper::http::RawStatus;
use servo_util::task::spawn_named;
@@ -33,7 +32,7 @@ pub enum ControlMsg {
pub struct LoadData {
pub url: Url,
pub method: Method,
- pub headers: RequestHeaderCollection,
+ pub headers: Headers,
pub data: Option<Vec<u8>>,
pub cors: Option<ResourceCORSData>,
pub consumer: Sender<LoadResponse>,
@@ -44,7 +43,7 @@ impl LoadData {
LoadData {
url: url,
method: Get,
- headers: RequestHeaderCollection::new(),
+ headers: Headers::new(),
data: None,
cors: None,
consumer: consumer,
@@ -72,10 +71,10 @@ pub struct Metadata {
pub charset: Option<String>,
/// Headers
- pub headers: Option<ResponseHeaderCollection>,
+ pub headers: Option<Headers>,
/// HTTP Status
- pub status: Option<Status>
+ pub status: Option<RawStatus>
}
impl Metadata {
@@ -86,21 +85,19 @@ impl Metadata {
content_type: None,
charset: None,
headers: None,
- status: Some(StatusOk) // http://fetch.spec.whatwg.org/#concept-response-status-message
+ status: Some(RawStatus(200, "OK".into_string())) // http://fetch.spec.whatwg.org/#concept-response-status-message
}
}
- /// Extract the parts of a MediaType that we care about.
- pub fn set_content_type(&mut self, content_type: &Option<MediaType>) {
- match *content_type {
+ /// Extract the parts of a Mime that we care about.
+ pub fn set_content_type(&mut self, content_type: Option<&Mime>) {
+ match content_type {
None => (),
- Some(MediaType { ref type_,
- ref subtype,
- ref parameters }) => {
- self.content_type = Some((type_.clone(), subtype.clone()));
+ Some(&Mime(ref type_, ref subtype, ref parameters)) => {
+ self.content_type = Some((type_.to_string(), subtype.to_string()));
for &(ref k, ref v) in parameters.iter() {
- if "charset" == k.as_slice() {
- self.charset = Some(v.clone());
+ if &Charset == k {
+ self.charset = Some(v.to_string());
}
}
}
@@ -224,7 +221,7 @@ impl ResourceManager {
fn load(&self, load_data: LoadData) {
let mut load_data = load_data;
- load_data.headers.user_agent = self.user_agent.clone();
+ self.user_agent.map(|ref ua| load_data.headers.set(UserAgent(ua.clone())));
let senders = ResponseSenders {
immediate_consumer: self.sniffer_task.clone(),
eventual_consumer: load_data.consumer.clone(),