diff --git a/src/server/mod.rs b/src/server/mod.rs index 52594a41..b4f06f65 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -173,7 +173,7 @@ impl + 'static> Http { /// driven on the connection. /// /// This additionally skips the tokio-proto infrastructure internally. - pub fn no_proto(&self, io: I, service: S) -> Connection + pub fn no_proto(&self, io: I, service: S) -> Connection where S: Service, Error = ::Error> + 'static, Bd: Stream + 'static, I: AsyncRead + AsyncWrite + 'static, @@ -211,19 +211,73 @@ impl + 'static> Http { } } +use self::hyper_service::HyperService; +mod hyper_service { + use super::{Request, Response, Service, Stream}; + /// A "trait alias" for any type that implements `Service` with hyper's + /// Request, Response, and Error types, and a streaming body. + /// + /// There is an auto implementation inside hyper, so no one can actually + /// implement this trait. It simply exists to reduce the amount of generics + /// needed. + pub trait HyperService: Service + Sealed { + #[doc(hidden)] + type ResponseBody; + #[doc(hidden)] + type Sealed: Sealed2; + } + + pub trait Sealed {} + pub trait Sealed2 {} + + #[allow(missing_debug_implementations)] + pub struct Opaque { + _inner: (), + } + + impl Sealed2 for Opaque {} + + impl Sealed for S + where + S: Service< + Request=Request, + Response=Response, + Error=::Error, + >, + B: Stream, + B::Item: AsRef<[u8]>, + {} + + impl HyperService for S + where + S: Service< + Request=Request, + Response=Response, + Error=::Error, + >, + S: Sealed, + B: Stream, + B::Item: AsRef<[u8]>, + { + type ResponseBody = B; + type Sealed = Opaque; + } + +} /// A future binding a connection with a Service. /// /// Polling this future will drive HTTP forward. #[must_use = "futures do nothing unless polled"] -pub struct Connection -where S: Service, - B: Stream, - B::Item: AsRef<[u8]>, +pub struct Connection +where + S: HyperService, + S::ResponseBody: Stream, + ::Item: AsRef<[u8]>, { - conn: proto::dispatch::Dispatcher, B, I, B::Item, proto::ServerTransaction, proto::KA>, + conn: proto::dispatch::Dispatcher, S::ResponseBody, I, ::Item, proto::ServerTransaction, proto::KA>, } -impl Future for Connection +impl Future for Connection where S: Service, Error = ::Error> + 'static, I: AsyncRead + AsyncWrite + 'static, B: Stream + 'static, @@ -238,10 +292,11 @@ where S: Service, Error = ::Error> + ' } } -impl fmt::Debug for Connection -where S: Service, - B: Stream, - B::Item: AsRef<[u8]>, +impl fmt::Debug for Connection +where + S: HyperService, + S::ResponseBody: Stream, + ::Item: AsRef<[u8]>, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Connection")