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

157 lines
4.7 KiB
Rust
Raw Normal View History

use std::marker::PhantomData;
2019-11-21 07:17:01 +01:00
use std::pin::Pin;
use std::task::{Context, Poll};
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};
2019-11-21 07:17:01 +01:00
use actix_service::{Service, ServiceFactory};
use futures::future::{err, ok, Either, Ready};
use futures::Future;
/// Service that verifies incoming request if it is valid websocket
/// upgrade request. In case of error returns `HandshakeError`
2019-05-12 17:34:51 +02:00
pub struct VerifyWebSockets<T, C> {
_t: PhantomData<(T, C)>,
}
2019-05-12 17:34:51 +02:00
impl<T, C> Default for VerifyWebSockets<T, C> {
fn default() -> Self {
VerifyWebSockets { _t: PhantomData }
}
}
2019-11-21 07:17:01 +01:00
impl<T, C> ServiceFactory for VerifyWebSockets<T, C> {
2019-05-12 17:34:51 +02:00
type Config = C;
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 = ();
2019-05-12 17:34:51 +02:00
type Service = VerifyWebSockets<T, C>;
2019-11-21 07:17:01 +01:00
type Future = Ready<Result<Self::Service, Self::InitError>>;
2019-12-02 16:37:13 +01:00
fn new_service(&self, _: C) -> Self::Future {
ok(VerifyWebSockets { _t: PhantomData })
}
}
2019-05-12 17:34:51 +02:00
impl<T, C> Service for VerifyWebSockets<T, C> {
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>);
2019-11-21 07:17:01 +01:00
type Future = Ready<Result<Self::Response, Self::Error>>;
2019-11-21 07:17:01 +01:00
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
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()) {
2019-11-21 07:17:01 +01:00
Err(e) => err((e, framed)),
Ok(_) => ok((req, framed)),
}
}
}
/// Send http/1 error response
2019-05-12 17:34:51 +02:00
pub struct SendError<T, R, E, C>(PhantomData<(T, R, E, C)>);
2019-05-12 17:34:51 +02:00
impl<T, R, E, C> Default for SendError<T, R, E, C>
where
T: AsyncRead + AsyncWrite,
E: ResponseError,
{
fn default() -> Self {
SendError(PhantomData)
}
}
2019-11-21 07:17:01 +01:00
impl<T, R, E, C> ServiceFactory for SendError<T, R, E, C>
where
2019-11-21 07:17:01 +01:00
T: AsyncRead + AsyncWrite + Unpin + 'static,
R: 'static,
E: ResponseError + 'static,
{
2019-05-12 17:34:51 +02:00
type Config = C;
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 = ();
2019-05-12 17:34:51 +02:00
type Service = SendError<T, R, E, C>;
2019-11-21 07:17:01 +01:00
type Future = Ready<Result<Self::Service, Self::InitError>>;
2019-12-02 16:37:13 +01:00
fn new_service(&self, _: C) -> Self::Future {
ok(SendError(PhantomData))
}
}
2019-05-12 17:34:51 +02:00
impl<T, R, E, C> Service for SendError<T, R, E, C>
where
2019-11-21 07:17:01 +01:00
T: AsyncRead + AsyncWrite + Unpin + '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>);
2019-11-21 07:17:01 +01:00
type Future = Either<Ready<Result<R, (E, Framed<T, Codec>)>>, SendErrorFut<T, R, E>>;
2019-11-21 07:17:01 +01:00
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
2019-04-11 23:18:58 +02:00
fn call(&mut self, req: Result<R, (E, Framed<T, Codec>)>) -> Self::Future {
match req {
2019-11-21 07:17:01 +01:00
Ok(r) => Either::Left(ok(r)),
Err((e, framed)) => {
2019-04-12 00:12:23 +02:00
let res = e.error_response().drop_body();
2019-11-21 07:17:01 +01:00
Either::Right(SendErrorFut {
2019-04-12 00:12:23 +02:00
framed: Some(framed),
res: Some((res, BodySize::Empty).into()),
err: Some(e),
_t: PhantomData,
})
}
}
}
}
2019-04-11 23:18:58 +02:00
2019-11-21 07:17:01 +01:00
#[pin_project::pin_project]
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-11-21 07:17:01 +01:00
T: AsyncRead + AsyncWrite + Unpin,
2019-04-11 23:18:58 +02:00
{
2019-11-21 07:17:01 +01:00
type Output = Result<R, (E, Framed<T, Codec>)>;
2019-04-11 23:18:58 +02:00
2019-11-21 07:17:01 +01:00
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
2019-04-12 00:12:23 +02:00
if let Some(res) = self.res.take() {
2019-11-21 07:17:01 +01:00
if self.framed.as_mut().unwrap().write(res).is_err() {
return Poll::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
}
2019-11-21 07:17:01 +01:00
match self.framed.as_mut().unwrap().flush(cx) {
Poll::Ready(Ok(_)) => {
Poll::Ready(Err((self.err.take().unwrap(), self.framed.take().unwrap())))
}
Poll::Ready(Err(_)) => {
Poll::Ready(Err((self.err.take().unwrap(), self.framed.take().unwrap())))
2019-04-11 23:18:58 +02:00
}
2019-11-21 07:17:01 +01:00
Poll::Pending => Poll::Pending,
2019-04-11 23:18:58 +02:00
}
}
}