mirror of
https://github.com/actix/actix-web.git
synced 2024-11-26 11:31:09 +00:00
remove direct dep on pin-project in -http (#2524)
This commit is contained in:
parent
5359fa56c2
commit
2cf27863cb
2 changed files with 158 additions and 123 deletions
|
@ -45,7 +45,7 @@ __compress = []
|
||||||
actix-service = "2.0.0"
|
actix-service = "2.0.0"
|
||||||
actix-codec = "0.4.1"
|
actix-codec = "0.4.1"
|
||||||
actix-utils = "3.0.0"
|
actix-utils = "3.0.0"
|
||||||
actix-rt = "2.2"
|
actix-rt = { version = "2.2", default-features = false }
|
||||||
|
|
||||||
ahash = "0.7"
|
ahash = "0.7"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
@ -66,7 +66,6 @@ local-channel = "0.1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
pin-project = "1.0.0"
|
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
sha-1 = "0.9"
|
sha-1 = "0.9"
|
||||||
|
|
|
@ -15,7 +15,7 @@ use bitflags::bitflags;
|
||||||
use bytes::{Buf, BytesMut};
|
use bytes::{Buf, BytesMut};
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
use pin_project::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
body::{BodySize, BoxBody, MessageBody},
|
body::{BodySize, BoxBody, MessageBody},
|
||||||
|
@ -46,10 +46,16 @@ bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project]
|
// there's 2 versions of Dispatcher state because of:
|
||||||
/// Dispatcher for HTTP/1.1 protocol
|
// https://github.com/taiki-e/pin-project-lite/issues/3
|
||||||
pub struct Dispatcher<T, S, B, X, U>
|
//
|
||||||
where
|
// tl;dr: pin-project-lite doesn't play well with other attribute macros
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
pin_project! {
|
||||||
|
/// Dispatcher for HTTP/1.1 protocol
|
||||||
|
pub struct Dispatcher<T, S, B, X, U>
|
||||||
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
S::Error: Into<Response<BoxBody>>,
|
S::Error: Into<Response<BoxBody>>,
|
||||||
|
|
||||||
|
@ -60,17 +66,40 @@ where
|
||||||
|
|
||||||
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
||||||
U::Error: fmt::Display,
|
U::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
|
#[pin]
|
||||||
|
inner: DispatcherState<T, S, B, X, U>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pin_project! {
|
||||||
|
/// Dispatcher for HTTP/1.1 protocol
|
||||||
|
pub struct Dispatcher<T, S, B, X, U>
|
||||||
|
where
|
||||||
|
S: Service<Request>,
|
||||||
|
S::Error: Into<Response<BoxBody>>,
|
||||||
|
|
||||||
|
B: MessageBody,
|
||||||
|
|
||||||
|
X: Service<Request, Response = Request>,
|
||||||
|
X::Error: Into<Response<BoxBody>>,
|
||||||
|
|
||||||
|
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
||||||
|
U::Error: fmt::Display,
|
||||||
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
inner: DispatcherState<T, S, B, X, U>,
|
inner: DispatcherState<T, S, B, X, U>,
|
||||||
|
|
||||||
#[cfg(test)]
|
// used in tests
|
||||||
poll_count: u64,
|
poll_count: u64,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project(project = DispatcherStateProj)]
|
pin_project! {
|
||||||
enum DispatcherState<T, S, B, X, U>
|
#[project = DispatcherStateProj]
|
||||||
where
|
enum DispatcherState<T, S, B, X, U>
|
||||||
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
S::Error: Into<Response<BoxBody>>,
|
S::Error: Into<Response<BoxBody>>,
|
||||||
|
|
||||||
|
@ -81,14 +110,16 @@ where
|
||||||
|
|
||||||
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
||||||
U::Error: fmt::Display,
|
U::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
Normal(#[pin] InnerDispatcher<T, S, B, X, U>),
|
Normal { #[pin] inner: InnerDispatcher<T, S, B, X, U> },
|
||||||
Upgrade(#[pin] U::Future),
|
Upgrade { #[pin] fut: U::Future },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project(project = InnerDispatcherProj)]
|
pin_project! {
|
||||||
struct InnerDispatcher<T, S, B, X, U>
|
#[project = InnerDispatcherProj]
|
||||||
where
|
struct InnerDispatcher<T, S, B, X, U>
|
||||||
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
S::Error: Into<Response<BoxBody>>,
|
S::Error: Into<Response<BoxBody>>,
|
||||||
|
|
||||||
|
@ -99,7 +130,7 @@ where
|
||||||
|
|
||||||
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
||||||
U::Error: fmt::Display,
|
U::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
flow: Rc<HttpFlow<S, X, U>>,
|
flow: Rc<HttpFlow<S, X, U>>,
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
peer_addr: Option<net::SocketAddr>,
|
peer_addr: Option<net::SocketAddr>,
|
||||||
|
@ -119,6 +150,7 @@ where
|
||||||
read_buf: BytesMut,
|
read_buf: BytesMut,
|
||||||
write_buf: BytesMut,
|
write_buf: BytesMut,
|
||||||
codec: Codec,
|
codec: Codec,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DispatcherMessage {
|
enum DispatcherMessage {
|
||||||
|
@ -127,19 +159,21 @@ enum DispatcherMessage {
|
||||||
Error(Response<()>),
|
Error(Response<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project(project = StateProj)]
|
pin_project! {
|
||||||
enum State<S, B, X>
|
#[project = StateProj]
|
||||||
where
|
enum State<S, B, X>
|
||||||
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
X: Service<Request, Response = Request>,
|
X: Service<Request, Response = Request>,
|
||||||
|
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
ExpectCall(#[pin] X::Future),
|
ExpectCall { #[pin] fut: X::Future },
|
||||||
ServiceCall(#[pin] S::Future),
|
ServiceCall { #[pin] fut: S::Future },
|
||||||
SendPayload(#[pin] B),
|
SendPayload { #[pin] body: B },
|
||||||
SendErrorPayload(#[pin] BoxBody),
|
SendErrorPayload { #[pin] body: BoxBody },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, B, X> State<S, B, X>
|
impl<S, B, X> State<S, B, X>
|
||||||
|
@ -198,7 +232,8 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
Dispatcher {
|
Dispatcher {
|
||||||
inner: DispatcherState::Normal(InnerDispatcher {
|
inner: DispatcherState::Normal {
|
||||||
|
inner: InnerDispatcher {
|
||||||
flow,
|
flow,
|
||||||
flags,
|
flags,
|
||||||
peer_addr,
|
peer_addr,
|
||||||
|
@ -216,7 +251,8 @@ where
|
||||||
read_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
|
read_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
|
||||||
write_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
|
write_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
|
||||||
codec: Codec::new(config),
|
codec: Codec::new(config),
|
||||||
}),
|
},
|
||||||
|
},
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
poll_count: 0,
|
poll_count: 0,
|
||||||
|
@ -316,7 +352,7 @@ where
|
||||||
let size = self.as_mut().send_response_inner(message, &body)?;
|
let size = self.as_mut().send_response_inner(message, &body)?;
|
||||||
let state = match size {
|
let state = match size {
|
||||||
BodySize::None | BodySize::Sized(0) => State::None,
|
BodySize::None | BodySize::Sized(0) => State::None,
|
||||||
_ => State::SendPayload(body),
|
_ => State::SendPayload { body },
|
||||||
};
|
};
|
||||||
self.project().state.set(state);
|
self.project().state.set(state);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -330,7 +366,7 @@ where
|
||||||
let size = self.as_mut().send_response_inner(message, &body)?;
|
let size = self.as_mut().send_response_inner(message, &body)?;
|
||||||
let state = match size {
|
let state = match size {
|
||||||
BodySize::None | BodySize::Sized(0) => State::None,
|
BodySize::None | BodySize::Sized(0) => State::None,
|
||||||
_ => State::SendErrorPayload(body),
|
_ => State::SendErrorPayload { body },
|
||||||
};
|
};
|
||||||
self.project().state.set(state);
|
self.project().state.set(state);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -356,12 +392,12 @@ where
|
||||||
// Handle `EXPECT: 100-Continue` header
|
// Handle `EXPECT: 100-Continue` header
|
||||||
if req.head().expect() {
|
if req.head().expect() {
|
||||||
// set InnerDispatcher state and continue loop to poll it.
|
// set InnerDispatcher state and continue loop to poll it.
|
||||||
let task = this.flow.expect.call(req);
|
let fut = this.flow.expect.call(req);
|
||||||
this.state.set(State::ExpectCall(task));
|
this.state.set(State::ExpectCall { fut });
|
||||||
} else {
|
} else {
|
||||||
// the same as expect call.
|
// the same as expect call.
|
||||||
let task = this.flow.service.call(req);
|
let fut = this.flow.service.call(req);
|
||||||
this.state.set(State::ServiceCall(task));
|
this.state.set(State::ServiceCall { fut });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +417,7 @@ where
|
||||||
// all messages are dealt with.
|
// all messages are dealt with.
|
||||||
None => return Ok(PollResponse::DoNothing),
|
None => return Ok(PollResponse::DoNothing),
|
||||||
},
|
},
|
||||||
StateProj::ServiceCall(fut) => match fut.poll(cx) {
|
StateProj::ServiceCall { fut } => match fut.poll(cx) {
|
||||||
// service call resolved. send response.
|
// service call resolved. send response.
|
||||||
Poll::Ready(Ok(res)) => {
|
Poll::Ready(Ok(res)) => {
|
||||||
let (res, body) = res.into().replace_body(());
|
let (res, body) = res.into().replace_body(());
|
||||||
|
@ -407,11 +443,11 @@ where
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
StateProj::SendPayload(mut stream) => {
|
StateProj::SendPayload { mut body } => {
|
||||||
// keep populate writer buffer until buffer size limit hit,
|
// keep populate writer buffer until buffer size limit hit,
|
||||||
// get blocked or finished.
|
// get blocked or finished.
|
||||||
while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
|
while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
|
||||||
match stream.as_mut().poll_next(cx) {
|
match body.as_mut().poll_next(cx) {
|
||||||
Poll::Ready(Some(Ok(item))) => {
|
Poll::Ready(Some(Ok(item))) => {
|
||||||
this.codec
|
this.codec
|
||||||
.encode(Message::Chunk(Some(item)), this.write_buf)?;
|
.encode(Message::Chunk(Some(item)), this.write_buf)?;
|
||||||
|
@ -437,13 +473,13 @@ where
|
||||||
return Ok(PollResponse::DrainWriteBuf);
|
return Ok(PollResponse::DrainWriteBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
StateProj::SendErrorPayload(mut stream) => {
|
StateProj::SendErrorPayload { mut body } => {
|
||||||
// TODO: de-dupe impl with SendPayload
|
// TODO: de-dupe impl with SendPayload
|
||||||
|
|
||||||
// keep populate writer buffer until buffer size limit hit,
|
// keep populate writer buffer until buffer size limit hit,
|
||||||
// get blocked or finished.
|
// get blocked or finished.
|
||||||
while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
|
while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
|
||||||
match stream.as_mut().poll_next(cx) {
|
match body.as_mut().poll_next(cx) {
|
||||||
Poll::Ready(Some(Ok(item))) => {
|
Poll::Ready(Some(Ok(item))) => {
|
||||||
this.codec
|
this.codec
|
||||||
.encode(Message::Chunk(Some(item)), this.write_buf)?;
|
.encode(Message::Chunk(Some(item)), this.write_buf)?;
|
||||||
|
@ -469,14 +505,14 @@ where
|
||||||
return Ok(PollResponse::DrainWriteBuf);
|
return Ok(PollResponse::DrainWriteBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
StateProj::ExpectCall(fut) => match fut.poll(cx) {
|
StateProj::ExpectCall { fut } => match fut.poll(cx) {
|
||||||
// expect resolved. write continue to buffer and set InnerDispatcher state
|
// expect resolved. write continue to buffer and set InnerDispatcher state
|
||||||
// to service call.
|
// to service call.
|
||||||
Poll::Ready(Ok(req)) => {
|
Poll::Ready(Ok(req)) => {
|
||||||
this.write_buf
|
this.write_buf
|
||||||
.extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
|
.extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
|
||||||
let fut = this.flow.service.call(req);
|
let fut = this.flow.service.call(req);
|
||||||
this.state.set(State::ServiceCall(fut));
|
this.state.set(State::ServiceCall { fut });
|
||||||
}
|
}
|
||||||
|
|
||||||
// send expect error as response
|
// send expect error as response
|
||||||
|
@ -502,25 +538,25 @@ where
|
||||||
let mut this = self.as_mut().project();
|
let mut this = self.as_mut().project();
|
||||||
if req.head().expect() {
|
if req.head().expect() {
|
||||||
// set dispatcher state so the future is pinned.
|
// set dispatcher state so the future is pinned.
|
||||||
let task = this.flow.expect.call(req);
|
let fut = this.flow.expect.call(req);
|
||||||
this.state.set(State::ExpectCall(task));
|
this.state.set(State::ExpectCall { fut });
|
||||||
} else {
|
} else {
|
||||||
// the same as above.
|
// the same as above.
|
||||||
let task = this.flow.service.call(req);
|
let fut = this.flow.service.call(req);
|
||||||
this.state.set(State::ServiceCall(task));
|
this.state.set(State::ServiceCall { fut });
|
||||||
};
|
};
|
||||||
|
|
||||||
// eagerly poll the future for once(or twice if expect is resolved immediately).
|
// eagerly poll the future for once(or twice if expect is resolved immediately).
|
||||||
loop {
|
loop {
|
||||||
match self.as_mut().project().state.project() {
|
match self.as_mut().project().state.project() {
|
||||||
StateProj::ExpectCall(fut) => {
|
StateProj::ExpectCall { fut } => {
|
||||||
match fut.poll(cx) {
|
match fut.poll(cx) {
|
||||||
// expect is resolved. continue loop and poll the service call branch.
|
// expect is resolved. continue loop and poll the service call branch.
|
||||||
Poll::Ready(Ok(req)) => {
|
Poll::Ready(Ok(req)) => {
|
||||||
self.as_mut().send_continue();
|
self.as_mut().send_continue();
|
||||||
let mut this = self.as_mut().project();
|
let mut this = self.as_mut().project();
|
||||||
let task = this.flow.service.call(req);
|
let fut = this.flow.service.call(req);
|
||||||
this.state.set(State::ServiceCall(task));
|
this.state.set(State::ServiceCall { fut });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// future is pending. return Ok(()) to notify that a new state is
|
// future is pending. return Ok(()) to notify that a new state is
|
||||||
|
@ -536,7 +572,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StateProj::ServiceCall(fut) => {
|
StateProj::ServiceCall { fut } => {
|
||||||
// return no matter the service call future's result.
|
// return no matter the service call future's result.
|
||||||
return match fut.poll(cx) {
|
return match fut.poll(cx) {
|
||||||
// future is resolved. send response and return a result. On success
|
// future is resolved. send response and return a result. On success
|
||||||
|
@ -901,7 +937,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
match this.inner.project() {
|
match this.inner.project() {
|
||||||
DispatcherStateProj::Normal(mut inner) => {
|
DispatcherStateProj::Normal { mut inner } => {
|
||||||
inner.as_mut().poll_keepalive(cx)?;
|
inner.as_mut().poll_keepalive(cx)?;
|
||||||
|
|
||||||
if inner.flags.contains(Flags::SHUTDOWN) {
|
if inner.flags.contains(Flags::SHUTDOWN) {
|
||||||
|
@ -941,7 +977,7 @@ where
|
||||||
self.as_mut()
|
self.as_mut()
|
||||||
.project()
|
.project()
|
||||||
.inner
|
.inner
|
||||||
.set(DispatcherState::Upgrade(upgrade));
|
.set(DispatcherState::Upgrade { fut: upgrade });
|
||||||
return self.poll(cx);
|
return self.poll(cx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -993,8 +1029,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DispatcherStateProj::Upgrade(fut) => fut.poll(cx).map_err(|e| {
|
DispatcherStateProj::Upgrade { fut: upgrade } => upgrade.poll(cx).map_err(|err| {
|
||||||
error!("Upgrade handler error: {}", e);
|
error!("Upgrade handler error: {}", err);
|
||||||
DispatchError::Upgrade
|
DispatchError::Upgrade
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1124,7 @@ mod tests {
|
||||||
Poll::Ready(res) => assert!(res.is_err()),
|
Poll::Ready(res) => assert!(res.is_err()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if let DispatcherStateProj::Normal(inner) = h1.project().inner.project() {
|
if let DispatcherStateProj::Normal { inner } = h1.project().inner.project() {
|
||||||
assert!(inner.flags.contains(Flags::READ_DISCONNECT));
|
assert!(inner.flags.contains(Flags::READ_DISCONNECT));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&inner.project().io.take().unwrap().write_buf[..26],
|
&inner.project().io.take().unwrap().write_buf[..26],
|
||||||
|
@ -1123,7 +1159,7 @@ mod tests {
|
||||||
|
|
||||||
actix_rt::pin!(h1);
|
actix_rt::pin!(h1);
|
||||||
|
|
||||||
assert!(matches!(&h1.inner, DispatcherState::Normal(_)));
|
assert!(matches!(&h1.inner, DispatcherState::Normal { .. }));
|
||||||
|
|
||||||
match h1.as_mut().poll(cx) {
|
match h1.as_mut().poll(cx) {
|
||||||
Poll::Pending => panic!("first poll should not be pending"),
|
Poll::Pending => panic!("first poll should not be pending"),
|
||||||
|
@ -1133,7 +1169,7 @@ mod tests {
|
||||||
// polls: initial => shutdown
|
// polls: initial => shutdown
|
||||||
assert_eq!(h1.poll_count, 2);
|
assert_eq!(h1.poll_count, 2);
|
||||||
|
|
||||||
if let DispatcherStateProj::Normal(inner) = h1.project().inner.project() {
|
if let DispatcherStateProj::Normal { inner } = h1.project().inner.project() {
|
||||||
let res = &mut inner.project().io.take().unwrap().write_buf[..];
|
let res = &mut inner.project().io.take().unwrap().write_buf[..];
|
||||||
stabilize_date_header(res);
|
stabilize_date_header(res);
|
||||||
|
|
||||||
|
@ -1177,7 +1213,7 @@ mod tests {
|
||||||
|
|
||||||
actix_rt::pin!(h1);
|
actix_rt::pin!(h1);
|
||||||
|
|
||||||
assert!(matches!(&h1.inner, DispatcherState::Normal(_)));
|
assert!(matches!(&h1.inner, DispatcherState::Normal { .. }));
|
||||||
|
|
||||||
match h1.as_mut().poll(cx) {
|
match h1.as_mut().poll(cx) {
|
||||||
Poll::Pending => panic!("first poll should not be pending"),
|
Poll::Pending => panic!("first poll should not be pending"),
|
||||||
|
@ -1187,7 +1223,7 @@ mod tests {
|
||||||
// polls: initial => shutdown
|
// polls: initial => shutdown
|
||||||
assert_eq!(h1.poll_count, 1);
|
assert_eq!(h1.poll_count, 1);
|
||||||
|
|
||||||
if let DispatcherStateProj::Normal(inner) = h1.project().inner.project() {
|
if let DispatcherStateProj::Normal { inner } = h1.project().inner.project() {
|
||||||
let res = &mut inner.project().io.take().unwrap().write_buf[..];
|
let res = &mut inner.project().io.take().unwrap().write_buf[..];
|
||||||
stabilize_date_header(res);
|
stabilize_date_header(res);
|
||||||
|
|
||||||
|
@ -1237,13 +1273,13 @@ mod tests {
|
||||||
actix_rt::pin!(h1);
|
actix_rt::pin!(h1);
|
||||||
|
|
||||||
assert!(h1.as_mut().poll(cx).is_pending());
|
assert!(h1.as_mut().poll(cx).is_pending());
|
||||||
assert!(matches!(&h1.inner, DispatcherState::Normal(_)));
|
assert!(matches!(&h1.inner, DispatcherState::Normal { .. }));
|
||||||
|
|
||||||
// polls: manual
|
// polls: manual
|
||||||
assert_eq!(h1.poll_count, 1);
|
assert_eq!(h1.poll_count, 1);
|
||||||
eprintln!("poll count: {}", h1.poll_count);
|
eprintln!("poll count: {}", h1.poll_count);
|
||||||
|
|
||||||
if let DispatcherState::Normal(ref inner) = h1.inner {
|
if let DispatcherState::Normal { ref inner } = h1.inner {
|
||||||
let io = inner.io.as_ref().unwrap();
|
let io = inner.io.as_ref().unwrap();
|
||||||
let res = &io.write_buf()[..];
|
let res = &io.write_buf()[..];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1258,7 +1294,7 @@ mod tests {
|
||||||
// polls: manual manual shutdown
|
// polls: manual manual shutdown
|
||||||
assert_eq!(h1.poll_count, 3);
|
assert_eq!(h1.poll_count, 3);
|
||||||
|
|
||||||
if let DispatcherState::Normal(ref inner) = h1.inner {
|
if let DispatcherState::Normal { ref inner } = h1.inner {
|
||||||
let io = inner.io.as_ref().unwrap();
|
let io = inner.io.as_ref().unwrap();
|
||||||
let mut res = (&io.write_buf()[..]).to_owned();
|
let mut res = (&io.write_buf()[..]).to_owned();
|
||||||
stabilize_date_header(&mut res);
|
stabilize_date_header(&mut res);
|
||||||
|
@ -1309,12 +1345,12 @@ mod tests {
|
||||||
actix_rt::pin!(h1);
|
actix_rt::pin!(h1);
|
||||||
|
|
||||||
assert!(h1.as_mut().poll(cx).is_ready());
|
assert!(h1.as_mut().poll(cx).is_ready());
|
||||||
assert!(matches!(&h1.inner, DispatcherState::Normal(_)));
|
assert!(matches!(&h1.inner, DispatcherState::Normal { .. }));
|
||||||
|
|
||||||
// polls: manual shutdown
|
// polls: manual shutdown
|
||||||
assert_eq!(h1.poll_count, 2);
|
assert_eq!(h1.poll_count, 2);
|
||||||
|
|
||||||
if let DispatcherState::Normal(ref inner) = h1.inner {
|
if let DispatcherState::Normal { ref inner } = h1.inner {
|
||||||
let io = inner.io.as_ref().unwrap();
|
let io = inner.io.as_ref().unwrap();
|
||||||
let mut res = (&io.write_buf()[..]).to_owned();
|
let mut res = (&io.write_buf()[..]).to_owned();
|
||||||
stabilize_date_header(&mut res);
|
stabilize_date_header(&mut res);
|
||||||
|
@ -1386,7 +1422,7 @@ mod tests {
|
||||||
actix_rt::pin!(h1);
|
actix_rt::pin!(h1);
|
||||||
|
|
||||||
assert!(h1.as_mut().poll(cx).is_ready());
|
assert!(h1.as_mut().poll(cx).is_ready());
|
||||||
assert!(matches!(&h1.inner, DispatcherState::Upgrade(_)));
|
assert!(matches!(&h1.inner, DispatcherState::Upgrade { .. }));
|
||||||
|
|
||||||
// polls: manual shutdown
|
// polls: manual shutdown
|
||||||
assert_eq!(h1.poll_count, 2);
|
assert_eq!(h1.poll_count, 2);
|
||||||
|
|
Loading…
Reference in a new issue