1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-06-26 10:27:42 +02:00

migrate to actix-web beta 14 (#209)

This commit is contained in:
Rob Ede
2021-12-11 16:05:21 +00:00
committed by GitHub
parent 700d90b68b
commit 74ec115161
27 changed files with 134 additions and 128 deletions

View File

@ -4,11 +4,14 @@ use std::{
use actix_utils::future::{self, Ready};
use actix_web::{
body::MessageBody,
body::{EitherBody, MessageBody},
dev::{RequestHead, Service, ServiceRequest, ServiceResponse, Transform},
error::{Error, Result},
http::{self, header::HeaderName, Error as HttpError, HeaderValue, Method, Uri},
Either,
error::HttpError,
http::{
header::{HeaderName, HeaderValue},
Method, Uri,
},
Either, Error, Result,
};
use log::error;
use once_cell::sync::Lazy;
@ -20,7 +23,7 @@ use crate::{AllOrSome, CorsError, CorsMiddleware, Inner, OriginFn};
/// Additionally, always causes first error (if any) to be reported during initialization.
fn cors<'a>(
inner: &'a mut Rc<Inner>,
err: &Option<Either<http::Error, CorsError>>,
err: &Option<Either<HttpError, CorsError>>,
) -> Option<&'a mut Inner> {
if err.is_some() {
return None;
@ -74,7 +77,7 @@ static ALL_METHODS_SET: Lazy<HashSet<Method>> = Lazy::new(|| {
#[derive(Debug)]
pub struct Cors {
inner: Rc<Inner>,
error: Option<Either<http::Error, CorsError>>,
error: Option<Either<HttpError, CorsError>>,
}
impl Cors {
@ -490,7 +493,7 @@ where
B: MessageBody + 'static,
B::Error: StdError,
{
type Response = ServiceResponse;
type Response = ServiceResponse<EitherBody<B>>;
type Error = Error;
type InitError = ();
type Transform = CorsMiddleware<S>;
@ -571,15 +574,13 @@ where
#[cfg(test)]
mod test {
use std::convert::{Infallible, TryInto};
use std::pin::Pin;
use std::task::{Context, Poll};
use actix_web::{
body::{BodySize, MessageBody},
body,
dev::{fn_service, Transform},
http::{HeaderName, StatusCode},
http::{header::HeaderName, StatusCode},
test::{self, TestRequest},
web::{Bytes, HttpResponse},
web::HttpResponse,
};
use super::*;
@ -634,23 +635,8 @@ mod test {
#[actix_rt::test]
async fn middleware_generic_over_body_type() {
struct Foo;
impl MessageBody for Foo {
type Error = std::io::Error;
fn size(&self) -> BodySize {
BodySize::None
}
fn poll_next(
self: Pin<&mut Self>,
_: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Self::Error>>> {
Poll::Ready(None)
}
}
let srv = fn_service(|req: ServiceRequest| async move {
Ok(req.into_response(HttpResponse::Ok().message_body(Foo)?))
Ok(req.into_response(HttpResponse::Ok().message_body(body::None::new())?))
});
Cors::default().new_transform(srv).await.unwrap();

View File

@ -7,35 +7,35 @@ use derive_more::{Display, Error};
#[non_exhaustive]
pub enum CorsError {
/// Allowed origin argument must not be wildcard (`*`).
#[display(fmt = "`allowed_origin` argument must not be wildcard (`*`).")]
#[display(fmt = "`allowed_origin` argument must not be wildcard (`*`)")]
WildcardOrigin,
/// Request header `Origin` is required but was not provided.
#[display(fmt = "Request header `Origin` is required but was not provided.")]
#[display(fmt = "Request header `Origin` is required but was not provided")]
MissingOrigin,
/// Request header `Access-Control-Request-Method` is required but is missing.
#[display(fmt = "Request header `Access-Control-Request-Method` is required but is missing.")]
#[display(fmt = "Request header `Access-Control-Request-Method` is required but is missing")]
MissingRequestMethod,
/// Request header `Access-Control-Request-Method` has an invalid value.
#[display(fmt = "Request header `Access-Control-Request-Method` has an invalid value.")]
#[display(fmt = "Request header `Access-Control-Request-Method` has an invalid value")]
BadRequestMethod,
/// Request header `Access-Control-Request-Headers` has an invalid value.
#[display(fmt = "Request header `Access-Control-Request-Headers` has an invalid value.")]
#[display(fmt = "Request header `Access-Control-Request-Headers` has an invalid value")]
BadRequestHeaders,
/// Origin is not allowed to make this request.
#[display(fmt = "Origin is not allowed to make this request.")]
#[display(fmt = "Origin is not allowed to make this request")]
OriginNotAllowed,
/// Request method is not allowed.
#[display(fmt = "Requested method is not allowed.")]
#[display(fmt = "Requested method is not allowed")]
MethodNotAllowed,
/// One or more request headers are not allowed.
#[display(fmt = "One or more request headers are not allowed.")]
#[display(fmt = "One or more request headers are not allowed")]
HeadersNotAllowed,
}
@ -45,6 +45,6 @@ impl ResponseError for CorsError {
}
fn error_response(&self) -> HttpResponse {
HttpResponse::with_body(StatusCode::BAD_REQUEST, self.to_string().into())
HttpResponse::with_body(StatusCode::BAD_REQUEST, self.to_string()).map_into_boxed_body()
}
}

View File

@ -205,7 +205,10 @@ mod test {
use actix_web::{
dev::Transform,
http::{header, HeaderValue, Method, StatusCode},
http::{
header::{self, HeaderValue},
Method, StatusCode,
},
test::{self, TestRequest},
};

View File

@ -1,8 +1,8 @@
use std::{collections::HashSet, convert::TryInto, error::Error as StdError, rc::Rc};
use actix_utils::future::{ok, Either, Ready};
use actix_utils::future::ok;
use actix_web::{
body::{AnyBody, MessageBody},
body::{EitherBody, MessageBody},
dev::{Service, ServiceRequest, ServiceResponse},
error::{Error, Result},
http::{
@ -11,7 +11,7 @@ use actix_web::{
},
HttpResponse,
};
use futures_util::future::{FutureExt as _, LocalBoxFuture, TryFutureExt as _};
use futures_util::future::{FutureExt as _, LocalBoxFuture};
use log::debug;
use crate::{builder::intersperse_header_values, AllOrSome, Inner};
@ -134,11 +134,6 @@ impl<S> CorsMiddleware<S> {
}
}
type CorsMiddlewareServiceFuture = Either<
Ready<Result<ServiceResponse, Error>>,
LocalBoxFuture<'static, Result<ServiceResponse, Error>>,
>;
impl<S, B> Service<ServiceRequest> for CorsMiddleware<S>
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
@ -146,9 +141,9 @@ where
B: MessageBody + 'static,
B::Error: StdError,
{
type Response = ServiceResponse;
type Response = ServiceResponse<EitherBody<B>>;
type Error = Error;
type Future = CorsMiddlewareServiceFuture;
type Future = LocalBoxFuture<'static, Result<ServiceResponse<EitherBody<B>>, Error>>;
actix_service::forward_ready!(service);
@ -156,7 +151,7 @@ where
if self.inner.preflight && req.method() == Method::OPTIONS {
let inner = Rc::clone(&self.inner);
let res = Self::handle_preflight(&inner, req);
Either::left(ok(res))
ok(res.map_into_right_body()).boxed_local()
} else {
let origin = req.headers().get(header::ORIGIN).cloned();
@ -164,27 +159,37 @@ where
// Only check requests with a origin header.
if let Err(err) = self.inner.validate_origin(req.head()) {
debug!("origin validation failed; inner service is not called");
return Either::left(ok(req.error_response(err)));
return ok(req.error_response(err).map_into_right_body()).boxed_local();
}
}
let (req, pl) = req.into_parts();
let req2 = req.clone();
let req = ServiceRequest::from_parts(req, pl);
let inner = Rc::clone(&self.inner);
let fut = self.service.call(req);
let res = async move {
async move {
let res = fut.await;
if origin.is_some() {
let res = res?;
let res = match res {
Ok(res) => res,
Err(err) => {
let res = HttpResponse::from_error(err);
let res = ServiceResponse::new(req2, res);
return Ok(res.map_into_right_body());
}
};
Ok(Self::augment_response(&inner, res))
} else {
res
}
.map(|res| res.map_into_left_body())
}
.map_ok(|res| res.map_body(|_, body| AnyBody::new_boxed(body)))
.boxed_local();
Either::right(res)
.boxed_local()
}
}
}