Skip to content

Commit 48aae50

Browse files
authored
Merge pull request #55 from yoshuawuyts/simplify-examples
Simplify examples
2 parents 70a365e + 02607e9 commit 48aae50

File tree

10 files changed

+130
-149
lines changed

10 files changed

+130
-149
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ edition = "2018"
1414
[dependencies]
1515
url = "2.1.0"
1616
httparse = "1.3.3"
17-
async-std = { version = "1.4.0", default-features = false }
17+
async-std = { version = "1.5.0", features = ["unstable"] }
1818
http-types = { path = '../http-types' }
1919
pin-project-lite = "0.1.1"
2020
byte-pool = "0.2.1"

examples/client.rs

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,19 @@
1-
use std::pin::Pin;
2-
use std::sync::Arc;
3-
41
use async_h1::client;
5-
use async_std::io::{self, Read, Write};
6-
use async_std::net::{self, TcpStream};
7-
use async_std::task::{self, Context, Poll};
2+
use async_std::net::{TcpStream};
83
use http_types::{Error, Method, Request, Url};
94

10-
fn main() -> Result<(), Error> {
11-
task::block_on(async {
12-
let stream = net::TcpStream::connect("127.0.0.1:8080").await?;
13-
let peer_addr = stream.peer_addr()?;
14-
println!("connecting to {}", peer_addr);
15-
16-
// TODO: Delete this line when we implement `Clone` for `TcpStream`.
17-
let stream = Stream(Arc::new(stream));
18-
19-
for i in 0usize..2 {
20-
println!("making request {}/2", i + 1);
21-
let url = Url::parse(&format!("http://{}/foo", peer_addr)).unwrap();
22-
let req = Request::new(Method::Get, dbg!(url));
23-
let res = client::connect(stream.clone(), req).await?;
24-
println!("{:?}", res);
25-
}
26-
Ok(())
27-
})
28-
}
29-
30-
#[derive(Clone)]
31-
struct Stream(Arc<TcpStream>);
32-
33-
impl Read for Stream {
34-
fn poll_read(
35-
self: Pin<&mut Self>,
36-
cx: &mut Context,
37-
buf: &mut [u8],
38-
) -> Poll<io::Result<usize>> {
39-
Pin::new(&mut &*self.0).poll_read(cx, buf)
40-
}
41-
}
42-
43-
impl Write for Stream {
44-
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
45-
Pin::new(&mut &*self.0).poll_write(cx, buf)
46-
}
47-
48-
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
49-
Pin::new(&mut &*self.0).poll_flush(cx)
50-
}
51-
52-
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
53-
Pin::new(&mut &*self.0).poll_close(cx)
5+
#[async_std::main]
6+
async fn main() -> Result<(), Error> {
7+
let stream = TcpStream::connect("127.0.0.1:8080").await?;
8+
let peer_addr = stream.peer_addr()?;
9+
println!("connecting to {}", peer_addr);
10+
11+
for i in 0usize..2 {
12+
println!("making request {}/2", i + 1);
13+
let url = Url::parse(&format!("http://{}/foo", peer_addr)).unwrap();
14+
let req = Request::new(Method::Get, url);
15+
let res = client::connect(stream.clone(), req).await?;
16+
println!("{:?}", res);
5417
}
18+
Ok(())
5519
}

examples/server.rs

Lines changed: 33 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,38 @@
1-
use std::pin::Pin;
2-
use std::str::FromStr;
3-
use std::sync::Arc;
4-
5-
use async_h1::server;
6-
use async_std::io::{self, Read, Write};
7-
use async_std::net::{self, TcpStream};
1+
use async_std::net::{TcpStream, TcpListener};
82
use async_std::prelude::*;
9-
use async_std::task::{self, Context, Poll};
10-
use http_types::headers::{HeaderName, HeaderValue};
11-
use http_types::{Error, Response, StatusCode};
12-
13-
async fn accept(addr: String, stream: TcpStream) -> Result<(), Error> {
14-
// println!("starting new connection from {}", stream.peer_addr()?);
15-
16-
// TODO: Delete this line when we implement `Clone` for `TcpStream`.
17-
let stream = Stream(Arc::new(stream));
18-
19-
server::accept(&addr, stream.clone(), |req| {
20-
async move {
21-
dbg!(req.method());
22-
let mut resp = Response::new(StatusCode::Ok);
23-
resp.insert_header(
24-
HeaderName::from_str("Content-Type")?,
25-
HeaderValue::from_str("text/plain")?,
26-
)?;
27-
resp.set_body("Hello");
28-
// To try chunked encoding, replace `set_body_string` with the following method call
29-
// .set_body(io::Cursor::new(vec![
30-
// 0x48u8, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21,
31-
// ]));
32-
Ok(resp)
33-
}
34-
})
35-
.await
36-
}
37-
38-
fn main() -> Result<(), Error> {
39-
task::block_on(async {
40-
let listener = net::TcpListener::bind(("127.0.0.1", 8080)).await?;
41-
let addr = format!("http://{}", listener.local_addr()?);
42-
println!("listening on {}", addr);
43-
let mut incoming = listener.incoming();
44-
45-
while let Some(stream) = incoming.next().await {
46-
let stream = stream?;
47-
let addr = addr.clone();
48-
task::spawn(async {
49-
if let Err(err) = accept(addr, stream).await {
50-
eprintln!("{}", err);
51-
}
52-
});
53-
}
54-
Ok(())
55-
})
56-
}
57-
58-
#[derive(Clone)]
59-
struct Stream(Arc<TcpStream>);
60-
61-
impl Read for Stream {
62-
fn poll_read(
63-
self: Pin<&mut Self>,
64-
cx: &mut Context,
65-
buf: &mut [u8],
66-
) -> Poll<io::Result<usize>> {
67-
Pin::new(&mut &*self.0).poll_read(cx, buf)
3+
use async_std::task;
4+
use http_types::{Response, StatusCode};
5+
6+
#[async_std::main]
7+
async fn main() -> http_types::Result<()> {
8+
// Open up a TCP connection and create a URL.
9+
let listener = TcpListener::bind(("127.0.0.1", 8080)).await?;
10+
let addr = format!("http://{}", listener.local_addr()?);
11+
println!("listening on {}", addr);
12+
13+
// For each incoming TCP connection, spawn a task and call `accept`.
14+
let mut incoming = listener.incoming();
15+
while let Some(stream) = incoming.next().await {
16+
let stream = stream?;
17+
let addr = addr.clone();
18+
task::spawn(async {
19+
if let Err(err) = accept(addr, stream).await {
20+
eprintln!("{}", err);
21+
}
22+
});
6823
}
24+
Ok(())
6925
}
7026

71-
impl Write for Stream {
72-
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
73-
Pin::new(&mut &*self.0).poll_write(cx, buf)
74-
}
75-
76-
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
77-
Pin::new(&mut &*self.0).poll_flush(cx)
78-
}
79-
80-
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
81-
Pin::new(&mut &*self.0).poll_close(cx)
82-
}
27+
// Take a TCP stream, and convert it into sequential HTTP request / response pairs.
28+
async fn accept(addr: String, stream: TcpStream) -> http_types::Result<()> {
29+
println!("starting new connection from {}", stream.peer_addr()?);
30+
async_h1::accept(&addr, stream.clone(), |_req| async move {
31+
let mut res = Response::new(StatusCode::Ok);
32+
res.insert_header("Content-Type", "text/plain")?;
33+
res.set_body("Hello");
34+
Ok(res)
35+
})
36+
.await?;
37+
Ok(())
8338
}

src/check.rs

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/client.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::date::fmt_http_date;
1818
use crate::MAX_HEADERS;
1919

2020
/// An HTTP encoder.
21+
#[doc(hidden)]
2122
#[derive(Debug)]
2223
pub struct Encoder {
2324
/// Keep track how far we've indexed into the headers + body.
@@ -48,7 +49,7 @@ impl Encoder {
4849
}
4950
}
5051

51-
/// Send an HTTP request over a stream.
52+
/// Opens an HTTP/1.1 connection to a remote host.
5253
pub async fn connect<RW>(mut stream: RW, req: Request) -> Result<Response, Error>
5354
where
5455
RW: Read + Write + Send + Sync + Unpin + 'static,
@@ -65,7 +66,8 @@ where
6566
}
6667

6768
/// Encode an HTTP request on the client.
68-
pub async fn encode(req: Request) -> Result<Encoder, Error> {
69+
#[doc(hidden)]
70+
async fn encode(req: Request) -> Result<Encoder, Error> {
6971
let mut buf: Vec<u8> = vec![];
7072

7173
let mut url = req.url().path().to_owned();
@@ -132,6 +134,7 @@ pub async fn encode(req: Request) -> Result<Encoder, Error> {
132134
}
133135

134136
/// Decode an HTTP response on the client.
137+
#[doc(hidden)]
135138
pub async fn decode<R>(reader: R) -> Result<Response, Error>
136139
where
137140
R: Read + Unpin + Send + Sync + 'static,

src/date.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct HttpDate {
3838
/// Supports the preferred IMF-fixdate and the legacy RFC 805 and
3939
/// ascdate formats. Two digit years are mapped to dates between
4040
/// 1970 and 2069.
41+
#[allow(dead_code)]
4142
pub(crate) fn parse_http_date(s: &str) -> Result<SystemTime, Error> {
4243
s.parse::<HttpDate>().map(|d| d.into())
4344
}

src/lib.rs

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,71 @@
2424
//!
2525
//! # Example
2626
//!
27+
//! __HTTP client__
28+
//!
29+
//! ```no_run
30+
//! use async_h1::client;
31+
//! use async_std::net::{TcpStream};
32+
//! use http_types::{Error, Method, Request, Url};
33+
//!
34+
//! #[async_std::main]
35+
//! async fn main() -> Result<(), Error> {
36+
//! let stream = TcpStream::connect("127.0.0.1:8080").await?;
37+
//! let peer_addr = stream.peer_addr()?;
38+
//! println!("connecting to {}", peer_addr);
39+
//!
40+
//! for i in 0usize..2 {
41+
//! println!("making request {}/2", i + 1);
42+
//! let url = Url::parse(&format!("http://{}/foo", peer_addr)).unwrap();
43+
//! let req = Request::new(Method::Get, dbg!(url));
44+
//! let res = client::connect(stream.clone(), req).await?;
45+
//! println!("{:?}", res);
46+
//! }
47+
//! Ok(())
48+
//! }
2749
//! ```
28-
//! // tbi
50+
//!
51+
//! __HTTP Server__
52+
//!
53+
//! ```no_run
54+
//! use async_std::net::{TcpStream, TcpListener};
55+
//! use async_std::prelude::*;
56+
//! use async_std::task;
57+
//! use http_types::{Response, StatusCode};
58+
//!
59+
//! #[async_std::main]
60+
//! async fn main() -> http_types::Result<()> {
61+
//! // Open up a TCP connection and create a URL.
62+
//! let listener = TcpListener::bind(("127.0.0.1", 8080)).await?;
63+
//! let addr = format!("http://{}", listener.local_addr()?);
64+
//! println!("listening on {}", addr);
65+
//!
66+
//! // For each incoming TCP connection, spawn a task and call `accept`.
67+
//! let mut incoming = listener.incoming();
68+
//! while let Some(stream) = incoming.next().await {
69+
//! let stream = stream?;
70+
//! let addr = addr.clone();
71+
//! task::spawn(async {
72+
//! if let Err(err) = accept(addr, stream).await {
73+
//! eprintln!("{}", err);
74+
//! }
75+
//! });
76+
//! }
77+
//! Ok(())
78+
//! }
79+
//!
80+
//! // Take a TCP stream, and convert it into sequential HTTP request / response pairs.
81+
//! async fn accept(addr: String, stream: TcpStream) -> http_types::Result<()> {
82+
//! println!("starting new connection from {}", stream.peer_addr()?);
83+
//! async_h1::accept(&addr, stream.clone(), |_req| async move {
84+
//! let mut res = Response::new(StatusCode::Ok);
85+
//! res.insert_header("Content-Type", "text/plain")?;
86+
//! res.set_body("Hello");
87+
//! Ok(res)
88+
//! })
89+
//! .await?;
90+
//! Ok(())
91+
//! }
2992
//! ```
3093
3194
// #![forbid(unsafe_code, rust_2018_idioms)]
@@ -36,12 +99,12 @@
3699
/// The maximum amount of headers parsed on the server.
37100
const MAX_HEADERS: usize = 128;
38101

39-
pub use check::check;
40-
41-
mod check;
102+
mod server;
103+
mod chunked;
104+
mod date;
42105

106+
#[doc(hidden)]
43107
pub mod client;
44-
pub mod server;
45108

46-
mod chunked;
47-
mod date;
109+
pub use client::connect;
110+
pub use server::accept;

src/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::MAX_HEADERS;
2020
const CR: u8 = b'\r';
2121
const LF: u8 = b'\n';
2222

23-
/// Parse an incoming HTTP connection.
23+
/// Accept a new incoming HTTP/1.1 connection.
2424
///
2525
/// Supports `KeepAlive` requests by default.
2626
pub async fn accept<RW, F, Fut>(addr: &str, mut io: RW, endpoint: F) -> http_types::Result<()>

tests/common/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ pub struct TestCase {
2222
}
2323

2424
impl TestCase {
25+
#[allow(dead_code)]
2526
pub async fn new_server(request_file_path: &str, response_file_path: &str) -> TestCase {
2627
Self::new(Direction::Server, request_file_path, response_file_path).await
2728
}
2829

30+
#[allow(dead_code)]
2931
pub async fn new_client(request_file_path: &str, response_file_path: &str) -> TestCase {
3032
Self::new(Direction::Client, request_file_path, response_file_path).await
3133
}

tests/server.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use async_h1::server;
21
use async_std::io::Cursor;
32
use async_std::prelude::*;
43
use common::TestCase;
@@ -11,7 +10,7 @@ async fn test_basic_request() {
1110
let case = TestCase::new_server("fixtures/request1.txt", "fixtures/response1.txt").await;
1211
let addr = "http://example.com";
1312

14-
server::accept(addr, case.clone(), |_req| async {
13+
async_h1::accept(addr, case.clone(), |_req| async {
1514
let mut resp = Response::new(StatusCode::Ok);
1615
resp.set_body("");
1716
Ok(resp)
@@ -31,7 +30,7 @@ async fn test_chunked_basic() {
3130
.await;
3231
let addr = "http://example.com";
3332

34-
server::accept(addr, case.clone(), |_req| async {
33+
async_h1::accept(addr, case.clone(), |_req| async {
3534
let mut resp = Response::new(StatusCode::Ok);
3635
resp.set_body(Body::from_reader(
3736
Cursor::new(b"Mozilla")
@@ -57,7 +56,7 @@ async fn test_chunked_echo() {
5756
.await;
5857
let addr = "http://example.com";
5958

60-
server::accept(addr, case.clone(), |req| async {
59+
async_h1::accept(addr, case.clone(), |req| async {
6160
let mut resp = Response::new(StatusCode::Ok);
6261
let ct = req.content_type();
6362
let body: Body = req.into();

0 commit comments

Comments
 (0)