1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-25 19:11:10 +00:00

Payload extractor

This commit is contained in:
Nikolay Kim 2019-03-07 13:33:40 -08:00
parent d77954d19e
commit b211966c28
4 changed files with 107 additions and 52 deletions

View file

@ -1,31 +0,0 @@
use std::collections::HashSet;
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn;
/// Thrift mux server impl
pub struct Server {}
impl Server {
fn new() -> Server {
Server {}
}
/// generate servers
pub fn generate(input: TokenStream) {
let mut srv = Server::new();
let ast: syn::ItemFn = syn::parse2(input).unwrap();
println!("T: {:?}", ast.ident);
// quote! {
// #ast
// #(#servers)*
// }
}
}

View file

@ -1,6 +1,8 @@
use futures::IntoFuture;
use actix_web::macros::get;
#[macro_use]
extern crate actix_web;
use actix_web::{middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer};
#[get("/resource1/{name}/index.html")]

View file

@ -409,7 +409,7 @@ impl<T> DerefMut for Form<T> {
impl<T, P> FromRequest<P> for Form<T>
where
T: DeserializeOwned + 'static,
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
{
type Error = Error;
type Future = Box<Future<Item = Self, Error = Error>>;
@ -653,7 +653,7 @@ impl<T: Serialize> Responder for Json<T> {
impl<T, P> FromRequest<P> for Json<T>
where
T: DeserializeOwned + 'static,
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
{
type Error = Error;
type Future = Box<Future<Item = Self, Error = Error>>;
@ -739,6 +739,97 @@ impl Default for JsonConfig {
}
}
/// Payload extractor returns request 's payload stream.
///
/// ## Example
///
/// ```rust
/// use futures::{Future, Stream};
/// use actix_web::{web, error, App, Error, HttpResponse};
///
/// /// extract binary data from request
/// fn index<P>(body: web::Payload<P>) -> impl Future<Item = HttpResponse, Error = Error>
/// where
/// P: Stream<Item = web::Bytes, Error = error::PayloadError>
/// {
/// body.map_err(Error::from)
/// .fold(web::BytesMut::new(), move |mut body, chunk| {
/// body.extend_from_slice(&chunk);
/// Ok::<_, Error>(body)
/// })
/// .and_then(|body| {
/// format!("Body {:?}!", body);
/// Ok(HttpResponse::Ok().finish())
/// })
/// }
///
/// fn main() {
/// let app = App::new().service(
/// web::resource("/index.html").route(
/// web::get().to_async(index))
/// );
/// }
/// ```
pub struct Payload<T>(crate::dev::Payload<T>);
impl<T> Stream for Payload<T>
where
T: Stream<Item = Bytes, Error = PayloadError>,
{
type Item = Bytes;
type Error = PayloadError;
#[inline]
fn poll(&mut self) -> Poll<Option<Self::Item>, PayloadError> {
self.0.poll()
}
}
/// Get request's payload stream
///
/// ## Example
///
/// ```rust
/// use futures::{Future, Stream};
/// use actix_web::{web, error, App, Error, HttpResponse};
///
/// /// extract binary data from request
/// fn index<P>(body: web::Payload<P>) -> impl Future<Item = HttpResponse, Error = Error>
/// where
/// P: Stream<Item = web::Bytes, Error = error::PayloadError>
/// {
/// body.map_err(Error::from)
/// .fold(web::BytesMut::new(), move |mut body, chunk| {
/// body.extend_from_slice(&chunk);
/// Ok::<_, Error>(body)
/// })
/// .and_then(|body| {
/// format!("Body {:?}!", body);
/// Ok(HttpResponse::Ok().finish())
/// })
/// }
///
/// fn main() {
/// let app = App::new().service(
/// web::resource("/index.html").route(
/// web::get().to_async(index))
/// );
/// }
/// ```
impl<P> FromRequest<P> for Payload<P>
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
type Error = Error;
type Future = Result<Payload<P>, Error>;
type Config = ();
#[inline]
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
Ok(Payload(req.take_payload()))
}
}
/// Request binary data from a request's payload.
///
/// Loads request's payload and construct Bytes instance.

View file

@ -18,23 +18,12 @@ mod service;
mod state;
pub mod test;
/// Attribute macros for route registration
///
/// ```rust
/// use actix_web::{macros, App, HttpResponse};
///
/// #[macros::get("/index.html")]
/// fn index() -> HttpResponse {
/// HttpResponse::Ok().finish()
/// }
///
/// fn main() {
/// let app = App::new().service(index);
/// }
/// ```
pub mod macros {
pub use actix_web_codegen::{get, post, put};
}
#[allow(unused_imports)]
#[macro_use]
extern crate actix_web_codegen;
#[doc(hidden)]
pub use actix_web_codegen::*;
// re-export for convenience
pub use actix_http::Response as HttpResponse;
@ -85,6 +74,9 @@ pub mod web {
use actix_http::{http::Method, Error, Response};
use futures::IntoFuture;
pub use actix_http::Response as HttpResponse;
pub use bytes::{Bytes, BytesMut};
use crate::extract::FromRequest;
use crate::handler::{AsyncFactory, Factory};
use crate::resource::Resource;
@ -92,7 +84,8 @@ pub mod web {
use crate::route::Route;
use crate::scope::Scope;
pub use crate::extract::{Json, Path, Query};
pub use crate::extract::{Json, Path, Payload, Query};
pub use crate::request::HttpRequest;
pub use crate::state::State;
/// Create resource for a specific path.