mirror of
https://github.com/fafhrd91/actix-web
synced 2025-06-27 07:19:04 +02:00
apply standard formatting
This commit is contained in:
@ -99,8 +99,7 @@ fn responder(c: &mut Criterion) {
|
||||
let req = TestRequest::default().to_http_request();
|
||||
c.bench_function("responder", move |b| {
|
||||
b.iter_custom(|_| {
|
||||
let responders =
|
||||
(0..100_000).map(|_| StringResponder(String::from("Hello World!!")));
|
||||
let responders = (0..100_000).map(|_| StringResponder(String::from("Hello World!!")));
|
||||
|
||||
let start = Instant::now();
|
||||
let _res = rt.block_on(async {
|
||||
|
@ -1,11 +1,12 @@
|
||||
use actix_service::Service;
|
||||
use actix_web::dev::{ServiceRequest, ServiceResponse};
|
||||
use actix_web::{web, App, Error, HttpResponse};
|
||||
use criterion::{criterion_main, Criterion};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use actix_web::test::{init_service, ok_service, TestRequest};
|
||||
use actix_service::Service;
|
||||
use actix_web::{
|
||||
dev::{ServiceRequest, ServiceResponse},
|
||||
test::{init_service, ok_service, TestRequest},
|
||||
web, App, Error, HttpResponse,
|
||||
};
|
||||
use criterion::{criterion_main, Criterion};
|
||||
|
||||
/// Criterion Benchmark for async Service
|
||||
/// Should be used from within criterion group:
|
||||
|
@ -7,8 +7,7 @@
|
||||
use std::{any::Any, io, net::SocketAddr};
|
||||
|
||||
use actix_web::{
|
||||
dev::Extensions, rt::net::TcpStream, web, App, HttpRequest, HttpResponse, HttpServer,
|
||||
Responder,
|
||||
dev::Extensions, rt::net::TcpStream, web, App, HttpRequest, HttpResponse, HttpServer, Responder,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -24,9 +23,7 @@ async fn route_whoami(req: HttpRequest) -> impl Responder {
|
||||
Some(info) => HttpResponse::Ok().body(format!(
|
||||
"Here is some info about your connection:\n\n{info:#?}",
|
||||
)),
|
||||
None => {
|
||||
HttpResponse::InternalServerError().body("Missing expected request extension data")
|
||||
}
|
||||
None => HttpResponse::InternalServerError().body("Missing expected request extension data"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,12 +264,8 @@ where
|
||||
pub fn default_service<F, U>(mut self, svc: F) -> Self
|
||||
where
|
||||
F: IntoServiceFactory<U, ServiceRequest>,
|
||||
U: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
|
||||
+ 'static,
|
||||
U::InitError: fmt::Debug,
|
||||
{
|
||||
let svc = svc
|
||||
|
@ -348,13 +348,17 @@ impl ServiceFactory<ServiceRequest> for AppEntry {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
};
|
||||
|
||||
use actix_service::Service;
|
||||
|
||||
use crate::test::{init_service, TestRequest};
|
||||
use crate::{web, App, HttpResponse};
|
||||
use crate::{
|
||||
test::{init_service, TestRequest},
|
||||
web, App, HttpResponse,
|
||||
};
|
||||
|
||||
struct DropData(Arc<AtomicBool>);
|
||||
|
||||
|
@ -232,12 +232,8 @@ impl ServiceConfig {
|
||||
pub fn default_service<F, U>(&mut self, f: F) -> &mut Self
|
||||
where
|
||||
F: IntoServiceFactory<U, ServiceRequest>,
|
||||
U: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
|
||||
+ 'static,
|
||||
U::InitError: std::fmt::Debug,
|
||||
{
|
||||
let svc = f
|
||||
@ -308,9 +304,11 @@ mod tests {
|
||||
use bytes::Bytes;
|
||||
|
||||
use super::*;
|
||||
use crate::http::{Method, StatusCode};
|
||||
use crate::test::{assert_body_eq, call_service, init_service, read_body, TestRequest};
|
||||
use crate::{web, App, HttpRequest, HttpResponse};
|
||||
use crate::{
|
||||
http::{Method, StatusCode},
|
||||
test::{assert_body_eq, call_service, init_service, read_body, TestRequest},
|
||||
web, App, HttpRequest, HttpResponse,
|
||||
};
|
||||
|
||||
// allow deprecated `ServiceConfig::data`
|
||||
#[allow(deprecated)]
|
||||
|
@ -186,12 +186,14 @@ mod tests {
|
||||
#[allow(deprecated)]
|
||||
#[actix_rt::test]
|
||||
async fn test_data_extractor() {
|
||||
let srv = init_service(App::new().data("TEST".to_string()).service(
|
||||
web::resource("/").to(|data: web::Data<String>| {
|
||||
assert_eq!(data.to_lowercase(), "test");
|
||||
HttpResponse::Ok()
|
||||
}),
|
||||
))
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.data("TEST".to_string())
|
||||
.service(web::resource("/").to(|data: web::Data<String>| {
|
||||
assert_eq!(data.to_lowercase(), "test");
|
||||
HttpResponse::Ok()
|
||||
})),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
@ -286,16 +288,17 @@ mod tests {
|
||||
#[allow(deprecated)]
|
||||
#[actix_rt::test]
|
||||
async fn test_override_data() {
|
||||
let srv =
|
||||
init_service(App::new().data(1usize).service(
|
||||
web::resource("/").data(10usize).route(web::get().to(
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.data(1usize)
|
||||
.service(web::resource("/").data(10usize).route(web::get().to(
|
||||
|data: web::Data<usize>| {
|
||||
assert_eq!(**data, 10);
|
||||
HttpResponse::Ok()
|
||||
},
|
||||
)),
|
||||
))
|
||||
.await;
|
||||
))),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
|
@ -7,26 +7,25 @@
|
||||
//! - [`ConnectionInfo`]: Connection information
|
||||
//! - [`PeerAddr`]: Connection information
|
||||
|
||||
#[cfg(feature = "__compress")]
|
||||
pub use actix_http::encoding::Decoder as Decompress;
|
||||
pub use actix_http::{Extensions, Payload, RequestHead, Response, ResponseHead};
|
||||
use actix_router::Patterns;
|
||||
pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
|
||||
pub use actix_server::{Server, ServerHandle};
|
||||
pub use actix_service::{
|
||||
always_ready, fn_factory, fn_service, forward_ready, Service, ServiceFactory, Transform,
|
||||
};
|
||||
|
||||
#[cfg(feature = "__compress")]
|
||||
pub use actix_http::encoding::Decoder as Decompress;
|
||||
|
||||
pub use crate::config::{AppConfig, AppService};
|
||||
#[doc(hidden)]
|
||||
pub use crate::handler::Handler;
|
||||
pub use crate::info::{ConnectionInfo, PeerAddr};
|
||||
pub use crate::rmap::ResourceMap;
|
||||
pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService};
|
||||
|
||||
pub use crate::types::{JsonBody, Readlines, UrlEncoded};
|
||||
|
||||
use actix_router::Patterns;
|
||||
pub use crate::{
|
||||
config::{AppConfig, AppService},
|
||||
info::{ConnectionInfo, PeerAddr},
|
||||
rmap::ResourceMap,
|
||||
service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService},
|
||||
types::{JsonBody, Readlines, UrlEncoded},
|
||||
};
|
||||
|
||||
pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns {
|
||||
match &mut patterns {
|
||||
|
@ -42,8 +42,7 @@ macro_rules! downcast_dyn {
|
||||
/// Downcasts generic body to a specific type.
|
||||
#[allow(dead_code)]
|
||||
pub fn downcast_ref<T: $name + 'static>(&self) -> Option<&T> {
|
||||
if self.__private_get_type_id__(PrivateHelper(())).0
|
||||
== std::any::TypeId::of::<T>()
|
||||
if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::<T>()
|
||||
{
|
||||
// SAFETY: external crates cannot override the default
|
||||
// implementation of `__private_get_type_id__`, since
|
||||
@ -59,8 +58,7 @@ macro_rules! downcast_dyn {
|
||||
/// Downcasts a generic body to a mutable specific type.
|
||||
#[allow(dead_code)]
|
||||
pub fn downcast_mut<T: $name + 'static>(&mut self) -> Option<&mut T> {
|
||||
if self.__private_get_type_id__(PrivateHelper(())).0
|
||||
== std::any::TypeId::of::<T>()
|
||||
if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::<T>()
|
||||
{
|
||||
// SAFETY: external crates cannot override the default
|
||||
// implementation of `__private_get_type_id__`, since
|
||||
@ -76,7 +74,8 @@ macro_rules! downcast_dyn {
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use {downcast_dyn, downcast_get_type_id};
|
||||
pub(crate) use downcast_dyn;
|
||||
pub(crate) use downcast_get_type_id;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -5,14 +5,10 @@
|
||||
// expanded manually.
|
||||
//
|
||||
// See <https://github.com/rust-lang/rust/issues/83375>
|
||||
pub use actix_http::error::{
|
||||
ContentTypeError, DispatchError, HttpError, ParseError, PayloadError,
|
||||
};
|
||||
|
||||
pub use actix_http::error::{ContentTypeError, DispatchError, HttpError, ParseError, PayloadError};
|
||||
use derive_more::{Display, Error, From};
|
||||
use serde_json::error::Error as JsonError;
|
||||
use serde_urlencoded::de::Error as FormDeError;
|
||||
use serde_urlencoded::ser::Error as FormError;
|
||||
use serde_urlencoded::{de::Error as FormDeError, ser::Error as FormError};
|
||||
use url::ParseError as UrlParseError;
|
||||
|
||||
use crate::http::StatusCode;
|
||||
@ -23,10 +19,8 @@ mod internal;
|
||||
mod macros;
|
||||
mod response_error;
|
||||
|
||||
pub use self::error::Error;
|
||||
pub use self::internal::*;
|
||||
pub use self::response_error::ResponseError;
|
||||
pub(crate) use macros::{downcast_dyn, downcast_get_type_id};
|
||||
pub(crate) use self::macros::{downcast_dyn, downcast_get_type_id};
|
||||
pub use self::{error::Error, internal::*, response_error::ResponseError};
|
||||
|
||||
/// A convenience [`Result`](std::result::Result) for Actix Web operations.
|
||||
///
|
||||
|
@ -429,8 +429,10 @@ mod tests {
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::types::{Form, FormConfig};
|
||||
use crate::{
|
||||
test::TestRequest,
|
||||
types::{Form, FormConfig},
|
||||
};
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
struct Info {
|
||||
|
@ -61,8 +61,10 @@ use crate::{http::header::Header, service::ServiceRequest, HttpMessage as _};
|
||||
mod acceptable;
|
||||
mod host;
|
||||
|
||||
pub use self::acceptable::Acceptable;
|
||||
pub use self::host::{Host, HostGuard};
|
||||
pub use self::{
|
||||
acceptable::Acceptable,
|
||||
host::{Host, HostGuard},
|
||||
};
|
||||
|
||||
/// Provides access to request parts that are useful during routing.
|
||||
#[derive(Debug)]
|
||||
|
@ -94,10 +94,7 @@ impl AcceptEncoding {
|
||||
/// includes the server's supported encodings in the body plus a [`Vary`] header.
|
||||
///
|
||||
/// [`Vary`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary
|
||||
pub fn negotiate<'a>(
|
||||
&self,
|
||||
supported: impl Iterator<Item = &'a Encoding>,
|
||||
) -> Option<Encoding> {
|
||||
pub fn negotiate<'a>(&self, supported: impl Iterator<Item = &'a Encoding>) -> Option<Encoding> {
|
||||
// 1. If no Accept-Encoding field is in the request, any content-coding is considered
|
||||
// acceptable by the user agent.
|
||||
|
||||
@ -375,9 +372,7 @@ mod tests {
|
||||
Some(Encoding::deflate())
|
||||
);
|
||||
assert_eq!(
|
||||
test.negotiate(
|
||||
[Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()
|
||||
),
|
||||
test.negotiate([Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()),
|
||||
Some(Encoding::gzip())
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -592,9 +592,8 @@ mod tests {
|
||||
fn test_from_raw_basic() {
|
||||
assert!(ContentDisposition::from_raw(&HeaderValue::from_static("")).is_err());
|
||||
|
||||
let a = HeaderValue::from_static(
|
||||
"form-data; dummy=3; name=upload; filename=\"sample.png\"",
|
||||
);
|
||||
let a =
|
||||
HeaderValue::from_static("form-data; dummy=3; name=upload; filename=\"sample.png\"");
|
||||
let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
|
||||
let b = ContentDisposition {
|
||||
disposition: DispositionType::FormData,
|
||||
@ -648,8 +647,8 @@ mod tests {
|
||||
charset: Charset::Ext(String::from("UTF-8")),
|
||||
language_tag: None,
|
||||
value: vec![
|
||||
0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r',
|
||||
b'a', b't', b'e', b's',
|
||||
0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a',
|
||||
b't', b'e', b's',
|
||||
],
|
||||
})],
|
||||
};
|
||||
@ -665,8 +664,8 @@ mod tests {
|
||||
charset: Charset::Ext(String::from("UTF-8")),
|
||||
language_tag: None,
|
||||
value: vec![
|
||||
0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r',
|
||||
b'a', b't', b'e', b's',
|
||||
0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a',
|
||||
b't', b'e', b's',
|
||||
],
|
||||
})],
|
||||
};
|
||||
@ -742,8 +741,8 @@ mod tests {
|
||||
};
|
||||
assert_eq!(a, b);
|
||||
|
||||
let a = ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param"))
|
||||
.unwrap();
|
||||
let a =
|
||||
ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param")).unwrap();
|
||||
let b = ContentDisposition {
|
||||
disposition: DispositionType::Ext(String::from("unknown-disp-param")),
|
||||
parameters: vec![],
|
||||
@ -782,8 +781,7 @@ mod tests {
|
||||
Mainstream browsers like Firefox (gecko) and Chrome use UTF-8 directly as above.
|
||||
(And now, only UTF-8 is handled by this implementation.)
|
||||
*/
|
||||
let a =
|
||||
HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap();
|
||||
let a = HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap();
|
||||
let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
|
||||
let b = ContentDisposition {
|
||||
disposition: DispositionType::FormData,
|
||||
@ -803,9 +801,7 @@ mod tests {
|
||||
disposition: DispositionType::FormData,
|
||||
parameters: vec![
|
||||
DispositionParam::Name(String::from("upload")),
|
||||
DispositionParam::Filename(String::from(
|
||||
"余固知謇謇之為患兮,忍而不能舍也.pptx",
|
||||
)),
|
||||
DispositionParam::Filename(String::from("余固知謇謇之為患兮,忍而不能舍也.pptx")),
|
||||
],
|
||||
};
|
||||
assert_eq!(a, b);
|
||||
@ -870,8 +866,7 @@ mod tests {
|
||||
};
|
||||
assert_eq!(a, b);
|
||||
|
||||
let a =
|
||||
HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\"");
|
||||
let a = HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\"");
|
||||
let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
|
||||
let b = ContentDisposition {
|
||||
disposition: DispositionType::FormData,
|
||||
|
@ -127,8 +127,7 @@ impl FromStr for ContentRangeSpec {
|
||||
fn from_str(s: &str) -> Result<Self, ParseError> {
|
||||
let res = match split_in_two(s, ' ') {
|
||||
Some(("bytes", resp)) => {
|
||||
let (range, instance_length) =
|
||||
split_in_two(resp, '/').ok_or(ParseError::Header)?;
|
||||
let (range, instance_length) = split_in_two(resp, '/').ok_or(ParseError::Header)?;
|
||||
|
||||
let instance_length = if instance_length == "*" {
|
||||
None
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::CONTENT_TYPE;
|
||||
use mime::Mime;
|
||||
|
||||
use super::CONTENT_TYPE;
|
||||
|
||||
crate::http::header::common_header! {
|
||||
/// `Content-Type` header, defined
|
||||
/// in [RFC 7231 §3.1.1.5](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5)
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::{HttpDate, DATE};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use super::{HttpDate, DATE};
|
||||
|
||||
crate::http::header::common_header! {
|
||||
/// `Date` header, defined
|
||||
/// in [RFC 7231 §7.1.1.2](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2)
|
||||
|
@ -152,9 +152,7 @@ impl FromStr for EntityTag {
|
||||
return Err(crate::error::ParseError::Header);
|
||||
}
|
||||
// The etag is weak if its first char is not a DQUOTE.
|
||||
if slice.len() >= 2
|
||||
&& slice.starts_with('"')
|
||||
&& check_slice_validity(&slice[1..length - 1])
|
||||
if slice.len() >= 2 && slice.starts_with('"') && check_slice_validity(&slice[1..length - 1])
|
||||
{
|
||||
// No need to check if the last char is a DQUOTE,
|
||||
// we already did that above.
|
||||
|
@ -4,9 +4,7 @@ use super::{
|
||||
from_one_raw_str, EntityTag, Header, HeaderName, HeaderValue, HttpDate, InvalidHeaderValue,
|
||||
TryIntoHeaderValue, Writer,
|
||||
};
|
||||
use crate::error::ParseError;
|
||||
use crate::http::header;
|
||||
use crate::HttpMessage;
|
||||
use crate::{error::ParseError, http::header, HttpMessage};
|
||||
|
||||
/// `If-Range` header, defined
|
||||
/// in [RFC 7233 §3.2](https://datatracker.ietf.org/doc/html/rfc7233#section-3.2)
|
||||
|
@ -314,7 +314,7 @@ macro_rules! common_header {
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use {common_header, common_header_test_module};
|
||||
|
||||
pub(crate) use common_header;
|
||||
#[cfg(test)]
|
||||
pub(crate) use common_header_test;
|
||||
pub(crate) use common_header_test_module;
|
||||
|
@ -6,8 +6,6 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
|
||||
// re-export from actix-http
|
||||
// - header name / value types
|
||||
// - relevant traits for converting to header name / value
|
||||
@ -16,6 +14,7 @@ use bytes::{Bytes, BytesMut};
|
||||
// - the few typed headers from actix-http
|
||||
// - header parsing utils
|
||||
pub use actix_http::header::*;
|
||||
use bytes::{Bytes, BytesMut};
|
||||
|
||||
mod accept;
|
||||
mod accept_charset;
|
||||
@ -43,32 +42,33 @@ mod preference;
|
||||
mod range;
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) use macros::common_header_test;
|
||||
pub(crate) use macros::{common_header, common_header_test_module};
|
||||
|
||||
pub use self::accept::Accept;
|
||||
pub use self::accept_charset::AcceptCharset;
|
||||
pub use self::accept_encoding::AcceptEncoding;
|
||||
pub use self::accept_language::AcceptLanguage;
|
||||
pub use self::allow::Allow;
|
||||
pub use self::cache_control::{CacheControl, CacheDirective};
|
||||
pub use self::content_disposition::{ContentDisposition, DispositionParam, DispositionType};
|
||||
pub use self::content_language::ContentLanguage;
|
||||
pub use self::content_range::{ContentRange, ContentRangeSpec};
|
||||
pub use self::content_type::ContentType;
|
||||
pub use self::date::Date;
|
||||
pub use self::encoding::Encoding;
|
||||
pub use self::entity::EntityTag;
|
||||
pub use self::etag::ETag;
|
||||
pub use self::expires::Expires;
|
||||
pub use self::if_match::IfMatch;
|
||||
pub use self::if_modified_since::IfModifiedSince;
|
||||
pub use self::if_none_match::IfNoneMatch;
|
||||
pub use self::if_range::IfRange;
|
||||
pub use self::if_unmodified_since::IfUnmodifiedSince;
|
||||
pub use self::last_modified::LastModified;
|
||||
pub use self::preference::Preference;
|
||||
pub use self::range::{ByteRangeSpec, Range};
|
||||
pub(crate) use self::macros::common_header_test;
|
||||
pub(crate) use self::macros::{common_header, common_header_test_module};
|
||||
pub use self::{
|
||||
accept::Accept,
|
||||
accept_charset::AcceptCharset,
|
||||
accept_encoding::AcceptEncoding,
|
||||
accept_language::AcceptLanguage,
|
||||
allow::Allow,
|
||||
cache_control::{CacheControl, CacheDirective},
|
||||
content_disposition::{ContentDisposition, DispositionParam, DispositionType},
|
||||
content_language::ContentLanguage,
|
||||
content_range::{ContentRange, ContentRangeSpec},
|
||||
content_type::ContentType,
|
||||
date::Date,
|
||||
encoding::Encoding,
|
||||
entity::EntityTag,
|
||||
etag::ETag,
|
||||
expires::Expires,
|
||||
if_match::IfMatch,
|
||||
if_modified_since::IfModifiedSince,
|
||||
if_none_match::IfNoneMatch,
|
||||
if_range::IfRange,
|
||||
if_unmodified_since::IfUnmodifiedSince,
|
||||
last_modified::LastModified,
|
||||
preference::Preference,
|
||||
range::{ByteRangeSpec, Range},
|
||||
};
|
||||
|
||||
/// Format writer ([`fmt::Write`]) for a [`BytesMut`].
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -74,6 +74,11 @@
|
||||
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
||||
pub use actix_http::{body, HttpMessage};
|
||||
#[cfg(feature = "cookies")]
|
||||
#[doc(inline)]
|
||||
pub use cookie;
|
||||
|
||||
mod app;
|
||||
mod app_service;
|
||||
mod config;
|
||||
@ -102,25 +107,21 @@ pub mod test;
|
||||
pub(crate) mod types;
|
||||
pub mod web;
|
||||
|
||||
pub use crate::app::App;
|
||||
#[doc(inline)]
|
||||
pub use crate::error::Result;
|
||||
pub use crate::error::{Error, ResponseError};
|
||||
pub use crate::extract::FromRequest;
|
||||
pub use crate::handler::Handler;
|
||||
pub use crate::request::HttpRequest;
|
||||
pub use crate::resource::Resource;
|
||||
pub use crate::response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder};
|
||||
pub use crate::route::Route;
|
||||
pub use crate::scope::Scope;
|
||||
pub use crate::server::HttpServer;
|
||||
pub use crate::types::Either;
|
||||
|
||||
pub use actix_http::{body, HttpMessage};
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
#[doc(inline)]
|
||||
pub use cookie;
|
||||
pub use crate::{
|
||||
app::App,
|
||||
error::{Error, ResponseError},
|
||||
extract::FromRequest,
|
||||
handler::Handler,
|
||||
request::HttpRequest,
|
||||
resource::Resource,
|
||||
response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder},
|
||||
route::Route,
|
||||
scope::Scope,
|
||||
server::HttpServer,
|
||||
types::Either,
|
||||
};
|
||||
|
||||
macro_rules! codegen_reexport {
|
||||
($name:ident) => {
|
||||
|
@ -146,10 +146,9 @@ mod tests {
|
||||
// easier to code when cookies feature is disabled
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use super::*;
|
||||
|
||||
use actix_service::IntoService;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
dev::ServiceRequest,
|
||||
http::StatusCode,
|
||||
@ -207,9 +206,9 @@ mod tests {
|
||||
#[actix_rt::test]
|
||||
async fn test_condition_scope_middleware() {
|
||||
let srv = |req: ServiceRequest| {
|
||||
Box::pin(async move {
|
||||
Ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||
})
|
||||
Box::pin(
|
||||
async move { Ok(req.into_response(HttpResponse::InternalServerError().finish())) },
|
||||
)
|
||||
};
|
||||
|
||||
let logger = Logger::default();
|
||||
|
@ -540,21 +540,17 @@ mod tests {
|
||||
let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await;
|
||||
let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn default_handlers_separate_client_server() {
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn error_handler_client<B>(
|
||||
mut res: ServiceResponse<B>,
|
||||
) -> Result<ErrorHandlerResponse<B>> {
|
||||
fn error_handler_client<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||
res.response_mut()
|
||||
.headers_mut()
|
||||
.insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
@ -562,9 +558,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn error_handler_server<B>(
|
||||
mut res: ServiceResponse<B>,
|
||||
) -> Result<ErrorHandlerResponse<B>> {
|
||||
fn error_handler_server<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||
res.response_mut()
|
||||
.headers_mut()
|
||||
.insert(CONTENT_TYPE, HeaderValue::from_static("0002"));
|
||||
@ -582,21 +576,17 @@ mod tests {
|
||||
let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await;
|
||||
let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn default_handlers_specialization() {
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn error_handler_client<B>(
|
||||
mut res: ServiceResponse<B>,
|
||||
) -> Result<ErrorHandlerResponse<B>> {
|
||||
fn error_handler_client<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||
res.response_mut()
|
||||
.headers_mut()
|
||||
.insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
@ -624,12 +614,10 @@ mod tests {
|
||||
let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
|
||||
let mw_specific = make_mw(StatusCode::UNPROCESSABLE_ENTITY).await;
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0003");
|
||||
}
|
||||
}
|
||||
|
@ -489,12 +489,8 @@ impl Format {
|
||||
unreachable!("regex and code mismatch")
|
||||
}
|
||||
}
|
||||
"i" => {
|
||||
FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap())
|
||||
}
|
||||
"o" => {
|
||||
FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap())
|
||||
}
|
||||
"i" => FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap()),
|
||||
"o" => FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap()),
|
||||
"e" => FormatText::EnvironHeader(key.as_str().to_owned()),
|
||||
"xi" => FormatText::CustomRequest(key.as_str().to_owned(), None),
|
||||
"xo" => FormatText::CustomResponse(key.as_str().to_owned(), None),
|
||||
@ -710,9 +706,7 @@ impl FormatText {
|
||||
}
|
||||
|
||||
/// Converter to get a String from something that writes to a Formatter.
|
||||
pub(crate) struct FormatDisplay<'a>(
|
||||
&'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>,
|
||||
);
|
||||
pub(crate) struct FormatDisplay<'a>(&'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>);
|
||||
|
||||
impl<'a> fmt::Display for FormatDisplay<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
|
@ -9,14 +9,16 @@ mod logger;
|
||||
mod noop;
|
||||
mod normalize;
|
||||
|
||||
pub use self::compat::Compat;
|
||||
pub use self::condition::Condition;
|
||||
pub use self::default_headers::DefaultHeaders;
|
||||
pub use self::err_handlers::{ErrorHandlerResponse, ErrorHandlers};
|
||||
pub use self::logger::Logger;
|
||||
#[cfg(test)]
|
||||
pub(crate) use self::noop::Noop;
|
||||
pub use self::normalize::{NormalizePath, TrailingSlash};
|
||||
pub use self::{
|
||||
compat::Compat,
|
||||
condition::Condition,
|
||||
default_headers::DefaultHeaders,
|
||||
err_handlers::{ErrorHandlerResponse, ErrorHandlers},
|
||||
logger::Logger,
|
||||
normalize::{NormalizePath, TrailingSlash},
|
||||
};
|
||||
|
||||
#[cfg(feature = "__compress")]
|
||||
mod compress;
|
||||
@ -26,9 +28,8 @@ pub use self::compress::Compress;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{http::StatusCode, App};
|
||||
|
||||
use super::*;
|
||||
use crate::{http::StatusCode, App};
|
||||
|
||||
#[test]
|
||||
fn common_combinations() {
|
||||
|
@ -181,9 +181,8 @@ impl Responder for Redirect {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{dev::Service, http::StatusCode, test, App};
|
||||
|
||||
use super::*;
|
||||
use crate::{dev::Service, http::StatusCode, test, App};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn absolute_redirects() {
|
||||
|
@ -653,13 +653,13 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_drop_http_request_pool() {
|
||||
let srv = init_service(App::new().service(web::resource("/").to(
|
||||
|req: HttpRequest| {
|
||||
let srv = init_service(
|
||||
App::new().service(web::resource("/").to(|req: HttpRequest| {
|
||||
HttpResponse::Ok()
|
||||
.insert_header(("pool_cap", req.app_state().pool().cap))
|
||||
.finish()
|
||||
},
|
||||
)))
|
||||
})),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
@ -807,10 +807,7 @@ mod tests {
|
||||
web::scope("/user/{id}")
|
||||
.service(web::resource("/profile").route(web::get().to(
|
||||
move |req: HttpRequest| {
|
||||
assert_eq!(
|
||||
req.match_pattern(),
|
||||
Some("/user/{id}/profile".to_owned())
|
||||
);
|
||||
assert_eq!(req.match_pattern(), Some("/user/{id}/profile".to_owned()));
|
||||
|
||||
HttpResponse::Ok().finish()
|
||||
},
|
||||
|
@ -353,12 +353,8 @@ where
|
||||
pub fn default_service<F, U>(mut self, f: F) -> Self
|
||||
where
|
||||
F: IntoServiceFactory<U, ServiceRequest>,
|
||||
U: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
|
||||
+ 'static,
|
||||
U::InitError: fmt::Debug,
|
||||
{
|
||||
// create and configure default resource
|
||||
@ -625,10 +621,8 @@ mod tests {
|
||||
let fut = srv.call(req);
|
||||
async {
|
||||
fut.await.map(|mut res| {
|
||||
res.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
);
|
||||
res.headers_mut()
|
||||
.insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
res
|
||||
})
|
||||
}
|
||||
@ -660,12 +654,9 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_pattern() {
|
||||
let srv = init_service(
|
||||
App::new().service(
|
||||
web::resource(["/test", "/test2"])
|
||||
.to(|| async { Ok::<_, Error>(HttpResponse::Ok()) }),
|
||||
),
|
||||
)
|
||||
let srv = init_service(App::new().service(
|
||||
web::resource(["/test", "/test2"]).to(|| async { Ok::<_, Error>(HttpResponse::Ok()) }),
|
||||
))
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
@ -804,17 +795,18 @@ mod tests {
|
||||
#[allow(deprecated)]
|
||||
#[actix_rt::test]
|
||||
async fn test_data_default_service() {
|
||||
let srv = init_service(
|
||||
App::new().data(1usize).service(
|
||||
web::resource("/test")
|
||||
.data(10usize)
|
||||
.default_service(web::to(|data: web::Data<usize>| {
|
||||
assert_eq!(**data, 10);
|
||||
HttpResponse::Ok()
|
||||
})),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let srv =
|
||||
init_service(
|
||||
App::new().data(1usize).service(
|
||||
web::resource("/test")
|
||||
.data(10usize)
|
||||
.default_service(web::to(|data: web::Data<usize>| {
|
||||
assert_eq!(**data, 10);
|
||||
HttpResponse::Ok()
|
||||
})),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::get().uri("/test").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
|
@ -14,8 +14,10 @@ use crate::{
|
||||
body::{BodyStream, BoxBody, MessageBody},
|
||||
dev::Extensions,
|
||||
error::{Error, JsonPayloadError},
|
||||
http::header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue},
|
||||
http::{ConnectionType, StatusCode},
|
||||
http::{
|
||||
header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue},
|
||||
ConnectionType, StatusCode,
|
||||
},
|
||||
BoxError, HttpRequest, HttpResponse, Responder,
|
||||
};
|
||||
|
||||
@ -472,9 +474,8 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_serde_json_in_body() {
|
||||
let resp = HttpResponse::Ok().body(
|
||||
serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap(),
|
||||
);
|
||||
let resp = HttpResponse::Ok()
|
||||
.body(serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap());
|
||||
|
||||
assert_eq!(
|
||||
body::to_bytes(resp.into_body()).await.unwrap().as_ref(),
|
||||
|
@ -1,5 +1,7 @@
|
||||
use actix_http::{
|
||||
body::EitherBody, error::HttpError, header::HeaderMap, header::TryIntoHeaderPair,
|
||||
body::EitherBody,
|
||||
error::HttpError,
|
||||
header::{HeaderMap, TryIntoHeaderPair},
|
||||
StatusCode,
|
||||
};
|
||||
|
||||
@ -168,9 +170,8 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bytes::Bytes;
|
||||
|
||||
use actix_http::body::to_bytes;
|
||||
use bytes::Bytes;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
|
@ -87,8 +87,7 @@ impl HttpResponse {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::http::StatusCode;
|
||||
use crate::HttpResponse;
|
||||
use crate::{http::StatusCode, HttpResponse};
|
||||
|
||||
#[test]
|
||||
fn test_build() {
|
||||
|
@ -5,10 +5,9 @@ mod responder;
|
||||
#[allow(clippy::module_inception)]
|
||||
mod response;
|
||||
|
||||
pub use self::builder::HttpResponseBuilder;
|
||||
pub use self::customize_responder::CustomizeResponder;
|
||||
pub use self::responder::Responder;
|
||||
pub use self::response::HttpResponse;
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
pub use self::response::CookieIter;
|
||||
pub use self::{
|
||||
builder::HttpResponseBuilder, customize_responder::CustomizeResponder, responder::Responder,
|
||||
response::HttpResponse,
|
||||
};
|
||||
|
@ -186,11 +186,10 @@ impl_into_string_responder!(Cow<'_, str>);
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use actix_http::body::to_bytes;
|
||||
use actix_service::Service;
|
||||
use bytes::{Bytes, BytesMut};
|
||||
|
||||
use actix_http::body::to_bytes;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
error,
|
||||
|
@ -8,7 +8,6 @@ use actix_http::{
|
||||
header::HeaderMap,
|
||||
Extensions, Response, ResponseHead, StatusCode,
|
||||
};
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
use {
|
||||
actix_http::{
|
||||
|
@ -290,31 +290,32 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_route() {
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.service(
|
||||
web::resource("/test")
|
||||
.route(web::get().to(HttpResponse::Ok))
|
||||
.route(web::put().to(|| async {
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
}))
|
||||
.route(web::post().to(|| async {
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
Ok::<_, Infallible>(HttpResponse::Created())
|
||||
}))
|
||||
.route(web::delete().to(|| async {
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
})),
|
||||
)
|
||||
.service(web::resource("/json").route(web::get().to(|| async {
|
||||
sleep(Duration::from_millis(25)).await;
|
||||
web::Json(MyObject {
|
||||
name: "test".to_string(),
|
||||
})
|
||||
}))),
|
||||
)
|
||||
.await;
|
||||
let srv =
|
||||
init_service(
|
||||
App::new()
|
||||
.service(
|
||||
web::resource("/test")
|
||||
.route(web::get().to(HttpResponse::Ok))
|
||||
.route(web::put().to(|| async {
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
}))
|
||||
.route(web::post().to(|| async {
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
Ok::<_, Infallible>(HttpResponse::Created())
|
||||
}))
|
||||
.route(web::delete().to(|| async {
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
})),
|
||||
)
|
||||
.service(web::resource("/json").route(web::get().to(|| async {
|
||||
sleep(Duration::from_millis(25)).await;
|
||||
web::Json(MyObject {
|
||||
name: "test".to_string(),
|
||||
})
|
||||
}))),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/test")
|
||||
.method(Method::GET)
|
||||
|
@ -66,8 +66,7 @@
|
||||
// - Re-export but hide the runtime macros because they won't work directly but are required for
|
||||
// `#[actix_web::main]` and `#[actix_web::test]` to work.
|
||||
|
||||
pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner};
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
#[doc(hidden)]
|
||||
pub use actix_macros::{main, test};
|
||||
pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner};
|
||||
|
@ -3,8 +3,8 @@ use std::{cell::RefCell, fmt, future::Future, mem, rc::Rc};
|
||||
use actix_http::{body::MessageBody, Extensions};
|
||||
use actix_router::{ResourceDef, Router};
|
||||
use actix_service::{
|
||||
apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory,
|
||||
ServiceFactoryExt, Transform,
|
||||
apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt,
|
||||
Transform,
|
||||
};
|
||||
use futures_core::future::LocalBoxFuture;
|
||||
use futures_util::future::join_all;
|
||||
@ -273,12 +273,8 @@ where
|
||||
pub fn default_service<F, U>(mut self, f: F) -> Self
|
||||
where
|
||||
F: IntoServiceFactory<U, ServiceRequest>,
|
||||
U: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
|
||||
+ 'static,
|
||||
U::InitError: fmt::Debug,
|
||||
{
|
||||
// create and configure default resource
|
||||
@ -604,11 +600,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_scope() {
|
||||
let srv =
|
||||
init_service(App::new().service(
|
||||
web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok)),
|
||||
))
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.service(web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok))),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/app/path1").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
@ -638,8 +634,7 @@ mod tests {
|
||||
#[actix_rt::test]
|
||||
async fn test_scope_root2() {
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))),
|
||||
App::new().service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))),
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -784,10 +779,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_nested_scope_no_slash() {
|
||||
let srv = init_service(App::new().service(web::scope("/app").service(
|
||||
web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)),
|
||||
)))
|
||||
.await;
|
||||
let srv =
|
||||
init_service(App::new().service(web::scope("/app").service(
|
||||
web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/app/t1/path1").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
@ -845,12 +841,9 @@ mod tests {
|
||||
#[actix_rt::test]
|
||||
async fn test_nested_scope_with_variable_segment() {
|
||||
let srv = init_service(App::new().service(web::scope("/app").service(
|
||||
web::scope("/{project_id}").service(web::resource("/path1").to(
|
||||
|r: HttpRequest| {
|
||||
HttpResponse::Created()
|
||||
.body(format!("project: {}", &r.match_info()["project_id"]))
|
||||
},
|
||||
)),
|
||||
web::scope("/{project_id}").service(web::resource("/path1").to(|r: HttpRequest| {
|
||||
HttpResponse::Created().body(format!("project: {}", &r.match_info()["project_id"]))
|
||||
})),
|
||||
)))
|
||||
.await;
|
||||
|
||||
@ -1065,15 +1058,16 @@ mod tests {
|
||||
#[allow(deprecated)]
|
||||
#[actix_rt::test]
|
||||
async fn test_override_data_default_service() {
|
||||
let srv = init_service(App::new().data(1usize).service(
|
||||
web::scope("app").data(10usize).default_service(web::to(
|
||||
|data: web::Data<usize>| {
|
||||
assert_eq!(**data, 10);
|
||||
HttpResponse::Ok()
|
||||
},
|
||||
)),
|
||||
))
|
||||
.await;
|
||||
let srv =
|
||||
init_service(App::new().data(1usize).service(
|
||||
web::scope("app").data(10usize).default_service(web::to(
|
||||
|data: web::Data<usize>| {
|
||||
assert_eq!(**data, 10);
|
||||
HttpResponse::Ok()
|
||||
},
|
||||
)),
|
||||
))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/app/t").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
@ -1150,11 +1144,11 @@ mod tests {
|
||||
#[actix_rt::test]
|
||||
async fn test_url_for_nested() {
|
||||
let srv = init_service(App::new().service(web::scope("/a").service(
|
||||
web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(
|
||||
web::get().to(|req: HttpRequest| {
|
||||
web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(web::get().to(
|
||||
|req: HttpRequest| {
|
||||
HttpResponse::Ok().body(format!("{}", req.url_for("c", ["12345"]).unwrap()))
|
||||
}),
|
||||
)),
|
||||
},
|
||||
))),
|
||||
)))
|
||||
.await;
|
||||
|
||||
|
@ -7,20 +7,18 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
use actix_http::TlsAcceptorConfig;
|
||||
use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
|
||||
use actix_server::{Server, ServerBuilder};
|
||||
use actix_service::{
|
||||
map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
|
||||
};
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder};
|
||||
#[cfg(feature = "rustls")]
|
||||
use actix_tls::accept::rustls::reexports::ServerConfig as RustlsServerConfig;
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
use actix_http::TlsAcceptorConfig;
|
||||
|
||||
use crate::{config::AppConfig, Error};
|
||||
|
||||
struct Socket {
|
||||
@ -437,9 +435,8 @@ where
|
||||
.local_addr(addr);
|
||||
|
||||
if let Some(handler) = on_connect_fn.clone() {
|
||||
svc = svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(handler)(io as &dyn Any, ext)
|
||||
})
|
||||
svc =
|
||||
svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
|
||||
};
|
||||
|
||||
let fac = factory()
|
||||
@ -481,9 +478,8 @@ where
|
||||
.local_addr(addr);
|
||||
|
||||
if let Some(handler) = on_connect_fn.clone() {
|
||||
svc = svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(handler)(io as &dyn Any, ext)
|
||||
})
|
||||
svc =
|
||||
svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
|
||||
};
|
||||
|
||||
let fac = factory()
|
||||
@ -715,8 +711,7 @@ where
|
||||
.client_disconnect_timeout(c.client_disconnect_timeout);
|
||||
|
||||
if let Some(handler) = on_connect_fn.clone() {
|
||||
svc = svc
|
||||
.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
|
||||
svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
|
||||
}
|
||||
|
||||
let fac = factory()
|
||||
@ -759,10 +754,7 @@ where
|
||||
}
|
||||
|
||||
/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
|
||||
fn bind_addrs(
|
||||
addrs: impl net::ToSocketAddrs,
|
||||
backlog: u32,
|
||||
) -> io::Result<Vec<net::TcpListener>> {
|
||||
fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
|
||||
let mut err = None;
|
||||
let mut success = false;
|
||||
let mut sockets = Vec::new();
|
||||
|
@ -696,30 +696,36 @@ service_tuple! { A B C D E F G H I J K L }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::{self, init_service, TestRequest};
|
||||
use crate::{guard, http, web, App, HttpResponse};
|
||||
use actix_service::Service;
|
||||
use actix_utils::future::ok;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
guard, http,
|
||||
test::{self, init_service, TestRequest},
|
||||
web, App, HttpResponse,
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service() {
|
||||
let srv = init_service(
|
||||
App::new().service(web::service("/test").name("test").finish(
|
||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
let srv =
|
||||
init_service(
|
||||
App::new().service(web::service("/test").name("test").finish(
|
||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), http::StatusCode::OK);
|
||||
|
||||
let srv = init_service(
|
||||
App::new().service(web::service("/test").guard(guard::Get()).finish(
|
||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
let srv =
|
||||
init_service(
|
||||
App::new().service(web::service("/test").guard(guard::Get()).finish(
|
||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test")
|
||||
.method(http::Method::PUT)
|
||||
.to_request();
|
||||
@ -731,18 +737,19 @@ mod tests {
|
||||
#[allow(deprecated)]
|
||||
#[actix_rt::test]
|
||||
async fn test_service_data() {
|
||||
let srv =
|
||||
init_service(
|
||||
App::new()
|
||||
.data(42u32)
|
||||
.service(web::service("/test").name("test").finish(
|
||||
|req: ServiceRequest| {
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.data(42u32)
|
||||
.service(
|
||||
web::service("/test")
|
||||
.name("test")
|
||||
.finish(|req: ServiceRequest| {
|
||||
assert_eq!(req.app_data::<web::Data<u32>>().unwrap().as_ref(), &42);
|
||||
ok(req.into_response(HttpResponse::Ok().finish()))
|
||||
},
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), http::StatusCode::OK);
|
||||
@ -773,9 +780,7 @@ mod tests {
|
||||
async fn test_services_macro() {
|
||||
let scoped = services![
|
||||
web::service("/scoped_test1").name("scoped_test1").finish(
|
||||
|req: ServiceRequest| async {
|
||||
Ok(req.into_response(HttpResponse::Ok().finish()))
|
||||
}
|
||||
|req: ServiceRequest| async { Ok(req.into_response(HttpResponse::Ok().finish())) }
|
||||
),
|
||||
web::resource("/scoped_test2").to(|| async { "test2" }),
|
||||
];
|
||||
@ -861,9 +866,7 @@ mod tests {
|
||||
svc.call(req)
|
||||
})
|
||||
.route("/", web::get().to(|| async { "" }))
|
||||
.service(
|
||||
web::resource("/resource1/{name}/index.html").route(web::get().to(index)),
|
||||
),
|
||||
.service(web::resource("/resource1/{name}/index.html").route(web::get().to(index))),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
@ -29,18 +29,20 @@ mod test_request;
|
||||
mod test_services;
|
||||
mod test_utils;
|
||||
|
||||
pub use self::test_request::TestRequest;
|
||||
#[allow(deprecated)]
|
||||
pub use self::test_services::{default_service, ok_service, simple_service, status_service};
|
||||
#[allow(deprecated)]
|
||||
pub use self::test_utils::{
|
||||
call_and_read_body, call_and_read_body_json, call_service, init_service, read_body,
|
||||
read_body_json, read_response, read_response_json, try_call_and_read_body_json,
|
||||
try_call_service, try_read_body, try_read_body_json,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) use self::test_utils::try_init_service;
|
||||
#[allow(deprecated)]
|
||||
pub use self::test_utils::{read_response, read_response_json};
|
||||
pub use self::{
|
||||
test_request::TestRequest,
|
||||
test_utils::{
|
||||
call_and_read_body, call_and_read_body_json, call_service, init_service, read_body,
|
||||
read_body_json, try_call_and_read_body_json, try_call_service, try_read_body,
|
||||
try_read_body_json,
|
||||
},
|
||||
};
|
||||
|
||||
/// Reduces boilerplate code when testing expected response payloads.
|
||||
///
|
||||
|
@ -3,13 +3,17 @@ use std::{borrow::Cow, net::SocketAddr, rc::Rc};
|
||||
use actix_http::{test::TestRequest as HttpTestRequest, Request};
|
||||
use serde::Serialize;
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
use crate::cookie::{Cookie, CookieJar};
|
||||
use crate::{
|
||||
app_service::AppInitServiceState,
|
||||
config::AppConfig,
|
||||
data::Data,
|
||||
dev::{Extensions, Path, Payload, ResourceDef, Service, Url},
|
||||
http::header::ContentType,
|
||||
http::{header::TryIntoHeaderPair, Method, Uri, Version},
|
||||
http::{
|
||||
header::{ContentType, TryIntoHeaderPair},
|
||||
Method, Uri, Version,
|
||||
},
|
||||
rmap::ResourceMap,
|
||||
service::{ServiceRequest, ServiceResponse},
|
||||
test,
|
||||
@ -17,9 +21,6 @@ use crate::{
|
||||
HttpRequest, HttpResponse,
|
||||
};
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
use crate::cookie::{Cookie, CookieJar};
|
||||
|
||||
/// Test `Request` builder.
|
||||
///
|
||||
/// For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern.
|
||||
@ -197,8 +198,7 @@ impl TestRequest {
|
||||
///
|
||||
/// The `Content-Type` header is set to `application/json`.
|
||||
pub fn set_json(mut self, data: impl Serialize) -> Self {
|
||||
let bytes =
|
||||
serde_json::to_string(&data).expect("Failed to serialize test data to json");
|
||||
let bytes = serde_json::to_string(&data).expect("Failed to serialize test data to json");
|
||||
self.req.set_payload(bytes);
|
||||
self.req.insert_header(ContentType::json());
|
||||
self
|
||||
|
@ -201,9 +201,7 @@ where
|
||||
}
|
||||
|
||||
/// Fallible version of [`read_body`] that allows testing MessageBody reading errors.
|
||||
pub async fn try_read_body<B>(
|
||||
res: ServiceResponse<B>,
|
||||
) -> Result<Bytes, <B as MessageBody>::Error>
|
||||
pub async fn try_read_body<B>(res: ServiceResponse<B>) -> Result<Bytes, <B as MessageBody>::Error>
|
||||
where
|
||||
B: MessageBody,
|
||||
{
|
||||
@ -363,8 +361,7 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage,
|
||||
HttpResponse,
|
||||
dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage, HttpResponse,
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
@ -408,10 +405,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_response_json() {
|
||||
let app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
|
||||
|
||||
@ -427,10 +425,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_try_response_json_error() {
|
||||
let app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
|
||||
|
||||
@ -447,10 +446,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_body_json() {
|
||||
let app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
|
||||
|
||||
@ -467,10 +467,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_try_body_json_error() {
|
||||
let app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
// Use a number for id to cause a deserialization error.
|
||||
let payload = r#"{"id":12345,"name":"User name"}"#.as_bytes();
|
||||
@ -488,10 +489,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_request_response_form() {
|
||||
let app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Form<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Form<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let payload = Person {
|
||||
id: "12345".to_string(),
|
||||
@ -531,10 +533,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_request_response_json() {
|
||||
let app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let payload = Person {
|
||||
id: "12345".to_string(),
|
||||
@ -565,9 +568,11 @@ mod tests {
|
||||
InitError = (),
|
||||
>,
|
||||
> {
|
||||
App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
))
|
||||
App::new().service(
|
||||
web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
async fn test_service(
|
||||
|
@ -238,8 +238,7 @@ where
|
||||
match res {
|
||||
Ok(bytes) => {
|
||||
let fallback = bytes.clone();
|
||||
let left =
|
||||
L::from_request(this.req, &mut payload_from_bytes(bytes));
|
||||
let left = L::from_request(this.req, &mut payload_from_bytes(bytes));
|
||||
EitherExtractState::Left { left, fallback }
|
||||
}
|
||||
Err(err) => break Err(EitherExtractError::Bytes(err)),
|
||||
@ -266,10 +265,7 @@ where
|
||||
match res {
|
||||
Ok(data) => break Ok(Either::Right(data)),
|
||||
Err(err) => {
|
||||
break Err(EitherExtractError::Extract(
|
||||
left_err.take().unwrap(),
|
||||
err,
|
||||
));
|
||||
break Err(EitherExtractError::Extract(left_err.take().unwrap(), err));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,12 +335,11 @@ mod tests {
|
||||
.set_payload(Bytes::from_static(b"!@$%^&*()"))
|
||||
.to_http_parts();
|
||||
|
||||
let payload = Either::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(
|
||||
&req, &mut pl,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_right();
|
||||
let payload =
|
||||
Either::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(&req, &mut pl)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_right();
|
||||
assert_eq!(&payload.as_ref(), &b"!@$%^&*()");
|
||||
}
|
||||
|
||||
@ -356,14 +351,13 @@ mod tests {
|
||||
})
|
||||
.to_http_parts();
|
||||
|
||||
let form = Either::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(
|
||||
&req, &mut pl,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_left()
|
||||
.unwrap_right()
|
||||
.into_inner();
|
||||
let form =
|
||||
Either::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(&req, &mut pl)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_left()
|
||||
.unwrap_right()
|
||||
.into_inner();
|
||||
assert_eq!(&form.hello, "world");
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,8 @@ use serde::{de::DeserializeOwned, Serialize};
|
||||
#[cfg(feature = "__compress")]
|
||||
use crate::dev::Decompress;
|
||||
use crate::{
|
||||
body::EitherBody, error::UrlencodedError, extract::FromRequest,
|
||||
http::header::CONTENT_LENGTH, web, Error, HttpMessage, HttpRequest, HttpResponse,
|
||||
Responder,
|
||||
body::EitherBody, error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH,
|
||||
web, Error, HttpMessage, HttpRequest, HttpResponse, Responder,
|
||||
};
|
||||
|
||||
/// URL encoded payload extractor and responder.
|
||||
@ -417,13 +416,12 @@ mod tests {
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::{
|
||||
http::{
|
||||
header::{HeaderValue, CONTENT_LENGTH, CONTENT_TYPE},
|
||||
StatusCode,
|
||||
},
|
||||
test::assert_body_eq,
|
||||
test::{assert_body_eq, TestRequest},
|
||||
};
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
||||
|
@ -75,8 +75,10 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::http::{header, Method};
|
||||
use crate::test::TestRequest;
|
||||
use crate::{
|
||||
http::{header, Method},
|
||||
test::TestRequest,
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_header_extract() {
|
||||
|
@ -10,12 +10,11 @@ use std::{
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use actix_http::Payload;
|
||||
use bytes::BytesMut;
|
||||
use futures_core::{ready, Stream as _};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use actix_http::Payload;
|
||||
|
||||
#[cfg(feature = "__compress")]
|
||||
use crate::dev::Decompress;
|
||||
use crate::{
|
||||
@ -158,8 +157,7 @@ impl<T: DeserializeOwned> FromRequest for Json<T> {
|
||||
}
|
||||
}
|
||||
|
||||
type JsonErrorHandler =
|
||||
Option<Arc<dyn Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync>>;
|
||||
type JsonErrorHandler = Option<Arc<dyn Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync>>;
|
||||
|
||||
pub struct JsonExtractFut<T> {
|
||||
req: Option<HttpRequest>,
|
||||
@ -423,9 +421,7 @@ impl<T: DeserializeOwned> Future for JsonBody<T> {
|
||||
let chunk = chunk?;
|
||||
let buf_len = buf.len() + chunk.len();
|
||||
if buf_len > *limit {
|
||||
return Poll::Ready(Err(JsonPayloadError::Overflow {
|
||||
limit: *limit,
|
||||
}));
|
||||
return Poll::Ready(Err(JsonPayloadError::Overflow { limit: *limit }));
|
||||
} else {
|
||||
buf.extend_from_slice(&chunk);
|
||||
}
|
||||
@ -508,8 +504,7 @@ mod tests {
|
||||
let msg = MyObject {
|
||||
name: "invalid request".to_string(),
|
||||
};
|
||||
let resp =
|
||||
HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap());
|
||||
let resp = HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap());
|
||||
InternalError::from_response(err, resp).into()
|
||||
}))
|
||||
.to_http_parts();
|
||||
@ -747,7 +742,8 @@ mod tests {
|
||||
assert!(s.is_err());
|
||||
|
||||
let err_str = s.err().unwrap().to_string();
|
||||
assert!(err_str
|
||||
.contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes)."));
|
||||
assert!(
|
||||
err_str.contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes).")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,13 @@ mod payload;
|
||||
mod query;
|
||||
mod readlines;
|
||||
|
||||
pub use self::either::Either;
|
||||
pub use self::form::{Form, FormConfig, UrlEncoded};
|
||||
pub use self::header::Header;
|
||||
pub use self::json::{Json, JsonBody, JsonConfig};
|
||||
pub use self::path::{Path, PathConfig};
|
||||
pub use self::payload::{Payload, PayloadConfig};
|
||||
pub use self::query::{Query, QueryConfig};
|
||||
pub use self::readlines::Readlines;
|
||||
pub use self::{
|
||||
either::Either,
|
||||
form::{Form, FormConfig, UrlEncoded},
|
||||
header::Header,
|
||||
json::{Json, JsonBody, JsonConfig},
|
||||
path::{Path, PathConfig},
|
||||
payload::{Payload, PayloadConfig},
|
||||
query::{Query, QueryConfig},
|
||||
readlines::Readlines,
|
||||
};
|
||||
|
@ -156,8 +156,7 @@ mod tests {
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::{error, http, HttpResponse};
|
||||
use crate::{error, http, test::TestRequest, HttpResponse};
|
||||
|
||||
#[derive(Deserialize, Debug, Display)]
|
||||
#[display(fmt = "MyStruct({}, {})", key, value)]
|
||||
@ -276,8 +275,7 @@ mod tests {
|
||||
async fn test_custom_err_handler() {
|
||||
let (req, mut pl) = TestRequest::with_uri("/name/user1/")
|
||||
.app_data(PathConfig::default().error_handler(|err, _| {
|
||||
error::InternalError::from_response(err, HttpResponse::Conflict().finish())
|
||||
.into()
|
||||
error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
|
||||
}))
|
||||
.to_http_parts();
|
||||
|
||||
|
@ -16,8 +16,7 @@ use futures_core::{ready, stream::Stream};
|
||||
use mime::Mime;
|
||||
|
||||
use crate::{
|
||||
dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage,
|
||||
HttpRequest,
|
||||
dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage, HttpRequest,
|
||||
};
|
||||
|
||||
/// Extract a request's raw payload stream.
|
||||
@ -377,9 +376,11 @@ mod tests {
|
||||
use bytes::Bytes;
|
||||
|
||||
use super::*;
|
||||
use crate::http::{header, StatusCode};
|
||||
use crate::test::{call_service, init_service, TestRequest};
|
||||
use crate::{web, App, Responder};
|
||||
use crate::{
|
||||
http::{header, StatusCode},
|
||||
test::{call_service, init_service, TestRequest},
|
||||
web, App, Responder,
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_payload_config() {
|
||||
|
@ -21,17 +21,14 @@ use std::{borrow::Cow, future::Future};
|
||||
use actix_router::IntoPatterns;
|
||||
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
|
||||
|
||||
pub use crate::{
|
||||
config::ServiceConfig, data::Data, redirect::Redirect, request_data::ReqData, types::*,
|
||||
};
|
||||
use crate::{
|
||||
error::BlockingError, http::Method, service::WebService, FromRequest, Handler, Resource,
|
||||
Responder, Route, Scope,
|
||||
};
|
||||
|
||||
pub use crate::config::ServiceConfig;
|
||||
pub use crate::data::Data;
|
||||
pub use crate::redirect::Redirect;
|
||||
pub use crate::request_data::ReqData;
|
||||
pub use crate::types::*;
|
||||
|
||||
/// Creates a new resource for a specific path.
|
||||
///
|
||||
/// Resources may have dynamic path segments. For example, a resource with the path `/a/{name}/c`
|
||||
@ -200,10 +197,7 @@ pub fn service<T: IntoPatterns>(path: T) -> WebService {
|
||||
/// // the client will resolve this redirect to /api/to-path
|
||||
/// .service(web::redirect("/api/from-path", "to-path"));
|
||||
/// ```
|
||||
pub fn redirect(
|
||||
from: impl Into<Cow<'static, str>>,
|
||||
to: impl Into<Cow<'static, str>>,
|
||||
) -> Redirect {
|
||||
pub fn redirect(from: impl Into<Cow<'static, str>>, to: impl Into<Cow<'static, str>>) -> Redirect {
|
||||
Redirect::new(from, to)
|
||||
}
|
||||
|
||||
|
@ -19,14 +19,13 @@ use actix_web::{
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use futures_core::ready;
|
||||
use rand::{distributions::Alphanumeric, Rng as _};
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
use openssl::{
|
||||
pkey::PKey,
|
||||
ssl::{SslAcceptor, SslMethod},
|
||||
x509::X509,
|
||||
};
|
||||
use rand::{distributions::Alphanumeric, Rng as _};
|
||||
|
||||
mod utils;
|
||||
|
||||
@ -94,9 +93,8 @@ impl futures_core::stream::Stream for TestBody {
|
||||
#[actix_rt::test]
|
||||
async fn test_body() {
|
||||
let srv = actix_test::start(|| {
|
||||
App::new().service(
|
||||
web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })),
|
||||
)
|
||||
App::new()
|
||||
.service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })))
|
||||
});
|
||||
|
||||
let mut res = srv.get("/").send().await.unwrap();
|
||||
@ -226,8 +224,7 @@ async fn test_body_chunked_implicit() {
|
||||
App::new()
|
||||
.wrap(Compress::default())
|
||||
.service(web::resource("/").route(web::get().to(|| async {
|
||||
HttpResponse::Ok()
|
||||
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
|
||||
HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
|
||||
})))
|
||||
});
|
||||
|
||||
@ -256,8 +253,7 @@ async fn test_body_br_streaming() {
|
||||
App::new()
|
||||
.wrap(Compress::default())
|
||||
.service(web::resource("/").route(web::to(|| async {
|
||||
HttpResponse::Ok()
|
||||
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
|
||||
HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
|
||||
})))
|
||||
});
|
||||
|
||||
@ -392,8 +388,7 @@ async fn test_body_zstd_streaming() {
|
||||
App::new()
|
||||
.wrap(Compress::default())
|
||||
.service(web::resource("/").route(web::to(move || async {
|
||||
HttpResponse::Ok()
|
||||
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
|
||||
HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
|
||||
})))
|
||||
});
|
||||
|
||||
@ -686,15 +681,14 @@ async fn test_brotli_encoding_large_openssl() {
|
||||
use actix_web::http::header;
|
||||
|
||||
let data = STR.repeat(10);
|
||||
let srv =
|
||||
actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
|
||||
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
|
||||
// echo decompressed request body back in response
|
||||
HttpResponse::Ok()
|
||||
.insert_header(header::ContentEncoding::Identity)
|
||||
.body(bytes)
|
||||
})))
|
||||
});
|
||||
let srv = actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
|
||||
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
|
||||
// echo decompressed request body back in response
|
||||
HttpResponse::Ok()
|
||||
.insert_header(header::ContentEncoding::Identity)
|
||||
.body(bytes)
|
||||
})))
|
||||
});
|
||||
|
||||
let mut res = srv
|
||||
.post("/")
|
||||
|
@ -4,9 +4,10 @@
|
||||
use std::io::{Read as _, Write as _};
|
||||
|
||||
pub mod gzip {
|
||||
use super::*;
|
||||
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec<u8> {
|
||||
let mut encoder = GzEncoder::new(Vec::new(), Compression::fast());
|
||||
encoder.write_all(bytes.as_ref()).unwrap();
|
||||
@ -22,9 +23,10 @@ pub mod gzip {
|
||||
}
|
||||
|
||||
pub mod deflate {
|
||||
use super::*;
|
||||
use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec<u8> {
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::fast());
|
||||
encoder.write_all(bytes.as_ref()).unwrap();
|
||||
@ -40,9 +42,10 @@ pub mod deflate {
|
||||
}
|
||||
|
||||
pub mod brotli {
|
||||
use super::*;
|
||||
use ::brotli::{reader::Decompressor as BrotliDecoder, CompressorWriter as BrotliEncoder};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec<u8> {
|
||||
let mut encoder = BrotliEncoder::new(
|
||||
Vec::new(),
|
||||
@ -64,9 +67,10 @@ pub mod brotli {
|
||||
}
|
||||
|
||||
pub mod zstd {
|
||||
use super::*;
|
||||
use ::zstd::stream::{read::Decoder, write::Encoder};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec<u8> {
|
||||
let mut encoder = Encoder::new(Vec::new(), 3).unwrap();
|
||||
encoder.write_all(bytes.as_ref()).unwrap();
|
||||
|
Reference in New Issue
Block a user