mirror of https://github.com/rwf2/Rocket.git
parent
9d56249d86
commit
e493be8d3c
|
@ -211,6 +211,12 @@ pub fn derive_from_form(input: proc_macro::TokenStream) -> TokenStream {
|
|||
__fut.await;
|
||||
})))
|
||||
)
|
||||
.inner_mapper(MapperBuild::new()
|
||||
.with_output(|_, _| quote! {
|
||||
fn push_error(__c: &mut Self::Context, __e: #_form::Error<'r>) {
|
||||
__c.__errors.push(__e);
|
||||
}
|
||||
}))
|
||||
.inner_mapper(MapperBuild::new()
|
||||
.with_output(|_, output| quote! {
|
||||
fn finalize(mut __c: Self::Context) -> #_Result<Self, #_form::Errors<'r>> {
|
||||
|
|
|
@ -67,10 +67,17 @@ impl<'r, 'i> Parser<'r, 'i> {
|
|||
.get("data-form")
|
||||
.unwrap_or(Limits::DATA_FORM);
|
||||
|
||||
// Increase internal limit by 1 so multer can limit to `form_limit`.
|
||||
let stream = data.open(form_limit + 1);
|
||||
let constraints = multer::Constraints::new()
|
||||
.size_limit(multer::SizeLimit::new()
|
||||
.whole_stream(form_limit.into())
|
||||
.per_field(form_limit.into()));
|
||||
|
||||
Ok(Parser::Multipart(MultipartParser {
|
||||
request: req,
|
||||
buffer: local_cache_once!(req, SharedStack::new()),
|
||||
source: Multipart::with_reader(data.open(form_limit), boundary),
|
||||
source: Multipart::with_reader_with_constraints(stream, boundary, constraints),
|
||||
done: false,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#[macro_use] extern crate rocket;
|
||||
|
||||
use rocket::{Config, Build, Rocket};
|
||||
use rocket::{data::Limits, form::Form};
|
||||
use rocket::http::{ContentType, Status};
|
||||
use ubyte::{ToByteUnit, ByteUnit};
|
||||
|
||||
#[derive(FromForm)]
|
||||
struct Data<'r> {
|
||||
foo: Option<&'r str>,
|
||||
}
|
||||
|
||||
#[rocket::post("/", data = "<form>")]
|
||||
fn form<'r>(form: Form<Data<'r>>) -> &'r str {
|
||||
form.foo.unwrap_or("missing")
|
||||
}
|
||||
|
||||
fn rocket_with_form_data_limit(limit: ByteUnit) -> Rocket<Build> {
|
||||
rocket::custom(Config {
|
||||
limits: Limits::default().limit("data-form", limit),
|
||||
..Config::debug_default()
|
||||
}).mount("/", routes![form])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multipart_limit() {
|
||||
use rocket::local::blocking::Client;
|
||||
|
||||
let body = &[
|
||||
"--X-BOUNDARY",
|
||||
r#"Content-Disposition: form-data; name="foo"; filename="foo.txt""#,
|
||||
"Content-Type: text/plain",
|
||||
"",
|
||||
"hi",
|
||||
"--X-BOUNDARY--",
|
||||
"",
|
||||
].join("\r\n");
|
||||
|
||||
let client = Client::debug(rocket_with_form_data_limit(body.len().bytes())).unwrap();
|
||||
let response = client.post("/")
|
||||
.header("multipart/form-data; boundary=X-BOUNDARY".parse::<ContentType>().unwrap())
|
||||
.body(body)
|
||||
.dispatch();
|
||||
|
||||
assert_eq!(response.into_string().unwrap(), "hi");
|
||||
|
||||
let client = Client::debug(rocket_with_form_data_limit(body.len().bytes() - 1)).unwrap();
|
||||
let response = client.post("/")
|
||||
.header("multipart/form-data; boundary=X-BOUNDARY".parse::<ContentType>().unwrap())
|
||||
.body(body)
|
||||
.dispatch();
|
||||
|
||||
assert_eq!(response.status(), Status::PayloadTooLarge);
|
||||
}
|
Loading…
Reference in New Issue