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:
		
				
					committed by
					
						 Jonathan Reem
						Jonathan Reem
					
				
			
			
				
	
			
			
			
						parent
						
							a8d7b681da
						
					
				
				
					commit
					0285fc2acc
				
			| @@ -3,15 +3,15 @@ | ||||
| //! These are responses sent by a `hyper::Server` to clients, after | ||||
| //! receiving a request. | ||||
| use std::io::{BufferedWriter, IoResult}; | ||||
| use std::io::net::tcp::TcpStream; | ||||
|  | ||||
| use time::now_utc; | ||||
|  | ||||
| use header; | ||||
| use header::common; | ||||
| use status; | ||||
| use version; | ||||
| use rfc7230::{CR, LF, LINE_ENDING}; | ||||
| use status; | ||||
| use net::NetworkStream; | ||||
| use version; | ||||
|  | ||||
| /// Phantom type indicating Headers and StatusCode have not been written. | ||||
| pub struct Fresh; | ||||
| @@ -26,18 +26,18 @@ impl WriteStatus for Streaming {} | ||||
| impl WriteStatus for Fresh {} | ||||
|  | ||||
| /// The outgoing half for a Tcp connection, created by a `Server` and given to a `Handler`. | ||||
| pub struct Response<W: WriteStatus> { | ||||
| pub struct Response<W: WriteStatus, S: NetworkStream> { | ||||
|     /// The HTTP version of this response. | ||||
|     pub version: version::HttpVersion, | ||||
|     // Stream the Response is writing to, not accessible through UnwrittenResponse | ||||
|     body: BufferedWriter<TcpStream>, // TODO: use a HttpWriter from rfc7230 | ||||
|     body: BufferedWriter<S>, // TODO: use a HttpWriter from rfc7230 | ||||
|     // The status code for the request. | ||||
|     status: status::StatusCode, | ||||
|     // The outgoing headers on this response. | ||||
|     headers: header::Headers | ||||
| } | ||||
|  | ||||
| impl<W: WriteStatus> Response<W> { | ||||
| impl<W: WriteStatus, S: NetworkStream> Response<W, S> { | ||||
|     /// The status of this response. | ||||
|     #[inline] | ||||
|     pub fn status(&self) -> status::StatusCode { self.status } | ||||
| @@ -47,9 +47,9 @@ impl<W: WriteStatus> Response<W> { | ||||
|  | ||||
|     /// Construct a Response from its constituent parts. | ||||
|     pub fn construct(version: version::HttpVersion, | ||||
|                      body: BufferedWriter<TcpStream>, | ||||
|                      body: BufferedWriter<S>, | ||||
|                      status: status::StatusCode, | ||||
|                      headers: header::Headers) -> Response<Fresh> { | ||||
|                      headers: header::Headers) -> Response<Fresh, S> { | ||||
|         Response { | ||||
|             status: status, | ||||
|             version: version, | ||||
| @@ -59,19 +59,19 @@ impl<W: WriteStatus> Response<W> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Response<Fresh> { | ||||
| impl<S: NetworkStream> Response<Fresh, S> { | ||||
|     /// Creates a new Response that can be used to write to a network stream. | ||||
|     pub fn new(tcp: TcpStream) -> Response<Fresh> { | ||||
|     pub fn new(stream: S) -> Response<Fresh, S> { | ||||
|         Response { | ||||
|             status: status::Ok, | ||||
|             version: version::Http11, | ||||
|             headers: header::Headers::new(), | ||||
|             body: BufferedWriter::new(tcp) | ||||
|             body: BufferedWriter::new(stream) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Consume this Response<Fresh>, writing the Headers and Status and creating a Response<Streaming> | ||||
|     pub fn start(mut self) -> IoResult<Response<Streaming>> { | ||||
|     pub fn start(mut self) -> IoResult<Response<Streaming, S>> { | ||||
|         debug!("writing head: {} {}", self.version, self.status); | ||||
|         try!(write!(self.body, "{} {}{}{}", self.version, self.status, CR as char, LF as char)); | ||||
|  | ||||
| @@ -104,12 +104,12 @@ impl Response<Fresh> { | ||||
|     pub fn headers_mut(&mut self) -> &mut header::Headers { &mut self.headers } | ||||
|  | ||||
|     /// Deconstruct this Response into its constituent parts. | ||||
|     pub fn deconstruct(self) -> (version::HttpVersion, BufferedWriter<TcpStream>, status::StatusCode, header::Headers) { | ||||
|     pub fn deconstruct(self) -> (version::HttpVersion, BufferedWriter<S>, status::StatusCode, header::Headers) { | ||||
|         (self.version, self.body, self.status, self.headers) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Response<Streaming> { | ||||
| impl<S: NetworkStream> Response<Streaming, S> { | ||||
|     /// Flushes all writing of a response to the client. | ||||
|     pub fn end(mut self) -> IoResult<()> { | ||||
|         debug!("ending"); | ||||
| @@ -117,7 +117,7 @@ impl Response<Streaming> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Writer for Response<Streaming> { | ||||
| impl<S: NetworkStream> Writer for Response<Streaming, S> { | ||||
|     fn write(&mut self, msg: &[u8]) -> IoResult<()> { | ||||
|         debug!("write {:u} bytes", msg.len()); | ||||
|         self.body.write(msg) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user