mirror of
https://github.com/ntex-rs/ntex.git
synced 2025-04-01 20:07:39 +03:00
update ServiceFactory api
This commit is contained in:
parent
359d94fd5a
commit
f0f899a36e
12 changed files with 71 additions and 123 deletions
|
@ -86,8 +86,7 @@ impl Filter for Base {
|
|||
Poll::Ready(WriteStatus::Terminate)
|
||||
} else if flags.intersects(Flags::IO_SHUTDOWN) {
|
||||
Poll::Ready(WriteStatus::Shutdown(self.0 .0.disconnect_timeout.get()))
|
||||
} else if flags.contains(Flags::IO_FILTERS)
|
||||
&& !flags.contains(Flags::IO_FILTERS_TO)
|
||||
} else if flags.contains(Flags::IO_FILTERS) && !flags.contains(Flags::IO_FILTERS_TO)
|
||||
{
|
||||
flags.insert(Flags::IO_FILTERS_TO);
|
||||
self.0.set_flags(flags);
|
||||
|
|
|
@ -559,9 +559,12 @@ impl<F> Io<F> {
|
|||
pub fn poll_flush(&self, cx: &mut Context<'_>, full: bool) -> Poll<io::Result<()>> {
|
||||
// check io error
|
||||
if !self.0 .0.is_io_open() {
|
||||
return Poll::Ready(Err(self.0 .0.error.take().unwrap_or_else(|| {
|
||||
io::Error::new(io::ErrorKind::Other, "disconnected")
|
||||
})));
|
||||
return Poll::Ready(Err(self
|
||||
.0
|
||||
.0
|
||||
.error
|
||||
.take()
|
||||
.unwrap_or_else(|| io::Error::new(io::ErrorKind::Other, "disconnected"))));
|
||||
}
|
||||
|
||||
if let Some(buf) = self.0 .0.write_buf.take() {
|
||||
|
|
|
@ -185,11 +185,7 @@ impl IoRef {
|
|||
/// Encode and write item to a buffer and wake up write task
|
||||
///
|
||||
/// Returns write buffer state, false is returned if write buffer if full.
|
||||
pub fn encode<U>(
|
||||
&self,
|
||||
item: U::Item,
|
||||
codec: &U,
|
||||
) -> Result<bool, <U as Encoder>::Error>
|
||||
pub fn encode<U>(&self, item: U::Item, codec: &U) -> Result<bool, <U as Encoder>::Error>
|
||||
where
|
||||
U: Encoder,
|
||||
{
|
||||
|
|
|
@ -29,9 +29,7 @@ pub use self::io::{Io, IoRef, OnDisconnect};
|
|||
pub use self::tasks::{ReadContext, WriteContext};
|
||||
pub use self::time::Timer;
|
||||
|
||||
pub use self::utils::{
|
||||
filter_factory, seal, sealed_service, SealedFactory, SealedService,
|
||||
};
|
||||
pub use self::utils::{filter_factory, seal, sealed_service, SealedFactory, SealedService};
|
||||
|
||||
pub type IoBoxed = Io<Sealed>;
|
||||
|
||||
|
@ -148,24 +146,6 @@ pub mod rt {
|
|||
pub use crate::tokio_rt::*;
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[doc(hidden)]
|
||||
pub fn into_boxed<F, S>(
|
||||
srv: S,
|
||||
) -> impl ntex_service::ServiceFactory<
|
||||
Io<F>,
|
||||
Config = S::Config,
|
||||
Response = S::Response,
|
||||
Error = S::Error,
|
||||
InitError = S::InitError,
|
||||
>
|
||||
where
|
||||
F: Filter + 'static,
|
||||
S: ntex_service::ServiceFactory<IoBoxed>,
|
||||
{
|
||||
seal(srv)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -187,7 +167,8 @@ mod tests {
|
|||
.contains("DispatchItem::WBackPressureEnabled"));
|
||||
assert!(format!("{:?}", T::WBackPressureDisabled)
|
||||
.contains("DispatchItem::WBackPressureDisabled"));
|
||||
assert!(format!("{:?}", T::KeepAliveTimeout)
|
||||
.contains("DispatchItem::KeepAliveTimeout"));
|
||||
assert!(
|
||||
format!("{:?}", T::KeepAliveTimeout).contains("DispatchItem::KeepAliveTimeout")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,7 @@ use ntex_bytes::{Buf, BufMut, BytesMut};
|
|||
use ntex_util::future::poll_fn;
|
||||
use ntex_util::time::{sleep, Millis, Sleep};
|
||||
|
||||
use crate::{
|
||||
types, Handle, IoStream, ReadContext, ReadStatus, WriteContext, WriteStatus,
|
||||
};
|
||||
use crate::{types, Handle, IoStream, ReadContext, ReadStatus, WriteContext, WriteStatus};
|
||||
|
||||
#[derive(Default)]
|
||||
struct AtomicWaker(Arc<Mutex<RefCell<Option<Waker>>>>);
|
||||
|
@ -411,10 +409,7 @@ impl Future for ReadTask {
|
|||
|
||||
match io.poll_read_buf(cx, &mut buf) {
|
||||
Poll::Pending => {
|
||||
log::trace!(
|
||||
"no more data in io stream, read: {:?}",
|
||||
new_bytes
|
||||
);
|
||||
log::trace!("no more data in io stream, read: {:?}", new_bytes);
|
||||
break;
|
||||
}
|
||||
Poll::Ready(Ok(n)) => {
|
||||
|
@ -732,10 +727,7 @@ mod tokio_impl {
|
|||
}
|
||||
}
|
||||
|
||||
fn poll_flush(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@ impl Future for ReadTask {
|
|||
Poll::Ready(Ok(n)) => {
|
||||
if n == 0 {
|
||||
log::trace!("io stream is disconnected");
|
||||
if let Err(e) =
|
||||
this.state.release_read_buf(buf, new_bytes)
|
||||
if let Err(e) = this.state.release_read_buf(buf, new_bytes)
|
||||
{
|
||||
this.state.close(Some(e));
|
||||
} else {
|
||||
|
@ -221,8 +220,7 @@ impl Future for WriteTask {
|
|||
}
|
||||
Shutdown::Flushed => {
|
||||
// shutdown WRITE side
|
||||
match Pin::new(&mut *this.io.borrow_mut()).poll_shutdown(cx)
|
||||
{
|
||||
match Pin::new(&mut *this.io.borrow_mut()).poll_shutdown(cx) {
|
||||
Poll::Ready(Ok(_)) => {
|
||||
*st = Shutdown::Stopping;
|
||||
continue;
|
||||
|
@ -386,10 +384,7 @@ impl<F: Filter> AsyncWrite for Io<F> {
|
|||
Io::poll_flush(&*self, cx, false)
|
||||
}
|
||||
|
||||
fn poll_shutdown(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Io::poll_shutdown(&*self, cx)
|
||||
}
|
||||
}
|
||||
|
@ -431,10 +426,7 @@ impl AsyncWrite for IoBoxed {
|
|||
Self::poll_flush(&*self, cx, false)
|
||||
}
|
||||
|
||||
fn poll_shutdown(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Self::poll_shutdown(&*self, cx)
|
||||
}
|
||||
}
|
||||
|
@ -446,11 +438,7 @@ mod unixstream {
|
|||
use super::*;
|
||||
|
||||
impl IoStream for UnixStream {
|
||||
fn start(
|
||||
self,
|
||||
read: ReadContext,
|
||||
write: WriteContext,
|
||||
) -> Option<Box<dyn Handle>> {
|
||||
fn start(self, read: ReadContext, write: WriteContext) -> Option<Box<dyn Handle>> {
|
||||
let io = Rc::new(RefCell::new(self));
|
||||
|
||||
tok_io::task::spawn_local(ReadTask::new(io.clone(), read));
|
||||
|
@ -604,8 +592,7 @@ mod unixstream {
|
|||
Poll::Ready(WriteStatus::Terminate) => {
|
||||
log::trace!("write task is instructed to terminate");
|
||||
|
||||
let _ =
|
||||
Pin::new(&mut *this.io.borrow_mut()).poll_shutdown(cx);
|
||||
let _ = Pin::new(&mut *this.io.borrow_mut()).poll_shutdown(cx);
|
||||
this.state.close(None);
|
||||
Poll::Ready(())
|
||||
}
|
||||
|
@ -619,11 +606,8 @@ mod unixstream {
|
|||
match st {
|
||||
Shutdown::None => {
|
||||
// flush write buffer
|
||||
match flush_io(
|
||||
&mut *this.io.borrow_mut(),
|
||||
&this.state,
|
||||
cx,
|
||||
) {
|
||||
match flush_io(&mut *this.io.borrow_mut(), &this.state, cx)
|
||||
{
|
||||
Poll::Ready(true) => {
|
||||
*st = Shutdown::Flushed;
|
||||
continue;
|
||||
|
@ -639,15 +623,16 @@ mod unixstream {
|
|||
}
|
||||
Shutdown::Flushed => {
|
||||
// shutdown WRITE side
|
||||
match Pin::new(&mut *this.io.borrow_mut())
|
||||
.poll_shutdown(cx)
|
||||
match Pin::new(&mut *this.io.borrow_mut()).poll_shutdown(cx)
|
||||
{
|
||||
Poll::Ready(Ok(_)) => {
|
||||
*st = Shutdown::Stopping;
|
||||
continue;
|
||||
}
|
||||
Poll::Ready(Err(e)) => {
|
||||
log::trace!("write task is closed with err during shutdown");
|
||||
log::trace!(
|
||||
"write task is closed with err during shutdown"
|
||||
);
|
||||
this.state.close(Some(e));
|
||||
return Poll::Ready(());
|
||||
}
|
||||
|
@ -660,8 +645,7 @@ mod unixstream {
|
|||
let mut io = this.io.borrow_mut();
|
||||
loop {
|
||||
let mut read_buf = ReadBuf::new(&mut buf);
|
||||
match Pin::new(&mut *io).poll_read(cx, &mut read_buf)
|
||||
{
|
||||
match Pin::new(&mut *io).poll_read(cx, &mut read_buf) {
|
||||
Poll::Ready(Err(_)) | Poll::Ready(Ok(_))
|
||||
if read_buf.filled().is_empty() =>
|
||||
{
|
||||
|
|
|
@ -6,20 +6,20 @@ use ntex_util::{future::Ready, ready};
|
|||
use super::{Filter, FilterFactory, Io, IoBoxed};
|
||||
|
||||
/// Service that converts any Io<F> stream to IoBoxed stream
|
||||
pub fn seal<F, S>(
|
||||
pub fn seal<F, S, C>(
|
||||
srv: S,
|
||||
) -> impl ServiceFactory<
|
||||
Io<F>,
|
||||
Config = S::Config,
|
||||
C,
|
||||
Response = S::Response,
|
||||
Error = S::Error,
|
||||
InitError = S::InitError,
|
||||
>
|
||||
where
|
||||
F: Filter + 'static,
|
||||
S: ServiceFactory<IoBoxed>,
|
||||
S: ServiceFactory<IoBoxed, C>,
|
||||
{
|
||||
fn_factory_with_config(move |cfg: S::Config| {
|
||||
fn_factory_with_config(move |cfg: C| {
|
||||
let fut = srv.new_service(cfg);
|
||||
async move {
|
||||
let srv = fut.await?;
|
||||
|
@ -72,19 +72,18 @@ impl<S: Clone, R> Clone for SealedFactory<S, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S, R, F> ServiceFactory<R> for SealedFactory<S, R>
|
||||
impl<S, R, C, F> ServiceFactory<R, C> for SealedFactory<S, R>
|
||||
where
|
||||
F: Filter,
|
||||
S: ServiceFactory<R, Response = Io<F>>,
|
||||
S: ServiceFactory<R, C, Response = Io<F>>,
|
||||
{
|
||||
type Config = S::Config;
|
||||
type Response = IoBoxed;
|
||||
type Error = S::Error;
|
||||
type Service = SealedService<S::Service, R>;
|
||||
type InitError = S::InitError;
|
||||
type Future = SealedFactoryResponse<S, R>;
|
||||
type Future = SealedFactoryResponse<S, R, C>;
|
||||
|
||||
fn new_service(&self, cfg: S::Config) -> Self::Future {
|
||||
fn new_service(&self, cfg: C) -> Self::Future {
|
||||
SealedFactoryResponse {
|
||||
fut: self.inner.new_service(cfg),
|
||||
_t: PhantomData,
|
||||
|
@ -138,14 +137,14 @@ where
|
|||
}
|
||||
|
||||
pin_project_lite::pin_project! {
|
||||
pub struct SealedFactoryResponse<S: ServiceFactory<R>, R> {
|
||||
pub struct SealedFactoryResponse<S: ServiceFactory<R, C>, R, C> {
|
||||
#[pin]
|
||||
fut: S::Future,
|
||||
_t: PhantomData<R>
|
||||
_t: PhantomData<(R, C)>
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ServiceFactory<R>, R> Future for SealedFactoryResponse<S, R> {
|
||||
impl<S: ServiceFactory<R, C>, R, C> Future for SealedFactoryResponse<S, R, C> {
|
||||
type Output = Result<SealedService<S::Service, R>, S::InitError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
|
@ -165,9 +164,7 @@ pin_project_lite::pin_project! {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Service<R, Response = Io<F>>, R, F: Filter> Future
|
||||
for SealedServiceResponse<S, R>
|
||||
{
|
||||
impl<S: Service<R, Response = Io<F>>, R, F: Filter> Future for SealedServiceResponse<S, R> {
|
||||
type Output = Result<IoBoxed, S::Error>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
|
@ -180,12 +177,11 @@ pub struct FilterServiceFactory<T, F> {
|
|||
_t: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<T, F> ServiceFactory<Io<F>> for FilterServiceFactory<T, F>
|
||||
impl<T, F> ServiceFactory<Io<F>, ()> for FilterServiceFactory<T, F>
|
||||
where
|
||||
T: FilterFactory<F> + Clone,
|
||||
F: Filter,
|
||||
{
|
||||
type Config = ();
|
||||
type Response = Io<T::Filter>;
|
||||
type Error = T::Error;
|
||||
type Service = FilterService<T, F>;
|
||||
|
|
|
@ -17,8 +17,7 @@ async fn main() -> io::Result<()> {
|
|||
// load ssl keys
|
||||
let cert_file =
|
||||
&mut BufReader::new(File::open("../ntex-tls/examples/cert.pem").unwrap());
|
||||
let key_file =
|
||||
&mut BufReader::new(File::open("../ntex-tls/examples/key.pem").unwrap());
|
||||
let key_file = &mut BufReader::new(File::open("../ntex-tls/examples/key.pem").unwrap());
|
||||
let keys = PrivateKey(rsa_private_keys(key_file).unwrap().remove(0));
|
||||
let cert_chain = certs(cert_file)
|
||||
.unwrap()
|
||||
|
@ -36,8 +35,8 @@ async fn main() -> io::Result<()> {
|
|||
// start server
|
||||
server::ServerBuilder::new()
|
||||
.bind("basic", "127.0.0.1:8443", move |_| {
|
||||
pipeline_factory(filter_factory(TlsAcceptor::new(tls_config.clone())))
|
||||
.and_then(fn_service(|io: Io<_>| async move {
|
||||
pipeline_factory(filter_factory(TlsAcceptor::new(tls_config.clone()))).and_then(
|
||||
fn_service(|io: Io<_>| async move {
|
||||
println!("New client is connected");
|
||||
|
||||
io.send(
|
||||
|
@ -64,7 +63,8 @@ async fn main() -> io::Result<()> {
|
|||
}
|
||||
println!("Client is disconnected");
|
||||
Ok(())
|
||||
}))
|
||||
}),
|
||||
)
|
||||
})?
|
||||
.workers(1)
|
||||
.run()
|
||||
|
|
|
@ -25,8 +25,8 @@ async fn main() -> io::Result<()> {
|
|||
// start server
|
||||
server::ServerBuilder::new()
|
||||
.bind("basic", "127.0.0.1:8443", move |_| {
|
||||
pipeline_factory(filter_factory(SslAcceptor::new(acceptor.clone())))
|
||||
.and_then(fn_service(|io: Io<_>| async move {
|
||||
pipeline_factory(filter_factory(SslAcceptor::new(acceptor.clone()))).and_then(
|
||||
fn_service(|io: Io<_>| async move {
|
||||
println!("New client is connected");
|
||||
loop {
|
||||
match io.recv(&codec::BytesCodec).await {
|
||||
|
@ -45,7 +45,8 @@ async fn main() -> io::Result<()> {
|
|||
}
|
||||
println!("Client is disconnected");
|
||||
Ok(())
|
||||
}))
|
||||
}),
|
||||
)
|
||||
})?
|
||||
.workers(1)
|
||||
.run()
|
||||
|
|
|
@ -56,15 +56,15 @@ impl<F> Clone for Acceptor<F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<F: Filter> ServiceFactory<Io<F>> for Acceptor<F> {
|
||||
impl<F: Filter, C> ServiceFactory<Io<F>, C> for Acceptor<F> {
|
||||
type Response = Io<SslFilter<F>>;
|
||||
type Error = Box<dyn Error>;
|
||||
type Config = ();
|
||||
type Service = AcceptorService<F>;
|
||||
type InitError = ();
|
||||
type Future = Ready<Self::Service, Self::InitError>;
|
||||
|
||||
fn new_service(&self, _: ()) -> Self::Future {
|
||||
#[inline]
|
||||
fn new_service(&self, _: C) -> Self::Future {
|
||||
MAX_SSL_ACCEPT_COUNTER.with(|conns| {
|
||||
Ready::Ok(AcceptorService {
|
||||
acceptor: self.acceptor.clone(),
|
||||
|
|
|
@ -65,17 +65,16 @@ impl<F: Filter> io::Write for IoInner<F> {
|
|||
impl<F: Filter> Filter for SslFilter<F> {
|
||||
fn query(&self, id: any::TypeId) -> Option<Box<dyn any::Any>> {
|
||||
if id == any::TypeId::of::<types::HttpProtocol>() {
|
||||
let proto = if let Some(protos) =
|
||||
self.inner.borrow().ssl().selected_alpn_protocol()
|
||||
{
|
||||
if protos.windows(2).any(|window| window == b"h2") {
|
||||
types::HttpProtocol::Http2
|
||||
let proto =
|
||||
if let Some(protos) = self.inner.borrow().ssl().selected_alpn_protocol() {
|
||||
if protos.windows(2).any(|window| window == b"h2") {
|
||||
types::HttpProtocol::Http2
|
||||
} else {
|
||||
types::HttpProtocol::Http1
|
||||
}
|
||||
} else {
|
||||
types::HttpProtocol::Http1
|
||||
}
|
||||
} else {
|
||||
types::HttpProtocol::Http1
|
||||
};
|
||||
};
|
||||
Some(Box::new(proto))
|
||||
} else {
|
||||
self.inner.borrow().get_ref().inner.query(id)
|
||||
|
@ -160,12 +159,12 @@ impl<F: Filter> Filter for SslFilter<F> {
|
|||
let (hw, lw) = pool.read_params().unpack();
|
||||
|
||||
// get inner filter buffer
|
||||
let mut buf =
|
||||
if let Some(buf) = self.inner.borrow().get_ref().inner.get_read_buf() {
|
||||
buf
|
||||
} else {
|
||||
BytesMut::with_capacity_in(lw, pool)
|
||||
};
|
||||
let mut buf = if let Some(buf) = self.inner.borrow().get_ref().inner.get_read_buf()
|
||||
{
|
||||
buf
|
||||
} else {
|
||||
BytesMut::with_capacity_in(lw, pool)
|
||||
};
|
||||
|
||||
let mut new_bytes = 0;
|
||||
loop {
|
||||
|
@ -330,10 +329,8 @@ impl<F: Filter> FilterFactory<F> for SslConnector {
|
|||
})
|
||||
})?;
|
||||
|
||||
poll_fn(|cx| {
|
||||
handle_result(st.filter().inner.borrow_mut().connect(), &st, cx)
|
||||
})
|
||||
.await?;
|
||||
poll_fn(|cx| handle_result(st.filter().inner.borrow_mut().connect(), &st, cx))
|
||||
.await?;
|
||||
|
||||
Ok(st)
|
||||
})
|
||||
|
|
|
@ -51,16 +51,15 @@ impl<F> Clone for Acceptor<F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<F: Filter> ServiceFactory<Io<F>> for Acceptor<F> {
|
||||
impl<F: Filter, C> ServiceFactory<Io<F>, C> for Acceptor<F> {
|
||||
type Response = Io<TlsFilter<F>>;
|
||||
type Error = io::Error;
|
||||
type Service = AcceptorService<F>;
|
||||
|
||||
type Config = ();
|
||||
type InitError = ();
|
||||
type Future = Ready<Self::Service, Self::InitError>;
|
||||
|
||||
fn new_service(&self, _: ()) -> Self::Future {
|
||||
fn new_service(&self, _: C) -> Self::Future {
|
||||
MAX_SSL_ACCEPT_COUNTER.with(|conns| {
|
||||
Ready::Ok(AcceptorService {
|
||||
acceptor: self.inner.clone(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue