1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 17:52:40 +01:00
actix-extras/actix-framed/src/service.rs

148 lines
4.3 KiB
Rust
Raw Normal View History

use std::marker::PhantomData;
use actix_codec::{AsyncRead, AsyncWrite, Framed};
2019-04-12 00:12:23 +02:00
use actix_http::body::BodySize;
use actix_http::error::ResponseError;
2019-04-11 23:18:58 +02:00
use actix_http::h1::{Codec, Message};
use actix_http::ws::{verify_handshake, HandshakeError};
2019-04-11 23:18:58 +02:00
use actix_http::{Request, Response};
use actix_service::{NewService, Service};
use futures::future::{ok, Either, FutureResult};
2019-04-11 23:18:58 +02:00
use futures::{Async, Future, IntoFuture, Poll, Sink};
/// Service that verifies incoming request if it is valid websocket
/// upgrade request. In case of error returns `HandshakeError`
pub struct VerifyWebSockets<T> {
_t: PhantomData<T>,
}
impl<T> Default for VerifyWebSockets<T> {
fn default() -> Self {
VerifyWebSockets { _t: PhantomData }
}
}
2019-04-12 00:12:23 +02:00
impl<T, C> NewService<C> for VerifyWebSockets<T> {
2019-04-11 23:18:58 +02:00
type Request = (Request, Framed<T, Codec>);
type Response = (Request, Framed<T, Codec>);
type Error = (HandshakeError, Framed<T, Codec>);
type InitError = ();
type Service = VerifyWebSockets<T>;
type Future = FutureResult<Self::Service, Self::InitError>;
2019-04-12 00:12:23 +02:00
fn new_service(&self, _: &C) -> Self::Future {
ok(VerifyWebSockets { _t: PhantomData })
}
}
impl<T> Service for VerifyWebSockets<T> {
2019-04-11 23:18:58 +02:00
type Request = (Request, Framed<T, Codec>);
type Response = (Request, Framed<T, Codec>);
type Error = (HandshakeError, Framed<T, Codec>);
type Future = FutureResult<Self::Response, Self::Error>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
2019-04-11 23:18:58 +02:00
fn call(&mut self, (req, framed): (Request, Framed<T, Codec>)) -> Self::Future {
match verify_handshake(req.head()) {
Err(e) => Err((e, framed)).into_future(),
Ok(_) => Ok((req, framed)).into_future(),
}
}
}
/// Send http/1 error response
pub struct SendError<T, R, E>(PhantomData<(T, R, E)>);
impl<T, R, E> Default for SendError<T, R, E>
where
T: AsyncRead + AsyncWrite,
E: ResponseError,
{
fn default() -> Self {
SendError(PhantomData)
}
}
2019-04-12 00:12:23 +02:00
impl<T, R, E, C> NewService<C> for SendError<T, R, E>
where
T: AsyncRead + AsyncWrite + 'static,
R: 'static,
E: ResponseError + 'static,
{
2019-04-11 23:18:58 +02:00
type Request = Result<R, (E, Framed<T, Codec>)>;
type Response = R;
2019-04-12 00:12:23 +02:00
type Error = (E, Framed<T, Codec>);
type InitError = ();
type Service = SendError<T, R, E>;
type Future = FutureResult<Self::Service, Self::InitError>;
2019-04-12 00:12:23 +02:00
fn new_service(&self, _: &C) -> Self::Future {
ok(SendError(PhantomData))
}
}
impl<T, R, E> Service for SendError<T, R, E>
where
T: AsyncRead + AsyncWrite + 'static,
R: 'static,
E: ResponseError + 'static,
{
2019-04-11 23:18:58 +02:00
type Request = Result<R, (E, Framed<T, Codec>)>;
type Response = R;
2019-04-12 00:12:23 +02:00
type Error = (E, Framed<T, Codec>);
type Future = Either<FutureResult<R, (E, Framed<T, Codec>)>, SendErrorFut<T, R, E>>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
2019-04-11 23:18:58 +02:00
fn call(&mut self, req: Result<R, (E, Framed<T, Codec>)>) -> Self::Future {
match req {
Ok(r) => Either::A(ok(r)),
Err((e, framed)) => {
2019-04-12 00:12:23 +02:00
let res = e.error_response().drop_body();
Either::B(SendErrorFut {
framed: Some(framed),
res: Some((res, BodySize::Empty).into()),
err: Some(e),
_t: PhantomData,
})
}
}
}
}
2019-04-11 23:18:58 +02:00
2019-04-12 00:12:23 +02:00
pub struct SendErrorFut<T, R, E> {
2019-04-11 23:18:58 +02:00
res: Option<Message<(Response<()>, BodySize)>>,
framed: Option<Framed<T, Codec>>,
2019-04-12 00:12:23 +02:00
err: Option<E>,
_t: PhantomData<R>,
2019-04-11 23:18:58 +02:00
}
2019-04-12 00:12:23 +02:00
impl<T, R, E> Future for SendErrorFut<T, R, E>
2019-04-11 23:18:58 +02:00
where
2019-04-12 00:12:23 +02:00
E: ResponseError,
2019-04-11 23:18:58 +02:00
T: AsyncRead + AsyncWrite,
{
2019-04-12 00:12:23 +02:00
type Item = R;
type Error = (E, Framed<T, Codec>);
2019-04-11 23:18:58 +02:00
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
2019-04-12 00:12:23 +02:00
if let Some(res) = self.res.take() {
if self.framed.as_mut().unwrap().force_send(res).is_err() {
return Err((self.err.take().unwrap(), self.framed.take().unwrap()));
2019-04-11 23:18:58 +02:00
}
2019-04-12 00:12:23 +02:00
}
match self.framed.as_mut().unwrap().poll_complete() {
Ok(Async::Ready(_)) => {
Err((self.err.take().unwrap(), self.framed.take().unwrap()))
2019-04-11 23:18:58 +02:00
}
2019-04-12 00:12:23 +02:00
Ok(Async::NotReady) => Ok(Async::NotReady),
Err(_) => Err((self.err.take().unwrap(), self.framed.take().unwrap())),
2019-04-11 23:18:58 +02:00
}
}
}