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:
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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| {
|
||||
|
Reference in New Issue
Block a user