Abstract out NetworkStream

This introduces a new Trait, NetworkStream, which abstracts over
the functionality provided by TcpStream so that it can be easily
mocked and extended in testing and hyper can be used for
other connection sources.
This commit is contained in:
Sean McArthur
2014-09-07 14:18:51 -07:00
committed by Jonathan Reem
parent a8d7b681da
commit 0285fc2acc
9 changed files with 240 additions and 111 deletions

View File

@@ -1,33 +1,33 @@
//! Client Responses
use std::io::{BufferedReader, IoResult};
use std::io::net::tcp::TcpStream;
use header;
use header::common::{ContentLength, TransferEncoding};
use header::common::transfer_encoding::Chunked;
use net::{NetworkStream, HttpStream};
use rfc7230::{read_status_line, HttpReader, SizedReader, ChunkedReader, EofReader};
use status;
use version;
use {HttpResult};
/// A response for a client request to a remote server.
pub struct Response {
pub struct Response<S = HttpStream> {
/// The status from the server.
pub status: status::StatusCode,
/// The headers from the server.
pub headers: header::Headers,
/// The HTTP version of this response from the server.
pub version: version::HttpVersion,
body: HttpReader<BufferedReader<TcpStream>>,
body: HttpReader<BufferedReader<S>>,
}
impl Response {
impl<S: NetworkStream> Response<S> {
/// Creates a new response from a server.
pub fn new(tcp: TcpStream) -> HttpResult<Response> {
let mut tcp = BufferedReader::new(tcp);
let (version, status) = try!(read_status_line(&mut tcp));
let mut headers = try!(header::Headers::from_raw(&mut tcp));
pub fn new(stream: S) -> HttpResult<Response<S>> {
let mut stream = BufferedReader::new(stream);
let (version, status) = try!(read_status_line(&mut stream));
let mut headers = try!(header::Headers::from_raw(&mut stream));
debug!("{} {}", version, status);
debug!("{}", headers);
@@ -40,22 +40,22 @@ impl Response {
};
if codings.contains(&Chunked) {
ChunkedReader(tcp, None)
ChunkedReader(stream, None)
} else {
debug!("not chucked. read till eof");
EofReader(tcp)
debug!("not chuncked. read till eof");
EofReader(stream)
}
}
None => unreachable!()
}
} else if headers.has::<ContentLength>() {
match headers.get_ref::<ContentLength>() {
Some(&ContentLength(len)) => SizedReader(tcp, len),
Some(&ContentLength(len)) => SizedReader(stream, len),
None => unreachable!()
}
} else {
debug!("neither Transfer-Encoding nor Content-Length");
EofReader(tcp)
EofReader(stream)
};
Ok(Response {
@@ -67,7 +67,8 @@ impl Response {
}
}
impl Reader for Response {
impl<S: NetworkStream> Reader for Response<S> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
self.body.read(buf)
}