Skip to content

Commit

Permalink
add tests for 100-continue
Browse files Browse the repository at this point in the history
  • Loading branch information
jbr committed Aug 31, 2020
1 parent 4c29727 commit 6f9b757
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ pretty_assertions = "0.6.1"
async-std = { version = "1.4.0", features = ["unstable", "attributes"] }
tempfile = "3.1.0"
async-test = "1.0.0"
duplexify = { version = "1.1.0", git = "https://github.com/jbr/duplexify", branch = "impl-clone-when-reader-and-writer-are-clone" }
async-dup = "1.2.1"
100 changes: 100 additions & 0 deletions tests/continue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use async_dup::{Arc, Mutex};
use async_std::io::{Cursor, SeekFrom};
use async_std::{prelude::*, task};
use duplexify::Duplex;
use http_types::Result;

const REQUEST_WITH_EXPECT: &[u8] = b"POST / HTTP/1.1\r\n\
Host: example.com\r\n\
Content-Length: 10\r\n\
Expect: 100-continue\r\n\r\n";

#[async_std::test]
async fn test_with_expect_when_reading_body() -> Result<()> {
let client_str: Vec<u8> = REQUEST_WITH_EXPECT.to_vec();
let server_str: Vec<u8> = vec![];

let mut client = Arc::new(Mutex::new(Cursor::new(client_str)));
let server = Arc::new(Mutex::new(Cursor::new(server_str)));

let mut request = async_h1::server::decode(Duplex::new(client.clone(), server.clone()))
.await?
.unwrap();

task::sleep(std::time::Duration::from_millis(1)).await; //prove we're not just testing before we've written

{
let lock = server.lock();
assert_eq!("", std::str::from_utf8(lock.get_ref())?); //we haven't written yet
};

let mut buf = vec![0u8; 1];
let bytes = request.read(&mut buf).await?; //this triggers the 100-continue even though there's nothing to read yet
assert_eq!(bytes, 0); // normally we'd actually be waiting for the end of the buffer, but this lets us test this sequentially

task::sleep(std::time::Duration::from_millis(1)).await; // just long enough to wait for the channel and io

{
let lock = server.lock();
assert_eq!(
"HTTP/1.1 100 Continue\r\n\r\n",
std::str::from_utf8(lock.get_ref())?
);
};

client.write_all(b"0123456789\r\n").await?;
client
.seek(SeekFrom::Start(REQUEST_WITH_EXPECT.len() as u64))
.await?;

assert_eq!("0123456789", request.body_string().await?);

Ok(())
}

#[async_std::test]
async fn test_without_expect_when_not_reading_body() -> Result<()> {
let client_str: Vec<u8> = REQUEST_WITH_EXPECT.to_vec();
let server_str: Vec<u8> = vec![];

let mut client = Arc::new(Mutex::new(Cursor::new(client_str)));
let server = Arc::new(Mutex::new(Cursor::new(server_str)));

let mut request = async_h1::server::decode(Duplex::new(client.clone(), server.clone()))
.await?
.unwrap();

task::sleep(std::time::Duration::from_millis(1)).await; // just long enough to wait for the channel

{
let lock = server.lock();
assert_eq!("", std::str::from_utf8(lock.get_ref())?); // we haven't written 100-continue
};

client.write_all(b"0123456789").await?;
client
.seek(SeekFrom::Start(REQUEST_WITH_EXPECT.len() as u64))
.await?;

assert_eq!("0123456789", request.body_string().await?);

{
let lock = server.lock();
assert_eq!("", std::str::from_utf8(lock.get_ref())?); // we still haven't written 100-continue
};

{
let lock = client.lock();
assert_eq!(
"POST / HTTP/1.1\r\n\
Host: example.com\r\n\
Content-Length: 10\r\n\
Expect: 100-continue\r\n\
\r\n\
0123456789",
std::str::from_utf8(lock.get_ref())?
);
};

Ok(())
}

0 comments on commit 6f9b757

Please sign in to comment.