|
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}; |
8 | 2 | 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 | + }); |
68 | 23 | } |
| 24 | + Ok(()) |
69 | 25 | } |
70 | 26 |
|
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(()) |
83 | 38 | } |
0 commit comments