feat(hyper): switch to std::io, std::net, and std::path.
All instances of `old_io` and `old_path` were switched to use the new shiny `std::io`, `std::net`, and `std::path` modules. This means that `Request` and `Response` implement `Read` and `Write` now. Because of the changes to `TcpListener`, this also takes the opportunity to correct the method usage of `Server`. As with other languages/frameworks, the server is first created with a handler, and then a host/port is passed to a `listen` method. This reverses what `Server` used to do. Closes #347 BREAKING CHANGE: Check the docs. Everything was touched.
This commit is contained in:
@@ -18,8 +18,7 @@
|
||||
//! to the `status`, the `headers`, and the response body via the `Writer`
|
||||
//! trait.
|
||||
use std::default::Default;
|
||||
use std::old_io::IoResult;
|
||||
use std::old_io::util::copy;
|
||||
use std::io::{self, copy, Read};
|
||||
use std::iter::Extend;
|
||||
|
||||
use url::UrlParser;
|
||||
@@ -30,7 +29,7 @@ use header::{ContentLength, Location};
|
||||
use method::Method;
|
||||
use net::{NetworkConnector, HttpConnector, ContextVerifier};
|
||||
use status::StatusClass::Redirection;
|
||||
use {Url, Port, HttpResult};
|
||||
use {Url, HttpResult};
|
||||
use HttpError::HttpUriError;
|
||||
|
||||
pub use self::request::Request;
|
||||
@@ -238,9 +237,9 @@ pub trait IntoBody<'a> {
|
||||
/// The target enum for the IntoBody trait.
|
||||
pub enum Body<'a> {
|
||||
/// A Reader does not necessarily know it's size, so it is chunked.
|
||||
ChunkedBody(&'a mut (Reader + 'a)),
|
||||
ChunkedBody(&'a mut (Read + 'a)),
|
||||
/// For Readers that can know their size, like a `File`.
|
||||
SizedBody(&'a mut (Reader + 'a), u64),
|
||||
SizedBody(&'a mut (Read + 'a), u64),
|
||||
/// A String has a size, and uses Content-Length.
|
||||
BufBody(&'a [u8] , usize),
|
||||
}
|
||||
@@ -255,13 +254,13 @@ impl<'a> Body<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Reader for Body<'a> {
|
||||
impl<'a> Read for Body<'a> {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
match *self {
|
||||
Body::ChunkedBody(ref mut r) => r.read(buf),
|
||||
Body::SizedBody(ref mut r, _) => r.read(buf),
|
||||
Body::BufBody(ref mut r, _) => r.read(buf),
|
||||
Body::BufBody(ref mut r, _) => Read::read(r, buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,7 +287,7 @@ impl<'a> IntoBody<'a> for &'a str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: Reader> IntoBody<'a> for &'a mut R {
|
||||
impl<'a, R: Read> IntoBody<'a> for &'a mut R {
|
||||
#[inline]
|
||||
fn into_body(self) -> Body<'a> {
|
||||
Body::ChunkedBody(self)
|
||||
@@ -337,7 +336,7 @@ impl Default for RedirectPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_host_and_port(url: &Url) -> HttpResult<(String, Port)> {
|
||||
fn get_host_and_port(url: &Url) -> HttpResult<(String, u16)> {
|
||||
let host = match url.serialize_host() {
|
||||
Some(host) => host,
|
||||
None => return Err(HttpUriError(UrlError::EmptyHost))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Client Requests
|
||||
use std::old_io::{BufferedWriter, IoResult};
|
||||
use std::marker::PhantomData;
|
||||
use std::io::{self, Write, BufWriter};
|
||||
|
||||
use url::Url;
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct Request<W> {
|
||||
/// The HTTP version of this request.
|
||||
pub version: version::HttpVersion,
|
||||
|
||||
body: HttpWriter<BufferedWriter<Box<NetworkStream + Send>>>,
|
||||
body: HttpWriter<BufWriter<Box<NetworkStream + Send>>>,
|
||||
headers: Headers,
|
||||
method: method::Method,
|
||||
|
||||
@@ -59,7 +59,7 @@ impl Request<Fresh> {
|
||||
let (host, port) = try!(get_host_and_port(&url));
|
||||
|
||||
let stream = try!(connector.connect(&*host, port, &*url.scheme));
|
||||
let stream = ThroughWriter(BufferedWriter::new(box stream as Box<NetworkStream + Send>));
|
||||
let stream = ThroughWriter(BufWriter::new(box stream as Box<NetworkStream + Send>));
|
||||
|
||||
let mut headers = Headers::new();
|
||||
headers.set(Host {
|
||||
@@ -96,7 +96,7 @@ impl Request<Fresh> {
|
||||
Method::Get | Method::Head => {
|
||||
debug!("headers [\n{:?}]", self.headers);
|
||||
try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING));
|
||||
EmptyWriter(self.body.unwrap())
|
||||
EmptyWriter(self.body.into_inner())
|
||||
},
|
||||
_ => {
|
||||
let mut chunked = true;
|
||||
@@ -131,9 +131,9 @@ impl Request<Fresh> {
|
||||
try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING));
|
||||
|
||||
if chunked {
|
||||
ChunkedWriter(self.body.unwrap())
|
||||
ChunkedWriter(self.body.into_inner())
|
||||
} else {
|
||||
SizedWriter(self.body.unwrap(), len)
|
||||
SizedWriter(self.body.into_inner(), len)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -158,19 +158,19 @@ impl Request<Streaming> {
|
||||
///
|
||||
/// Consumes the Request.
|
||||
pub fn send(self) -> HttpResult<Response> {
|
||||
let raw = try!(self.body.end()).into_inner();
|
||||
let raw = try!(self.body.end()).into_inner().unwrap(); // end() already flushes
|
||||
Response::new(raw)
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer for Request<Streaming> {
|
||||
impl Write for Request<Streaming> {
|
||||
#[inline]
|
||||
fn write_all(&mut self, msg: &[u8]) -> IoResult<()> {
|
||||
self.body.write_all(msg)
|
||||
fn write(&mut self, msg: &[u8]) -> io::Result<usize> {
|
||||
self.body.write(msg)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.body.flush()
|
||||
}
|
||||
}
|
||||
@@ -191,8 +191,8 @@ mod tests {
|
||||
).unwrap();
|
||||
let req = req.start().unwrap();
|
||||
let stream = *req.body.end().unwrap()
|
||||
.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||
let bytes = stream.write.into_inner();
|
||||
.into_inner().unwrap().downcast::<MockStream>().ok().unwrap();
|
||||
let bytes = stream.write;
|
||||
let s = from_utf8(&bytes[..]).unwrap();
|
||||
assert!(!s.contains("Content-Length:"));
|
||||
assert!(!s.contains("Transfer-Encoding:"));
|
||||
@@ -205,8 +205,8 @@ mod tests {
|
||||
).unwrap();
|
||||
let req = req.start().unwrap();
|
||||
let stream = *req.body.end().unwrap()
|
||||
.into_inner().downcast::<MockStream>().ok().unwrap();
|
||||
let bytes = stream.write.into_inner();
|
||||
.into_inner().unwrap().downcast::<MockStream>().ok().unwrap();
|
||||
let bytes = stream.write;
|
||||
let s = from_utf8(&bytes[..]).unwrap();
|
||||
assert!(!s.contains("Content-Length:"));
|
||||
assert!(!s.contains("Transfer-Encoding:"));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Client Responses
|
||||
use std::io::{self, Read, BufReader};
|
||||
use std::num::FromPrimitive;
|
||||
use std::old_io::{BufferedReader, IoResult};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use header;
|
||||
@@ -23,7 +23,7 @@ pub struct Response<S = HttpStream> {
|
||||
/// The HTTP version of this response from the server.
|
||||
pub version: version::HttpVersion,
|
||||
status_raw: RawStatus,
|
||||
body: HttpReader<BufferedReader<Box<NetworkStream + Send>>>,
|
||||
body: HttpReader<BufReader<Box<NetworkStream + Send>>>,
|
||||
|
||||
_marker: PhantomData<S>,
|
||||
}
|
||||
@@ -35,7 +35,7 @@ impl Response {
|
||||
|
||||
/// Creates a new response from a server.
|
||||
pub fn new(stream: Box<NetworkStream + Send>) -> HttpResult<Response> {
|
||||
let mut stream = BufferedReader::new(stream);
|
||||
let mut stream = BufReader::new(stream);
|
||||
let (version, raw_status) = try!(read_status_line(&mut stream));
|
||||
let status = match FromPrimitive::from_u16(raw_status.0) {
|
||||
Some(status) => status,
|
||||
@@ -89,13 +89,13 @@ impl Response {
|
||||
|
||||
/// Consumes the Request to return the NetworkStream underneath.
|
||||
pub fn into_inner(self) -> Box<NetworkStream + Send> {
|
||||
self.body.unwrap().into_inner()
|
||||
self.body.into_inner().into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl Reader for Response {
|
||||
impl Read for Response {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.body.read(buf)
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ impl Reader for Response {
|
||||
mod tests {
|
||||
use std::borrow::Cow::Borrowed;
|
||||
use std::boxed::BoxAny;
|
||||
use std::old_io::BufferedReader;
|
||||
use std::io::{self, Read, BufReader};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use header::Headers;
|
||||
@@ -119,14 +119,20 @@ mod tests {
|
||||
|
||||
use super::Response;
|
||||
|
||||
fn read_to_string(mut r: Response) -> io::Result<String> {
|
||||
let mut s = String::new();
|
||||
try!(r.read_to_string(&mut s));
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_unwrap() {
|
||||
fn test_into_inner() {
|
||||
let res = Response {
|
||||
status: status::StatusCode::Ok,
|
||||
headers: Headers::new(),
|
||||
version: version::HttpVersion::Http11,
|
||||
body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)),
|
||||
body: EofReader(BufReader::new(box MockStream::new() as Box<NetworkStream + Send>)),
|
||||
status_raw: RawStatus(200, Borrowed("OK")),
|
||||
_marker: PhantomData,
|
||||
};
|
||||
@@ -152,7 +158,7 @@ mod tests {
|
||||
\r\n"
|
||||
);
|
||||
|
||||
let mut res = Response::new(box stream).unwrap();
|
||||
let res = Response::new(box stream).unwrap();
|
||||
|
||||
// The status line is correct?
|
||||
assert_eq!(res.status, status::StatusCode::Ok);
|
||||
@@ -166,8 +172,7 @@ mod tests {
|
||||
None => panic!("Transfer-Encoding: chunked expected!"),
|
||||
};
|
||||
// The body is correct?
|
||||
let body = res.read_to_string().unwrap();
|
||||
assert_eq!("qwert", body);
|
||||
assert_eq!(read_to_string(res), Ok("qwert".to_string()));
|
||||
}
|
||||
|
||||
/// Tests that when a chunk size is not a valid radix-16 number, an error
|
||||
@@ -184,9 +189,9 @@ mod tests {
|
||||
\r\n"
|
||||
);
|
||||
|
||||
let mut res = Response::new(box stream).unwrap();
|
||||
let res = Response::new(box stream).unwrap();
|
||||
|
||||
assert!(res.read_to_string().is_err());
|
||||
assert!(read_to_string(res).is_err());
|
||||
}
|
||||
|
||||
/// Tests that when a chunk size contains an invalid extension, an error is
|
||||
@@ -203,9 +208,9 @@ mod tests {
|
||||
\r\n"
|
||||
);
|
||||
|
||||
let mut res = Response::new(box stream).unwrap();
|
||||
let res = Response::new(box stream).unwrap();
|
||||
|
||||
assert!(res.read_to_string().is_err());
|
||||
assert!(read_to_string(res).is_err());
|
||||
}
|
||||
|
||||
/// Tests that when a valid extension that contains a digit is appended to
|
||||
@@ -222,8 +227,8 @@ mod tests {
|
||||
\r\n"
|
||||
);
|
||||
|
||||
let mut res = Response::new(box stream).unwrap();
|
||||
let res = Response::new(box stream).unwrap();
|
||||
|
||||
assert_eq!("1", res.read_to_string().unwrap())
|
||||
assert_eq!(read_to_string(res), Ok("1".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user