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]
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["extra-traits"] }
|
||||
proc-macro2 = "1"
|
||||
|
||||
# [dev-dependencies]
|
||||
actix-multipart = "0.3.0-beta.1"
|
||||
|
|
|
@ -2,6 +2,7 @@ use proc_macro::TokenStream;
|
|||
use quote::quote;
|
||||
use syn::{
|
||||
parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident,
|
||||
Meta, MetaList, MetaNameValue, NestedMeta, Path,
|
||||
};
|
||||
|
||||
#[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 { ident, .. } = f;
|
||||
let Field { ident, attrs, .. } = f;
|
||||
|
||||
// TODO: parse field attributes find
|
||||
// #[multipart(max_size = n)]
|
||||
for attr in attrs {
|
||||
// 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| {
|
||||
|
|
|
@ -6,7 +6,7 @@ use bytes::BytesMut;
|
|||
struct Form {
|
||||
name: String,
|
||||
|
||||
#[multipart(max_size = 8096)]
|
||||
#[multipart(max_size = 1024)]
|
||||
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)]
|
||||
|
||||
mod byte_builder;
|
||||
mod error;
|
||||
mod extractor;
|
||||
mod server;
|
||||
|
||||
pub use self::byte_builder::BuildFromBytes;
|
||||
pub use self::error::MultipartError;
|
||||
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