Skip to content

Commit 62dec59

Browse files
authored
Merge pull request #11 from yoshuawuyts/working-keep-alive
Proper keep-alive
2 parents 3fed77b + 5519000 commit 62dec59

File tree

2 files changed

+26
-39
lines changed

2 files changed

+26
-39
lines changed

examples/server.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use async_h1::{server, Body};
2-
use async_std::prelude::*;
32
use async_std::net;
3+
use async_std::prelude::*;
44
use async_std::task;
55

66
fn main() -> Result<(), async_h1::Exception> {
@@ -13,9 +13,11 @@ fn main() -> Result<(), async_h1::Exception> {
1313
task::spawn(async {
1414
let stream = stream?;
1515
let (reader, writer) = &mut (&stream, &stream);
16-
server::connect(reader, writer, |_| async {
17-
let body = Body::from_string("hello chashu".to_owned());
18-
Ok(http::Response::new(body))
16+
server::connect(reader, writer, |_| {
17+
async {
18+
let body = Body::from_string("hello chashu".to_owned());
19+
Ok(http::Response::new(body))
20+
}
1921
})
2022
.await
2123
});

src/server.rs

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
//! Process HTTP connections on the server.
22
3-
use async_std::future::Future;
3+
use async_std::future::{timeout, Future, TimeoutError};
44
use async_std::io::{self, BufReader};
55
use async_std::io::{Read, Write};
66
use async_std::prelude::*;
77
use async_std::task::{Context, Poll};
88
use futures_core::ready;
99
use http::{Request, Response, Version};
10-
use std::time::{Duration, Instant};
10+
use std::time::Duration;
1111

1212
use std::pin::Pin;
1313

@@ -25,36 +25,27 @@ where
2525
Fut: Future<Output = Result<Response<Body<O>>, Exception>>,
2626
O: Read + Unpin + Send,
2727
{
28+
// TODO: make configurable
29+
let timeout_duration = Duration::from_secs(10);
30+
const MAX_REQUESTS: usize = 200;
31+
2832
let req = decode(reader).await?;
29-
if let RequestOrReader::Request(mut req) = req {
30-
let headers = req.headers();
31-
let timeout = match (headers.get("Connection"), headers.get("Keep-Alive")) {
32-
(Some(connection), Some(_v))
33-
if connection == http::header::HeaderValue::from_static("Keep-Alive") =>
34-
{
35-
// TODO: parse timeout
36-
Duration::from_secs(5)
33+
let mut num_requests = 0;
34+
if let Some(mut req) = req {
35+
loop {
36+
num_requests += 1;
37+
if num_requests > MAX_REQUESTS {
38+
return Ok(());
3739
}
38-
_ => Duration::from_secs(5),
39-
};
4040

41-
let beginning = Instant::now();
42-
loop {
4341
// TODO: what to do when the callback returns Err
4442
let mut res = encode(callback(&mut req).await?).await?;
4543
io::copy(&mut res, writer).await?;
46-
let mut stream = req.into_body().into_reader().into_inner();
47-
req = loop {
48-
match decode(stream).await? {
49-
RequestOrReader::Request(r) => break r,
50-
RequestOrReader::Reader(r) => {
51-
let now = Instant::now();
52-
if now - beginning > timeout {
53-
return Ok(());
54-
}
55-
stream = r;
56-
}
57-
}
44+
let stream = req.into_body().into_reader().into_inner();
45+
req = match timeout(timeout_duration, decode(stream)).await {
46+
Ok(Ok(Some(r))) => r,
47+
Ok(Ok(None)) | Err(TimeoutError { .. }) => break, /* EOF or timeout */
48+
Ok(Err(e)) => return Err(e),
5849
};
5950
}
6051
}
@@ -165,14 +156,8 @@ where
165156
Ok(Encoder::new(buf, res.into_body()))
166157
}
167158

168-
#[derive(Debug)]
169-
pub enum RequestOrReader<R: Read> {
170-
Request(Request<Body<BufReader<R>>>),
171-
Reader(R),
172-
}
173-
174159
/// Decode an HTTP request on the server.
175-
pub async fn decode<R>(reader: R) -> Result<RequestOrReader<R>, Exception>
160+
pub async fn decode<R>(reader: R) -> Result<Option<Request<Body<BufReader<R>>>>, Exception>
176161
where
177162
R: Read + Unpin + Send,
178163
{
@@ -186,7 +171,7 @@ where
186171
let bytes_read = reader.read_until(b'\n', &mut buf).await?;
187172
// No more bytes are yielded from the stream.
188173
if bytes_read == 0 {
189-
return Ok(RequestOrReader::Reader(reader.into_inner()));
174+
return Ok(None);
190175
}
191176

192177
// We've hit the end delimiter of the stream.
@@ -232,5 +217,5 @@ where
232217
};
233218

234219
// Return the request.
235-
Ok(RequestOrReader::Request(req.body(body)?))
220+
Ok(Some(req.body(body)?))
236221
}

0 commit comments

Comments
 (0)