mirror of https://github.com/fafhrd91/actix-web
support max_size attribute
This commit is contained in:
parent
9161f279de
commit
90b122c999
|
@ -10,6 +10,7 @@ proc-macro = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quote = "1"
|
quote = "1"
|
||||||
syn = { version = "1", features = ["extra-traits"] }
|
syn = { version = "1", features = ["extra-traits"] }
|
||||||
|
proc-macro2 = "1"
|
||||||
|
|
||||||
# [dev-dependencies]
|
# [dev-dependencies]
|
||||||
actix-multipart = "0.3.0-beta.1"
|
actix-multipart = "0.3.0-beta.1"
|
||||||
|
|
|
@ -2,6 +2,7 @@ use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident,
|
parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident,
|
||||||
|
Meta, MetaList, MetaNameValue, NestedMeta, Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[proc_macro_derive(MultipartForm, attributes(multipart))]
|
#[proc_macro_derive(MultipartForm, attributes(multipart))]
|
||||||
|
@ -29,12 +30,45 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||||
});
|
});
|
||||||
|
|
||||||
let field_max_sizes = fields.iter().map(|f| {
|
let field_max_sizes = fields.iter().map(|f| {
|
||||||
let Field { ident, .. } = f;
|
let Field { ident, attrs, .. } = f;
|
||||||
|
|
||||||
// TODO: parse field attributes find
|
for attr in attrs {
|
||||||
// #[multipart(max_size = n)]
|
// TODO: use something like https://github.com/TedDriggs/darling ??
|
||||||
|
|
||||||
quote! { stringify!(#ident) => Some(8096) }
|
if let Ok(m) = attr.parse_meta() {
|
||||||
|
if let Meta::List(MetaList { path, nested, .. }) = m {
|
||||||
|
if path.get_ident().unwrap()
|
||||||
|
!= &Ident::new("multipart", proc_macro2::Span::call_site())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// it's our meta list, marked by multipart
|
||||||
|
|
||||||
|
if let Some(NestedMeta::Meta(Meta::NameValue(MetaNameValue {
|
||||||
|
path: Path { segments, .. },
|
||||||
|
lit,
|
||||||
|
..
|
||||||
|
}))) = nested.first()
|
||||||
|
{
|
||||||
|
for seg in segments {
|
||||||
|
// if there's a max_size attr in the list, extract the lit
|
||||||
|
if &seg.ident
|
||||||
|
== &Ident::new(
|
||||||
|
"max_size",
|
||||||
|
proc_macro2::Span::call_site(),
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// TODO: ensure literal is numeric
|
||||||
|
return quote! { stringify!(#ident) => Some(#lit) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quote! { stringify!(#ident) => None }
|
||||||
});
|
});
|
||||||
|
|
||||||
let build_fields = fields.iter().map(|f| {
|
let build_fields = fields.iter().map(|f| {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use bytes::BytesMut;
|
||||||
struct Form {
|
struct Form {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
||||||
#[multipart(max_size = 8096)]
|
#[multipart(max_size = 1024)]
|
||||||
file: BytesMut,
|
file: BytesMut,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
|
|
||||||
|
pub trait BuildFromBytes {
|
||||||
|
fn append(&mut self, next: Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildFromBytes for String {
|
||||||
|
fn append(&mut self, chunk: Bytes) {
|
||||||
|
let chunk_str = std::str::from_utf8(&chunk).expect("string field is not utf-8");
|
||||||
|
self.push_str(chunk_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildFromBytes for BytesMut {
|
||||||
|
fn append(&mut self, chunk: Bytes) {
|
||||||
|
self.put(&chunk[..]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,27 +1,10 @@
|
||||||
#![allow(clippy::borrow_interior_mutable_const)]
|
#![allow(clippy::borrow_interior_mutable_const)]
|
||||||
|
|
||||||
|
mod byte_builder;
|
||||||
mod error;
|
mod error;
|
||||||
mod extractor;
|
mod extractor;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
|
pub use self::byte_builder::BuildFromBytes;
|
||||||
pub use self::error::MultipartError;
|
pub use self::error::MultipartError;
|
||||||
pub use self::server::{Field, Multipart};
|
pub use self::server::{Field, Multipart};
|
||||||
|
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
|
||||||
|
|
||||||
pub trait BuildFromBytes {
|
|
||||||
fn append(&mut self, next: Bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BuildFromBytes for String {
|
|
||||||
fn append(&mut self, chunk: Bytes) {
|
|
||||||
let chunk_str = std::str::from_utf8(&chunk).expect("string field is not utf-8");
|
|
||||||
self.push_str(chunk_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BuildFromBytes for BytesMut {
|
|
||||||
fn append(&mut self, chunk: Bytes) {
|
|
||||||
self.put(&chunk[..]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue