init project, impl authorization

This commit is contained in:
2022-06-06 14:17:58 +05:00
commit ec73d6584f
26 changed files with 2680 additions and 0 deletions

View File

@ -0,0 +1 @@
pub mod msgpack;

View File

@ -0,0 +1,149 @@
use actix_web::body::EitherBody;
use actix_web::dev::{Decompress, Payload};
use actix_web::error::PayloadError;
use actix_web::http::StatusCode;
use actix_web::web::{Bytes, BytesMut};
use actix_web::{Error, FromRequest, HttpRequest, HttpResponse, Responder, ResponseError};
use derive_more::Display;
use futures::{ready, Stream};
use rmp_serde::{decode::Error as RmpDecodeError, encode::Error as RmpEncodeError};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::task::Poll::{Pending, Ready};
use std::task::{Context, Poll};
pub struct MsgPack<T>(pub T);
impl<T: DeserializeOwned> FromRequest for MsgPack<T> {
type Error = Error;
type Future = MsgPackExtractFuture<T>;
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
MsgPackExtractFuture::new(req.clone(), payload)
}
}
#[derive(Debug, Display)]
pub enum MsgPackError {
#[display(fmt = "Can not deserialize")]
Deserialize(RmpDecodeError),
#[display(fmt = "Reading payload error {}", _0)]
ReadPayload(PayloadError),
#[display(fmt = "Can not serialize msgpack")]
Serialize(RmpEncodeError),
}
impl ResponseError for MsgPackError {
fn status_code(&self) -> StatusCode {
match self {
MsgPackError::Deserialize(_) => StatusCode::UNPROCESSABLE_ENTITY,
MsgPackError::ReadPayload(err) => err.status_code(),
MsgPackError::Serialize(_) => StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
pub struct MsgPackExtractFuture<T> {
_req: HttpRequest,
fut: MsgPackBody<T>,
_res: PhantomData<T>,
}
impl<T: DeserializeOwned> MsgPackExtractFuture<T> {
fn new(req: HttpRequest, payload: &mut Payload) -> Self {
MsgPackExtractFuture {
_req: req.clone(),
fut: MsgPackBody::new(req.clone(), payload),
_res: PhantomData {},
}
}
}
impl<T> Unpin for MsgPackExtractFuture<T> {}
impl<T: DeserializeOwned> Future for MsgPackExtractFuture<T> {
type Output = Result<MsgPack<T>, Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let res = ready!(Pin::new(&mut this.fut).poll(cx));
match res {
Ok(data) => Ready(Ok(MsgPack(data))),
Err(err) => Ready(Err(err.into())),
}
}
}
struct MsgPackBody<T> {
buf: BytesMut,
payload: Decompress<Payload>,
_res: PhantomData<T>,
}
impl<T> Unpin for MsgPackBody<T> {}
impl<T: DeserializeOwned> MsgPackBody<T> {
fn new(req: HttpRequest, payload: &mut Payload) -> Self {
MsgPackBody {
payload: Decompress::from_headers(payload.take(), req.headers()),
buf: BytesMut::new(),
_res: PhantomData {},
}
}
}
impl<T: DeserializeOwned> Future for MsgPackBody<T> {
type Output = Result<T, MsgPackError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let next = ready!(Pin::new(&mut this.payload).poll_next(cx));
match next {
None => {
let res = match rmp_serde::from_slice(&this.buf) {
Ok(data) => data,
Err(err) => {
return Ready(Err(MsgPackError::Deserialize(err)));
}
};
Ready(Ok(res))
}
Some(res) => {
let data: Bytes = match res {
Ok(data) => data,
Err(err) => {
return Ready(Err(MsgPackError::ReadPayload(err)));
}
};
this.buf.extend_from_slice(&data);
Pending
}
}
}
}
impl<T: Serialize> Responder for MsgPack<T> {
type Body = EitherBody<Bytes>;
fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
match rmp_serde::to_vec(&self.0) {
Ok(data) => {
match HttpResponse::Ok()
.content_type(mime::APPLICATION_MSGPACK)
.message_body(Bytes::from(data))
{
Ok(response) => response.map_into_left_body(),
Err(err) => HttpResponse::from_error(err).map_into_right_body(),
}
}
Err(err) => {
HttpResponse::from_error(MsgPackError::Serialize(err)).map_into_right_body()
}
}
}
}