mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 07:53:00 +01:00
migrate to actix-service 0.2
This commit is contained in:
parent
76866f054f
commit
3269e35722
10
Cargo.toml
10
Cargo.toml
@ -37,12 +37,10 @@ session = ["cookie/secure"]
|
|||||||
ssl = ["openssl", "actix-connector/ssl"]
|
ssl = ["openssl", "actix-connector/ssl"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "0.1.6"
|
actix-service = "0.2.0"
|
||||||
actix-codec = "0.1.0"
|
actix-codec = "0.1.0"
|
||||||
# actix-connector = "0.1.0"
|
actix-connector = "0.2.0"
|
||||||
# actix-utils = "0.1.0"
|
actix-utils = "0.2.0"
|
||||||
actix-connector = { git = "https://github.com/actix/actix-net.git" }
|
|
||||||
actix-utils = { git = "https://github.com/actix/actix-net.git" }
|
|
||||||
|
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
@ -78,7 +76,7 @@ openssl = { version="0.10", optional = true }
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "0.1.0"
|
actix-rt = "0.1.0"
|
||||||
actix-web = "0.7"
|
actix-web = "0.7"
|
||||||
actix-server = "0.1"
|
actix-server = "0.2"
|
||||||
actix-http-test = { path="test-server" }
|
actix-http-test = { path="test-server" }
|
||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
@ -135,8 +135,11 @@ impl Connector {
|
|||||||
/// Finish configuration process and create connector service.
|
/// Finish configuration process and create connector service.
|
||||||
pub fn service(
|
pub fn service(
|
||||||
self,
|
self,
|
||||||
) -> impl Service<Connect, Response = impl Connection, Error = ConnectorError> + Clone
|
) -> impl Service<
|
||||||
{
|
Request = Connect,
|
||||||
|
Response = impl Connection,
|
||||||
|
Error = ConnectorError,
|
||||||
|
> + Clone {
|
||||||
#[cfg(not(feature = "ssl"))]
|
#[cfg(not(feature = "ssl"))]
|
||||||
{
|
{
|
||||||
let connector = TimeoutService::new(
|
let connector = TimeoutService::new(
|
||||||
@ -237,7 +240,11 @@ mod connect_impl {
|
|||||||
pub(crate) struct InnerConnector<T, Io>
|
pub(crate) struct InnerConnector<T, Io>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
Io: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
pub(crate) tcp_pool: ConnectionPool<T, Io>,
|
pub(crate) tcp_pool: ConnectionPool<T, Io>,
|
||||||
}
|
}
|
||||||
@ -245,8 +252,11 @@ mod connect_impl {
|
|||||||
impl<T, Io> Clone for InnerConnector<T, Io>
|
impl<T, Io> Clone for InnerConnector<T, Io>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
Io: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io, Protocol), Error = ConnectorError>
|
T: Service<
|
||||||
+ Clone,
|
Request = Connect,
|
||||||
|
Response = (Connect, Io, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
> + Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
InnerConnector {
|
InnerConnector {
|
||||||
@ -255,15 +265,20 @@ mod connect_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Io> Service<Connect> for InnerConnector<T, Io>
|
impl<T, Io> Service for InnerConnector<T, Io>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
Io: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
|
type Request = Connect;
|
||||||
type Response = IoConnection<Io>;
|
type Response = IoConnection<Io>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
<ConnectionPool<T, Io> as Service<Connect>>::Future,
|
<ConnectionPool<T, Io> as Service>::Future,
|
||||||
FutureResult<IoConnection<Io>, ConnectorError>,
|
FutureResult<IoConnection<Io>, ConnectorError>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@ -298,12 +313,12 @@ mod connect_impl {
|
|||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
T1: Service<
|
T1: Service<
|
||||||
Connect,
|
Request = Connect,
|
||||||
Response = (Connect, Io1, Protocol),
|
Response = (Connect, Io1, Protocol),
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
>,
|
>,
|
||||||
T2: Service<
|
T2: Service<
|
||||||
Connect,
|
Request = Connect,
|
||||||
Response = (Connect, Io2, Protocol),
|
Response = (Connect, Io2, Protocol),
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
>,
|
>,
|
||||||
@ -317,12 +332,12 @@ mod connect_impl {
|
|||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
T1: Service<
|
T1: Service<
|
||||||
Connect,
|
Request = Connect,
|
||||||
Response = (Connect, Io1, Protocol),
|
Response = (Connect, Io1, Protocol),
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
> + Clone,
|
> + Clone,
|
||||||
T2: Service<
|
T2: Service<
|
||||||
Connect,
|
Request = Connect,
|
||||||
Response = (Connect, Io2, Protocol),
|
Response = (Connect, Io2, Protocol),
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
> + Clone,
|
> + Clone,
|
||||||
@ -335,21 +350,22 @@ mod connect_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T1, T2, Io1, Io2> Service<Connect> for InnerConnector<T1, T2, Io1, Io2>
|
impl<T1, T2, Io1, Io2> Service for InnerConnector<T1, T2, Io1, Io2>
|
||||||
where
|
where
|
||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
T1: Service<
|
T1: Service<
|
||||||
Connect,
|
Request = Connect,
|
||||||
Response = (Connect, Io1, Protocol),
|
Response = (Connect, Io1, Protocol),
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
>,
|
>,
|
||||||
T2: Service<
|
T2: Service<
|
||||||
Connect,
|
Request = Connect,
|
||||||
Response = (Connect, Io2, Protocol),
|
Response = (Connect, Io2, Protocol),
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
type Request = Connect;
|
||||||
type Response = EitherConnection<Io1, Io2>;
|
type Response = EitherConnection<Io1, Io2>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
@ -384,15 +400,23 @@ mod connect_impl {
|
|||||||
pub(crate) struct InnerConnectorResponseA<T, Io1, Io2>
|
pub(crate) struct InnerConnectorResponseA<T, Io1, Io2>
|
||||||
where
|
where
|
||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io1, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io1, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
fut: <ConnectionPool<T, Io1> as Service<Connect>>::Future,
|
fut: <ConnectionPool<T, Io1> as Service>::Future,
|
||||||
_t: PhantomData<Io2>,
|
_t: PhantomData<Io2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Io1, Io2> Future for InnerConnectorResponseA<T, Io1, Io2>
|
impl<T, Io1, Io2> Future for InnerConnectorResponseA<T, Io1, Io2>
|
||||||
where
|
where
|
||||||
T: Service<Connect, Response = (Connect, Io1, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io1, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
{
|
{
|
||||||
@ -410,15 +434,23 @@ mod connect_impl {
|
|||||||
pub(crate) struct InnerConnectorResponseB<T, Io1, Io2>
|
pub(crate) struct InnerConnectorResponseB<T, Io1, Io2>
|
||||||
where
|
where
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io2, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io2, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
fut: <ConnectionPool<T, Io2> as Service<Connect>>::Future,
|
fut: <ConnectionPool<T, Io2> as Service>::Future,
|
||||||
_t: PhantomData<Io1>,
|
_t: PhantomData<Io1>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Io1, Io2> Future for InnerConnectorResponseB<T, Io1, Io2>
|
impl<T, Io1, Io2> Future for InnerConnectorResponseB<T, Io1, Io2>
|
||||||
where
|
where
|
||||||
T: Service<Connect, Response = (Connect, Io2, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io2, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,11 @@ pub(crate) struct ConnectionPool<T, Io: AsyncRead + AsyncWrite + 'static>(
|
|||||||
impl<T, Io> ConnectionPool<T, Io>
|
impl<T, Io> ConnectionPool<T, Io>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
Io: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
connector: T,
|
connector: T,
|
||||||
@ -84,11 +88,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Io> Service<Connect> for ConnectionPool<T, Io>
|
impl<T, Io> Service for ConnectionPool<T, Io>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
Io: AsyncRead + AsyncWrite + 'static,
|
||||||
T: Service<Connect, Response = (Connect, Io, Protocol), Error = ConnectorError>,
|
T: Service<
|
||||||
|
Request = Connect,
|
||||||
|
Response = (Connect, Io, Protocol),
|
||||||
|
Error = ConnectorError,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
|
type Request = Connect;
|
||||||
type Response = IoConnection<Io>;
|
type Response = IoConnection<Io>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
|
@ -176,7 +176,7 @@ where
|
|||||||
) -> impl Future<Item = ClientResponse, Error = SendRequestError>
|
) -> impl Future<Item = ClientResponse, Error = SendRequestError>
|
||||||
where
|
where
|
||||||
B: 'static,
|
B: 'static,
|
||||||
T: Service<Connect, Response = I, Error = ConnectorError>,
|
T: Service<Request = Connect, Response = I, Error = ConnectorError>,
|
||||||
I: Connection,
|
I: Connection,
|
||||||
{
|
{
|
||||||
let Self { head, body } = self;
|
let Self { head, body } = self;
|
||||||
|
@ -35,14 +35,14 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Dispatcher for HTTP/1.1 protocol
|
/// Dispatcher for HTTP/1.1 protocol
|
||||||
pub struct Dispatcher<T, S: Service<Request>, B: MessageBody>
|
pub struct Dispatcher<T, S: Service, B: MessageBody>
|
||||||
where
|
where
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
{
|
{
|
||||||
inner: Option<InnerDispatcher<T, S, B>>,
|
inner: Option<InnerDispatcher<T, S, B>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InnerDispatcher<T, S: Service<Request>, B: MessageBody>
|
struct InnerDispatcher<T, S: Service, B: MessageBody>
|
||||||
where
|
where
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
{
|
{
|
||||||
@ -66,13 +66,13 @@ enum DispatcherMessage {
|
|||||||
Error(Response<()>),
|
Error(Response<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State<S: Service<Request>, B: MessageBody> {
|
enum State<S: Service, B: MessageBody> {
|
||||||
None,
|
None,
|
||||||
ServiceCall(S::Future),
|
ServiceCall(S::Future),
|
||||||
SendPayload(ResponseBody<B>),
|
SendPayload(ResponseBody<B>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Service<Request>, B: MessageBody> State<S, B> {
|
impl<S: Service, B: MessageBody> State<S, B> {
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
if let State::None = self {
|
if let State::None = self {
|
||||||
true
|
true
|
||||||
@ -85,7 +85,7 @@ impl<S: Service<Request>, B: MessageBody> State<S, B> {
|
|||||||
impl<T, S, B> Dispatcher<T, S, B>
|
impl<T, S, B> Dispatcher<T, S, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: Service<Request, Response = Response<B>>,
|
S: Service<Request = Request, Response = Response<B>>,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
@ -139,7 +139,7 @@ where
|
|||||||
impl<T, S, B> InnerDispatcher<T, S, B>
|
impl<T, S, B> InnerDispatcher<T, S, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: Service<Request, Response = Response<B>>,
|
S: Service<Request = Request, Response = Response<B>>,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
@ -459,7 +459,7 @@ where
|
|||||||
impl<T, S, B> Future for Dispatcher<T, S, B>
|
impl<T, S, B> Future for Dispatcher<T, S, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: Service<Request, Response = Response<B>>,
|
S: Service<Request = Request, Response = Response<B>>,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
|
@ -27,13 +27,13 @@ pub struct H1Service<T, S, B> {
|
|||||||
|
|
||||||
impl<T, S, B> H1Service<T, S, B>
|
impl<T, S, B> H1Service<T, S, B>
|
||||||
where
|
where
|
||||||
S: NewService<Request, Response = Response<B>> + Clone,
|
S: NewService<Request = Request, Response = Response<B>> + Clone,
|
||||||
S::Service: Clone,
|
S::Service: Clone,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
/// Create new `HttpService` instance.
|
/// Create new `HttpService` instance.
|
||||||
pub fn new<F: IntoNewService<S, Request>>(service: F) -> Self {
|
pub fn new<F: IntoNewService<S>>(service: F) -> Self {
|
||||||
let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0);
|
let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0);
|
||||||
|
|
||||||
H1Service {
|
H1Service {
|
||||||
@ -49,14 +49,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> NewService<T> for H1Service<T, S, B>
|
impl<T, S, B> NewService for H1Service<T, S, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: NewService<Request, Response = Response<B>> + Clone,
|
S: NewService<Request = Request, Response = Response<B>> + Clone,
|
||||||
S::Service: Clone,
|
S::Service: Clone,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
|
type Request = T;
|
||||||
type Response = H1ServiceResult<T>;
|
type Response = H1ServiceResult<T>;
|
||||||
type Error = DispatchError<S::Error>;
|
type Error = DispatchError<S::Error>;
|
||||||
type InitError = S::InitError;
|
type InitError = S::InitError;
|
||||||
@ -88,7 +89,7 @@ pub struct H1ServiceBuilder<T, S> {
|
|||||||
|
|
||||||
impl<T, S> H1ServiceBuilder<T, S>
|
impl<T, S> H1ServiceBuilder<T, S>
|
||||||
where
|
where
|
||||||
S: NewService<Request>,
|
S: NewService<Request = Request>,
|
||||||
S::Service: Clone,
|
S::Service: Clone,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
{
|
{
|
||||||
@ -187,7 +188,7 @@ where
|
|||||||
pub fn finish<F, B>(self, service: F) -> H1Service<T, S, B>
|
pub fn finish<F, B>(self, service: F) -> H1Service<T, S, B>
|
||||||
where
|
where
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
F: IntoNewService<S, Request>,
|
F: IntoNewService<S>,
|
||||||
{
|
{
|
||||||
let cfg = ServiceConfig::new(
|
let cfg = ServiceConfig::new(
|
||||||
self.keep_alive,
|
self.keep_alive,
|
||||||
@ -203,7 +204,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct H1ServiceResponse<T, S: NewService<Request>, B> {
|
pub struct H1ServiceResponse<T, S: NewService, B> {
|
||||||
fut: S::Future,
|
fut: S::Future,
|
||||||
cfg: Option<ServiceConfig>,
|
cfg: Option<ServiceConfig>,
|
||||||
_t: PhantomData<(T, B)>,
|
_t: PhantomData<(T, B)>,
|
||||||
@ -212,7 +213,7 @@ pub struct H1ServiceResponse<T, S: NewService<Request>, B> {
|
|||||||
impl<T, S, B> Future for H1ServiceResponse<T, S, B>
|
impl<T, S, B> Future for H1ServiceResponse<T, S, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: NewService<Request, Response = Response<B>>,
|
S: NewService<Request = Request, Response = Response<B>>,
|
||||||
S::Service: Clone,
|
S::Service: Clone,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
@ -238,7 +239,7 @@ pub struct H1ServiceHandler<T, S, B> {
|
|||||||
|
|
||||||
impl<T, S, B> H1ServiceHandler<T, S, B>
|
impl<T, S, B> H1ServiceHandler<T, S, B>
|
||||||
where
|
where
|
||||||
S: Service<Request, Response = Response<B>> + Clone,
|
S: Service<Request = Request, Response = Response<B>> + Clone,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
@ -251,13 +252,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> Service<T> for H1ServiceHandler<T, S, B>
|
impl<T, S, B> Service for H1ServiceHandler<T, S, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: Service<Request, Response = Response<B>> + Clone,
|
S: Service<Request = Request, Response = Response<B>> + Clone,
|
||||||
S::Error: Debug,
|
S::Error: Debug,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
|
type Request = T;
|
||||||
type Response = H1ServiceResult<T>;
|
type Response = H1ServiceResult<T>;
|
||||||
type Error = DispatchError<S::Error>;
|
type Error = DispatchError<S::Error>;
|
||||||
type Future = Dispatcher<T, S, B>;
|
type Future = Dispatcher<T, S, B>;
|
||||||
@ -291,10 +293,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> NewService<T> for OneRequest<T>
|
impl<T> NewService for OneRequest<T>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
|
type Request = T;
|
||||||
type Response = (Request, Framed<T, Codec>);
|
type Response = (Request, Framed<T, Codec>);
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
@ -316,10 +319,11 @@ pub struct OneRequestService<T> {
|
|||||||
_t: PhantomData<T>,
|
_t: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Service<T> for OneRequestService<T>
|
impl<T> Service for OneRequestService<T>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
|
type Request = T;
|
||||||
type Response = (Request, Framed<T, Codec>);
|
type Response = (Request, Framed<T, Codec>);
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
type Future = OneRequestServiceResponse<T>;
|
type Future = OneRequestServiceResponse<T>;
|
||||||
|
20
src/h2/mod.rs
Normal file
20
src/h2/mod.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
mod service;
|
||||||
|
|
||||||
|
/// H1 service response type
|
||||||
|
pub enum H2ServiceResult<T> {
|
||||||
|
Disconnected,
|
||||||
|
Shutdown(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: fmt::Debug> fmt::Debug for H2ServiceResult<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
H2ServiceResult::Disconnected => write!(f, "H2ServiceResult::Disconnected"),
|
||||||
|
H2ServiceResult::Shutdown(ref v) => {
|
||||||
|
write!(f, "H2ServiceResult::Shutdown({:?})", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
310
src/h2/service.rs
Normal file
310
src/h2/service.rs
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
use std::fmt::Debug;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::net;
|
||||||
|
|
||||||
|
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||||
|
use actix_service::{IntoNewService, NewService, Service};
|
||||||
|
use bytes::Bytes;
|
||||||
|
use futures::future::{ok, FutureResult};
|
||||||
|
use futures::{try_ready, Async, Future, Poll, Stream};
|
||||||
|
use h2::server::{self, Connection, Handshake};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
|
use crate::body::MessageBody;
|
||||||
|
use crate::config::{KeepAlive, ServiceConfig};
|
||||||
|
use crate::error::{DispatchError, ParseError};
|
||||||
|
use crate::request::Request;
|
||||||
|
use crate::response::Response;
|
||||||
|
|
||||||
|
// use super::dispatcher::Dispatcher;
|
||||||
|
use super::H2ServiceResult;
|
||||||
|
|
||||||
|
/// `NewService` implementation for HTTP2 transport
|
||||||
|
pub struct H2Service<T, S, B> {
|
||||||
|
srv: S,
|
||||||
|
cfg: ServiceConfig,
|
||||||
|
_t: PhantomData<(T, B)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> H2Service<T, S, B>
|
||||||
|
where
|
||||||
|
S: NewService<Request = Request, Response = Response<B>> + Clone,
|
||||||
|
S::Service: Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
/// Create new `HttpService` instance.
|
||||||
|
pub fn new<F: IntoNewService<S>>(service: F) -> Self {
|
||||||
|
let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0);
|
||||||
|
|
||||||
|
H2Service {
|
||||||
|
cfg,
|
||||||
|
srv: service.into_new_service(),
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create builder for `HttpService` instance.
|
||||||
|
pub fn build() -> H2ServiceBuilder<T, S> {
|
||||||
|
H2ServiceBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> NewService for H2Service<T, S, B>
|
||||||
|
where
|
||||||
|
T: AsyncRead + AsyncWrite,
|
||||||
|
S: NewService<Request = Request, Response = Response<B>> + Clone,
|
||||||
|
S::Service: Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
type Request = T;
|
||||||
|
type Response = H2ServiceResult<T>;
|
||||||
|
type Error = (); //DispatchError<S::Error>;
|
||||||
|
type InitError = S::InitError;
|
||||||
|
type Service = H2ServiceHandler<T, S::Service, B>;
|
||||||
|
type Future = H2ServiceResponse<T, S, B>;
|
||||||
|
|
||||||
|
fn new_service(&self) -> Self::Future {
|
||||||
|
H2ServiceResponse {
|
||||||
|
fut: self.srv.new_service(),
|
||||||
|
cfg: Some(self.cfg.clone()),
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A http/2 new service builder
|
||||||
|
///
|
||||||
|
/// This type can be used to construct an instance of `ServiceConfig` through a
|
||||||
|
/// builder-like pattern.
|
||||||
|
pub struct H2ServiceBuilder<T, S> {
|
||||||
|
keep_alive: KeepAlive,
|
||||||
|
client_timeout: u64,
|
||||||
|
client_disconnect: u64,
|
||||||
|
host: String,
|
||||||
|
addr: net::SocketAddr,
|
||||||
|
secure: bool,
|
||||||
|
_t: PhantomData<(T, S)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S> H2ServiceBuilder<T, S>
|
||||||
|
where
|
||||||
|
S: NewService<Request = Request>,
|
||||||
|
S::Service: Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
{
|
||||||
|
/// Create instance of `H2ServiceBuilder`
|
||||||
|
pub fn new() -> H2ServiceBuilder<T, S> {
|
||||||
|
H2ServiceBuilder {
|
||||||
|
keep_alive: KeepAlive::Timeout(5),
|
||||||
|
client_timeout: 5000,
|
||||||
|
client_disconnect: 0,
|
||||||
|
secure: false,
|
||||||
|
host: "localhost".to_owned(),
|
||||||
|
addr: "127.0.0.1:8080".parse().unwrap(),
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable secure flag for current server.
|
||||||
|
/// This flags also enables `client disconnect timeout`.
|
||||||
|
///
|
||||||
|
/// By default this flag is set to false.
|
||||||
|
pub fn secure(mut self) -> Self {
|
||||||
|
self.secure = true;
|
||||||
|
if self.client_disconnect == 0 {
|
||||||
|
self.client_disconnect = 3000;
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server keep-alive setting.
|
||||||
|
///
|
||||||
|
/// By default keep alive is set to a 5 seconds.
|
||||||
|
pub fn keep_alive<U: Into<KeepAlive>>(mut self, val: U) -> Self {
|
||||||
|
self.keep_alive = val.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server client timeout in milliseconds for first request.
|
||||||
|
///
|
||||||
|
/// Defines a timeout for reading client request header. If a client does not transmit
|
||||||
|
/// the entire set headers within this time, the request is terminated with
|
||||||
|
/// the 408 (Request Time-out) error.
|
||||||
|
///
|
||||||
|
/// To disable timeout set value to 0.
|
||||||
|
///
|
||||||
|
/// By default client timeout is set to 5000 milliseconds.
|
||||||
|
pub fn client_timeout(mut self, val: u64) -> Self {
|
||||||
|
self.client_timeout = val;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server connection disconnect timeout in milliseconds.
|
||||||
|
///
|
||||||
|
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
|
||||||
|
/// within this time, the request get dropped. This timeout affects secure connections.
|
||||||
|
///
|
||||||
|
/// To disable timeout set value to 0.
|
||||||
|
///
|
||||||
|
/// By default disconnect timeout is set to 3000 milliseconds.
|
||||||
|
pub fn client_disconnect(mut self, val: u64) -> Self {
|
||||||
|
self.client_disconnect = val;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server host name.
|
||||||
|
///
|
||||||
|
/// Host name is used by application router aa a hostname for url
|
||||||
|
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
||||||
|
/// html#method.host) documentation for more information.
|
||||||
|
///
|
||||||
|
/// By default host name is set to a "localhost" value.
|
||||||
|
pub fn server_hostname(mut self, val: &str) -> Self {
|
||||||
|
self.host = val.to_owned();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server ip address.
|
||||||
|
///
|
||||||
|
/// Host name is used by application router aa a hostname for url
|
||||||
|
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
||||||
|
/// html#method.host) documentation for more information.
|
||||||
|
///
|
||||||
|
/// By default server address is set to a "127.0.0.1:8080"
|
||||||
|
pub fn server_address<U: net::ToSocketAddrs>(mut self, addr: U) -> Self {
|
||||||
|
match addr.to_socket_addrs() {
|
||||||
|
Err(err) => error!("Can not convert to SocketAddr: {}", err),
|
||||||
|
Ok(mut addrs) => {
|
||||||
|
if let Some(addr) = addrs.next() {
|
||||||
|
self.addr = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finish service configuration and create `H1Service` instance.
|
||||||
|
pub fn finish<F, B>(self, service: F) -> H2Service<T, S, B>
|
||||||
|
where
|
||||||
|
B: MessageBody,
|
||||||
|
F: IntoNewService<S>,
|
||||||
|
{
|
||||||
|
let cfg = ServiceConfig::new(
|
||||||
|
self.keep_alive,
|
||||||
|
self.client_timeout,
|
||||||
|
self.client_disconnect,
|
||||||
|
);
|
||||||
|
H2Service {
|
||||||
|
cfg,
|
||||||
|
srv: service.into_new_service(),
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct H2ServiceResponse<T, S: NewService, B> {
|
||||||
|
fut: S::Future,
|
||||||
|
cfg: Option<ServiceConfig>,
|
||||||
|
_t: PhantomData<(T, B)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> Future for H2ServiceResponse<T, S, B>
|
||||||
|
where
|
||||||
|
T: AsyncRead + AsyncWrite,
|
||||||
|
S: NewService<Request = Request, Response = Response<B>>,
|
||||||
|
S::Service: Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
type Item = H2ServiceHandler<T, S::Service, B>;
|
||||||
|
type Error = S::InitError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
let service = try_ready!(self.fut.poll());
|
||||||
|
Ok(Async::Ready(H2ServiceHandler::new(
|
||||||
|
self.cfg.take().unwrap(),
|
||||||
|
service,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Service` implementation for http/2 transport
|
||||||
|
pub struct H2ServiceHandler<T, S, B> {
|
||||||
|
srv: S,
|
||||||
|
cfg: ServiceConfig,
|
||||||
|
_t: PhantomData<(T, B)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> H2ServiceHandler<T, S, B>
|
||||||
|
where
|
||||||
|
S: Service<Request = Request, Response = Response<B>> + Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
fn new(cfg: ServiceConfig, srv: S) -> H2ServiceHandler<T, S, B> {
|
||||||
|
H2ServiceHandler {
|
||||||
|
srv,
|
||||||
|
cfg,
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> Service for H2ServiceHandler<T, S, B>
|
||||||
|
where
|
||||||
|
T: AsyncRead + AsyncWrite,
|
||||||
|
S: Service<Request = Request, Response = Response<B>> + Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
type Request = T;
|
||||||
|
type Response = H2ServiceResult<T>;
|
||||||
|
type Error = (); // DispatchError<S::Error>;
|
||||||
|
type Future = H2ServiceHandlerResponse<T, S, B>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
self.srv.poll_ready().map_err(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: T) -> Self::Future {
|
||||||
|
H2ServiceHandlerResponse {
|
||||||
|
state: State::Handshake(server::handshake(req)),
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum State<T: AsyncRead + AsyncWrite> {
|
||||||
|
Handshake(Handshake<T, Bytes>),
|
||||||
|
Connection(Connection<T, Bytes>),
|
||||||
|
Empty,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct H2ServiceHandlerResponse<T, S, B>
|
||||||
|
where
|
||||||
|
T: AsyncRead + AsyncWrite,
|
||||||
|
S: Service<Request = Request, Response = Response<B>> + Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
state: State<T>,
|
||||||
|
_t: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> Future for H2ServiceHandlerResponse<T, S, B>
|
||||||
|
where
|
||||||
|
T: AsyncRead + AsyncWrite,
|
||||||
|
S: Service<Request = Request, Response = Response<B>> + Clone,
|
||||||
|
S::Error: Debug,
|
||||||
|
B: MessageBody,
|
||||||
|
{
|
||||||
|
type Item = H2ServiceResult<T>;
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
@ -85,6 +85,7 @@ mod service;
|
|||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod h1;
|
pub mod h1;
|
||||||
|
pub mod h2;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
|
|
||||||
|
@ -22,11 +22,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, R, E> NewService<Result<R, (E, Framed<T, Codec>)>> for SendError<T, R, E>
|
impl<T, R, E> NewService for SendError<T, R, E>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
E: ResponseError,
|
E: ResponseError,
|
||||||
{
|
{
|
||||||
|
type Request = Result<R, (E, Framed<T, Codec>)>;
|
||||||
type Response = R;
|
type Response = R;
|
||||||
type Error = (E, Framed<T, Codec>);
|
type Error = (E, Framed<T, Codec>);
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
@ -38,11 +39,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, R, E> Service<Result<R, (E, Framed<T, Codec>)>> for SendError<T, R, E>
|
impl<T, R, E> Service for SendError<T, R, E>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
E: ResponseError,
|
E: ResponseError,
|
||||||
{
|
{
|
||||||
|
type Request = Result<R, (E, Framed<T, Codec>)>;
|
||||||
type Response = R;
|
type Response = R;
|
||||||
type Error = (E, Framed<T, Codec>);
|
type Error = (E, Framed<T, Codec>);
|
||||||
type Future = Either<FutureResult<R, (E, Framed<T, Codec>)>, SendErrorFut<T, R, E>>;
|
type Future = Either<FutureResult<R, (E, Framed<T, Codec>)>, SendErrorFut<T, R, E>>;
|
||||||
@ -128,11 +130,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, B> NewService<(Response<B>, Framed<T, Codec>)> for SendResponse<T, B>
|
impl<T, B> NewService for SendResponse<T, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
|
type Request = (Response<B>, Framed<T, Codec>);
|
||||||
type Response = Framed<T, Codec>;
|
type Response = Framed<T, Codec>;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
@ -144,11 +147,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, B> Service<(Response<B>, Framed<T, Codec>)> for SendResponse<T, B>
|
impl<T, B> Service for SendResponse<T, B>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
|
type Request = (Response<B>, Framed<T, Codec>);
|
||||||
type Response = Framed<T, Codec>;
|
type Response = Framed<T, Codec>;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = SendResponseFut<T, B>;
|
type Future = SendResponseFut<T, B>;
|
||||||
|
@ -26,7 +26,7 @@ pub type DefaultClient = Client<DefaultConnector>;
|
|||||||
/// WebSocket's client
|
/// WebSocket's client
|
||||||
pub struct Client<T>
|
pub struct Client<T>
|
||||||
where
|
where
|
||||||
T: Service<TcpConnect, Error = ConnectorError>,
|
T: Service<Request = TcpConnect, Error = ConnectorError>,
|
||||||
T::Response: AsyncRead + AsyncWrite,
|
T::Response: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
connector: T,
|
connector: T,
|
||||||
@ -34,7 +34,7 @@ where
|
|||||||
|
|
||||||
impl<T> Client<T>
|
impl<T> Client<T>
|
||||||
where
|
where
|
||||||
T: Service<TcpConnect, Error = ConnectorError>,
|
T: Service<Request = TcpConnect, Error = ConnectorError>,
|
||||||
T::Response: AsyncRead + AsyncWrite,
|
T::Response: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
/// Create new websocket's client factory
|
/// Create new websocket's client factory
|
||||||
@ -51,7 +51,7 @@ impl Default for Client<DefaultConnector> {
|
|||||||
|
|
||||||
impl<T> Clone for Client<T>
|
impl<T> Clone for Client<T>
|
||||||
where
|
where
|
||||||
T: Service<TcpConnect, Error = ConnectorError> + Clone,
|
T: Service<Request = TcpConnect, Error = ConnectorError> + Clone,
|
||||||
T::Response: AsyncRead + AsyncWrite,
|
T::Response: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
@ -61,12 +61,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Service<Connect> for Client<T>
|
impl<T> Service for Client<T>
|
||||||
where
|
where
|
||||||
T: Service<TcpConnect, Error = ConnectorError>,
|
T: Service<Request = TcpConnect, Error = ConnectorError>,
|
||||||
T::Response: AsyncRead + AsyncWrite + 'static,
|
T::Response: AsyncRead + AsyncWrite + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
{
|
{
|
||||||
|
type Request = Connect;
|
||||||
type Response = Framed<T::Response, Codec>;
|
type Response = Framed<T::Response, Codec>;
|
||||||
type Error = ClientError;
|
type Error = ClientError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
|
@ -117,7 +117,7 @@ impl Parser {
|
|||||||
// control frames must have length <= 125
|
// control frames must have length <= 125
|
||||||
match opcode {
|
match opcode {
|
||||||
OpCode::Ping | OpCode::Pong if length > 125 => {
|
OpCode::Ping | OpCode::Pong if length > 125 => {
|
||||||
return Err(ProtocolError::InvalidLength(length))
|
return Err(ProtocolError::InvalidLength(length));
|
||||||
}
|
}
|
||||||
OpCode::Close if length > 125 => {
|
OpCode::Close if length > 125 => {
|
||||||
debug!("Received close frame with payload length exceeding 125. Morphing to protocol close frame.");
|
debug!("Received close frame with payload length exceeding 125. Morphing to protocol close frame.");
|
||||||
|
@ -20,7 +20,8 @@ impl<T> Default for VerifyWebSockets<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> NewService<(Request, Framed<T, Codec>)> for VerifyWebSockets<T> {
|
impl<T> NewService for VerifyWebSockets<T> {
|
||||||
|
type Request = (Request, Framed<T, Codec>);
|
||||||
type Response = (Request, Framed<T, Codec>);
|
type Response = (Request, Framed<T, Codec>);
|
||||||
type Error = (HandshakeError, Framed<T, Codec>);
|
type Error = (HandshakeError, Framed<T, Codec>);
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
@ -32,7 +33,8 @@ impl<T> NewService<(Request, Framed<T, Codec>)> for VerifyWebSockets<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Service<(Request, Framed<T, Codec>)> for VerifyWebSockets<T> {
|
impl<T> Service for VerifyWebSockets<T> {
|
||||||
|
type Request = (Request, Framed<T, Codec>);
|
||||||
type Response = (Request, Framed<T, Codec>);
|
type Response = (Request, Framed<T, Codec>);
|
||||||
type Error = (HandshakeError, Framed<T, Codec>);
|
type Error = (HandshakeError, Framed<T, Codec>);
|
||||||
type Future = FutureResult<Self::Response, Self::Error>;
|
type Future = FutureResult<Self::Response, Self::Error>;
|
||||||
|
@ -7,7 +7,7 @@ use super::{Codec, Frame, Message};
|
|||||||
|
|
||||||
pub struct Transport<S, T>
|
pub struct Transport<S, T>
|
||||||
where
|
where
|
||||||
S: Service<Frame, Response = Message> + 'static,
|
S: Service<Request = Frame, Response = Message> + 'static,
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
inner: FramedTransport<S, T, Codec>,
|
inner: FramedTransport<S, T, Codec>,
|
||||||
@ -16,17 +16,17 @@ where
|
|||||||
impl<S, T> Transport<S, T>
|
impl<S, T> Transport<S, T>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: Service<Frame, Response = Message>,
|
S: Service<Request = Frame, Response = Message>,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
{
|
{
|
||||||
pub fn new<F: IntoService<S, Frame>>(io: T, service: F) -> Self {
|
pub fn new<F: IntoService<S>>(io: T, service: F) -> Self {
|
||||||
Transport {
|
Transport {
|
||||||
inner: FramedTransport::new(Framed::new(io, Codec::new()), service),
|
inner: FramedTransport::new(Framed::new(io, Codec::new()), service),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with<F: IntoService<S, Frame>>(framed: Framed<T, Codec>, service: F) -> Self {
|
pub fn with<F: IntoService<S>>(framed: Framed<T, Codec>, service: F) -> Self {
|
||||||
Transport {
|
Transport {
|
||||||
inner: FramedTransport::new(framed, service),
|
inner: FramedTransport::new(framed, service),
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ where
|
|||||||
impl<S, T> Future for Transport<S, T>
|
impl<S, T> Future for Transport<S, T>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
S: Service<Frame, Response = Message>,
|
S: Service<Request = Frame, Response = Message>,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
{
|
{
|
||||||
|
@ -30,11 +30,11 @@ session = ["cookie/secure"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.1"
|
actix-codec = "0.1"
|
||||||
actix-service = "0.1.6"
|
actix-service = "0.2.0"
|
||||||
actix-rt = "0.1.0"
|
actix-rt = "0.1.0"
|
||||||
actix-server = "0.1.0"
|
actix-server = "0.2.0"
|
||||||
|
actix-utils = "0.2.0"
|
||||||
actix-http = { path=".." }
|
actix-http = { path=".." }
|
||||||
actix-utils = { git = "https://github.com/actix/actix-net.git" }
|
|
||||||
|
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
|
@ -57,7 +57,8 @@ impl TestServer {
|
|||||||
pub fn with_factory<F: StreamServiceFactory>(
|
pub fn with_factory<F: StreamServiceFactory>(
|
||||||
factory: F,
|
factory: F,
|
||||||
) -> TestServerRuntime<
|
) -> TestServerRuntime<
|
||||||
impl Service<Connect, Response = impl Connection, Error = ConnectorError> + Clone,
|
impl Service<Request = Connect, Response = impl Connection, Error = ConnectorError>
|
||||||
|
+ Clone,
|
||||||
> {
|
> {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
@ -89,8 +90,11 @@ impl TestServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_connector(
|
fn new_connector(
|
||||||
) -> impl Service<Connect, Response = impl Connection, Error = ConnectorError> + Clone
|
) -> impl Service<
|
||||||
{
|
Request = Connect,
|
||||||
|
Response = impl Connection,
|
||||||
|
Error = ConnectorError,
|
||||||
|
> + Clone {
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
{
|
{
|
||||||
use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||||
@ -191,7 +195,7 @@ impl<T> TestServerRuntime<T> {
|
|||||||
|
|
||||||
impl<T> TestServerRuntime<T>
|
impl<T> TestServerRuntime<T>
|
||||||
where
|
where
|
||||||
T: Service<Connect, Error = ConnectorError> + Clone,
|
T: Service<Request = Connect, Error = ConnectorError> + Clone,
|
||||||
T::Response: Connection,
|
T::Response: Connection,
|
||||||
{
|
{
|
||||||
/// Connect to websocket server at a given path
|
/// Connect to websocket server at a given path
|
||||||
|
Loading…
Reference in New Issue
Block a user