Use dynamic dispatch for client Request and Response through Box<NetworkStream>
Also adds a convenience `abstract` method to NetworkStream for creating Box<NetworkStream + Send> from a NetworkStream.
This commit is contained in:
@@ -14,7 +14,7 @@ use super::{Response};
|
|||||||
|
|
||||||
|
|
||||||
/// A client request to a remote server.
|
/// A client request to a remote server.
|
||||||
pub struct Request<S = HttpStream> {
|
pub struct Request {
|
||||||
/// The method of this request.
|
/// The method of this request.
|
||||||
pub method: method::Method,
|
pub method: method::Method,
|
||||||
/// The headers that will be sent with this request.
|
/// The headers that will be sent with this request.
|
||||||
@@ -24,13 +24,13 @@ pub struct Request<S = HttpStream> {
|
|||||||
/// The HTTP version of this request.
|
/// The HTTP version of this request.
|
||||||
pub version: version::HttpVersion,
|
pub version: version::HttpVersion,
|
||||||
headers_written: bool,
|
headers_written: bool,
|
||||||
body: BufferedWriter<S>,
|
body: BufferedWriter<Box<NetworkStream + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: NetworkStream> Request<S> {
|
impl Request {
|
||||||
|
|
||||||
/// Create a new client request.
|
/// Create a new client request.
|
||||||
pub fn new(method: method::Method, url: Url) -> HttpResult<Request<S>> {
|
pub fn new(method: method::Method, url: Url) -> HttpResult<Request> {
|
||||||
debug!("{} {}", method, url);
|
debug!("{} {}", method, url);
|
||||||
let host = match url.serialize_host() {
|
let host = match url.serialize_host() {
|
||||||
Some(host) => host,
|
Some(host) => host,
|
||||||
@@ -43,8 +43,8 @@ impl<S: NetworkStream> Request<S> {
|
|||||||
};
|
};
|
||||||
debug!("port={}", port);
|
debug!("port={}", port);
|
||||||
|
|
||||||
let stream = try_io!(NetworkStream::connect(host.as_slice(), port));
|
let stream: HttpStream = try_io!(NetworkStream::connect(host.as_slice(), port));
|
||||||
let stream = BufferedWriter::new(stream);
|
let stream = BufferedWriter::new(stream.abstract());
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(Host(host));
|
headers.set(Host(host));
|
||||||
Ok(Request {
|
Ok(Request {
|
||||||
@@ -82,7 +82,7 @@ impl<S: NetworkStream> Request<S> {
|
|||||||
/// Completes writing the request, and returns a response to read from.
|
/// Completes writing the request, and returns a response to read from.
|
||||||
///
|
///
|
||||||
/// Consumes the Request.
|
/// Consumes the Request.
|
||||||
pub fn send(mut self) -> HttpResult<Response<S>> {
|
pub fn send(mut self) -> HttpResult<Response> {
|
||||||
try_io!(self.flush());
|
try_io!(self.flush());
|
||||||
let raw = self.body.unwrap();
|
let raw = self.body.unwrap();
|
||||||
Response::new(raw)
|
Response::new(raw)
|
||||||
@@ -90,7 +90,7 @@ impl<S: NetworkStream> Request<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<S: NetworkStream> Writer for Request<S> {
|
impl Writer for Request {
|
||||||
fn write(&mut self, msg: &[u8]) -> IoResult<()> {
|
fn write(&mut self, msg: &[u8]) -> IoResult<()> {
|
||||||
if !self.headers_written {
|
if !self.headers_written {
|
||||||
try!(self.write_head());
|
try!(self.write_head());
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ pub struct Response<S = HttpStream> {
|
|||||||
pub headers: header::Headers,
|
pub headers: header::Headers,
|
||||||
/// The HTTP version of this response from the server.
|
/// The HTTP version of this response from the server.
|
||||||
pub version: version::HttpVersion,
|
pub version: version::HttpVersion,
|
||||||
body: HttpReader<BufferedReader<S>>,
|
body: HttpReader<BufferedReader<Box<NetworkStream + Send>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: NetworkStream> Response<S> {
|
impl Response {
|
||||||
|
|
||||||
/// Creates a new response from a server.
|
/// Creates a new response from a server.
|
||||||
pub fn new(stream: S) -> HttpResult<Response<S>> {
|
pub fn new(stream: Box<NetworkStream + Send>) -> HttpResult<Response> {
|
||||||
let mut stream = BufferedReader::new(stream);
|
let mut stream = BufferedReader::new(stream.abstract());
|
||||||
let (version, status) = try!(read_status_line(&mut stream));
|
let (version, status) = try!(read_status_line(&mut stream));
|
||||||
let mut headers = try!(header::Headers::from_raw(&mut stream));
|
let mut headers = try!(header::Headers::from_raw(&mut stream));
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ impl<S: NetworkStream> Response<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: NetworkStream> Reader for Response<S> {
|
impl Reader for Response {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||||
self.body.read(buf)
|
self.body.read(buf)
|
||||||
|
|||||||
16
src/net.rs
16
src/net.rs
@@ -28,6 +28,22 @@ pub trait NetworkStream: Stream + Clone + Send {
|
|||||||
|
|
||||||
/// Connect to a remote address.
|
/// Connect to a remote address.
|
||||||
fn connect(host: &str, port: Port) -> IoResult<Self>;
|
fn connect(host: &str, port: Port) -> IoResult<Self>;
|
||||||
|
|
||||||
|
/// Turn this into an appropriately typed trait object.
|
||||||
|
#[inline]
|
||||||
|
fn abstract(self) -> Box<NetworkStream + Send> {
|
||||||
|
box self as Box<NetworkStream + Send>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[inline]
|
||||||
|
// Hack to work around lack of Clone impl for Box<Clone>
|
||||||
|
fn clone_box(&self) -> Box<NetworkStream + Send> { self.clone().abstract() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Box<NetworkStream + Send> {
|
||||||
|
#[inline]
|
||||||
|
fn clone(&self) -> Box<NetworkStream + Send> { self.clone_box() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reader for Box<NetworkStream + Send> {
|
impl Reader for Box<NetworkStream + Send> {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ impl Request {
|
|||||||
/// immediately useful.
|
/// immediately useful.
|
||||||
pub fn new<S: NetworkStream>(mut stream: S) -> HttpResult<Request> {
|
pub fn new<S: NetworkStream>(mut stream: S) -> HttpResult<Request> {
|
||||||
let remote_addr = try_io!(stream.peer_name());
|
let remote_addr = try_io!(stream.peer_name());
|
||||||
let mut stream = BufferedReader::new(box stream as Box<NetworkStream + Send>);
|
let mut stream = BufferedReader::new(stream.abstract());
|
||||||
let (method, uri, version) = try!(read_request_line(&mut stream));
|
let (method, uri, version) = try!(read_request_line(&mut stream));
|
||||||
let mut headers = try!(Headers::from_raw(&mut stream));
|
let mut headers = try!(Headers::from_raw(&mut stream));
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ impl Response<Fresh> {
|
|||||||
status: status::Ok,
|
status: status::Ok,
|
||||||
version: version::Http11,
|
version: version::Http11,
|
||||||
headers: header::Headers::new(),
|
headers: header::Headers::new(),
|
||||||
body: BufferedWriter::new(box stream as Box<NetworkStream + Send>)
|
body: BufferedWriter::new(stream.abstract())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user