mirror of
https://github.com/actix/actix-extras.git
synced 2025-06-27 10:39:03 +02:00
refactor FromRequest trait
This commit is contained in:
@ -16,7 +16,6 @@ use crate::error::UrlencodedError;
|
||||
use crate::extract::FromRequest;
|
||||
use crate::http::header::CONTENT_LENGTH;
|
||||
use crate::request::HttpRequest;
|
||||
use crate::service::ServiceFromRequest;
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
/// Extract typed information from the request's body.
|
||||
@ -79,15 +78,15 @@ where
|
||||
type Future = Box<Future<Item = Self, Error = Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
let req2 = req.request().clone();
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
let req2 = req.clone();
|
||||
let (limit, err) = req
|
||||
.route_data::<FormConfig>()
|
||||
.map(|c| (c.limit, c.ehandler.clone()))
|
||||
.unwrap_or((16384, None));
|
||||
|
||||
Box::new(
|
||||
UrlEncoded::new(req)
|
||||
UrlEncoded::new(req, payload)
|
||||
.limit(limit)
|
||||
.map_err(move |e| {
|
||||
if let Some(err) = err {
|
||||
@ -183,8 +182,8 @@ impl Default for FormConfig {
|
||||
/// * content type is not `application/x-www-form-urlencoded`
|
||||
/// * content-length is greater than 32k
|
||||
///
|
||||
pub struct UrlEncoded<T: HttpMessage, U> {
|
||||
stream: Payload<T::Stream>,
|
||||
pub struct UrlEncoded<P, U> {
|
||||
stream: Payload<P>,
|
||||
limit: usize,
|
||||
length: Option<usize>,
|
||||
encoding: EncodingRef,
|
||||
@ -192,13 +191,12 @@ pub struct UrlEncoded<T: HttpMessage, U> {
|
||||
fut: Option<Box<Future<Item = U, Error = UrlencodedError>>>,
|
||||
}
|
||||
|
||||
impl<T, U> UrlEncoded<T, U>
|
||||
impl<P, U> UrlEncoded<P, U>
|
||||
where
|
||||
T: HttpMessage,
|
||||
T::Stream: Stream<Item = Bytes, Error = PayloadError>,
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
/// Create a new future to URL encode a request
|
||||
pub fn new(req: &mut T) -> UrlEncoded<T, U> {
|
||||
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> UrlEncoded<P, U> {
|
||||
// check content type
|
||||
if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
|
||||
return Self::err(UrlencodedError::ContentType);
|
||||
@ -223,7 +221,7 @@ where
|
||||
|
||||
UrlEncoded {
|
||||
encoding,
|
||||
stream: req.take_payload(),
|
||||
stream: payload.take(),
|
||||
limit: 32_768,
|
||||
length: len,
|
||||
fut: None,
|
||||
@ -249,10 +247,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Future for UrlEncoded<T, U>
|
||||
impl<P, U> Future for UrlEncoded<P, U>
|
||||
where
|
||||
T: HttpMessage,
|
||||
T::Stream: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
U: DeserializeOwned + 'static,
|
||||
{
|
||||
type Item = U;
|
||||
@ -320,13 +317,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_form() {
|
||||
let mut req =
|
||||
let (req, mut pl) =
|
||||
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header(CONTENT_LENGTH, "11")
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_from();
|
||||
.to_http_parts();
|
||||
|
||||
let s = block_on(Form::<Info>::from_request(&mut req)).unwrap();
|
||||
let s = block_on(Form::<Info>::from_request(&req, &mut pl)).unwrap();
|
||||
assert_eq!(s.hello, "world");
|
||||
}
|
||||
|
||||
@ -354,36 +351,36 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_urlencoded_error() {
|
||||
let mut req =
|
||||
let (req, mut pl) =
|
||||
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header(CONTENT_LENGTH, "xxxx")
|
||||
.to_request();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&mut req));
|
||||
.to_http_parts();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
|
||||
assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));
|
||||
|
||||
let mut req =
|
||||
let (req, mut pl) =
|
||||
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header(CONTENT_LENGTH, "1000000")
|
||||
.to_request();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&mut req));
|
||||
.to_http_parts();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
|
||||
assert!(eq(info.err().unwrap(), UrlencodedError::Overflow));
|
||||
|
||||
let mut req = TestRequest::with_header(CONTENT_TYPE, "text/plain")
|
||||
let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain")
|
||||
.header(CONTENT_LENGTH, "10")
|
||||
.to_request();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&mut req));
|
||||
.to_http_parts();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
|
||||
assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_urlencoded() {
|
||||
let mut req =
|
||||
let (req, mut pl) =
|
||||
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header(CONTENT_LENGTH, "11")
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_request();
|
||||
.to_http_parts();
|
||||
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&mut req)).unwrap();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap();
|
||||
assert_eq!(
|
||||
info,
|
||||
Info {
|
||||
@ -391,15 +388,15 @@ mod tests {
|
||||
}
|
||||
);
|
||||
|
||||
let mut req = TestRequest::with_header(
|
||||
let (req, mut pl) = TestRequest::with_header(
|
||||
CONTENT_TYPE,
|
||||
"application/x-www-form-urlencoded; charset=utf-8",
|
||||
)
|
||||
.header(CONTENT_LENGTH, "11")
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_request();
|
||||
.to_http_parts();
|
||||
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&mut req)).unwrap();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap();
|
||||
assert_eq!(
|
||||
info,
|
||||
Info {
|
||||
|
@ -16,7 +16,6 @@ use crate::error::{Error, JsonPayloadError, PayloadError};
|
||||
use crate::extract::FromRequest;
|
||||
use crate::request::HttpRequest;
|
||||
use crate::responder::Responder;
|
||||
use crate::service::ServiceFromRequest;
|
||||
|
||||
/// Json helper
|
||||
///
|
||||
@ -173,15 +172,15 @@ where
|
||||
type Future = Box<Future<Item = Self, Error = Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
let req2 = req.request().clone();
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
let req2 = req.clone();
|
||||
let (limit, err) = req
|
||||
.route_data::<JsonConfig>()
|
||||
.map(|c| (c.limit, c.ehandler.clone()))
|
||||
.unwrap_or((32768, None));
|
||||
|
||||
Box::new(
|
||||
JsonBody::new(req)
|
||||
JsonBody::new(req, payload)
|
||||
.limit(limit)
|
||||
.map_err(move |e| {
|
||||
if let Some(err) = err {
|
||||
@ -264,22 +263,21 @@ impl Default for JsonConfig {
|
||||
///
|
||||
/// * content type is not `application/json`
|
||||
/// * content length is greater than 256k
|
||||
pub struct JsonBody<T: HttpMessage, U> {
|
||||
pub struct JsonBody<P, U> {
|
||||
limit: usize,
|
||||
length: Option<usize>,
|
||||
stream: Payload<T::Stream>,
|
||||
stream: Payload<P>,
|
||||
err: Option<JsonPayloadError>,
|
||||
fut: Option<Box<Future<Item = U, Error = JsonPayloadError>>>,
|
||||
}
|
||||
|
||||
impl<T, U> JsonBody<T, U>
|
||||
impl<P, U> JsonBody<P, U>
|
||||
where
|
||||
T: HttpMessage,
|
||||
T::Stream: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
U: DeserializeOwned + 'static,
|
||||
{
|
||||
/// Create `JsonBody` for request.
|
||||
pub fn new(req: &mut T) -> Self {
|
||||
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> Self {
|
||||
// check content-type
|
||||
let json = if let Ok(Some(mime)) = req.mime_type() {
|
||||
mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
|
||||
@ -308,7 +306,7 @@ where
|
||||
JsonBody {
|
||||
limit: 262_144,
|
||||
length: len,
|
||||
stream: req.take_payload(),
|
||||
stream: payload.take(),
|
||||
fut: None,
|
||||
err: None,
|
||||
}
|
||||
@ -321,10 +319,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Future for JsonBody<T, U>
|
||||
impl<P, U> Future for JsonBody<P, U>
|
||||
where
|
||||
T: HttpMessage,
|
||||
T::Stream: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
U: DeserializeOwned + 'static,
|
||||
{
|
||||
type Item = U;
|
||||
@ -410,7 +407,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_extract() {
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/json"),
|
||||
@ -420,9 +417,9 @@ mod tests {
|
||||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.to_from();
|
||||
.to_http_parts();
|
||||
|
||||
let s = block_on(Json::<MyObject>::from_request(&mut req)).unwrap();
|
||||
let s = block_on(Json::<MyObject>::from_request(&req, &mut pl)).unwrap();
|
||||
assert_eq!(s.name, "test");
|
||||
assert_eq!(
|
||||
s.into_inner(),
|
||||
@ -431,7 +428,7 @@ mod tests {
|
||||
}
|
||||
);
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/json"),
|
||||
@ -442,12 +439,13 @@ mod tests {
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.route_data(JsonConfig::default().limit(10))
|
||||
.to_from();
|
||||
let s = block_on(Json::<MyObject>::from_request(&mut req));
|
||||
.to_http_parts();
|
||||
|
||||
let s = block_on(Json::<MyObject>::from_request(&req, &mut pl));
|
||||
assert!(format!("{}", s.err().unwrap())
|
||||
.contains("Json payload size is bigger than allowed."));
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/json"),
|
||||
@ -462,27 +460,27 @@ mod tests {
|
||||
.limit(10)
|
||||
.error_handler(|_, _| JsonPayloadError::ContentType.into()),
|
||||
)
|
||||
.to_from();
|
||||
let s = block_on(Json::<MyObject>::from_request(&mut req));
|
||||
.to_http_parts();
|
||||
let s = block_on(Json::<MyObject>::from_request(&req, &mut pl));
|
||||
assert!(format!("{}", s.err().unwrap()).contains("Content type error"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_body() {
|
||||
let mut req = TestRequest::default().to_request();
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&mut req));
|
||||
let (req, mut pl) = TestRequest::default().to_http_parts();
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
|
||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/text"),
|
||||
)
|
||||
.to_request();
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&mut req));
|
||||
.to_http_parts();
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
|
||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/json"),
|
||||
@ -491,12 +489,12 @@ mod tests {
|
||||
header::CONTENT_LENGTH,
|
||||
header::HeaderValue::from_static("10000"),
|
||||
)
|
||||
.to_request();
|
||||
.to_http_parts();
|
||||
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&mut req).limit(100));
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl).limit(100));
|
||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow));
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/json"),
|
||||
@ -506,9 +504,9 @@ mod tests {
|
||||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.to_request();
|
||||
.to_http_parts();
|
||||
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&mut req));
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
|
||||
assert_eq!(
|
||||
json.ok().unwrap(),
|
||||
MyObject {
|
||||
|
@ -6,8 +6,8 @@ use actix_http::error::{Error, ErrorNotFound};
|
||||
use actix_router::PathDeserializer;
|
||||
use serde::de;
|
||||
|
||||
use crate::dev::Payload;
|
||||
use crate::request::HttpRequest;
|
||||
use crate::service::ServiceFromRequest;
|
||||
use crate::FromRequest;
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
@ -66,15 +66,6 @@ impl<T> Path<T> {
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner
|
||||
}
|
||||
|
||||
/// Extract path information from a request
|
||||
pub fn extract(req: &HttpRequest) -> Result<Path<T>, de::value::Error>
|
||||
where
|
||||
T: de::DeserializeOwned,
|
||||
{
|
||||
de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
|
||||
.map(|inner| Path { inner })
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsRef<T> for Path<T> {
|
||||
@ -169,8 +160,10 @@ where
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
Self::extract(req.request()).map_err(ErrorNotFound)
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
|
||||
.map(|inner| Path { inner })
|
||||
.map_err(ErrorNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,25 +178,30 @@ mod tests {
|
||||
fn test_extract_path_single() {
|
||||
let resource = ResourceDef::new("/{value}/");
|
||||
|
||||
let mut req = TestRequest::with_uri("/32/").to_from();
|
||||
let mut req = TestRequest::with_uri("/32/").to_srv_request();
|
||||
resource.match_path(req.match_info_mut());
|
||||
|
||||
assert_eq!(*Path::<i8>::from_request(&mut req).unwrap(), 32);
|
||||
let (req, mut pl) = req.into_parts();
|
||||
assert_eq!(*Path::<i8>::from_request(&req, &mut pl).unwrap(), 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_extract() {
|
||||
let resource = ResourceDef::new("/{key}/{value}/");
|
||||
|
||||
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_from();
|
||||
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
||||
resource.match_path(req.match_info_mut());
|
||||
|
||||
let res = block_on(<(Path<(String, String)>,)>::from_request(&mut req)).unwrap();
|
||||
let (req, mut pl) = req.into_parts();
|
||||
let res =
|
||||
block_on(<(Path<(String, String)>,)>::from_request(&req, &mut pl)).unwrap();
|
||||
assert_eq!((res.0).0, "name");
|
||||
assert_eq!((res.0).1, "user1");
|
||||
|
||||
let res = block_on(
|
||||
<(Path<(String, String)>, Path<(String, String)>)>::from_request(&mut req),
|
||||
<(Path<(String, String)>, Path<(String, String)>)>::from_request(
|
||||
&req, &mut pl,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!((res.0).0, "name");
|
||||
@ -211,7 +209,7 @@ mod tests {
|
||||
assert_eq!((res.1).0, "name");
|
||||
assert_eq!((res.1).1, "user1");
|
||||
|
||||
let () = <()>::from_request(&mut req).unwrap();
|
||||
let () = <()>::from_request(&req, &mut pl).unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,9 +10,10 @@ use futures::future::{err, Either, FutureResult};
|
||||
use futures::{Future, Poll, Stream};
|
||||
use mime::Mime;
|
||||
|
||||
use crate::dev;
|
||||
use crate::extract::FromRequest;
|
||||
use crate::http::header;
|
||||
use crate::service::ServiceFromRequest;
|
||||
use crate::request::HttpRequest;
|
||||
|
||||
/// Payload extractor returns request 's payload stream.
|
||||
///
|
||||
@ -92,8 +93,8 @@ where
|
||||
type Future = Result<Payload, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
let pl = match req.take_payload() {
|
||||
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);
|
||||
@ -141,7 +142,7 @@ where
|
||||
Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
let mut tmp;
|
||||
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
|
||||
cfg
|
||||
@ -155,7 +156,9 @@ where
|
||||
}
|
||||
|
||||
let limit = cfg.limit;
|
||||
Either::A(Box::new(HttpMessageBody::new(req).limit(limit).from_err()))
|
||||
Either::A(Box::new(
|
||||
HttpMessageBody::new(req, payload).limit(limit).from_err(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,7 +197,7 @@ where
|
||||
Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
let mut tmp;
|
||||
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
|
||||
cfg
|
||||
@ -216,7 +219,7 @@ where
|
||||
let limit = cfg.limit;
|
||||
|
||||
Either::A(Box::new(
|
||||
HttpMessageBody::new(req)
|
||||
HttpMessageBody::new(req, payload)
|
||||
.limit(limit)
|
||||
.from_err()
|
||||
.and_then(move |body| {
|
||||
@ -260,7 +263,7 @@ impl PayloadConfig {
|
||||
self
|
||||
}
|
||||
|
||||
fn check_mimetype<P>(&self, req: &ServiceFromRequest<P>) -> Result<(), Error> {
|
||||
fn check_mimetype(&self, req: &HttpRequest) -> Result<(), Error> {
|
||||
// check content-type
|
||||
if let Some(ref mt) = self.mimetype {
|
||||
match req.mime_type() {
|
||||
@ -297,21 +300,20 @@ 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<T: HttpMessage> {
|
||||
pub struct HttpMessageBody<P> {
|
||||
limit: usize,
|
||||
length: Option<usize>,
|
||||
stream: actix_http::Payload<T::Stream>,
|
||||
stream: dev::Payload<P>,
|
||||
err: Option<PayloadError>,
|
||||
fut: Option<Box<Future<Item = Bytes, Error = PayloadError>>>,
|
||||
}
|
||||
|
||||
impl<T> HttpMessageBody<T>
|
||||
impl<P> HttpMessageBody<P>
|
||||
where
|
||||
T: HttpMessage,
|
||||
T::Stream: Stream<Item = Bytes, Error = PayloadError>,
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
/// Create `MessageBody` for request.
|
||||
pub fn new(req: &mut T) -> HttpMessageBody<T> {
|
||||
pub fn new(req: &HttpRequest, payload: &mut dev::Payload<P>) -> HttpMessageBody<P> {
|
||||
let mut len = None;
|
||||
if let Some(l) = req.headers().get(&header::CONTENT_LENGTH) {
|
||||
if let Ok(s) = l.to_str() {
|
||||
@ -326,7 +328,7 @@ where
|
||||
}
|
||||
|
||||
HttpMessageBody {
|
||||
stream: req.take_payload(),
|
||||
stream: payload.take(),
|
||||
limit: 262_144,
|
||||
length: len,
|
||||
fut: None,
|
||||
@ -342,7 +344,7 @@ where
|
||||
|
||||
fn err(e: PayloadError) -> Self {
|
||||
HttpMessageBody {
|
||||
stream: actix_http::Payload::None,
|
||||
stream: dev::Payload::None,
|
||||
limit: 262_144,
|
||||
fut: None,
|
||||
err: Some(e),
|
||||
@ -351,10 +353,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Future for HttpMessageBody<T>
|
||||
impl<P> Future for HttpMessageBody<P>
|
||||
where
|
||||
T: HttpMessage,
|
||||
T::Stream: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
{
|
||||
type Item = Bytes;
|
||||
type Error = PayloadError;
|
||||
@ -403,7 +404,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_payload_config() {
|
||||
let req = TestRequest::default().to_from();
|
||||
let req = TestRequest::default().to_http_request();
|
||||
let cfg = PayloadConfig::default().mimetype(mime::APPLICATION_JSON);
|
||||
assert!(cfg.check_mimetype(&req).is_err());
|
||||
|
||||
@ -411,62 +412,64 @@ mod tests {
|
||||
header::CONTENT_TYPE,
|
||||
"application/x-www-form-urlencoded",
|
||||
)
|
||||
.to_from();
|
||||
.to_http_request();
|
||||
assert!(cfg.check_mimetype(&req).is_err());
|
||||
|
||||
let req =
|
||||
TestRequest::with_header(header::CONTENT_TYPE, "application/json").to_from();
|
||||
let req = TestRequest::with_header(header::CONTENT_TYPE, "application/json")
|
||||
.to_http_request();
|
||||
assert!(cfg.check_mimetype(&req).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes() {
|
||||
let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_from();
|
||||
.to_http_parts();
|
||||
|
||||
let s = block_on(Bytes::from_request(&mut req)).unwrap();
|
||||
let s = block_on(Bytes::from_request(&req, &mut pl)).unwrap();
|
||||
assert_eq!(s, Bytes::from_static(b"hello=world"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string() {
|
||||
let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_from();
|
||||
.to_http_parts();
|
||||
|
||||
let s = block_on(String::from_request(&mut req)).unwrap();
|
||||
let s = block_on(String::from_request(&req, &mut pl)).unwrap();
|
||||
assert_eq!(s, "hello=world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_message_body() {
|
||||
let mut req =
|
||||
TestRequest::with_header(header::CONTENT_LENGTH, "xxxx").to_request();
|
||||
let res = block_on(HttpMessageBody::new(&mut req));
|
||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "xxxx")
|
||||
.to_srv_request()
|
||||
.into_parts();
|
||||
let res = block_on(HttpMessageBody::new(&req, &mut pl));
|
||||
match res.err().unwrap() {
|
||||
PayloadError::UnknownLength => (),
|
||||
_ => unreachable!("error"),
|
||||
}
|
||||
|
||||
let mut req =
|
||||
TestRequest::with_header(header::CONTENT_LENGTH, "1000000").to_request();
|
||||
let res = block_on(HttpMessageBody::new(&mut req));
|
||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "1000000")
|
||||
.to_srv_request()
|
||||
.into_parts();
|
||||
let res = block_on(HttpMessageBody::new(&req, &mut pl));
|
||||
match res.err().unwrap() {
|
||||
PayloadError::Overflow => (),
|
||||
_ => unreachable!("error"),
|
||||
}
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.set_payload(Bytes::from_static(b"test"))
|
||||
.to_request();
|
||||
let res = block_on(HttpMessageBody::new(&mut req));
|
||||
.to_http_parts();
|
||||
let res = block_on(HttpMessageBody::new(&req, &mut pl));
|
||||
assert_eq!(res.ok().unwrap(), Bytes::from_static(b"test"));
|
||||
|
||||
let mut req = TestRequest::default()
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
.set_payload(Bytes::from_static(b"11111111111111"))
|
||||
.to_request();
|
||||
let res = block_on(HttpMessageBody::new(&mut req).limit(5));
|
||||
.to_http_parts();
|
||||
let res = block_on(HttpMessageBody::new(&req, &mut pl).limit(5));
|
||||
match res.err().unwrap() {
|
||||
PayloadError::Overflow => (),
|
||||
_ => unreachable!("error"),
|
||||
|
@ -6,8 +6,9 @@ use actix_http::error::Error;
|
||||
use serde::de;
|
||||
use serde_urlencoded;
|
||||
|
||||
use crate::dev::Payload;
|
||||
use crate::extract::FromRequest;
|
||||
use crate::service::ServiceFromRequest;
|
||||
use crate::request::HttpRequest;
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
/// Extract typed information from from the request's query.
|
||||
@ -118,8 +119,8 @@ where
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||
serde_urlencoded::from_str::<T>(req.request().query_string())
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
serde_urlencoded::from_str::<T>(req.query_string())
|
||||
.map(|val| Ok(Query(val)))
|
||||
.unwrap_or_else(|e| Err(e.into()))
|
||||
}
|
||||
|
Reference in New Issue
Block a user