1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 09:42:40 +01:00

add ClientRequestBuilder::form()

This commit is contained in:
Ozgur Akkurt 2018-06-12 19:30:00 +03:00
parent ce6f9e848b
commit d4d3add17d
2 changed files with 64 additions and 0 deletions

View File

@ -10,6 +10,7 @@ use futures::Stream;
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET}; use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
use serde::Serialize; use serde::Serialize;
use serde_json; use serde_json;
use serde_urlencoded;
use url::Url; use url::Url;
use super::body::ClientBody; use super::body::ClientBody;
@ -659,6 +660,24 @@ impl ClientRequestBuilder {
self.body(body) self.body(body)
} }
/// Set a urlencoded body and generate `ClientRequest`
///
/// `ClientRequestBuilder` can not be used after this call.
pub fn form<T: Serialize>(&mut self, value: T) -> Result<ClientRequest, Error> {
let body = serde_urlencoded::to_string(&value)?;
let contains = if let Some(parts) = parts(&mut self.request, &self.err) {
parts.headers.contains_key(header::CONTENT_TYPE)
} else {
true
};
if !contains {
self.header(header::CONTENT_TYPE, "application/x-www-form-urlencoded");
}
self.body(body)
}
/// Set a streaming body and generate `ClientRequest`. /// Set a streaming body and generate `ClientRequest`.
/// ///
/// `ClientRequestBuilder` can not be used after this call. /// `ClientRequestBuilder` can not be used after this call.

View File

@ -16,6 +16,7 @@ use http_range::HttpRangeParseError;
use httparse; use httparse;
use serde::de::value::Error as DeError; use serde::de::value::Error as DeError;
use serde_json::error::Error as JsonError; use serde_json::error::Error as JsonError;
use serde_urlencoded::ser::Error as FormError;
use tokio_timer::Error as TimerError; use tokio_timer::Error as TimerError;
pub use url::ParseError as UrlParseError; pub use url::ParseError as UrlParseError;
@ -205,6 +206,9 @@ impl From<failure::Error> for Error {
/// `InternalServerError` for `JsonError` /// `InternalServerError` for `JsonError`
impl ResponseError for JsonError {} impl ResponseError for JsonError {}
/// `InternalServerError` for `FormError`
impl ResponseError for FormError {}
/// `InternalServerError` for `TimerError` /// `InternalServerError` for `TimerError`
impl ResponseError for TimerError {} impl ResponseError for TimerError {}
@ -586,6 +590,47 @@ impl From<JsonError> for JsonPayloadError {
} }
} }
/// A set of errors that can occur during parsing json payloads
#[derive(Fail, Debug)]
pub enum FormPayloadError {
/// Payload size is bigger than allowed. (default: 256kB)
#[fail(display = "Form payload size is bigger than allowed. (default: 256kB)")]
Overflow,
/// Content type error
#[fail(display = "Content type error")]
ContentType,
/// Deserialize error
#[fail(display = "Form deserialize error: {}", _0)]
Deserialize(#[cause] FormError),
/// Payload error
#[fail(display = "Error that occur during reading payload: {}", _0)]
Payload(#[cause] PayloadError),
}
/// Return `BadRequest` for `UrlencodedError`
impl ResponseError for FormPayloadError {
fn error_response(&self) -> HttpResponse {
match *self {
FormPayloadError::Overflow => {
HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE)
}
_ => HttpResponse::new(StatusCode::BAD_REQUEST),
}
}
}
impl From<PayloadError> for FormPayloadError {
fn from(err: PayloadError) -> FormPayloadError {
FormPayloadError::Payload(err)
}
}
impl From<FormError> for FormPayloadError {
fn from(err: FormError) -> FormPayloadError {
FormPayloadError::Deserialize(err)
}
}
/// Errors which can occur when attempting to interpret a segment string as a /// Errors which can occur when attempting to interpret a segment string as a
/// valid path segment. /// valid path segment.
#[derive(Fail, Debug, PartialEq)] #[derive(Fail, Debug, PartialEq)]