use Buffered Readers and Writers

This commit is contained in:
Sean McArthur
2014-09-02 14:14:56 -07:00
parent 818fac4128
commit b4b539091f
5 changed files with 23 additions and 19 deletions

View File

@@ -10,9 +10,9 @@ An HTTP library for Rust.
``` ```
running 3 tests running 3 tests
test bench_curl ... bench: 346762 ns/iter (+/- 16469) test bench_curl ... bench: 234539 ns/iter (+/- 22228)
test bench_http ... bench: 310861 ns/iter (+/- 123168) test bench_http ... bench: 290370 ns/iter (+/- 69179)
test bench_hyper ... bench: 284916 ns/iter (+/- 65935) test bench_hyper ... bench: 224482 ns/iter (+/- 95197)
test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured
``` ```

View File

@@ -1,6 +1,6 @@
//! Client Requests //! Client Requests
use std::io::net::tcp::TcpStream; use std::io::net::tcp::TcpStream;
use std::io::IoResult; use std::io::{BufferedWriter, IoResult};
use url::Url; use url::Url;
@@ -23,7 +23,7 @@ pub struct Request {
/// 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: TcpStream, body: BufferedWriter<TcpStream>,
} }
impl Request { impl Request {
@@ -43,6 +43,7 @@ impl Request {
debug!("port={}", port); debug!("port={}", port);
let stream = try_io!(TcpStream::connect(host.as_slice(), port)); let stream = try_io!(TcpStream::connect(host.as_slice(), port));
let stream = BufferedWriter::new(stream);
let mut headers = Headers::new(); let mut headers = Headers::new();
headers.set(Host(host)); headers.set(Host(host));
Ok(Request { Ok(Request {
@@ -82,8 +83,9 @@ impl Request {
/// Consumes the Request. /// Consumes the Request.
pub fn send(mut self) -> HttpResult<Response> { pub fn send(mut self) -> HttpResult<Response> {
try_io!(self.flush()); try_io!(self.flush());
try_io!(self.body.close_write()); let mut raw = self.body.unwrap();
Response::new(self.body) try_io!(raw.close_write());
Response::new(raw)
} }
} }

View File

@@ -1,5 +1,5 @@
//! Client Responses //! Client Responses
use std::io::{Reader, IoResult}; use std::io::{BufferedReader, IoResult};
use std::io::net::tcp::TcpStream; use std::io::net::tcp::TcpStream;
use header::{mod, ContentLength, TransferEncoding, Chunked}; use header::{mod, ContentLength, TransferEncoding, Chunked};
@@ -16,13 +16,14 @@ pub struct Response {
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<TcpStream>, body: HttpReader<BufferedReader<TcpStream>>,
} }
impl Response { impl Response {
/// Creates a new response from a server. /// Creates a new response from a server.
pub fn new(mut tcp: TcpStream) -> HttpResult<Response> { pub fn new(tcp: TcpStream) -> HttpResult<Response> {
let mut tcp = BufferedReader::new(tcp);
let (version, status) = try!(read_status_line(&mut tcp)); let (version, status) = try!(read_status_line(&mut tcp));
let mut headers = try!(header::Headers::from_raw(&mut tcp)); let mut headers = try!(header::Headers::from_raw(&mut tcp));

View File

@@ -2,7 +2,7 @@
//! //!
//! These are requests that a `hyper::Server` receives, and include its method, //! These are requests that a `hyper::Server` receives, and include its method,
//! target URI, headers, and message body. //! target URI, headers, and message body.
use std::io::{Reader, IoResult}; use std::io::{Reader, BufferedReader, IoResult};
use std::io::net::ip::SocketAddr; use std::io::net::ip::SocketAddr;
use std::io::net::tcp::TcpStream; use std::io::net::tcp::TcpStream;
@@ -26,7 +26,7 @@ pub struct Request {
pub uri: RequestUri, pub uri: RequestUri,
/// The version of HTTP for this request. /// The version of HTTP for this request.
pub version: HttpVersion, pub version: HttpVersion,
body: HttpReader<TcpStream> body: HttpReader<BufferedReader<TcpStream>>
} }
@@ -35,13 +35,14 @@ impl Request {
/// Create a new Request, reading the StartLine and Headers so they are /// Create a new Request, reading the StartLine and Headers so they are
/// immediately useful. /// immediately useful.
pub fn new(mut tcp: TcpStream) -> HttpResult<Request> { pub fn new(mut tcp: TcpStream) -> HttpResult<Request> {
let remote_addr = try_io!(tcp.peer_name());
let mut tcp = BufferedReader::new(tcp);
let (method, uri, version) = try!(read_request_line(&mut tcp)); let (method, uri, version) = try!(read_request_line(&mut tcp));
let mut headers = try!(Headers::from_raw(&mut tcp)); let mut headers = try!(Headers::from_raw(&mut tcp));
debug!("{} {} {}", method, uri, version); debug!("{} {} {}", method, uri, version);
debug!("{}", headers); debug!("{}", headers);
let remote_addr = try_io!(tcp.peer_name());
// TODO: handle Transfer-Encoding // TODO: handle Transfer-Encoding
let body = if headers.has::<ContentLength>() { let body = if headers.has::<ContentLength>() {

View File

@@ -2,7 +2,7 @@
//! //!
//! These are responses sent by a `hyper::Server` to clients, after //! These are responses sent by a `hyper::Server` to clients, after
//! receiving a request. //! receiving a request.
use std::io::IoResult; use std::io::{BufferedWriter, IoResult};
use std::io::net::tcp::TcpStream; use std::io::net::tcp::TcpStream;
use header; use header;
@@ -21,7 +21,7 @@ pub struct Response {
pub version: version::HttpVersion, pub version: version::HttpVersion,
headers_written: bool, // TODO: can this check be moved to compile time? headers_written: bool, // TODO: can this check be moved to compile time?
body: TcpStream body: BufferedWriter<TcpStream>, // TODO: use a HttpWriter from rfc7230
} }
impl Response { impl Response {
@@ -33,7 +33,7 @@ impl Response {
version: version::Http11, version: version::Http11,
headers: header::Headers::new(), headers: header::Headers::new(),
headers_written: false, headers_written: false,
body: tcp body: BufferedWriter::new(tcp)
} }
} }
@@ -56,9 +56,9 @@ impl Response {
} }
/// Flushes all writing of a response to the client. /// Flushes all writing of a response to the client.
pub fn end(&mut self) -> IoResult<()> { pub fn end(mut self) -> IoResult<()> {
try!(self.flush()); debug!("ending");
self.body.close_write() self.flush()
} }
} }