Skip to content

Commit b903413

Browse files
committed
Merge pull request #29 from reem/network-stream
Abstract over NetworkStream using dynamic dispatch
2 parents 4eb48ab + 632250b commit b903413

File tree

10 files changed

+252
-95
lines changed

10 files changed

+252
-95
lines changed

benches/client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ extern crate test;
88
use std::fmt::{mod, Show};
99
use std::io::net::ip::Ipv4Addr;
1010
use hyper::server::{Incoming, Server};
11+
use hyper::net::HttpAcceptor;
1112

12-
fn listen() -> hyper::server::Listening {
13+
fn listen() -> hyper::server::Listening<HttpAcceptor> {
1314
let server = Server::http(Ipv4Addr(127, 0, 0, 1), 0);
1415
server.listen(handle).unwrap()
1516
}

examples/concurrent-server.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(macro_rules)]
1+
#![feature(macro_rules, default_type_params)]
22

33
extern crate hyper;
44
extern crate debug;
@@ -10,15 +10,16 @@ use std::sync::Arc;
1010
use hyper::{Get, Post};
1111
use hyper::server::{Server, Handler, Incoming, Request, Response, Fresh};
1212
use hyper::header::common::ContentLength;
13+
use hyper::net::{HttpStream, HttpAcceptor};
1314

1415
trait ConcurrentHandler: Send + Sync {
1516
fn handle(&self, req: Request, res: Response<Fresh>);
1617
}
1718

1819
struct Concurrent<H: ConcurrentHandler> { handler: Arc<H> }
1920

20-
impl<H: ConcurrentHandler> Handler for Concurrent<H> {
21-
fn handle(self, mut incoming: Incoming) {
21+
impl<H: ConcurrentHandler> Handler<HttpAcceptor, HttpStream> for Concurrent<H> {
22+
fn handle(self, mut incoming: Incoming<HttpAcceptor>) {
2223
for (mut req, mut res) in incoming {
2324
let clone = self.handler.clone();
2425
spawn(proc() { clone.handle(req, res) })

examples/server.rs

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ use std::io::util::copy;
77
use std::io::net::ip::Ipv4Addr;
88

99
use hyper::{Get, Post};
10-
use hyper::server::{Server, Handler, Incoming};
1110
use hyper::header::common::ContentLength;
12-
13-
struct Echo;
11+
use hyper::server::{Server, Incoming};
1412

1513
macro_rules! try_continue(
1614
($e:expr) => {{
@@ -21,41 +19,39 @@ macro_rules! try_continue(
2119
}}
2220
)
2321

24-
impl Handler for Echo {
25-
fn handle(self, mut incoming: Incoming) {
26-
for (mut req, mut res) in incoming {
27-
match req.uri {
28-
hyper::uri::AbsolutePath(ref path) => match (&req.method, path.as_slice()) {
29-
(&Get, "/") | (&Get, "/echo") => {
30-
let out = b"Try POST /echo";
31-
32-
res.headers_mut().set(ContentLength(out.len()));
33-
let mut res = try_continue!(res.start());
34-
try_continue!(res.write(out));
35-
try_continue!(res.end());
36-
continue;
37-
},
38-
(&Post, "/echo") => (), // fall through, fighting mutable borrows
39-
_ => {
40-
*res.status_mut() = hyper::status::NotFound;
41-
try_continue!(res.start().and_then(|res| res.end()));
42-
continue;
43-
}
22+
fn echo(mut incoming: Incoming) {
23+
for (mut req, mut res) in incoming {
24+
match req.uri {
25+
hyper::uri::AbsolutePath(ref path) => match (&req.method, path.as_slice()) {
26+
(&Get, "/") | (&Get, "/echo") => {
27+
let out = b"Try POST /echo";
28+
29+
res.headers_mut().set(ContentLength(out.len()));
30+
let mut res = try_continue!(res.start());
31+
try_continue!(res.write(out));
32+
try_continue!(res.end());
33+
continue;
4434
},
35+
(&Post, "/echo") => (), // fall through, fighting mutable borrows
4536
_ => {
37+
*res.status_mut() = hyper::status::NotFound;
4638
try_continue!(res.start().and_then(|res| res.end()));
4739
continue;
4840
}
49-
};
50-
51-
let mut res = try_continue!(res.start());
52-
try_continue!(copy(&mut req, &mut res));
53-
try_continue!(res.end());
54-
}
41+
},
42+
_ => {
43+
try_continue!(res.start().and_then(|res| res.end()));
44+
continue;
45+
}
46+
};
47+
48+
let mut res = try_continue!(res.start());
49+
try_continue!(copy(&mut req, &mut res));
50+
try_continue!(res.end());
5551
}
5652
}
5753

5854
fn main() {
5955
let server = Server::http(Ipv4Addr(127, 0, 0, 1), 1337);
60-
server.listen(Echo).unwrap();
56+
server.listen(echo).unwrap();
6157
}

src/client/request.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! Client Requests
2-
use std::io::net::tcp::TcpStream;
32
use std::io::{BufferedWriter, IoResult};
43

54
use url::Url;
65

76
use method;
87
use header::Headers;
98
use header::common::Host;
9+
use net::{NetworkStream, HttpStream};
1010
use rfc7230::LINE_ENDING;
1111
use version;
1212
use {HttpResult, HttpUriError};
@@ -24,7 +24,7 @@ pub struct Request {
2424
/// The HTTP version of this request.
2525
pub version: version::HttpVersion,
2626
headers_written: bool,
27-
body: BufferedWriter<TcpStream>,
27+
body: BufferedWriter<Box<NetworkStream + Send>>,
2828
}
2929

3030
impl Request {
@@ -43,8 +43,8 @@ impl Request {
4343
};
4444
debug!("port={}", port);
4545

46-
let stream = try_io!(TcpStream::connect(host.as_slice(), port));
47-
let stream = BufferedWriter::new(stream);
46+
let stream: HttpStream = try_io!(NetworkStream::connect(host.as_slice(), port));
47+
let stream = BufferedWriter::new(stream.abstract());
4848
let mut headers = Headers::new();
4949
headers.set(Host(host));
5050
Ok(Request {
@@ -84,8 +84,7 @@ impl Request {
8484
/// Consumes the Request.
8585
pub fn send(mut self) -> HttpResult<Response> {
8686
try_io!(self.flush());
87-
let mut raw = self.body.unwrap();
88-
try_io!(raw.close_write());
87+
let raw = self.body.unwrap();
8988
Response::new(raw)
9089
}
9190
}

src/client/response.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
//! Client Responses
22
use std::io::{BufferedReader, IoResult};
3-
use std::io::net::tcp::TcpStream;
43

54
use header;
65
use header::common::{ContentLength, TransferEncoding};
76
use header::common::transfer_encoding::Chunked;
7+
use net::{NetworkStream, HttpStream};
88
use rfc7230::{read_status_line, HttpReader, SizedReader, ChunkedReader, EofReader};
99
use status;
1010
use version;
1111
use {HttpResult};
1212

1313
/// A response for a client request to a remote server.
14-
pub struct Response {
14+
pub struct Response<S = HttpStream> {
1515
/// The status from the server.
1616
pub status: status::StatusCode,
1717
/// The headers from the server.
1818
pub headers: header::Headers,
1919
/// The HTTP version of this response from the server.
2020
pub version: version::HttpVersion,
21-
body: HttpReader<BufferedReader<TcpStream>>,
21+
body: HttpReader<BufferedReader<Box<NetworkStream + Send>>>,
2222
}
2323

2424
impl Response {
2525

2626
/// Creates a new response from a server.
27-
pub fn new(tcp: TcpStream) -> HttpResult<Response> {
28-
let mut tcp = BufferedReader::new(tcp);
29-
let (version, status) = try!(read_status_line(&mut tcp));
30-
let mut headers = try!(header::Headers::from_raw(&mut tcp));
27+
pub fn new(stream: Box<NetworkStream + Send>) -> HttpResult<Response> {
28+
let mut stream = BufferedReader::new(stream.abstract());
29+
let (version, status) = try!(read_status_line(&mut stream));
30+
let mut headers = try!(header::Headers::from_raw(&mut stream));
3131

3232
debug!("{} {}", version, status);
3333
debug!("{}", headers);
@@ -40,22 +40,22 @@ impl Response {
4040
};
4141

4242
if codings.contains(&Chunked) {
43-
ChunkedReader(tcp, None)
43+
ChunkedReader(stream, None)
4444
} else {
45-
debug!("not chucked. read till eof");
46-
EofReader(tcp)
45+
debug!("not chuncked. read till eof");
46+
EofReader(stream)
4747
}
4848
}
4949
None => unreachable!()
5050
}
5151
} else if headers.has::<ContentLength>() {
5252
match headers.get_ref::<ContentLength>() {
53-
Some(&ContentLength(len)) => SizedReader(tcp, len),
53+
Some(&ContentLength(len)) => SizedReader(stream, len),
5454
None => unreachable!()
5555
}
5656
} else {
5757
debug!("neither Transfer-Encoding nor Content-Length");
58-
EofReader(tcp)
58+
EofReader(stream)
5959
};
6060

6161
Ok(Response {
@@ -68,6 +68,7 @@ impl Response {
6868
}
6969

7070
impl Reader for Response {
71+
#[inline]
7172
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
7273
self.body.read(buf)
7374
}

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! # hyper
2-
#![feature(macro_rules, phase)]
3-
#![warn(missing_doc)]
2+
#![feature(macro_rules, phase, default_type_params)]
3+
#![deny(missing_doc)]
44
#![deny(warnings)]
55
#![experimental]
66

@@ -53,6 +53,7 @@ macro_rules! trace(
5353
pub mod client;
5454
pub mod method;
5555
pub mod header;
56+
pub mod net;
5657
pub mod server;
5758
pub mod status;
5859
pub mod uri;

0 commit comments

Comments
 (0)