mirror of
https://github.com/Noratrieb/icefun.git
synced 2026-01-16 05:35:02 +01:00
loop
This commit is contained in:
parent
1d163b6fef
commit
20031c3035
3 changed files with 33 additions and 97 deletions
|
|
@ -149,32 +149,6 @@ impl<'a, T> Drop for OptGuard<'a, T> {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg_server! {
|
|
||||||
impl < S, B > Server < S, B > where S : HttpService < B >, { pub (crate) fn
|
|
||||||
new(service : S) -> Server < S, B > { Server { in_flight : Box::pin(None), service, }
|
|
||||||
} pub (crate) fn into_service(self) -> S { self.service } } impl < S : HttpService <
|
|
||||||
B >, B > Unpin for Server < S, B > {} impl < S, Bs > Dispatch for Server < S, Body >
|
|
||||||
where S : HttpService < Body, ResBody = Bs >, S::Error : Into < Box < dyn StdError +
|
|
||||||
Send + Sync >>, Bs : HttpBody, { type PollItem = MessageHead < http::StatusCode >;
|
|
||||||
type PollBody = Bs; type PollError = S::Error; type RecvItem = RequestHead; fn
|
|
||||||
poll_msg(mut self : Pin <& mut Self >, cx : & mut task::Context <'_ >,) -> Poll <
|
|
||||||
Option < Result < (Self::PollItem, Self::PollBody), Self::PollError >>> { let mut
|
|
||||||
this = self.as_mut(); let ret = if let Some(ref mut fut) = this.in_flight.as_mut()
|
|
||||||
.as_pin_mut() { let resp = ready!(fut.as_mut().poll(cx) ?); let (parts, body) = resp
|
|
||||||
.into_parts(); let head = MessageHead { version : parts.version, subject : parts
|
|
||||||
.status, headers : parts.headers, extensions : parts.extensions, };
|
|
||||||
Poll::Ready(Some(Ok((head, body)))) } else {
|
|
||||||
unreachable!("poll_msg shouldn't be called if no inflight"); }; this.in_flight
|
|
||||||
.set(None); ret } fn recv_msg(& mut self, msg : crate ::Result < (Self::RecvItem,
|
|
||||||
Body) >) -> crate ::Result < () > { let (msg, body) = msg ?; let mut req =
|
|
||||||
Request::new(body); * req.method_mut() = msg.subject.0; * req.uri_mut() = msg.subject
|
|
||||||
.1; * req.headers_mut() = msg.headers; * req.version_mut() = msg.version; * req
|
|
||||||
.extensions_mut() = msg.extensions; let fut = self.service.call(req); self.in_flight
|
|
||||||
.set(Some(fut)); Ok(()) } fn poll_ready(& mut self, cx : & mut task::Context <'_ >)
|
|
||||||
-> Poll < Result < (), () >> { if self.in_flight.is_some() { Poll::Pending } else {
|
|
||||||
self.service.poll_ready(cx).map_err(| _e | { trace!("service closed"); }) } } fn
|
|
||||||
should_poll(& self) -> bool { self.in_flight.is_some() } }
|
|
||||||
}
|
|
||||||
cfg_client! {
|
cfg_client! {
|
||||||
impl < B > Client < B > { pub (crate) fn new(rx : ClientRx < B >) -> Client < B > {
|
impl < B > Client < B > { pub (crate) fn new(rx : ClientRx < B >) -> Client < B > {
|
||||||
Client { callback : None, rx, rx_closed : false, } } } impl < B > Dispatch for Client
|
Client { callback : None, rx, rx_closed : false, } } } impl < B > Dispatch for Client
|
||||||
|
|
|
||||||
|
|
@ -42,17 +42,15 @@
|
||||||
//! }
|
//! }
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
#[cfg(
|
#[cfg(feature = "http2")]
|
||||||
all(
|
use crate::common::io::Rewind;
|
||||||
any(feature = "http1", feature = "http2"),
|
#[cfg(all(
|
||||||
not(all(feature = "http1", feature = "http2"))
|
any(feature = "http1", feature = "http2"),
|
||||||
)
|
not(all(feature = "http1", feature = "http2"))
|
||||||
)]
|
))]
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "runtime"))]
|
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "runtime"))]
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
#[cfg(feature = "http2")]
|
|
||||||
use crate::common::io::Rewind;
|
|
||||||
cfg_feature! {
|
cfg_feature! {
|
||||||
#![any(feature = "http1", feature = "http2")] use std::error::Error as StdError; use
|
#![any(feature = "http1", feature = "http2")] use std::error::Error as StdError; use
|
||||||
std::fmt; use bytes::Bytes; use pin_project_lite::pin_project; use tokio::io:: {
|
std::fmt; use bytes::Bytes; use pin_project_lite::pin_project; use tokio::io:: {
|
||||||
|
|
@ -66,11 +64,6 @@ cfg_feature! {
|
||||||
#[cfg(feature = "tcp")]
|
#[cfg(feature = "tcp")]
|
||||||
pub use super::tcp::{AddrIncoming, AddrStream};
|
pub use super::tcp::{AddrIncoming, AddrStream};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg(any(feature = "http1", feature = "http2"))]
|
#[cfg(any(feature = "http1", feature = "http2"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
|
||||||
|
|
@ -81,7 +74,6 @@ pub(crate) struct Http<E = Exec> {
|
||||||
#[cfg(any(feature = "http1", feature = "http2"))]
|
#[cfg(any(feature = "http1", feature = "http2"))]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum ConnectionMode {
|
enum ConnectionMode {
|
||||||
|
|
||||||
#[cfg(feature = "http1")]
|
#[cfg(feature = "http1")]
|
||||||
H1Only,
|
H1Only,
|
||||||
|
|
||||||
|
|
@ -93,20 +85,13 @@ enum ConnectionMode {
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "http1", feature = "http2"))]
|
#[cfg(any(feature = "http1", feature = "http2"))]
|
||||||
pin_project! {
|
pin_project! {
|
||||||
#[doc = " A future binding a connection with a Service."] #[doc = ""] #[doc =
|
|
||||||
" Polling this future will drive HTTP forward."] #[must_use =
|
pub struct Connection < T, S, E = Exec > { pub (super) conn : Option < ProtoServer < T, S, S, E >>,
|
||||||
"futures do nothing unless polled"] #[cfg_attr(docsrs, doc(cfg(any(feature = "http1",
|
|
||||||
feature = "http2"))))] pub struct Connection < T, S, E = Exec > where S : HttpService
|
|
||||||
< Body >, { pub (super) conn : Option < ProtoServer < T, S::ResBody, S, E >>,
|
|
||||||
fallback : Fallback < E >, }
|
fallback : Fallback < E >, }
|
||||||
}
|
}
|
||||||
#[cfg(feature = "http1")]
|
#[cfg(feature = "http1")]
|
||||||
type Http1Dispatcher<T, B, S> = proto::h1::Dispatcher<
|
type Http1Dispatcher<T, B, S> =
|
||||||
proto::h1::dispatch::Server<S, Body>,
|
proto::h1::Dispatcher<proto::h1::dispatch::Server<S, Body>, B, T, proto::ServerTransaction>;
|
||||||
B,
|
|
||||||
T,
|
|
||||||
proto::ServerTransaction,
|
|
||||||
>;
|
|
||||||
#[cfg(all(not(feature = "http1"), feature = "http2"))]
|
#[cfg(all(not(feature = "http1"), feature = "http2"))]
|
||||||
type Http1Dispatcher<T, B, S> = (Never, PhantomData<(T, Box<Pin<B>>, Box<Pin<S>>)>);
|
type Http1Dispatcher<T, B, S> = (Never, PhantomData<(T, Box<Pin<B>>, Box<Pin<S>>)>);
|
||||||
#[cfg(feature = "http2")]
|
#[cfg(feature = "http2")]
|
||||||
|
|
@ -118,9 +103,11 @@ type Http2Server<T, B, S, E> = (
|
||||||
);
|
);
|
||||||
#[cfg(any(feature = "http1", feature = "http2"))]
|
#[cfg(any(feature = "http1", feature = "http2"))]
|
||||||
pin_project! {
|
pin_project! {
|
||||||
#[project = ProtoServerProj] pub (super) enum ProtoServer < T, B, S, E = Exec > where
|
#[project = ProtoServerProj] pub (super) enum ProtoServer < T, B, S, E = Exec > {
|
||||||
S : HttpService < Body >, B : HttpBody, { H1 { #[pin] h1 : Http1Dispatcher < T, B, S
|
|
||||||
>, }, H2 { #[pin] h2 : Http2Server < T, B, S, E >, }, }
|
H1 { #[pin] h1 : (T, B, S), }, H2 { #[pin] h2 : (T, B, S ,E), },
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(all(feature = "http1", feature = "http2"))]
|
#[cfg(all(feature = "http1", feature = "http2"))]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -128,12 +115,10 @@ enum Fallback<E> {
|
||||||
ToHttp2(proto::h2::server::Config, E),
|
ToHttp2(proto::h2::server::Config, E),
|
||||||
Http1Only,
|
Http1Only,
|
||||||
}
|
}
|
||||||
#[cfg(
|
#[cfg(all(
|
||||||
all(
|
any(feature = "http1", feature = "http2"),
|
||||||
any(feature = "http1", feature = "http2"),
|
not(all(feature = "http1", feature = "http2"))
|
||||||
not(all(feature = "http1", feature = "http2"))
|
))]
|
||||||
)
|
|
||||||
)]
|
|
||||||
type Fallback<E> = PhantomData<E>;
|
type Fallback<E> = PhantomData<E>;
|
||||||
#[cfg(any(feature = "http1", feature = "http2"))]
|
#[cfg(any(feature = "http1", feature = "http2"))]
|
||||||
impl Http {}
|
impl Http {}
|
||||||
|
|
@ -157,8 +142,7 @@ mod upgrades {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[must_use = "futures do nothing unless polled"]
|
#[must_use = "futures do nothing unless polled"]
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct UpgradeableConnection<T, S, E>
|
pub struct UpgradeableConnection<T, S, E> {
|
||||||
{
|
|
||||||
pub(super) inner: (T, S, E),
|
pub(super) inner: (T, S, E),
|
||||||
}
|
}
|
||||||
impl<I, B, S, E> UpgradeableConnection<I, S, E>
|
impl<I, B, S, E> UpgradeableConnection<I, S, E>
|
||||||
|
|
@ -169,7 +153,8 @@ mod upgrades {
|
||||||
B: HttpBody + 'static,
|
B: HttpBody + 'static,
|
||||||
B::Error: Into<Box<dyn StdError + Send + Sync>>,
|
B::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
E: ConnStreamExec<S::Future, B>,
|
E: ConnStreamExec<S::Future, B>,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
impl<I, B, S, E> Future for UpgradeableConnection<I, S, E>
|
impl<I, B, S, E> Future for UpgradeableConnection<I, S, E>
|
||||||
where
|
where
|
||||||
S: HttpService<Body, ResBody = B>,
|
S: HttpService<Body, ResBody = B>,
|
||||||
|
|
@ -180,10 +165,7 @@ mod upgrades {
|
||||||
E: ConnStreamExec<S::Future, B>,
|
E: ConnStreamExec<S::Future, B>,
|
||||||
{
|
{
|
||||||
type Output = crate::Result<()>;
|
type Output = crate::Result<()>;
|
||||||
fn poll(
|
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
) -> Poll<Self::Output> {
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,14 @@
|
||||||
use std::error::Error as StdError;
|
|
||||||
use crate::body::HttpBody;
|
use crate::body::HttpBody;
|
||||||
use crate::common::{task, Future, Poll};
|
use crate::common::Future;
|
||||||
use crate::{Request, Response};
|
use crate::{Request, Response};
|
||||||
|
use std::error::Error as StdError;
|
||||||
|
|
||||||
pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
|
pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
|
||||||
|
type ResBody;
|
||||||
|
|
||||||
type ResBody: HttpBody;
|
type Error;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type Error: Into<Box<dyn StdError + Send + Sync>>;
|
|
||||||
|
|
||||||
type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>;
|
type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>;
|
||||||
#[doc(hidden)]
|
|
||||||
fn poll_ready(
|
|
||||||
&mut self,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
) -> Poll<Result<(), Self::Error>>;
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
|
|
||||||
}
|
}
|
||||||
impl<T, B1, B2> HttpService<B1> for T
|
impl<T, B1, B2> HttpService<B1> for T
|
||||||
where
|
where
|
||||||
|
|
@ -31,21 +19,13 @@ where
|
||||||
type ResBody = B2;
|
type ResBody = B2;
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
type Future = T::Future;
|
type Future = T::Future;
|
||||||
fn poll_ready(
|
|
||||||
&mut self,
|
|
||||||
cx: &mut task::Context<'_>,
|
|
||||||
) -> Poll<Result<(), Self::Error>> {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
fn call(&mut self, req: Request<B1>) -> Self::Future {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl<T, B1, B2> sealed::Sealed<B1> for T
|
impl<T, B1, B2> sealed::Sealed<B1> for T
|
||||||
where
|
where
|
||||||
T: tower_service::Service<Request<B1>, Response = Response<B2>>,
|
T: tower_service::Service<Request<B1>, Response = Response<B2>>,
|
||||||
B2: HttpBody,
|
B2: HttpBody,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
mod sealed {
|
mod sealed {
|
||||||
pub trait Sealed<T> {}
|
pub trait Sealed<T> {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue