mirror of https://github.com/fafhrd91/actix-web
build values from complete byte objects
This commit is contained in:
parent
90b122c999
commit
daf148a3d7
|
@ -76,21 +76,21 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||||
quote! { #ident: self.#ident.unwrap() }
|
quote! { #ident: self.#ident.unwrap() }
|
||||||
});
|
});
|
||||||
|
|
||||||
let field_appending = fields.iter().map(|f| {
|
let bytes_appending = fields.iter().map(|f| {
|
||||||
|
let Field { ident, .. } = f;
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
stringify!(#ident) => field_bytes.put(chunk),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let fields_from_bytes = fields.iter().map(|f| {
|
||||||
let Field { ident, ty, .. } = f;
|
let Field { ident, ty, .. } = f;
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
stringify!(#ident) => match builder.#ident {
|
stringify!(#ident) => {
|
||||||
Some(ref mut field) => {
|
builder.#ident.replace(#ty::from_bytes(field_bytes));
|
||||||
field.append(chunk);
|
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
let mut field = #ty::default();
|
|
||||||
field.append(chunk);
|
|
||||||
builder.#ident.replace(field);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,9 +121,11 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
fn from_request(req: &::actix_web::HttpRequest, payload: &mut ::actix_web::dev::Payload) -> Self::Future {
|
fn from_request(req: &::actix_web::HttpRequest, payload: &mut ::actix_web::dev::Payload) -> Self::Future {
|
||||||
use futures_util::future::FutureExt;
|
use ::futures_util::future::FutureExt;
|
||||||
use futures_util::stream::StreamExt;
|
use ::futures_util::stream::StreamExt;
|
||||||
use actix_multipart::BuildFromBytes;
|
use ::actix_web::error;
|
||||||
|
use ::actix_multipart::{FromBytes, Multipart};
|
||||||
|
use ::bytes::{BufMut, BytesMut};
|
||||||
|
|
||||||
let pl = payload.take();
|
let pl = payload.take();
|
||||||
let req2 = req.clone();
|
let req2 = req.clone();
|
||||||
|
@ -140,26 +142,36 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
let cd = field.content_disposition().unwrap();
|
let cd = field.content_disposition().unwrap();
|
||||||
let name = cd.get_name().unwrap();
|
let name = cd.get_name().unwrap();
|
||||||
println!("FIELD: {}", name);
|
|
||||||
|
|
||||||
let mut size = 0;
|
let mut size = 0;
|
||||||
|
let mut field_bytes = BytesMut::new();
|
||||||
|
|
||||||
while let Some(chunk) = field.next().await {
|
while let Some(chunk) = field.next().await {
|
||||||
let chunk = chunk?;
|
let chunk = chunk?;
|
||||||
size += chunk.len();
|
size += chunk.len();
|
||||||
|
|
||||||
if (size > #b_ident::max_size(&name).unwrap_or(std::usize::MAX)) {
|
if (size > #b_ident::max_size(&name).unwrap_or(std::usize::MAX)) {
|
||||||
return Err(::actix_web::error::ErrorPayloadTooLarge("field is too large"));
|
return Err(error::ErrorPayloadTooLarge("field is too large"));
|
||||||
}
|
}
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
#(#field_appending)*
|
#(#bytes_appending)*
|
||||||
|
|
||||||
_ => todo!("unknown field"),
|
_ => {
|
||||||
|
// unknown field
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!();
|
let field_bytes = field_bytes.freeze();
|
||||||
|
|
||||||
|
match name {
|
||||||
|
#(#fields_from_bytes)*
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
// unknown field
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.build()
|
builder.build()
|
||||||
|
|
|
@ -1,18 +1,25 @@
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
|
||||||
pub trait BuildFromBytes {
|
pub trait FromBytes {
|
||||||
fn append(&mut self, next: Bytes);
|
fn from_bytes(next: Bytes) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuildFromBytes for String {
|
impl FromBytes for String {
|
||||||
fn append(&mut self, chunk: Bytes) {
|
fn from_bytes(bytes: Bytes) -> Self {
|
||||||
let chunk_str = std::str::from_utf8(&chunk).expect("string field is not utf-8");
|
std::str::from_utf8(&bytes)
|
||||||
self.push_str(chunk_str);
|
.expect("string field is not utf-8")
|
||||||
|
.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuildFromBytes for BytesMut {
|
impl FromBytes for Bytes {
|
||||||
fn append(&mut self, chunk: Bytes) {
|
fn from_bytes(bytes: Bytes) -> Self {
|
||||||
self.put(&chunk[..]);
|
bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromBytes for BytesMut {
|
||||||
|
fn from_bytes(bytes: Bytes) -> Self {
|
||||||
|
BytesMut::from(bytes.as_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@ mod error;
|
||||||
mod extractor;
|
mod extractor;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
pub use self::byte_builder::BuildFromBytes;
|
pub use self::byte_builder::FromBytes;
|
||||||
pub use self::error::MultipartError;
|
pub use self::error::MultipartError;
|
||||||
pub use self::server::{Field, Multipart};
|
pub use self::server::{Field, Multipart};
|
||||||
|
|
Loading…
Reference in New Issue