mirror of
https://github.com/fafhrd91/actix-web
synced 2025-06-25 22:49:21 +02:00
replace cloneable service with httpflow abstraction (#1876)
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::VecDeque,
|
||||
fmt,
|
||||
future::Future,
|
||||
io, mem, net,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
@ -15,17 +17,14 @@ use bytes::{Buf, BytesMut};
|
||||
use log::{error, trace};
|
||||
use pin_project::pin_project;
|
||||
|
||||
use crate::cloneable::CloneableService;
|
||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::error::{DispatchError, Error};
|
||||
use crate::error::{ParseError, PayloadError};
|
||||
use crate::httpmessage::HttpMessage;
|
||||
use crate::request::Request;
|
||||
use crate::response::Response;
|
||||
use crate::{
|
||||
body::{Body, BodySize, MessageBody, ResponseBody},
|
||||
Extensions,
|
||||
};
|
||||
use crate::service::HttpFlow;
|
||||
use crate::OnConnectData;
|
||||
|
||||
use super::codec::Codec;
|
||||
use super::payload::{Payload, PayloadSender, PayloadStatus};
|
||||
@ -78,7 +77,7 @@ where
|
||||
U::Error: fmt::Display,
|
||||
{
|
||||
Normal(#[pin] InnerDispatcher<T, S, B, X, U>),
|
||||
Upgrade(Pin<Box<U::Future>>),
|
||||
Upgrade(#[pin] U::Future),
|
||||
}
|
||||
|
||||
#[pin_project(project = InnerDispatcherProj)]
|
||||
@ -92,10 +91,8 @@ where
|
||||
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
||||
U::Error: fmt::Display,
|
||||
{
|
||||
service: CloneableService<S>,
|
||||
expect: CloneableService<X>,
|
||||
upgrade: Option<CloneableService<U>>,
|
||||
on_connect_data: Extensions,
|
||||
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||
on_connect_data: OnConnectData,
|
||||
flags: Flags,
|
||||
peer_addr: Option<net::SocketAddr>,
|
||||
error: Option<DispatchError>,
|
||||
@ -180,10 +177,8 @@ where
|
||||
pub(crate) fn new(
|
||||
stream: T,
|
||||
config: ServiceConfig,
|
||||
service: CloneableService<S>,
|
||||
expect: CloneableService<X>,
|
||||
upgrade: Option<CloneableService<U>>,
|
||||
on_connect_data: Extensions,
|
||||
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||
on_connect_data: OnConnectData,
|
||||
peer_addr: Option<net::SocketAddr>,
|
||||
) -> Self {
|
||||
Dispatcher::with_timeout(
|
||||
@ -192,9 +187,7 @@ where
|
||||
config,
|
||||
BytesMut::with_capacity(HW_BUFFER_SIZE),
|
||||
None,
|
||||
service,
|
||||
expect,
|
||||
upgrade,
|
||||
services,
|
||||
on_connect_data,
|
||||
peer_addr,
|
||||
)
|
||||
@ -207,10 +200,8 @@ where
|
||||
config: ServiceConfig,
|
||||
read_buf: BytesMut,
|
||||
timeout: Option<Sleep>,
|
||||
service: CloneableService<S>,
|
||||
expect: CloneableService<X>,
|
||||
upgrade: Option<CloneableService<U>>,
|
||||
on_connect_data: Extensions,
|
||||
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||
on_connect_data: OnConnectData,
|
||||
peer_addr: Option<net::SocketAddr>,
|
||||
) -> Self {
|
||||
let keepalive = config.keep_alive_enabled();
|
||||
@ -239,9 +230,7 @@ where
|
||||
io: Some(io),
|
||||
codec,
|
||||
read_buf,
|
||||
service,
|
||||
expect,
|
||||
upgrade,
|
||||
services,
|
||||
on_connect_data,
|
||||
flags,
|
||||
peer_addr,
|
||||
@ -395,7 +384,8 @@ where
|
||||
Poll::Ready(Ok(req)) => {
|
||||
self.as_mut().send_continue();
|
||||
this = self.as_mut().project();
|
||||
this.state.set(State::ServiceCall(this.service.call(req)));
|
||||
let fut = this.services.borrow_mut().service.call(req);
|
||||
this.state.set(State::ServiceCall(fut));
|
||||
continue;
|
||||
}
|
||||
Poll::Ready(Err(e)) => {
|
||||
@ -483,12 +473,14 @@ where
|
||||
// Handle `EXPECT: 100-Continue` header
|
||||
if req.head().expect() {
|
||||
// set dispatcher state so the future is pinned.
|
||||
let task = self.as_mut().project().expect.call(req);
|
||||
self.as_mut().project().state.set(State::ExpectCall(task));
|
||||
let mut this = self.as_mut().project();
|
||||
let task = this.services.borrow_mut().expect.call(req);
|
||||
this.state.set(State::ExpectCall(task));
|
||||
} else {
|
||||
// the same as above.
|
||||
let task = self.as_mut().project().service.call(req);
|
||||
self.as_mut().project().state.set(State::ServiceCall(task));
|
||||
let mut this = self.as_mut().project();
|
||||
let task = this.services.borrow_mut().service.call(req);
|
||||
this.state.set(State::ServiceCall(task));
|
||||
};
|
||||
|
||||
// eagerly poll the future for once(or twice if expect is resolved immediately).
|
||||
@ -499,8 +491,9 @@ where
|
||||
// expect is resolved. continue loop and poll the service call branch.
|
||||
Poll::Ready(Ok(req)) => {
|
||||
self.as_mut().send_continue();
|
||||
let task = self.as_mut().project().service.call(req);
|
||||
self.as_mut().project().state.set(State::ServiceCall(task));
|
||||
let mut this = self.as_mut().project();
|
||||
let task = this.services.borrow_mut().service.call(req);
|
||||
this.state.set(State::ServiceCall(task));
|
||||
continue;
|
||||
}
|
||||
// future is pending. return Ok(()) to notify that a new state is
|
||||
@ -568,9 +561,11 @@ where
|
||||
req.head_mut().peer_addr = *this.peer_addr;
|
||||
|
||||
// merge on_connect_ext data into request extensions
|
||||
req.extensions_mut().drain_from(this.on_connect_data);
|
||||
this.on_connect_data.merge_into(&mut req);
|
||||
|
||||
if pl == MessageType::Stream && this.upgrade.is_some() {
|
||||
if pl == MessageType::Stream
|
||||
&& this.services.borrow().upgrade.is_some()
|
||||
{
|
||||
this.messages.push_back(DispatcherMessage::Upgrade(req));
|
||||
break;
|
||||
}
|
||||
@ -834,12 +829,17 @@ where
|
||||
);
|
||||
parts.write_buf = mem::take(inner_p.write_buf);
|
||||
let framed = Framed::from_parts(parts);
|
||||
let upgrade =
|
||||
inner_p.upgrade.take().unwrap().call((req, framed));
|
||||
let upgrade = inner_p
|
||||
.services
|
||||
.borrow_mut()
|
||||
.upgrade
|
||||
.take()
|
||||
.unwrap()
|
||||
.call((req, framed));
|
||||
self.as_mut()
|
||||
.project()
|
||||
.inner
|
||||
.set(DispatcherState::Upgrade(Box::pin(upgrade)));
|
||||
.set(DispatcherState::Upgrade(upgrade));
|
||||
return self.poll(cx);
|
||||
}
|
||||
|
||||
@ -890,7 +890,7 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
DispatcherStateProj::Upgrade(fut) => fut.as_mut().poll(cx).map_err(|e| {
|
||||
DispatcherStateProj::Upgrade(fut) => fut.poll(cx).map_err(|e| {
|
||||
error!("Upgrade handler error: {}", e);
|
||||
DispatchError::Upgrade
|
||||
}),
|
||||
@ -1028,13 +1028,13 @@ mod tests {
|
||||
lazy(|cx| {
|
||||
let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n");
|
||||
|
||||
let services = HttpFlow::new(ok_service(), ExpectHandler, None);
|
||||
|
||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||
buf,
|
||||
ServiceConfig::default(),
|
||||
CloneableService::new(ok_service()),
|
||||
CloneableService::new(ExpectHandler),
|
||||
None,
|
||||
Extensions::new(),
|
||||
services,
|
||||
OnConnectData::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -1068,13 +1068,13 @@ mod tests {
|
||||
|
||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None);
|
||||
|
||||
let services = HttpFlow::new(echo_path_service(), ExpectHandler, None);
|
||||
|
||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||
buf,
|
||||
cfg,
|
||||
CloneableService::new(echo_path_service()),
|
||||
CloneableService::new(ExpectHandler),
|
||||
None,
|
||||
Extensions::new(),
|
||||
services,
|
||||
OnConnectData::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -1122,13 +1122,13 @@ mod tests {
|
||||
|
||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None);
|
||||
|
||||
let services = HttpFlow::new(echo_path_service(), ExpectHandler, None);
|
||||
|
||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||
buf,
|
||||
cfg,
|
||||
CloneableService::new(echo_path_service()),
|
||||
CloneableService::new(ExpectHandler),
|
||||
None,
|
||||
Extensions::new(),
|
||||
services,
|
||||
OnConnectData::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -1171,13 +1171,14 @@ mod tests {
|
||||
lazy(|cx| {
|
||||
let mut buf = TestSeqBuffer::empty();
|
||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
||||
|
||||
let services = HttpFlow::new(echo_payload_service(), ExpectHandler, None);
|
||||
|
||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||
buf.clone(),
|
||||
cfg,
|
||||
CloneableService::new(echo_payload_service()),
|
||||
CloneableService::new(ExpectHandler),
|
||||
None,
|
||||
Extensions::new(),
|
||||
services,
|
||||
OnConnectData::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -1242,13 +1243,14 @@ mod tests {
|
||||
lazy(|cx| {
|
||||
let mut buf = TestSeqBuffer::empty();
|
||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
||||
|
||||
let services = HttpFlow::new(echo_path_service(), ExpectHandler, None);
|
||||
|
||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||
buf.clone(),
|
||||
cfg,
|
||||
CloneableService::new(echo_path_service()),
|
||||
CloneableService::new(ExpectHandler),
|
||||
None,
|
||||
Extensions::new(),
|
||||
services,
|
||||
OnConnectData::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -1301,13 +1303,15 @@ mod tests {
|
||||
lazy(|cx| {
|
||||
let mut buf = TestSeqBuffer::empty();
|
||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
||||
|
||||
let services =
|
||||
HttpFlow::new(ok_service(), ExpectHandler, Some(UpgradeHandler));
|
||||
|
||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||
buf.clone(),
|
||||
cfg,
|
||||
CloneableService::new(ok_service()),
|
||||
CloneableService::new(ExpectHandler),
|
||||
Some(CloneableService::new(UpgradeHandler)),
|
||||
Extensions::new(),
|
||||
services,
|
||||
OnConnectData::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
use std::cell::RefCell;
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
@ -12,12 +13,12 @@ use futures_core::ready;
|
||||
use futures_util::future::ready;
|
||||
|
||||
use crate::body::MessageBody;
|
||||
use crate::cloneable::CloneableService;
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::error::{DispatchError, Error};
|
||||
use crate::request::Request;
|
||||
use crate::response::Response;
|
||||
use crate::{ConnectCallback, Extensions};
|
||||
use crate::service::HttpFlow;
|
||||
use crate::{ConnectCallback, OnConnectData};
|
||||
|
||||
use super::codec::Codec;
|
||||
use super::dispatcher::Dispatcher;
|
||||
@ -299,7 +300,7 @@ where
|
||||
upgrade: Option<U::Service>,
|
||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||
cfg: Option<ServiceConfig>,
|
||||
_phantom: PhantomData<(T, B)>,
|
||||
_phantom: PhantomData<B>,
|
||||
}
|
||||
|
||||
impl<T, S, B, X, U> Future for H1ServiceResponse<T, S, B, X, U>
|
||||
@ -366,9 +367,7 @@ where
|
||||
X: Service<Request>,
|
||||
U: Service<(Request, Framed<T, Codec>)>,
|
||||
{
|
||||
srv: CloneableService<S>,
|
||||
expect: CloneableService<X>,
|
||||
upgrade: Option<CloneableService<U>>,
|
||||
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||
cfg: ServiceConfig,
|
||||
_phantom: PhantomData<B>,
|
||||
@ -387,15 +386,13 @@ where
|
||||
{
|
||||
fn new(
|
||||
cfg: ServiceConfig,
|
||||
srv: S,
|
||||
service: S,
|
||||
expect: X,
|
||||
upgrade: Option<U>,
|
||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||
) -> H1ServiceHandler<T, S, B, X, U> {
|
||||
H1ServiceHandler {
|
||||
srv: CloneableService::new(srv),
|
||||
expect: CloneableService::new(expect),
|
||||
upgrade: upgrade.map(CloneableService::new),
|
||||
services: HttpFlow::new(service, expect, upgrade),
|
||||
cfg,
|
||||
on_connect_ext,
|
||||
_phantom: PhantomData,
|
||||
@ -421,7 +418,8 @@ where
|
||||
type Future = Dispatcher<T, S, B, X, U>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
let ready = self
|
||||
let mut services = self.services.borrow_mut();
|
||||
let ready = services
|
||||
.expect
|
||||
.poll_ready(cx)
|
||||
.map_err(|e| {
|
||||
@ -431,8 +429,8 @@ where
|
||||
})?
|
||||
.is_ready();
|
||||
|
||||
let ready = self
|
||||
.srv
|
||||
let ready = services
|
||||
.service
|
||||
.poll_ready(cx)
|
||||
.map_err(|e| {
|
||||
let e = e.into();
|
||||
@ -442,7 +440,7 @@ where
|
||||
.is_ready()
|
||||
&& ready;
|
||||
|
||||
let ready = if let Some(ref mut upg) = self.upgrade {
|
||||
let ready = if let Some(ref mut upg) = services.upgrade {
|
||||
upg.poll_ready(cx)
|
||||
.map_err(|e| {
|
||||
let e = e.into();
|
||||
@ -463,19 +461,14 @@ where
|
||||
}
|
||||
|
||||
fn call(&mut self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
|
||||
let mut connect_extensions = Extensions::new();
|
||||
if let Some(ref handler) = self.on_connect_ext {
|
||||
// run on_connect_ext callback, populating connect extensions
|
||||
handler(&io, &mut connect_extensions);
|
||||
}
|
||||
let on_connect_data =
|
||||
OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
|
||||
|
||||
Dispatcher::new(
|
||||
io,
|
||||
self.cfg.clone(),
|
||||
self.srv.clone(),
|
||||
self.expect.clone(),
|
||||
self.upgrade.clone(),
|
||||
connect_extensions,
|
||||
self.services.clone(),
|
||||
on_connect_data,
|
||||
addr,
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user