diff options
author | Sean McArthur <sean.monstar@gmail.com> | 2014-11-14 11:57:32 -0800 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2014-12-04 10:06:39 -0800 |
commit | 12727d4dd0a93c7ab8139c8ae6893a1ec3b5edaf (patch) | |
tree | 31cbc8e8cfbbf7e95b6c9878f9589eaf63add8d1 /components/net | |
parent | 92a8c7a80ccd5721884da96dbd28c6c40ba32b70 (diff) | |
download | servo-12727d4dd0a93c7ab8139c8ae6893a1ec3b5edaf.tar.gz servo-12727d4dd0a93c7ab8139c8ae6893a1ec3b5edaf.zip |
convert net crate to use hyper
Diffstat (limited to 'components/net')
-rw-r--r-- | components/net/Cargo.toml | 4 | ||||
-rw-r--r-- | components/net/about_loader.rs | 4 | ||||
-rw-r--r-- | components/net/data_loader.rs | 7 | ||||
-rw-r--r-- | components/net/fetch/cors_cache.rs | 2 | ||||
-rw-r--r-- | components/net/fetch/request.rs | 12 | ||||
-rw-r--r-- | components/net/fetch/response.rs | 48 | ||||
-rw-r--r-- | components/net/http_loader.rs | 92 | ||||
-rw-r--r-- | components/net/lib.rs | 2 | ||||
-rw-r--r-- | components/net/resource_task.rs | 39 |
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(), |