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

Remove generic type for request payload, always use default

This commit is contained in:
Nikolay Kim
2019-04-13 14:50:54 -07:00
parent 043f6e77ae
commit 4f30fa9d46
38 changed files with 704 additions and 1207 deletions

View File

@ -3,15 +3,15 @@
use std::rc::Rc;
use std::{fmt, ops};
use actix_http::error::{Error, PayloadError};
use actix_http::{HttpMessage, Payload};
use bytes::{Bytes, BytesMut};
use actix_http::{Error, HttpMessage, Payload};
use bytes::BytesMut;
use encoding::all::UTF_8;
use encoding::types::{DecoderTrap, Encoding};
use encoding::EncodingRef;
use futures::{Future, Poll, Stream};
use serde::de::DeserializeOwned;
use crate::dev::Decompress;
use crate::error::UrlencodedError;
use crate::extract::FromRequest;
use crate::http::header::CONTENT_LENGTH;
@ -69,16 +69,15 @@ impl<T> ops::DerefMut for Form<T> {
}
}
impl<T, P> FromRequest<P> for Form<T>
impl<T> FromRequest for Form<T>
where
T: DeserializeOwned + 'static,
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
{
type Error = Error;
type Future = Box<Future<Item = Self, Error = Error>>;
#[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
let req2 = req.clone();
let (limit, err) = req
.route_data::<FormConfig>()
@ -182,8 +181,8 @@ impl Default for FormConfig {
/// * content type is not `application/x-www-form-urlencoded`
/// * content-length is greater than 32k
///
pub struct UrlEncoded<P, U> {
stream: Payload<P>,
pub struct UrlEncoded<U> {
stream: Option<Decompress<Payload>>,
limit: usize,
length: Option<usize>,
encoding: EncodingRef,
@ -191,12 +190,9 @@ pub struct UrlEncoded<P, U> {
fut: Option<Box<Future<Item = U, Error = UrlencodedError>>>,
}
impl<P, U> UrlEncoded<P, U>
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
impl<U> UrlEncoded<U> {
/// Create a new future to URL encode a request
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> UrlEncoded<P, U> {
pub fn new(req: &HttpRequest, payload: &mut Payload) -> UrlEncoded<U> {
// check content type
if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
return Self::err(UrlencodedError::ContentType);
@ -219,9 +215,10 @@ where
}
};
let payload = Decompress::from_headers(payload.take(), req.headers());
UrlEncoded {
encoding,
stream: payload.take(),
stream: Some(payload),
limit: 32_768,
length: len,
fut: None,
@ -231,7 +228,7 @@ where
fn err(e: UrlencodedError) -> Self {
UrlEncoded {
stream: Payload::None,
stream: None,
limit: 32_768,
fut: None,
err: Some(e),
@ -247,9 +244,8 @@ where
}
}
impl<P, U> Future for UrlEncoded<P, U>
impl<U> Future for UrlEncoded<U>
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
U: DeserializeOwned + 'static,
{
type Item = U;
@ -274,7 +270,10 @@ where
// future
let encoding = self.encoding;
let fut = std::mem::replace(&mut self.stream, Payload::None)
let fut = self
.stream
.take()
.unwrap()
.from_err()
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
if (body.len() + chunk.len()) > limit {
@ -355,20 +354,20 @@ mod tests {
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
.header(CONTENT_LENGTH, "xxxx")
.to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));
let (req, mut pl) =
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
.header(CONTENT_LENGTH, "1000000")
.to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
assert!(eq(info.err().unwrap(), UrlencodedError::Overflow));
let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain")
.header(CONTENT_LENGTH, "10")
.to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
}
@ -380,7 +379,7 @@ mod tests {
.set_payload(Bytes::from_static(b"hello=world"))
.to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap();
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
assert_eq!(
info,
Info {
@ -396,7 +395,7 @@ mod tests {
.set_payload(Bytes::from_static(b"hello=world"))
.to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap();
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
assert_eq!(
info,
Info {

View File

@ -3,7 +3,7 @@
use std::rc::Rc;
use std::{fmt, ops};
use bytes::{Bytes, BytesMut};
use bytes::BytesMut;
use futures::{Future, Poll, Stream};
use serde::de::DeserializeOwned;
use serde::Serialize;
@ -12,7 +12,8 @@ use serde_json;
use actix_http::http::{header::CONTENT_LENGTH, StatusCode};
use actix_http::{HttpMessage, Payload, Response};
use crate::error::{Error, JsonPayloadError, PayloadError};
use crate::dev::Decompress;
use crate::error::{Error, JsonPayloadError};
use crate::extract::FromRequest;
use crate::request::HttpRequest;
use crate::responder::Responder;
@ -163,16 +164,15 @@ impl<T: Serialize> Responder for Json<T> {
/// );
/// }
/// ```
impl<T, P> FromRequest<P> for Json<T>
impl<T> FromRequest for Json<T>
where
T: DeserializeOwned + 'static,
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
{
type Error = Error;
type Future = Box<Future<Item = Self, Error = Error>>;
#[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
let req2 = req.clone();
let (limit, err) = req
.route_data::<JsonConfig>()
@ -270,21 +270,20 @@ impl Default for JsonConfig {
///
/// * content type is not `application/json`
/// * content length is greater than 256k
pub struct JsonBody<P, U> {
pub struct JsonBody<U> {
limit: usize,
length: Option<usize>,
stream: Payload<P>,
stream: Option<Decompress<Payload>>,
err: Option<JsonPayloadError>,
fut: Option<Box<Future<Item = U, Error = JsonPayloadError>>>,
}
impl<P, U> JsonBody<P, U>
impl<U> JsonBody<U>
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
U: DeserializeOwned + 'static,
{
/// Create `JsonBody` for request.
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> Self {
pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self {
// check content-type
let json = if let Ok(Some(mime)) = req.mime_type() {
mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
@ -295,7 +294,7 @@ where
return JsonBody {
limit: 262_144,
length: None,
stream: Payload::None,
stream: None,
fut: None,
err: Some(JsonPayloadError::ContentType),
};
@ -309,11 +308,12 @@ where
}
}
}
let payload = Decompress::from_headers(payload.take(), req.headers());
JsonBody {
limit: 262_144,
length: len,
stream: payload.take(),
stream: Some(payload),
fut: None,
err: None,
}
@ -326,9 +326,8 @@ where
}
}
impl<P, U> Future for JsonBody<P, U>
impl<U> Future for JsonBody<U>
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
U: DeserializeOwned + 'static,
{
type Item = U;
@ -350,7 +349,10 @@ where
}
}
let fut = std::mem::replace(&mut self.stream, Payload::None)
let fut = self
.stream
.take()
.unwrap()
.from_err()
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
if (body.len() + chunk.len()) > limit {
@ -508,7 +510,7 @@ mod tests {
#[test]
fn test_json_body() {
let (req, mut pl) = TestRequest::default().to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
let (req, mut pl) = TestRequest::default()
@ -517,7 +519,7 @@ mod tests {
header::HeaderValue::from_static("application/text"),
)
.to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
let (req, mut pl) = TestRequest::default()
@ -531,7 +533,7 @@ mod tests {
)
.to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl).limit(100));
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl).limit(100));
assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow));
let (req, mut pl) = TestRequest::default()
@ -546,7 +548,7 @@ mod tests {
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
.to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
assert_eq!(
json.ok().unwrap(),
MyObject {

View File

@ -152,7 +152,7 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
/// );
/// }
/// ```
impl<T, P> FromRequest<P> for Path<T>
impl<T> FromRequest for Path<T>
where
T: de::DeserializeOwned,
{
@ -160,7 +160,7 @@ where
type Future = Result<Self, Error>;
#[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
.map(|inner| Path { inner })
.map_err(ErrorNotFound)

View File

@ -44,7 +44,7 @@ use crate::request::HttpRequest;
/// );
/// }
/// ```
pub struct Payload(crate::dev::Payload<Box<Stream<Item = Bytes, Error = PayloadError>>>);
pub struct Payload(crate::dev::Payload);
impl Stream for Payload {
type Item = Bytes;
@ -85,26 +85,13 @@ impl Stream for Payload {
/// );
/// }
/// ```
impl<P> FromRequest<P> for Payload
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
impl FromRequest for Payload {
type Error = Error;
type Future = Result<Payload, Error>;
#[inline]
fn from_request(_: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
let pl = match payload.take() {
crate::dev::Payload::Stream(s) => {
let pl: Box<dyn Stream<Item = Bytes, Error = PayloadError>> =
Box::new(s);
crate::dev::Payload::Stream(pl)
}
crate::dev::Payload::None => crate::dev::Payload::None,
crate::dev::Payload::H1(pl) => crate::dev::Payload::H1(pl),
crate::dev::Payload::H2(pl) => crate::dev::Payload::H2(pl),
};
Ok(Payload(pl))
fn from_request(_: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
Ok(Payload(payload.take()))
}
}
@ -133,16 +120,13 @@ where
/// );
/// }
/// ```
impl<P> FromRequest<P> for Bytes
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
impl FromRequest for Bytes {
type Error = Error;
type Future =
Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>;
#[inline]
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
let mut tmp;
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
cfg
@ -188,16 +172,13 @@ where
/// );
/// }
/// ```
impl<P> FromRequest<P> for String
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
impl FromRequest for String {
type Error = Error;
type Future =
Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>;
#[inline]
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
let mut tmp;
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
cfg
@ -300,20 +281,17 @@ impl Default for PayloadConfig {
/// By default only 256Kb payload reads to a memory, then
/// `PayloadError::Overflow` get returned. Use `MessageBody::limit()`
/// method to change upper limit.
pub struct HttpMessageBody<P> {
pub struct HttpMessageBody {
limit: usize,
length: Option<usize>,
stream: dev::Payload<P>,
stream: Option<dev::Decompress<dev::Payload>>,
err: Option<PayloadError>,
fut: Option<Box<Future<Item = Bytes, Error = PayloadError>>>,
}
impl<P> HttpMessageBody<P>
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
impl HttpMessageBody {
/// Create `MessageBody` for request.
pub fn new(req: &HttpRequest, payload: &mut dev::Payload<P>) -> HttpMessageBody<P> {
pub fn new(req: &HttpRequest, payload: &mut dev::Payload) -> HttpMessageBody {
let mut len = None;
if let Some(l) = req.headers().get(&header::CONTENT_LENGTH) {
if let Ok(s) = l.to_str() {
@ -328,7 +306,7 @@ where
}
HttpMessageBody {
stream: payload.take(),
stream: Some(dev::Decompress::from_headers(payload.take(), req.headers())),
limit: 262_144,
length: len,
fut: None,
@ -344,7 +322,7 @@ where
fn err(e: PayloadError) -> Self {
HttpMessageBody {
stream: dev::Payload::None,
stream: None,
limit: 262_144,
fut: None,
err: Some(e),
@ -353,10 +331,7 @@ where
}
}
impl<P> Future for HttpMessageBody<P>
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
impl Future for HttpMessageBody {
type Item = Bytes;
type Error = PayloadError;
@ -378,7 +353,9 @@ where
// future
let limit = self.limit;
self.fut = Some(Box::new(
std::mem::replace(&mut self.stream, actix_http::Payload::None)
self.stream
.take()
.unwrap()
.from_err()
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
if (body.len() + chunk.len()) > limit {

View File

@ -111,7 +111,7 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
/// .route(web::get().to(index))); // <- use `Query` extractor
/// }
/// ```
impl<T, P> FromRequest<P> for Query<T>
impl<T> FromRequest for Query<T>
where
T: de::DeserializeOwned,
{
@ -119,7 +119,7 @@ where
type Future = Result<Self, Error>;
#[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
serde_urlencoded::from_str::<T>(req.query_string())
.map(|val| Ok(Query(val)))
.unwrap_or_else(|e| {