Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,239 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn headers_return_before_body_and_download_ignores_buffered_total_limit() {
|
||||
let (opened, permit) = std::sync::mpsc::channel();
|
||||
let (port, server) = peer(move |listener| {
|
||||
let mut socket = accept(&listener);
|
||||
headers(&mut socket);
|
||||
socket
|
||||
.get_mut()
|
||||
.write_all(
|
||||
b"HTTP/1.1 200 OK\r\nContent-Length: 100003\r\nX-Test: one\r\nX-Test: two\r\n\r\n",
|
||||
)
|
||||
.unwrap();
|
||||
permit.recv_timeout(Duration::from_secs(2)).unwrap();
|
||||
socket.get_mut().write_all(&vec![b'x'; 100003]).unwrap();
|
||||
assert_eq!(socket.read(&mut [0]).unwrap(), 0);
|
||||
});
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let client = client(
|
||||
scope,
|
||||
port,
|
||||
&Limits {
|
||||
body_bytes: 1,
|
||||
..Default::default()
|
||||
},
|
||||
&PoolLimits {
|
||||
chunk_bytes: 7,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let response = client.open(message(), event).await.unwrap();
|
||||
assert_eq!(
|
||||
response
|
||||
.headers
|
||||
.iter()
|
||||
.filter(|header| header.name == "x-test")
|
||||
.count(),
|
||||
2
|
||||
);
|
||||
opened.send(()).unwrap();
|
||||
let body = collect(&response.body, 7).await;
|
||||
assert_eq!(body, vec![b'x'; 100003]);
|
||||
assert!(response.body.next().await.unwrap().is_none());
|
||||
client.close().await.unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
server.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unread_body_holds_slot_and_idle_clock_starts_after_eof() {
|
||||
let (port, server) = peer(|listener| {
|
||||
let mut socket = accept(&listener);
|
||||
for _ in 0..2 {
|
||||
headers(&mut socket);
|
||||
socket
|
||||
.get_mut()
|
||||
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nabcdef")
|
||||
.unwrap();
|
||||
}
|
||||
let start = std::time::Instant::now();
|
||||
assert_eq!(socket.read(&mut [0]).unwrap(), 0);
|
||||
assert!(start.elapsed() < Duration::from_secs(1));
|
||||
});
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let client = client(
|
||||
scope,
|
||||
port,
|
||||
&Limits {
|
||||
connections: 1,
|
||||
timeout_ms: 80,
|
||||
..Default::default()
|
||||
},
|
||||
&PoolLimits {
|
||||
idle_ms: 20,
|
||||
chunk_bytes: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let response = client.open(message(), event).await.unwrap();
|
||||
assert!(
|
||||
client
|
||||
.open(message(), event)
|
||||
.await
|
||||
.unwrap_err()
|
||||
.contains("timed out")
|
||||
);
|
||||
assert_eq!(collect(&response.body, 2).await, b"abcdef");
|
||||
assert_eq!(
|
||||
client.request(message()).await.unwrap().body.as_ref(),
|
||||
b"abcdef"
|
||||
);
|
||||
tokio::time::sleep(Duration::from_millis(80)).await;
|
||||
client.close().await.unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
server.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn early_close_of_buffered_frame_closes_http1_and_next_request_reconnects() {
|
||||
let (port, server) = peer(|listener| {
|
||||
let mut first = accept(&listener);
|
||||
headers(&mut first);
|
||||
first
|
||||
.get_mut()
|
||||
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nabcdef")
|
||||
.unwrap();
|
||||
assert_eq!(first.read(&mut [0]).unwrap(), 0);
|
||||
let mut second = accept(&listener);
|
||||
headers(&mut second);
|
||||
second
|
||||
.get_mut()
|
||||
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok")
|
||||
.unwrap();
|
||||
});
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let client = client(
|
||||
scope,
|
||||
port,
|
||||
&Limits {
|
||||
connections: 1,
|
||||
..Default::default()
|
||||
},
|
||||
&PoolLimits::default(),
|
||||
);
|
||||
let response = client.open(message(), event).await.unwrap();
|
||||
let alias = response.body.clone();
|
||||
tokio::time::sleep(Duration::from_millis(30)).await;
|
||||
response.body.close();
|
||||
assert!(alias.next().await.unwrap().is_none());
|
||||
assert_eq!(
|
||||
client.request(message()).await.unwrap().body.as_ref(),
|
||||
b"ok"
|
||||
);
|
||||
client.close().await.unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
server.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_timeout_and_protocol_failure_emit_one_error_then_eof() {
|
||||
for body in [
|
||||
b"".as_slice(),
|
||||
b"3\r\nabc\r\n0\r\nX-End: bad\r\n\r\n",
|
||||
b"invalid\r\n",
|
||||
] {
|
||||
let (port, server) = peer(move |listener| {
|
||||
let mut socket = accept(&listener);
|
||||
headers(&mut socket);
|
||||
socket
|
||||
.get_mut()
|
||||
.write_all(b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n")
|
||||
.unwrap();
|
||||
socket.get_mut().write_all(body).unwrap();
|
||||
let _ = socket.read(&mut [0]);
|
||||
});
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let client = client(
|
||||
scope,
|
||||
port,
|
||||
&Limits::default(),
|
||||
&PoolLimits {
|
||||
read_ms: 40,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let response = client.open(message(), event).await.unwrap();
|
||||
let mut failures = 0;
|
||||
while let Some(item) = response.body.next().await.unwrap() {
|
||||
failures += usize::from(item.is_err());
|
||||
}
|
||||
assert_eq!(failures, 1);
|
||||
assert!(response.body.next().await.unwrap().is_none());
|
||||
client.close().await.unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
server.join().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cancelling_consumer_closes_body_and_pool_close_wakes_body_and_slot_waiters() {
|
||||
for cancel in [true, false] {
|
||||
let (port, server) = peer(|listener| {
|
||||
let mut socket = accept(&listener);
|
||||
headers(&mut socket);
|
||||
socket
|
||||
.get_mut()
|
||||
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 20\r\n\r\n")
|
||||
.unwrap();
|
||||
assert_eq!(socket.read(&mut [0]).unwrap(), 0);
|
||||
});
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let client = client(
|
||||
scope,
|
||||
port,
|
||||
&Limits {
|
||||
connections: 1,
|
||||
..Default::default()
|
||||
},
|
||||
&PoolLimits::default(),
|
||||
);
|
||||
let response = client.open(message(), event).await.unwrap();
|
||||
let alias = response.body.clone();
|
||||
if cancel {
|
||||
let consume = async {
|
||||
let _owner = alias.close_on_drop();
|
||||
alias.next().await
|
||||
};
|
||||
assert!(
|
||||
tokio::time::timeout(Duration::from_millis(20), consume)
|
||||
.await
|
||||
.is_err()
|
||||
);
|
||||
assert!(response.body.next().await.unwrap().is_none());
|
||||
} else {
|
||||
let (item, waiting, ()) =
|
||||
tokio::join!(response.body.next(), client.open(message(), event), async {
|
||||
tokio::time::sleep(Duration::from_millis(20)).await;
|
||||
client.close().await.unwrap();
|
||||
});
|
||||
assert!(item.unwrap().unwrap().unwrap_err().contains("closed"));
|
||||
assert!(waiting.unwrap_err().contains("closed"));
|
||||
assert!(response.body.next().await.unwrap().is_none());
|
||||
}
|
||||
client.close().await.unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
server.join().unwrap();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user