fix(lib): remove deprecated tokio-proto APIs
BREAKING CHANGE: Many of these APIs have been deprecated for a while, check the documentation for the recommended way to use hyper now.
This commit is contained in:
@@ -35,7 +35,6 @@ percent-encoding = "1.0"
|
||||
relay = "0.1"
|
||||
time = "0.1"
|
||||
tokio-core = "0.1.11"
|
||||
tokio-proto = { version = "0.1", optional = true }
|
||||
tokio-service = "0.1"
|
||||
tokio-io = "0.1"
|
||||
unicase = "2.0"
|
||||
@@ -47,8 +46,7 @@ spmc = "0.2"
|
||||
url = "1.0"
|
||||
|
||||
[features]
|
||||
default = ["server-proto"]
|
||||
default = []
|
||||
nightly = []
|
||||
raw_status = []
|
||||
compat = [ "http" ]
|
||||
server-proto = ["tokio-proto"]
|
||||
|
||||
@@ -533,12 +533,6 @@ impl<C, B> Config<C, B> {
|
||||
self.set_host = val;
|
||||
self
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(since="0.11.11", note="no_proto is always enabled")]
|
||||
pub fn no_proto(self) -> Config<C, B> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, B> Config<C, B>
|
||||
|
||||
15
src/lib.rs
15
src/lib.rs
@@ -33,8 +33,6 @@ extern crate relay;
|
||||
extern crate time;
|
||||
extern crate tokio_core as tokio;
|
||||
#[macro_use] extern crate tokio_io;
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
extern crate tokio_proto;
|
||||
extern crate tokio_service;
|
||||
extern crate unicase;
|
||||
|
||||
@@ -55,19 +53,6 @@ pub use version::HttpVersion;
|
||||
#[cfg(feature = "raw_status")]
|
||||
pub use proto::RawStatus;
|
||||
|
||||
macro_rules! feat_server_proto {
|
||||
($($i:item)*) => ($(
|
||||
#[cfg(feature = "server-proto")]
|
||||
#[deprecated(
|
||||
since="0.11.11",
|
||||
note="All usage of the tokio-proto crate is going away."
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[allow(deprecated)]
|
||||
$i
|
||||
)*)
|
||||
}
|
||||
|
||||
mod common;
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
|
||||
14
src/mock.rs
14
src/mock.rs
@@ -118,12 +118,11 @@ impl<T> AsyncIo<T> {
|
||||
self.park_tasks = enabled;
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
//TODO: fix proto::conn::tests to not use tokio-proto API,
|
||||
//and then this cfg flag go away
|
||||
/*
|
||||
pub fn flushed(&self) -> bool {
|
||||
self.flushed
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn blocked(&self) -> bool {
|
||||
self.blocked
|
||||
@@ -148,12 +147,11 @@ impl AsyncIo<MockCursor> {
|
||||
AsyncIo::new(MockCursor::wrap(buf.into()), bytes)
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
//TODO: fix proto::conn::tests to not use tokio-proto API,
|
||||
//and then this cfg flag go away
|
||||
pub fn new_eof() -> AsyncIo<MockCursor> {
|
||||
AsyncIo::new(MockCursor::wrap(Vec::new().into()), 1)
|
||||
/*
|
||||
pub fn new_eof() -> AsyncIo<Buf> {
|
||||
AsyncIo::new(Buf::wrap(Vec::new().into()), 1)
|
||||
}
|
||||
*/
|
||||
|
||||
fn close(&mut self) {
|
||||
self.block_in(1);
|
||||
|
||||
@@ -3,14 +3,10 @@ use std::fmt;
|
||||
use bytes::Bytes;
|
||||
use futures::{Async, AsyncSink, Future, Poll, Sink, StartSend, Stream};
|
||||
use futures::sync::{mpsc, oneshot};
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
use tokio_proto;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::Chunk;
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
pub type TokioBody = tokio_proto::streaming::Body<Chunk, ::Error>;
|
||||
pub type BodySender = mpsc::Sender<Result<Chunk, ::Error>>;
|
||||
|
||||
/// A `Stream` for `Chunk`s used in requests and responses.
|
||||
@@ -21,8 +17,6 @@ pub struct Body {
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Kind {
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
Tokio(TokioBody),
|
||||
Chan {
|
||||
close_tx: oneshot::Sender<bool>,
|
||||
rx: mpsc::Receiver<Result<Chunk, ::Error>>,
|
||||
@@ -77,8 +71,6 @@ impl Body {
|
||||
|
||||
fn poll_inner(&mut self) -> Poll<Option<Chunk>, ::Error> {
|
||||
match self.kind {
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
Kind::Tokio(ref mut rx) => rx.poll(),
|
||||
Kind::Chan { ref mut rx, .. } => match rx.poll().expect("mpsc cannot error") {
|
||||
Async::Ready(Some(Ok(chunk))) => Ok(Async::Ready(Some(chunk))),
|
||||
Async::Ready(Some(Err(err))) => Err(err),
|
||||
@@ -160,42 +152,6 @@ impl ChunkSender {
|
||||
}
|
||||
}
|
||||
|
||||
feat_server_proto! {
|
||||
impl From<Body> for tokio_proto::streaming::Body<Chunk, ::Error> {
|
||||
fn from(b: Body) -> tokio_proto::streaming::Body<Chunk, ::Error> {
|
||||
match b.kind {
|
||||
Kind::Tokio(b) => b,
|
||||
Kind::Chan { close_tx, rx } => {
|
||||
// disable knowing if the Rx gets dropped, since we cannot
|
||||
// pass this tx along.
|
||||
let _ = close_tx.send(false);
|
||||
rx.into()
|
||||
},
|
||||
Kind::Once(Some(chunk)) => TokioBody::from(chunk),
|
||||
Kind::Once(None) |
|
||||
Kind::Empty => TokioBody::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<tokio_proto::streaming::Body<Chunk, ::Error>> for Body {
|
||||
fn from(tokio_body: tokio_proto::streaming::Body<Chunk, ::Error>) -> Body {
|
||||
Body::new(Kind::Tokio(tokio_body))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<mpsc::Receiver<Result<Chunk, ::Error>>> for Body {
|
||||
#[inline]
|
||||
fn from(src: mpsc::Receiver<Result<Chunk, ::Error>>) -> Body {
|
||||
let (tx, _) = oneshot::channel();
|
||||
Body::new(Kind::Chan {
|
||||
close_tx: tx,
|
||||
rx: src,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Chunk> for Body {
|
||||
#[inline]
|
||||
fn from (chunk: Chunk) -> Body {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::fmt;
|
||||
//use std::mem;
|
||||
|
||||
use bytes::Bytes;
|
||||
|
||||
|
||||
@@ -4,12 +4,8 @@ use std::marker::PhantomData;
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::{Async, AsyncSink, Poll, StartSend};
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
use futures::{Sink, Stream};
|
||||
use futures::task::Task;
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
use tokio_proto::streaming::pipeline::{Frame, Transport};
|
||||
|
||||
use proto::{Chunk, Decode, Http1Transaction, MessageHead};
|
||||
use super::io::{Cursor, Buffered};
|
||||
@@ -81,70 +77,6 @@ where I: AsyncRead + AsyncWrite,
|
||||
self.io.into_inner()
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
fn poll_incoming(&mut self) -> Poll<Option<Frame<MessageHead<T::Incoming>, Chunk, ::Error>>, io::Error> {
|
||||
trace!("Conn::poll_incoming()");
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ParseEof;
|
||||
|
||||
impl fmt::Display for ParseEof {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(::std::error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::error::Error for ParseEof {
|
||||
fn description(&self) -> &str {
|
||||
"end of file reached before parsing could complete"
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
if self.is_read_closed() {
|
||||
trace!("Conn::poll when closed");
|
||||
return Ok(Async::Ready(None));
|
||||
} else if self.can_read_head() {
|
||||
return match self.read_head() {
|
||||
Ok(Async::Ready(Some((head, body)))) => {
|
||||
Ok(Async::Ready(Some(Frame::Message {
|
||||
message: head,
|
||||
body: body,
|
||||
})))
|
||||
},
|
||||
Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Err(::Error::Io(err)) => Err(err),
|
||||
Err(::Error::Incomplete) => {
|
||||
Err(io::Error::new(io::ErrorKind::UnexpectedEof, ParseEof))
|
||||
},
|
||||
Err(err) => Ok(Async::Ready(Some(Frame::Error {
|
||||
error: err,
|
||||
}))),
|
||||
};
|
||||
} else if self.can_read_body() {
|
||||
return self.read_body()
|
||||
.map(|async| async.map(|chunk| Some(Frame::Body {
|
||||
chunk: chunk
|
||||
})))
|
||||
.or_else(|err| {
|
||||
self.state.close_read();
|
||||
Ok(Async::Ready(Some(Frame::Error { error: err.into() })))
|
||||
});
|
||||
} else {
|
||||
trace!("poll when on keep-alive");
|
||||
if !T::should_read_first() {
|
||||
self.require_empty_read()?;
|
||||
if self.is_read_closed() {
|
||||
return Ok(Async::Ready(None));
|
||||
}
|
||||
}
|
||||
self.maybe_park_read();
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_read_closed(&self) -> bool {
|
||||
self.state.is_read_closed()
|
||||
}
|
||||
@@ -667,101 +599,6 @@ where I: AsyncRead + AsyncWrite,
|
||||
}
|
||||
}
|
||||
|
||||
// ==== tokio_proto impl ====
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
impl<I, B, T> Stream for Conn<I, B, T>
|
||||
where I: AsyncRead + AsyncWrite,
|
||||
B: AsRef<[u8]>,
|
||||
T: Http1Transaction,
|
||||
T::Outgoing: fmt::Debug {
|
||||
type Item = Frame<MessageHead<T::Incoming>, Chunk, ::Error>;
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||
self.poll_incoming().map_err(|err| {
|
||||
debug!("poll error: {}", err);
|
||||
err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
impl<I, B, T> Sink for Conn<I, B, T>
|
||||
where I: AsyncRead + AsyncWrite,
|
||||
B: AsRef<[u8]>,
|
||||
T: Http1Transaction,
|
||||
T::Outgoing: fmt::Debug {
|
||||
type SinkItem = Frame<MessageHead<T::Outgoing>, B, ::Error>;
|
||||
type SinkError = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn start_send(&mut self, frame: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
|
||||
trace!("Conn::start_send( frame={:?} )", DebugFrame(&frame));
|
||||
|
||||
let frame: Self::SinkItem = match frame {
|
||||
Frame::Message { message: head, body } => {
|
||||
if self.can_write_head() {
|
||||
self.write_head(head, body);
|
||||
return Ok(AsyncSink::Ready);
|
||||
} else {
|
||||
Frame::Message { message: head, body: body }
|
||||
}
|
||||
},
|
||||
Frame::Body { chunk } => {
|
||||
if self.can_write_body() {
|
||||
return self.write_body(chunk)
|
||||
.map(|async| {
|
||||
match async {
|
||||
AsyncSink::Ready => AsyncSink::Ready,
|
||||
AsyncSink::NotReady(chunk) => AsyncSink::NotReady(Frame::Body {
|
||||
chunk: chunk,
|
||||
})
|
||||
}
|
||||
});
|
||||
// This allows when chunk is `None`, or `Some([])`.
|
||||
} else if chunk.as_ref().map(|c| c.as_ref().len()).unwrap_or(0) == 0 {
|
||||
return Ok(AsyncSink::Ready);
|
||||
} else {
|
||||
Frame::Body { chunk: chunk }
|
||||
}
|
||||
},
|
||||
Frame::Error { error } => {
|
||||
debug!("received error, closing: {:?}", error);
|
||||
self.state.close();
|
||||
return Ok(AsyncSink::Ready);
|
||||
},
|
||||
};
|
||||
|
||||
warn!("writing illegal frame; state={:?}, frame={:?}", self.state.writing, DebugFrame(&frame));
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput, "illegal frame"))
|
||||
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
|
||||
trace!("Conn::poll_complete()");
|
||||
self.flush().map_err(|err| {
|
||||
debug!("error writing: {}", err);
|
||||
err
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn close(&mut self) -> Poll<(), Self::SinkError> {
|
||||
try_ready!(self.flush());
|
||||
self.shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
impl<I, B, T> Transport for Conn<I, B, T>
|
||||
where I: AsyncRead + AsyncWrite + 'static,
|
||||
B: AsRef<[u8]> + 'static,
|
||||
T: Http1Transaction + 'static,
|
||||
T::Outgoing: fmt::Debug {}
|
||||
|
||||
impl<I, B: AsRef<[u8]>, T> fmt::Debug for Conn<I, B, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Conn")
|
||||
@@ -958,46 +795,12 @@ enum Version {
|
||||
Http11,
|
||||
}
|
||||
|
||||
// The DebugFrame and DebugChunk are simple Debug implementations that allow
|
||||
// us to dump the frame into logs, without logging the entirety of the bytes.
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
struct DebugFrame<'a, T: fmt::Debug + 'a, B: AsRef<[u8]> + 'a>(&'a Frame<MessageHead<T>, B, ::Error>);
|
||||
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
impl<'a, T: fmt::Debug + 'a, B: AsRef<[u8]> + 'a> fmt::Debug for DebugFrame<'a, T, B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self.0 {
|
||||
Frame::Message { ref body, .. } => {
|
||||
f.debug_struct("Message")
|
||||
.field("body", body)
|
||||
.finish()
|
||||
},
|
||||
Frame::Body { chunk: Some(ref chunk) } => {
|
||||
f.debug_struct("Body")
|
||||
.field("bytes", &chunk.as_ref().len())
|
||||
.finish()
|
||||
},
|
||||
Frame::Body { chunk: None } => {
|
||||
f.debug_struct("Body")
|
||||
.field("bytes", &None::<()>)
|
||||
.finish()
|
||||
},
|
||||
Frame::Error { ref error } => {
|
||||
f.debug_struct("Error")
|
||||
.field("error", error)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
//TODO: rewrite these using dispatch instead of tokio-proto API
|
||||
//TODO: rewrite these using dispatch
|
||||
mod tests {
|
||||
/*
|
||||
use futures::{Async, Future, Stream, Sink};
|
||||
use futures::future;
|
||||
use tokio_proto::streaming::pipeline::Frame;
|
||||
|
||||
use proto::{self, ClientTransaction, MessageHead, ServerTransaction};
|
||||
use super::super::Encoder;
|
||||
@@ -1326,4 +1129,5 @@ mod tests {
|
||||
assert!(conn.start_send(Frame::Body { chunk: Some(Vec::new().into()) }).unwrap().is_ready());
|
||||
conn.start_send(Frame::Body { chunk: Some(vec![b'a'].into()) }).unwrap_err();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ use version::HttpVersion;
|
||||
use version::HttpVersion::{Http10, Http11};
|
||||
|
||||
pub use self::body::Body;
|
||||
#[cfg(feature = "tokio-proto")]
|
||||
pub use self::body::TokioBody;
|
||||
pub use self::chunk::Chunk;
|
||||
pub use self::h1::{dispatch, Conn};
|
||||
|
||||
|
||||
@@ -37,16 +37,6 @@ use self::hyper_service::HyperService;
|
||||
pub use proto::response::Response;
|
||||
pub use proto::request::Request;
|
||||
|
||||
feat_server_proto! {
|
||||
mod server_proto;
|
||||
pub use self::server_proto::{
|
||||
__ProtoRequest,
|
||||
__ProtoResponse,
|
||||
__ProtoTransport,
|
||||
__ProtoBindTransport,
|
||||
};
|
||||
}
|
||||
|
||||
pub use self::conn::Connection;
|
||||
pub use self::service::{const_service, service_fn};
|
||||
|
||||
@@ -349,12 +339,6 @@ impl<S, B> Server<S, B>
|
||||
self
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(since="0.11.11", note="no_proto is always enabled")]
|
||||
pub fn no_proto(&mut self) -> &mut Self {
|
||||
self
|
||||
}
|
||||
|
||||
/// Execute this server infinitely.
|
||||
///
|
||||
/// This method does not currently return, but it will return an error if
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
//! The tokio-proto `ServerProto` machinery.
|
||||
//!
|
||||
//! Not to be confused with `hyper::proto`.
|
||||
//!
|
||||
//! Will be deprecated soon.
|
||||
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[cfg(feature = "compat")]
|
||||
use http;
|
||||
use futures::future::{self, Map};
|
||||
use futures::{Future, Stream, Poll, Sink, StartSend, AsyncSink};
|
||||
use tokio::reactor::Handle;
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
use tokio_proto::BindServer;
|
||||
use tokio_proto::streaming::Message;
|
||||
use tokio_proto::streaming::pipeline::{Transport, Frame, ServerProto};
|
||||
use tokio_service::Service;
|
||||
|
||||
use {Request, Response};
|
||||
use proto::{self, request, response};
|
||||
#[cfg(feature = "compat")]
|
||||
use proto::Body;
|
||||
#[cfg(feature = "compat")]
|
||||
use super::compat;
|
||||
use super::Http;
|
||||
|
||||
impl<B: AsRef<[u8]> + 'static> Http<B> {
|
||||
/// Use this `Http` instance to create a new server task which handles the
|
||||
/// connection `io` provided.
|
||||
///
|
||||
/// # Deprecated
|
||||
///
|
||||
/// This method is deprecated. If seeking a replacement, consider
|
||||
/// `Http::serve_connection`.
|
||||
pub fn bind_connection<S, I, Bd>(&self,
|
||||
handle: &Handle,
|
||||
io: I,
|
||||
remote_addr: SocketAddr,
|
||||
service: S)
|
||||
where S: Service<Request = Request, Response = Response<Bd>, Error = ::Error> + 'static,
|
||||
Bd: Stream<Item=B, Error=::Error> + 'static,
|
||||
I: AsyncRead + AsyncWrite + 'static,
|
||||
{
|
||||
self.bind_server(handle, io, HttpService {
|
||||
inner: service,
|
||||
remote_addr: remote_addr,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/// Bind a `Service` using types from the `http` crate.
|
||||
///
|
||||
/// See `Http::bind_connection`.
|
||||
#[cfg(feature = "compat")]
|
||||
pub fn bind_connection_compat<S, I, Bd>(&self,
|
||||
handle: &Handle,
|
||||
io: I,
|
||||
remote_addr: SocketAddr,
|
||||
service: S)
|
||||
where S: Service<Request = http::Request<Body>, Response = http::Response<Bd>, Error = ::Error> + 'static,
|
||||
Bd: Stream<Item=B, Error=::Error> + 'static,
|
||||
I: AsyncRead + AsyncWrite + 'static,
|
||||
{
|
||||
self.bind_server(handle, io, HttpService {
|
||||
inner: compat::service(service),
|
||||
remote_addr: remote_addr,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct __ProtoRequest(proto::RequestHead);
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct __ProtoResponse(proto::MessageHead<::StatusCode>);
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct __ProtoTransport<T, B>(proto::Conn<T, B, proto::ServerTransaction>);
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct __ProtoBindTransport<T, B> {
|
||||
inner: future::FutureResult<proto::Conn<T, B, proto::ServerTransaction>, io::Error>,
|
||||
}
|
||||
|
||||
impl<T, B> ServerProto<T> for Http<B>
|
||||
where T: AsyncRead + AsyncWrite + 'static,
|
||||
B: AsRef<[u8]> + 'static,
|
||||
{
|
||||
type Request = __ProtoRequest;
|
||||
type RequestBody = proto::Chunk;
|
||||
type Response = __ProtoResponse;
|
||||
type ResponseBody = B;
|
||||
type Error = ::Error;
|
||||
type Transport = __ProtoTransport<T, B>;
|
||||
type BindTransport = __ProtoBindTransport<T, B>;
|
||||
|
||||
#[inline]
|
||||
fn bind_transport(&self, io: T) -> Self::BindTransport {
|
||||
let mut conn = proto::Conn::new(io);
|
||||
if !self.keep_alive {
|
||||
conn.disable_keep_alive();
|
||||
}
|
||||
conn.set_flush_pipeline(self.pipeline);
|
||||
if let Some(max) = self.max_buf_size {
|
||||
conn.set_max_buf_size(max);
|
||||
}
|
||||
__ProtoBindTransport {
|
||||
inner: future::ok(conn),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, B> Sink for __ProtoTransport<T, B>
|
||||
where T: AsyncRead + AsyncWrite + 'static,
|
||||
B: AsRef<[u8]> + 'static,
|
||||
{
|
||||
type SinkItem = Frame<__ProtoResponse, B, ::Error>;
|
||||
type SinkError = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn start_send(&mut self, item: Self::SinkItem)
|
||||
-> StartSend<Self::SinkItem, io::Error> {
|
||||
let item = match item {
|
||||
Frame::Message { message, body } => {
|
||||
Frame::Message { message: message.0, body: body }
|
||||
}
|
||||
Frame::Body { chunk } => Frame::Body { chunk: chunk },
|
||||
Frame::Error { error } => Frame::Error { error: error },
|
||||
};
|
||||
match try!(self.0.start_send(item)) {
|
||||
AsyncSink::Ready => Ok(AsyncSink::Ready),
|
||||
AsyncSink::NotReady(Frame::Message { message, body }) => {
|
||||
Ok(AsyncSink::NotReady(Frame::Message {
|
||||
message: __ProtoResponse(message),
|
||||
body: body,
|
||||
}))
|
||||
}
|
||||
AsyncSink::NotReady(Frame::Body { chunk }) => {
|
||||
Ok(AsyncSink::NotReady(Frame::Body { chunk: chunk }))
|
||||
}
|
||||
AsyncSink::NotReady(Frame::Error { error }) => {
|
||||
Ok(AsyncSink::NotReady(Frame::Error { error: error }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_complete(&mut self) -> Poll<(), io::Error> {
|
||||
self.0.poll_complete()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn close(&mut self) -> Poll<(), io::Error> {
|
||||
self.0.close()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, B> Stream for __ProtoTransport<T, B>
|
||||
where T: AsyncRead + AsyncWrite + 'static,
|
||||
B: AsRef<[u8]> + 'static,
|
||||
{
|
||||
type Item = Frame<__ProtoRequest, proto::Chunk, ::Error>;
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn poll(&mut self) -> Poll<Option<Self::Item>, io::Error> {
|
||||
let item = match try_ready!(self.0.poll()) {
|
||||
Some(item) => item,
|
||||
None => return Ok(None.into()),
|
||||
};
|
||||
let item = match item {
|
||||
Frame::Message { message, body } => {
|
||||
Frame::Message { message: __ProtoRequest(message), body: body }
|
||||
}
|
||||
Frame::Body { chunk } => Frame::Body { chunk: chunk },
|
||||
Frame::Error { error } => Frame::Error { error: error },
|
||||
};
|
||||
Ok(Some(item).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, B> Transport for __ProtoTransport<T, B>
|
||||
where T: AsyncRead + AsyncWrite + 'static,
|
||||
B: AsRef<[u8]> + 'static,
|
||||
{
|
||||
#[inline]
|
||||
fn tick(&mut self) {
|
||||
self.0.tick()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn cancel(&mut self) -> io::Result<()> {
|
||||
self.0.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, B> Future for __ProtoBindTransport<T, B>
|
||||
where T: AsyncRead + AsyncWrite + 'static,
|
||||
{
|
||||
type Item = __ProtoTransport<T, B>;
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn poll(&mut self) -> Poll<__ProtoTransport<T, B>, io::Error> {
|
||||
self.inner.poll().map(|a| a.map(__ProtoTransport))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Message<__ProtoRequest, proto::TokioBody>> for Request {
|
||||
#[inline]
|
||||
fn from(message: Message<__ProtoRequest, proto::TokioBody>) -> Request {
|
||||
let (head, body) = match message {
|
||||
Message::WithoutBody(head) => (head.0, None),
|
||||
Message::WithBody(head, body) => (head.0, Some(body.into())),
|
||||
};
|
||||
request::from_wire(None, head, body)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> Into<Message<__ProtoResponse, B>> for Response<B> {
|
||||
#[inline]
|
||||
fn into(self) -> Message<__ProtoResponse, B> {
|
||||
let (head, body) = response::split(self);
|
||||
if let Some(body) = body {
|
||||
Message::WithBody(__ProtoResponse(head), body.into())
|
||||
} else {
|
||||
Message::WithoutBody(__ProtoResponse(head))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct HttpService<T> {
|
||||
inner: T,
|
||||
remote_addr: SocketAddr,
|
||||
}
|
||||
|
||||
impl<T, B> Service for HttpService<T>
|
||||
where T: Service<Request=Request, Response=Response<B>, Error=::Error>,
|
||||
B: Stream<Error=::Error>,
|
||||
B::Item: AsRef<[u8]>,
|
||||
{
|
||||
type Request = Message<__ProtoRequest, proto::TokioBody>;
|
||||
type Response = Message<__ProtoResponse, B>;
|
||||
type Error = ::Error;
|
||||
type Future = Map<T::Future, fn(Response<B>) -> Message<__ProtoResponse, B>>;
|
||||
|
||||
#[inline]
|
||||
fn call(&self, message: Self::Request) -> Self::Future {
|
||||
let (head, body) = match message {
|
||||
Message::WithoutBody(head) => (head.0, None),
|
||||
Message::WithBody(head, body) => (head.0, Some(body.into())),
|
||||
};
|
||||
let req = request::from_wire(Some(self.remote_addr), head, body);
|
||||
self.inner.call(req).map(Into::into)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user