Skip to content

Commit 33429ef

Browse files
authored
Merge pull request #39 from yoshuawuyts/single-io
Unified Reader and Writer
2 parents 699aea6 + 565819b commit 33429ef

File tree

4 files changed

+37
-24
lines changed

4 files changed

+37
-24
lines changed

examples/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async fn accept(addr: String, stream: TcpStream) -> Result<(), async_h1::Excepti
1616
// TODO: Delete this line when we implement `Clone` for `TcpStream`.
1717
let stream = Stream(Arc::new(stream));
1818

19-
server::accept(&addr, stream.clone(), stream, |req| {
19+
server::accept(&addr, stream.clone(), |req| {
2020
async move {
2121
dbg!(req.method());
2222
let mut resp = Response::new(StatusCode::Ok);

src/server.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,9 @@ use crate::{Exception, MAX_HEADERS};
1919
/// Parse an incoming HTTP connection.
2020
///
2121
/// Supports `KeepAlive` requests by default.
22-
pub async fn accept<R, W, F, Fut>(
23-
addr: &str,
24-
reader: R,
25-
mut writer: W,
26-
endpoint: F,
27-
) -> Result<(), Exception>
22+
pub async fn accept<RW, F, Fut>(addr: &str, mut io: RW, endpoint: F) -> Result<(), Exception>
2823
where
29-
R: Read + Unpin + Send + 'static + Clone,
30-
W: Write + Unpin,
24+
RW: Read + Write + Clone + Send + Unpin + 'static,
3125
F: Fn(Request) -> Fut,
3226
Fut: Future<Output = Result<Response, Exception>>,
3327
{
@@ -37,7 +31,7 @@ where
3731
let mut num_requests = 0;
3832

3933
// Decode a request. This may be the first of many since the connection is Keep-Alive by default.
40-
let r = reader.clone();
34+
let r = io.clone();
4135
let req = decode(addr, r).await?;
4236
if let Some(mut req) = req {
4337
loop {
@@ -49,11 +43,11 @@ where
4943
// TODO: what to do when the endpoint returns Err
5044
let res = endpoint(req).await?;
5145
let mut encoder = Encoder::encode(res);
52-
io::copy(&mut encoder, &mut writer).await?;
46+
io::copy(&mut encoder, &mut io).await?;
5347

5448
// Decode a new request, timing out if this takes longer than the
5549
// timeout duration.
56-
req = match timeout(timeout_duration, decode(addr, reader.clone())).await {
50+
req = match timeout(timeout_duration, decode(addr, io.clone())).await {
5751
Ok(Ok(Some(r))) => r,
5852
Ok(Ok(None)) | Err(TimeoutError { .. }) => break, /* EOF or timeout */
5953
Ok(Err(e)) => return Err(e),

tests/common/mod.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
use async_std::fs::File;
2-
use async_std::io::{self, Read, Write};
2+
use async_std::fs::OpenOptions;
3+
use async_std::io::{self, Read, SeekFrom, Write};
34
use async_std::path::PathBuf;
45
use async_std::sync::Arc;
56
use async_std::task::{Context, Poll};
67
use std::pin::Pin;
8+
use std::sync::Mutex;
79

810
#[macro_export]
911
macro_rules! assert {
1012
($actual:expr, $expected_file:expr, $block:expr) => {
1113
task::block_on(async {
1214
use async_std::io::prelude::*;
1315
$block.await.unwrap();
14-
let mut actual = std::string::String::from_utf8($actual).unwrap();
16+
let mut actual = $actual.to_string().await;
1517
let mut expected = std::string::String::new();
1618
$expected_file.read_to_string(&mut expected).await.unwrap();
1719
match expected.find("{DATE}") {
@@ -38,11 +40,29 @@ pub async fn read_fixture(name: &str) -> TestFile {
3840
let file = File::open(directory.join(path))
3941
.await
4042
.expect("Reading fixture file didn't work");
41-
TestFile(Arc::new(file))
43+
let temp = std::env::temp_dir().join("foo.txt");
44+
let temp = OpenOptions::new()
45+
.read(true)
46+
.write(true)
47+
.open(temp)
48+
.await
49+
.unwrap();
50+
TestFile(Arc::new(file), Arc::new(Mutex::new(temp)))
4251
}
4352

4453
#[derive(Clone)]
45-
pub struct TestFile(Arc<File>);
54+
pub struct TestFile(Arc<File>, Arc<Mutex<File>>);
55+
56+
impl TestFile {
57+
pub async fn to_string(self) -> String {
58+
use async_std::prelude::*;
59+
let mut buf = String::new();
60+
let mut file = self.1.lock().unwrap();
61+
file.seek(SeekFrom::Start(0)).await.unwrap();
62+
dbg!(file.read_to_string(&mut buf).await.unwrap());
63+
buf
64+
}
65+
}
4666

4767
impl Read for TestFile {
4868
fn poll_read(
@@ -56,14 +76,14 @@ impl Read for TestFile {
5676

5777
impl Write for TestFile {
5878
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
59-
Pin::new(&mut &*self.0).poll_write(cx, buf)
79+
Pin::new(&mut &*self.1.lock().unwrap()).poll_write(cx, buf)
6080
}
6181

6282
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
63-
Pin::new(&mut &*self.0).poll_flush(cx)
83+
Pin::new(&mut &*self.1.lock().unwrap()).poll_flush(cx)
6484
}
6585

6686
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
67-
Pin::new(&mut &*self.0).poll_close(cx)
87+
Pin::new(&mut &*self.1.lock().unwrap()).poll_close(cx)
6888
}
6989
}

tests/server.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,20 @@ use http_types::{Response, StatusCode};
77
#[test]
88
fn test_basic_request() {
99
task::block_on(async {
10-
let request = read_fixture("request1").await;
10+
let io = read_fixture("request1").await;
1111
let mut expected = read_fixture("response1").await;
12-
let mut actual = Vec::new();
1312
let addr = "http://example.com";
1413

1514
assert!(
16-
actual,
15+
io.clone(),
1716
expected,
18-
server::accept(addr, request.clone(), &mut actual, |_req| {
17+
server::accept(addr, io.clone(), |_req| {
1918
async {
2019
let mut resp = Response::new(StatusCode::Ok);
2120
resp.set_body("");
2221
Ok(resp)
2322
}
24-
})
23+
})
2524
);
2625
})
2726
}

0 commit comments

Comments
 (0)