mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-01 16:55:08 +02:00
change rustfmt line width to 96
This commit is contained in:
71
src/app.rs
71
src/app.rs
@ -8,8 +8,7 @@ use actix_http::body::{Body, MessageBody};
|
||||
use actix_http::{Extensions, Request};
|
||||
use actix_service::boxed::{self, BoxServiceFactory};
|
||||
use actix_service::{
|
||||
apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, ServiceFactoryExt,
|
||||
Transform,
|
||||
apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, ServiceFactoryExt, Transform,
|
||||
};
|
||||
use futures_util::future::FutureExt;
|
||||
|
||||
@ -473,17 +472,13 @@ mod tests {
|
||||
use crate::http::{header, HeaderValue, Method, StatusCode};
|
||||
use crate::middleware::DefaultHeaders;
|
||||
use crate::service::ServiceRequest;
|
||||
use crate::test::{
|
||||
call_service, init_service, read_body, try_init_service, TestRequest,
|
||||
};
|
||||
use crate::test::{call_service, init_service, read_body, try_init_service, TestRequest};
|
||||
use crate::{web, HttpRequest, HttpResponse};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_default_resource() {
|
||||
let srv = init_service(
|
||||
App::new().service(web::resource("/test").to(HttpResponse::Ok)),
|
||||
)
|
||||
.await;
|
||||
let srv =
|
||||
init_service(App::new().service(web::resource("/test").to(HttpResponse::Ok))).await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
@ -525,20 +520,22 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_data_factory() {
|
||||
let srv =
|
||||
init_service(App::new().data_factory(|| ok::<_, ()>(10usize)).service(
|
||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||
))
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.data_factory(|| ok::<_, ()>(10usize))
|
||||
.service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let srv =
|
||||
init_service(App::new().data_factory(|| ok::<_, ()>(10u32)).service(
|
||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||
))
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.data_factory(|| ok::<_, ()>(10u32))
|
||||
.service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
@ -546,23 +543,24 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_data_factory_errors() {
|
||||
let srv =
|
||||
try_init_service(App::new().data_factory(|| err::<u32, _>(())).service(
|
||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||
))
|
||||
.await;
|
||||
let srv = try_init_service(
|
||||
App::new()
|
||||
.data_factory(|| err::<u32, _>(()))
|
||||
.service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(srv.is_err());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_extension() {
|
||||
let srv = init_service(App::new().app_data(10usize).service(
|
||||
web::resource("/").to(|req: HttpRequest| {
|
||||
let srv = init_service(App::new().app_data(10usize).service(web::resource("/").to(
|
||||
|req: HttpRequest| {
|
||||
assert_eq!(*req.app_data::<usize>().unwrap(), 10);
|
||||
HttpResponse::Ok()
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
.await;
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
@ -617,10 +615,8 @@ mod tests {
|
||||
let fut = srv.call(req);
|
||||
async move {
|
||||
let mut res = fut.await?;
|
||||
res.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
);
|
||||
res.headers_mut()
|
||||
.insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
Ok(res)
|
||||
}
|
||||
})
|
||||
@ -645,10 +641,8 @@ mod tests {
|
||||
let fut = srv.call(req);
|
||||
async {
|
||||
let mut res = fut.await?;
|
||||
res.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
);
|
||||
res.headers_mut()
|
||||
.insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
Ok(res)
|
||||
}
|
||||
}),
|
||||
@ -671,9 +665,8 @@ mod tests {
|
||||
.route(
|
||||
"/test",
|
||||
web::get().to(|req: HttpRequest| {
|
||||
HttpResponse::Ok().body(
|
||||
req.url_for("youtube", &["12345"]).unwrap().to_string(),
|
||||
)
|
||||
HttpResponse::Ok()
|
||||
.body(req.url_for("youtube", &["12345"]).unwrap().to_string())
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
@ -241,16 +241,15 @@ impl ServiceFactory<ServiceRequest> for AppRoutingFactory {
|
||||
|
||||
fn new_service(&self, _: ()) -> Self::Future {
|
||||
// construct all services factory future with it's resource def and guards.
|
||||
let factory_fut =
|
||||
join_all(self.services.iter().map(|(path, factory, guards)| {
|
||||
let path = path.clone();
|
||||
let guards = guards.borrow_mut().take();
|
||||
let factory_fut = factory.new_service(());
|
||||
async move {
|
||||
let service = factory_fut.await?;
|
||||
Ok((path, guards, service))
|
||||
}
|
||||
}));
|
||||
let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
|
||||
let path = path.clone();
|
||||
let guards = guards.borrow_mut().take();
|
||||
let factory_fut = factory.new_service(());
|
||||
async move {
|
||||
let service = factory_fut.await?;
|
||||
Ok((path, guards, service))
|
||||
}
|
||||
}));
|
||||
|
||||
// construct default service factory future
|
||||
let default_fut = self.default.new_service(());
|
||||
|
@ -17,8 +17,7 @@ use crate::service::{
|
||||
};
|
||||
|
||||
type Guards = Vec<Box<dyn Guard>>;
|
||||
type HttpNewService =
|
||||
boxed::BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
type HttpNewService = boxed::BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
|
||||
/// Application configuration
|
||||
pub struct AppService {
|
||||
@ -99,12 +98,8 @@ impl AppService {
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
self.services.push((
|
||||
rdef,
|
||||
boxed::factory(factory.into_factory()),
|
||||
guards,
|
||||
nested,
|
||||
));
|
||||
self.services
|
||||
.push((rdef, boxed::factory(factory.into_factory()), guards, nested));
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,12 +258,12 @@ mod tests {
|
||||
cfg.app_data(15u8);
|
||||
};
|
||||
|
||||
let srv = init_service(App::new().configure(cfg).service(
|
||||
web::resource("/").to(|_: web::Data<usize>, req: HttpRequest| {
|
||||
let srv = init_service(App::new().configure(cfg).service(web::resource("/").to(
|
||||
|_: web::Data<usize>, req: HttpRequest| {
|
||||
assert_eq!(*req.app_data::<u8>().unwrap(), 15u8);
|
||||
HttpResponse::Ok()
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
.await;
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
@ -312,17 +307,13 @@ mod tests {
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.configure(|cfg| {
|
||||
cfg.external_resource(
|
||||
"youtube",
|
||||
"https://youtube.com/watch/{video_id}",
|
||||
);
|
||||
cfg.external_resource("youtube", "https://youtube.com/watch/{video_id}");
|
||||
})
|
||||
.route(
|
||||
"/test",
|
||||
web::get().to(|req: HttpRequest| {
|
||||
HttpResponse::Ok().body(
|
||||
req.url_for("youtube", &["12345"]).unwrap().to_string(),
|
||||
)
|
||||
HttpResponse::Ok()
|
||||
.body(req.url_for("youtube", &["12345"]).unwrap().to_string())
|
||||
}),
|
||||
),
|
||||
)
|
||||
@ -337,10 +328,8 @@ mod tests {
|
||||
#[actix_rt::test]
|
||||
async fn test_service() {
|
||||
let srv = init_service(App::new().configure(|cfg| {
|
||||
cfg.service(
|
||||
web::resource("/test").route(web::get().to(HttpResponse::Created)),
|
||||
)
|
||||
.route("/index.html", web::get().to(HttpResponse::Ok));
|
||||
cfg.service(web::resource("/test").route(web::get().to(HttpResponse::Created)))
|
||||
.route("/index.html", web::get().to(HttpResponse::Ok));
|
||||
}))
|
||||
.await;
|
||||
|
||||
|
52
src/data.rs
52
src/data.rs
@ -156,11 +156,12 @@ mod tests {
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let srv =
|
||||
init_service(App::new().data(10u32).service(
|
||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||
))
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.data(10u32)
|
||||
.service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
@ -186,21 +187,23 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_app_data_extractor() {
|
||||
let srv =
|
||||
init_service(App::new().app_data(Data::new(10usize)).service(
|
||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||
))
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.app_data(Data::new(10usize))
|
||||
.service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let srv =
|
||||
init_service(App::new().app_data(Data::new(10u32)).service(
|
||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||
))
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.app_data(Data::new(10u32))
|
||||
.service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
@ -237,15 +240,16 @@ mod tests {
|
||||
|
||||
#[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(
|
||||
|data: web::Data<usize>| {
|
||||
assert_eq!(**data, 10);
|
||||
HttpResponse::Ok()
|
||||
},
|
||||
)),
|
||||
))
|
||||
.await;
|
||||
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;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
|
@ -92,9 +92,7 @@ impl std::error::Error for JsonPayloadError {}
|
||||
impl ResponseError for JsonPayloadError {
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
match *self {
|
||||
JsonPayloadError::Overflow => {
|
||||
HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE)
|
||||
}
|
||||
JsonPayloadError::Overflow => HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE),
|
||||
_ => HttpResponse::new(StatusCode::BAD_REQUEST),
|
||||
}
|
||||
}
|
||||
|
@ -130,9 +130,7 @@ pub mod dev {
|
||||
pub use crate::handler::Handler;
|
||||
pub use crate::info::ConnectionInfo;
|
||||
pub use crate::rmap::ResourceMap;
|
||||
pub use crate::service::{
|
||||
HttpServiceFactory, ServiceRequest, ServiceResponse, WebService,
|
||||
};
|
||||
pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService};
|
||||
|
||||
pub use crate::types::form::UrlEncoded;
|
||||
pub use crate::types::json::JsonBody;
|
||||
@ -142,9 +140,7 @@ pub mod dev {
|
||||
#[cfg(feature = "compress")]
|
||||
pub use actix_http::encoding::Decoder as Decompress;
|
||||
pub use actix_http::ResponseBuilder as HttpResponseBuilder;
|
||||
pub use actix_http::{
|
||||
Extensions, Payload, PayloadStream, RequestHead, ResponseHead,
|
||||
};
|
||||
pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, ResponseHead};
|
||||
pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
|
||||
pub use actix_server::Server;
|
||||
pub use actix_service::{Service, Transform};
|
||||
|
@ -143,9 +143,7 @@ mod tests {
|
||||
web::scope("app")
|
||||
.wrap(Compat::new(logger))
|
||||
.wrap(Compat::new(compress))
|
||||
.service(
|
||||
web::resource("/test").route(web::get().to(HttpResponse::Ok)),
|
||||
),
|
||||
.service(web::resource("/test").route(web::get().to(HttpResponse::Ok))),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
@ -119,15 +119,13 @@ mod tests {
|
||||
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||
};
|
||||
|
||||
let mw =
|
||||
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||
let mw = ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||
|
||||
let mw = Condition::new(true, mw)
|
||||
.new_transform(srv.into_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let resp =
|
||||
test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
}
|
||||
|
||||
@ -137,16 +135,14 @@ mod tests {
|
||||
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||
};
|
||||
|
||||
let mw =
|
||||
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||
let mw = ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||
|
||||
let mw = Condition::new(false, mw)
|
||||
.new_transform(srv.into_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE), None);
|
||||
}
|
||||
}
|
||||
|
@ -229,8 +229,7 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_content_type() {
|
||||
let srv =
|
||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish()));
|
||||
let srv = |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish()));
|
||||
let mw = DefaultHeaders::new()
|
||||
.add_content_type()
|
||||
.new_transform(srv.into_service())
|
||||
|
@ -201,8 +201,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
}
|
||||
|
||||
@ -227,8 +226,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let resp =
|
||||
test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
}
|
||||
}
|
||||
|
@ -137,9 +137,9 @@ impl Logger {
|
||||
) -> Self {
|
||||
let inner = Rc::get_mut(&mut self.0).unwrap();
|
||||
|
||||
let ft = inner.format.0.iter_mut().find(|ft| {
|
||||
matches!(ft, FormatText::CustomRequest(unit_label, _) if label == unit_label)
|
||||
});
|
||||
let ft = inner.format.0.iter_mut().find(
|
||||
|ft| matches!(ft, FormatText::CustomRequest(unit_label, _) if label == unit_label),
|
||||
);
|
||||
|
||||
if let Some(FormatText::CustomRequest(_, request_fn)) = ft {
|
||||
// replace into None or previously registered fn using same label
|
||||
@ -363,8 +363,7 @@ impl Format {
|
||||
/// Returns `None` if the format string syntax is incorrect.
|
||||
pub fn new(s: &str) -> Format {
|
||||
log::trace!("Access log format: {}", s);
|
||||
let fmt =
|
||||
Regex::new(r"%(\{([A-Za-z0-9\-_]+)\}([aioe]|xi)|[atPrUsbTD]?)").unwrap();
|
||||
let fmt = Regex::new(r"%(\{([A-Za-z0-9\-_]+)\}([aioe]|xi)|[atPrUsbTD]?)").unwrap();
|
||||
|
||||
let mut idx = 0;
|
||||
let mut results = Vec::new();
|
||||
@ -385,12 +384,12 @@ impl Format {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
"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),
|
||||
_ => unreachable!(),
|
||||
@ -533,9 +532,7 @@ impl FormatText {
|
||||
};
|
||||
}
|
||||
FormatText::UrlPath => *self = FormatText::Str(req.path().to_string()),
|
||||
FormatText::RequestTime => {
|
||||
*self = FormatText::Str(now.format("%Y-%m-%dT%H:%M:%S"))
|
||||
}
|
||||
FormatText::RequestTime => *self = FormatText::Str(now.format("%Y-%m-%dT%H:%M:%S")),
|
||||
FormatText::RequestHeader(ref name) => {
|
||||
let s = if let Some(val) = req.headers().get(name) {
|
||||
if let Ok(s) = val.to_str() {
|
||||
@ -557,8 +554,7 @@ impl FormatText {
|
||||
*self = s;
|
||||
}
|
||||
FormatText::RealIPRemoteAddr => {
|
||||
let s = if let Some(remote) = req.connection_info().realip_remote_addr()
|
||||
{
|
||||
let s = if let Some(remote) = req.connection_info().realip_remote_addr() {
|
||||
FormatText::Str(remote.to_string())
|
||||
} else {
|
||||
FormatText::Str("-".to_string())
|
||||
@ -629,8 +625,8 @@ mod tests {
|
||||
.finish(),
|
||||
))
|
||||
};
|
||||
let logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test")
|
||||
.exclude_regex("\\w");
|
||||
let logger =
|
||||
Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test").exclude_regex("\\w");
|
||||
|
||||
let srv = logger.new_transform(srv.into_service()).await.unwrap();
|
||||
|
||||
@ -743,9 +739,7 @@ mod tests {
|
||||
let req = TestRequest::default()
|
||||
.insert_header((
|
||||
header::FORWARDED,
|
||||
header::HeaderValue::from_static(
|
||||
"for=192.0.2.60;proto=http;by=203.0.113.43",
|
||||
),
|
||||
header::HeaderValue::from_static("for=192.0.2.60;proto=http;by=203.0.113.43"),
|
||||
))
|
||||
.to_srv_request();
|
||||
|
||||
|
@ -175,11 +175,7 @@ impl HttpRequest {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub fn url_for<U, I>(
|
||||
&self,
|
||||
name: &str,
|
||||
elements: U,
|
||||
) -> Result<url::Url, UrlGenerationError>
|
||||
pub fn url_for<U, I>(&self, name: &str, elements: U) -> Result<url::Url, UrlGenerationError>
|
||||
where
|
||||
U: IntoIterator<Item = I>,
|
||||
I: AsRef<str>,
|
||||
@ -577,30 +573,30 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_data() {
|
||||
let srv = init_service(App::new().app_data(10usize).service(
|
||||
web::resource("/").to(|req: HttpRequest| {
|
||||
let srv = init_service(App::new().app_data(10usize).service(web::resource("/").to(
|
||||
|req: HttpRequest| {
|
||||
if req.app_data::<usize>().is_some() {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let srv = init_service(App::new().app_data(10u32).service(
|
||||
web::resource("/").to(|req: HttpRequest| {
|
||||
let srv = init_service(App::new().app_data(10u32).service(web::resource("/").to(
|
||||
|req: HttpRequest| {
|
||||
if req.app_data::<usize>().is_some() {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
@ -687,14 +683,14 @@ mod tests {
|
||||
let tracker = Rc::new(RefCell::new(Tracker { dropped: false }));
|
||||
{
|
||||
let tracker2 = Rc::clone(&tracker);
|
||||
let srv = init_service(App::new().data(10u32).service(
|
||||
web::resource("/").to(move |req: HttpRequest| {
|
||||
let srv = init_service(App::new().data(10u32).service(web::resource("/").to(
|
||||
move |req: HttpRequest| {
|
||||
req.extensions_mut().insert(Foo {
|
||||
tracker: Rc::clone(&tracker2),
|
||||
});
|
||||
HttpResponse::Ok()
|
||||
}),
|
||||
))
|
||||
},
|
||||
)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::default().to_request();
|
||||
|
@ -358,9 +358,10 @@ where
|
||||
U::InitError: fmt::Debug,
|
||||
{
|
||||
// create and configure default resource
|
||||
self.default = boxed::factory(f.into_factory().map_init_err(|e| {
|
||||
log::error!("Can not construct default service: {:?}", e)
|
||||
}));
|
||||
self.default = boxed::factory(
|
||||
f.into_factory()
|
||||
.map_init_err(|e| log::error!("Can not construct default service: {:?}", e)),
|
||||
);
|
||||
|
||||
self
|
||||
}
|
||||
@ -437,8 +438,7 @@ impl ServiceFactory<ServiceRequest> for ResourceFactory {
|
||||
let default_fut = self.default.new_service(());
|
||||
|
||||
// construct route service factory futures
|
||||
let factory_fut =
|
||||
join_all(self.routes.iter().map(|route| route.new_service(())));
|
||||
let factory_fut = join_all(self.routes.iter().map(|route| route.new_service(())));
|
||||
|
||||
let app_data = self.app_data.clone();
|
||||
|
||||
@ -530,19 +530,18 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_middleware() {
|
||||
let srv =
|
||||
init_service(
|
||||
App::new().service(
|
||||
web::resource("/test")
|
||||
.name("test")
|
||||
.wrap(DefaultHeaders::new().header(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
))
|
||||
.route(web::get().to(HttpResponse::Ok)),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let srv = init_service(
|
||||
App::new().service(
|
||||
web::resource("/test")
|
||||
.name("test")
|
||||
.wrap(
|
||||
DefaultHeaders::new()
|
||||
.header(header::CONTENT_TYPE, HeaderValue::from_static("0001")),
|
||||
)
|
||||
.route(web::get().to(HttpResponse::Ok)),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
@ -584,12 +583,11 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_to() {
|
||||
let srv =
|
||||
init_service(App::new().service(web::resource("/test").to(|| async {
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
Ok::<_, Error>(HttpResponse::Ok())
|
||||
})))
|
||||
.await;
|
||||
let srv = init_service(App::new().service(web::resource("/test").to(|| async {
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
Ok::<_, Error>(HttpResponse::Ok())
|
||||
})))
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
@ -262,9 +262,7 @@ pub(crate) mod tests {
|
||||
async fn test_option_responder() {
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.service(
|
||||
web::resource("/none").to(|| async { Option::<&'static str>::None }),
|
||||
)
|
||||
.service(web::resource("/none").to(|| async { Option::<&'static str>::None }))
|
||||
.service(web::resource("/some").to(|| async { Some("some") })),
|
||||
)
|
||||
.await;
|
||||
@ -364,8 +362,7 @@ pub(crate) mod tests {
|
||||
);
|
||||
|
||||
// InternalError
|
||||
let resp =
|
||||
error::InternalError::new("err", StatusCode::BAD_REQUEST).respond_to(&req);
|
||||
let resp = error::InternalError::new("err", StatusCode::BAD_REQUEST).respond_to(&req);
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
@ -382,9 +379,8 @@ pub(crate) mod tests {
|
||||
HeaderValue::from_static("text/plain; charset=utf-8")
|
||||
);
|
||||
|
||||
let res =
|
||||
Err::<String, _>(error::InternalError::new("err", StatusCode::BAD_REQUEST))
|
||||
.respond_to(&req);
|
||||
let res = Err::<String, _>(error::InternalError::new("err", StatusCode::BAD_REQUEST))
|
||||
.respond_to(&req);
|
||||
|
||||
assert_eq!(res.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
14
src/route.rs
14
src/route.rs
@ -238,12 +238,7 @@ where
|
||||
|
||||
impl<T> RouteNewService<T>
|
||||
where
|
||||
T: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
>,
|
||||
T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>,
|
||||
T::Future: 'static,
|
||||
T::Service: 'static,
|
||||
<T::Service as Service<ServiceRequest>>::Future: 'static,
|
||||
@ -255,12 +250,7 @@ where
|
||||
|
||||
impl<T> ServiceFactory<ServiceRequest> for RouteNewService<T>
|
||||
where
|
||||
T: ServiceFactory<
|
||||
ServiceRequest,
|
||||
Config = (),
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
>,
|
||||
T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>,
|
||||
T::Future: 'static,
|
||||
T::Service: 'static,
|
||||
<T::Service as Service<ServiceRequest>>::Future: 'static,
|
||||
|
70
src/scope.rs
70
src/scope.rs
@ -8,8 +8,8 @@ use actix_http::Extensions;
|
||||
use actix_router::{ResourceDef, Router};
|
||||
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
|
||||
use actix_service::{
|
||||
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory,
|
||||
ServiceFactoryExt, Transform,
|
||||
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt,
|
||||
Transform,
|
||||
};
|
||||
use futures_core::future::LocalBoxFuture;
|
||||
use futures_util::future::join_all;
|
||||
@ -476,16 +476,15 @@ impl ServiceFactory<ServiceRequest> for ScopeFactory {
|
||||
let default_fut = self.default.new_service(());
|
||||
|
||||
// construct all services factory future with it's resource def and guards.
|
||||
let factory_fut =
|
||||
join_all(self.services.iter().map(|(path, factory, guards)| {
|
||||
let path = path.clone();
|
||||
let guards = guards.borrow_mut().take();
|
||||
let factory_fut = factory.new_service(());
|
||||
async move {
|
||||
let service = factory_fut.await?;
|
||||
Ok((path, guards, service))
|
||||
}
|
||||
}));
|
||||
let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
|
||||
let path = path.clone();
|
||||
let guards = guards.borrow_mut().take();
|
||||
let factory_fut = factory.new_service(());
|
||||
async move {
|
||||
let service = factory_fut.await?;
|
||||
Ok((path, guards, service))
|
||||
}
|
||||
}));
|
||||
|
||||
let app_data = self.app_data.clone();
|
||||
|
||||
@ -589,10 +588,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();
|
||||
@ -621,9 +621,10 @@ 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)),
|
||||
))
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/app").to_request();
|
||||
@ -637,9 +638,10 @@ mod tests {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_scope_root3() {
|
||||
let srv = init_service(App::new().service(
|
||||
web::scope("/app/").service(web::resource("/").to(HttpResponse::Ok)),
|
||||
))
|
||||
let srv = init_service(
|
||||
App::new()
|
||||
.service(web::scope("/app/").service(web::resource("/").to(HttpResponse::Ok))),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/app").to_request();
|
||||
@ -737,8 +739,7 @@ mod tests {
|
||||
async fn test_scope_variable_segment() {
|
||||
let srv = init_service(App::new().service(web::scope("/ab-{project}").service(
|
||||
web::resource("/path1").to(|r: HttpRequest| {
|
||||
HttpResponse::Ok()
|
||||
.body(format!("project: {}", &r.match_info()["project"]))
|
||||
HttpResponse::Ok().body(format!("project: {}", &r.match_info()["project"]))
|
||||
}),
|
||||
)))
|
||||
.await;
|
||||
@ -945,14 +946,10 @@ mod tests {
|
||||
App::new().service(
|
||||
web::scope("app")
|
||||
.wrap(
|
||||
DefaultHeaders::new().header(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
),
|
||||
DefaultHeaders::new()
|
||||
.header(header::CONTENT_TYPE, HeaderValue::from_static("0001")),
|
||||
)
|
||||
.service(
|
||||
web::resource("/test").route(web::get().to(HttpResponse::Ok)),
|
||||
),
|
||||
.service(web::resource("/test").route(web::get().to(HttpResponse::Ok))),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
@ -975,10 +972,8 @@ mod tests {
|
||||
let fut = srv.call(req);
|
||||
async move {
|
||||
let mut res = fut.await?;
|
||||
res.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
);
|
||||
res.headers_mut()
|
||||
.insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
Ok(res)
|
||||
}
|
||||
})
|
||||
@ -1083,9 +1078,8 @@ mod tests {
|
||||
s.route(
|
||||
"/",
|
||||
web::get().to(|req: HttpRequest| {
|
||||
HttpResponse::Ok().body(
|
||||
req.url_for("youtube", &["xxxxxx"]).unwrap().to_string(),
|
||||
)
|
||||
HttpResponse::Ok()
|
||||
.body(req.url_for("youtube", &["xxxxxx"]).unwrap().to_string())
|
||||
}),
|
||||
);
|
||||
}));
|
||||
|
200
src/server.rs
200
src/server.rs
@ -277,32 +277,28 @@ where
|
||||
});
|
||||
let on_connect_fn = self.on_connect_fn.clone();
|
||||
|
||||
self.builder = self.builder.listen(
|
||||
format!("actix-web-service-{}", addr),
|
||||
lst,
|
||||
move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
self.builder =
|
||||
self.builder
|
||||
.listen(format!("actix-web-service-{}", addr), lst, move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.local_addr(addr);
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.local_addr(addr);
|
||||
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(handler)(io as &dyn Any, ext)
|
||||
})
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
|
||||
svc.finish(map_config(factory(), move |_| {
|
||||
AppConfig::new(false, addr, host.clone())
|
||||
}))
|
||||
.tcp()
|
||||
},
|
||||
)?;
|
||||
svc.finish(map_config(factory(), move |_| {
|
||||
AppConfig::new(false, addr, host.clone())
|
||||
}))
|
||||
.tcp()
|
||||
})?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@ -334,32 +330,30 @@ where
|
||||
|
||||
let on_connect_fn = self.on_connect_fn.clone();
|
||||
|
||||
self.builder = self.builder.listen(
|
||||
format!("actix-web-service-{}", addr),
|
||||
lst,
|
||||
move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
self.builder =
|
||||
self.builder
|
||||
.listen(format!("actix-web-service-{}", addr), lst, move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.client_disconnect(c.client_shutdown);
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.client_disconnect(c.client_shutdown);
|
||||
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(&*handler)(io as &dyn Any, ext)
|
||||
})
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(&*handler)(io as &dyn Any, ext)
|
||||
})
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
|
||||
svc.finish(map_config(factory(), move |_| {
|
||||
AppConfig::new(true, addr, host.clone())
|
||||
}))
|
||||
.openssl(acceptor.clone())
|
||||
},
|
||||
)?;
|
||||
svc.finish(map_config(factory(), move |_| {
|
||||
AppConfig::new(true, addr, host.clone())
|
||||
}))
|
||||
.openssl(acceptor.clone())
|
||||
})?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@ -391,32 +385,28 @@ where
|
||||
|
||||
let on_connect_fn = self.on_connect_fn.clone();
|
||||
|
||||
self.builder = self.builder.listen(
|
||||
format!("actix-web-service-{}", addr),
|
||||
lst,
|
||||
move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
self.builder =
|
||||
self.builder
|
||||
.listen(format!("actix-web-service-{}", addr), lst, move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.client_disconnect(c.client_shutdown);
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.client_disconnect(c.client_shutdown);
|
||||
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(handler)(io as &dyn Any, ext)
|
||||
})
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
|
||||
svc.finish(map_config(factory(), move |_| {
|
||||
AppConfig::new(true, addr, host.clone())
|
||||
}))
|
||||
.rustls(config.clone())
|
||||
},
|
||||
)?;
|
||||
svc.finish(map_config(factory(), move |_| {
|
||||
AppConfig::new(true, addr, host.clone())
|
||||
}))
|
||||
.rustls(config.clone())
|
||||
})?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@ -433,10 +423,7 @@ where
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn bind2<A: net::ToSocketAddrs>(
|
||||
&self,
|
||||
addr: A,
|
||||
) -> io::Result<Vec<net::TcpListener>> {
|
||||
fn bind2<A: net::ToSocketAddrs>(&self, addr: A) -> io::Result<Vec<net::TcpListener>> {
|
||||
let mut err = None;
|
||||
let mut success = false;
|
||||
let mut sockets = Vec::new();
|
||||
@ -469,11 +456,7 @@ where
|
||||
/// Start listening for incoming tls connections.
|
||||
///
|
||||
/// This method sets alpn protocols to "h2" and "http/1.1"
|
||||
pub fn bind_openssl<A>(
|
||||
mut self,
|
||||
addr: A,
|
||||
builder: SslAcceptorBuilder,
|
||||
) -> io::Result<Self>
|
||||
pub fn bind_openssl<A>(mut self, addr: A, builder: SslAcceptorBuilder) -> io::Result<Self>
|
||||
where
|
||||
A: net::ToSocketAddrs,
|
||||
{
|
||||
@ -505,18 +488,13 @@ where
|
||||
|
||||
#[cfg(unix)]
|
||||
/// Start listening for unix domain (UDS) connections on existing listener.
|
||||
pub fn listen_uds(
|
||||
mut self,
|
||||
lst: std::os::unix::net::UnixListener,
|
||||
) -> io::Result<Self> {
|
||||
pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
|
||||
use actix_rt::net::UnixStream;
|
||||
|
||||
let cfg = self.config.clone();
|
||||
let factory = self.factory.clone();
|
||||
let socket_addr = net::SocketAddr::new(
|
||||
net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)),
|
||||
8080,
|
||||
);
|
||||
let socket_addr =
|
||||
net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
|
||||
self.sockets.push(Socket {
|
||||
scheme: "http",
|
||||
addr: socket_addr,
|
||||
@ -533,23 +511,19 @@ where
|
||||
c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
|
||||
);
|
||||
|
||||
pipeline_factory(|io: UnixStream| ok((io, Protocol::Http1, None))).and_then(
|
||||
{
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout);
|
||||
pipeline_factory(|io: UnixStream| ok((io, Protocol::Http1, None))).and_then({
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout);
|
||||
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| {
|
||||
(&*handler)(io as &dyn Any, ext)
|
||||
})
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| (&*handler)(io as &dyn Any, ext))
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
|
||||
svc.finish(map_config(factory(), move |_| config.clone()))
|
||||
},
|
||||
)
|
||||
svc.finish(map_config(factory(), move |_| config.clone()))
|
||||
})
|
||||
})?;
|
||||
Ok(self)
|
||||
}
|
||||
@ -564,10 +538,8 @@ where
|
||||
|
||||
let cfg = self.config.clone();
|
||||
let factory = self.factory.clone();
|
||||
let socket_addr = net::SocketAddr::new(
|
||||
net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)),
|
||||
8080,
|
||||
);
|
||||
let socket_addr =
|
||||
net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
|
||||
self.sockets.push(Socket {
|
||||
scheme: "http",
|
||||
addr: socket_addr,
|
||||
@ -583,13 +555,12 @@ where
|
||||
socket_addr,
|
||||
c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
|
||||
);
|
||||
pipeline_factory(|io: UnixStream| ok((io, Protocol::Http1, None)))
|
||||
.and_then(
|
||||
HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.finish(map_config(factory(), move |_| config.clone())),
|
||||
)
|
||||
pipeline_factory(|io: UnixStream| ok((io, Protocol::Http1, None))).and_then(
|
||||
HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_timeout(c.client_timeout)
|
||||
.finish(map_config(factory(), move |_| config.clone())),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
Ok(self)
|
||||
@ -633,10 +604,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn create_tcp_listener(
|
||||
addr: net::SocketAddr,
|
||||
backlog: u32,
|
||||
) -> io::Result<net::TcpListener> {
|
||||
fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
|
||||
use socket2::{Domain, Protocol, Socket, Type};
|
||||
let domain = match addr {
|
||||
net::SocketAddr::V4(_) => Domain::ipv4(),
|
||||
|
@ -5,8 +5,7 @@ use std::{fmt, net};
|
||||
use actix_http::body::{Body, MessageBody, ResponseBody};
|
||||
use actix_http::http::{HeaderMap, Method, StatusCode, Uri, Version};
|
||||
use actix_http::{
|
||||
Error, Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response,
|
||||
ResponseHead,
|
||||
Error, Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response, ResponseHead,
|
||||
};
|
||||
use actix_router::{IntoPattern, Path, Resource, ResourceDef, Url};
|
||||
use actix_service::{IntoServiceFactory, ServiceFactory};
|
||||
@ -635,20 +634,18 @@ mod tests {
|
||||
|
||||
#[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| {
|
||||
assert_eq!(
|
||||
req.app_data::<web::Data<u32>>().unwrap().as_ref(),
|
||||
&42
|
||||
);
|
||||
ok(req.into_response(HttpResponse::Ok().finish()))
|
||||
},
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
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;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), http::StatusCode::OK);
|
||||
|
78
src/test.rs
78
src/test.rs
@ -12,9 +12,7 @@ use actix_http::test::TestRequest as HttpTestRequest;
|
||||
use actix_http::{cookie::Cookie, ws, Extensions, HttpService, Request};
|
||||
use actix_router::{Path, ResourceDef, Url};
|
||||
use actix_rt::{time::sleep, System};
|
||||
use actix_service::{
|
||||
map_config, IntoService, IntoServiceFactory, Service, ServiceFactory,
|
||||
};
|
||||
use actix_service::{map_config, IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||
use awc::error::PayloadError;
|
||||
use awc::{Client, ClientRequest, ClientResponse, Connector};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
@ -78,12 +76,7 @@ pub async fn init_service<R, S, B, E>(
|
||||
) -> impl Service<Request, Response = ServiceResponse<B>, Error = E>
|
||||
where
|
||||
R: IntoServiceFactory<S, Request>,
|
||||
S: ServiceFactory<
|
||||
Request,
|
||||
Config = AppConfig,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = E,
|
||||
>,
|
||||
S: ServiceFactory<Request, Config = AppConfig, Response = ServiceResponse<B>, Error = E>,
|
||||
S::InitError: std::fmt::Debug,
|
||||
{
|
||||
try_init_service(app)
|
||||
@ -97,12 +90,7 @@ pub(crate) async fn try_init_service<R, S, B, E>(
|
||||
) -> Result<impl Service<Request, Response = ServiceResponse<B>, Error = E>, S::InitError>
|
||||
where
|
||||
R: IntoServiceFactory<S, Request>,
|
||||
S: ServiceFactory<
|
||||
Request,
|
||||
Config = AppConfig,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = E,
|
||||
>,
|
||||
S: ServiceFactory<Request, Config = AppConfig, Response = ServiceResponse<B>, Error = E>,
|
||||
S::InitError: std::fmt::Debug,
|
||||
{
|
||||
let srv = app.into_factory();
|
||||
@ -264,9 +252,8 @@ where
|
||||
{
|
||||
let body = read_body(res).await;
|
||||
|
||||
serde_json::from_slice(&body).unwrap_or_else(|e| {
|
||||
panic!("read_response_json failed during deserialization: {}", e)
|
||||
})
|
||||
serde_json::from_slice(&body)
|
||||
.unwrap_or_else(|e| panic!("read_response_json failed during deserialization: {}", e))
|
||||
}
|
||||
|
||||
pub async fn load_stream<S>(mut stream: S) -> Result<Bytes, Error>
|
||||
@ -487,8 +474,7 @@ impl TestRequest {
|
||||
/// Serialize `data` to JSON and set it as the request payload. The `Content-Type` header is
|
||||
/// set to `application/json`.
|
||||
pub fn set_json<T: Serialize>(mut self, data: &T) -> 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
|
||||
@ -528,8 +514,7 @@ impl TestRequest {
|
||||
head.peer_addr = self.peer_addr;
|
||||
self.path.get_mut().update(&head.uri);
|
||||
|
||||
let app_state =
|
||||
AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
|
||||
let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
|
||||
|
||||
ServiceRequest::new(
|
||||
HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data)),
|
||||
@ -548,8 +533,7 @@ impl TestRequest {
|
||||
head.peer_addr = self.peer_addr;
|
||||
self.path.get_mut().update(&head.uri);
|
||||
|
||||
let app_state =
|
||||
AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
|
||||
let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
|
||||
|
||||
HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data))
|
||||
}
|
||||
@ -560,8 +544,7 @@ impl TestRequest {
|
||||
head.peer_addr = self.peer_addr;
|
||||
self.path.get_mut().update(&head.uri);
|
||||
|
||||
let app_state =
|
||||
AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
|
||||
let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
|
||||
|
||||
let req = HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data));
|
||||
|
||||
@ -678,24 +661,21 @@ where
|
||||
let srv = match cfg.stream {
|
||||
StreamType::Tcp => match cfg.tp {
|
||||
HttpVer::Http1 => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(false, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(false, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.h1(map_config(factory(), move |_| cfg.clone()))
|
||||
.tcp()
|
||||
}),
|
||||
HttpVer::Http2 => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(false, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(false, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.h2(map_config(factory(), move |_| cfg.clone()))
|
||||
.tcp()
|
||||
}),
|
||||
HttpVer::Both => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(false, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(false, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.finish(map_config(factory(), move |_| cfg.clone()))
|
||||
@ -705,24 +685,21 @@ where
|
||||
#[cfg(feature = "openssl")]
|
||||
StreamType::Openssl(acceptor) => match cfg.tp {
|
||||
HttpVer::Http1 => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.h1(map_config(factory(), move |_| cfg.clone()))
|
||||
.openssl(acceptor.clone())
|
||||
}),
|
||||
HttpVer::Http2 => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.h2(map_config(factory(), move |_| cfg.clone()))
|
||||
.openssl(acceptor.clone())
|
||||
}),
|
||||
HttpVer::Both => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.finish(map_config(factory(), move |_| cfg.clone()))
|
||||
@ -732,24 +709,21 @@ where
|
||||
#[cfg(feature = "rustls")]
|
||||
StreamType::Rustls(config) => match cfg.tp {
|
||||
HttpVer::Http1 => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.h1(map_config(factory(), move |_| cfg.clone()))
|
||||
.rustls(config.clone())
|
||||
}),
|
||||
HttpVer::Http2 => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.h2(map_config(factory(), move |_| cfg.clone()))
|
||||
.rustls(config.clone())
|
||||
}),
|
||||
HttpVer::Both => builder.listen("test", tcp, move || {
|
||||
let cfg =
|
||||
AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
let cfg = AppConfig::new(true, local_addr, format!("{}", local_addr));
|
||||
HttpService::build()
|
||||
.client_timeout(ctimeout)
|
||||
.finish(map_config(factory(), move |_| cfg.clone()))
|
||||
@ -887,8 +861,7 @@ impl TestServerConfig {
|
||||
/// Get first available unused address
|
||||
pub fn unused_addr() -> net::SocketAddr {
|
||||
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||
let socket =
|
||||
Socket::new(Domain::ipv4(), Type::stream(), Some(Protocol::tcp())).unwrap();
|
||||
let socket = Socket::new(Domain::ipv4(), Type::stream(), Some(Protocol::tcp())).unwrap();
|
||||
socket.bind(&addr.into()).unwrap();
|
||||
socket.set_reuse_address(true).unwrap();
|
||||
let tcp = socket.into_tcp_listener();
|
||||
@ -975,8 +948,7 @@ impl TestServer {
|
||||
pub async fn ws_at(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError>
|
||||
{
|
||||
) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError> {
|
||||
let url = self.url(path);
|
||||
let connect = self.client.ws(url).connect();
|
||||
connect.await.map(|(_, framed)| framed)
|
||||
@ -985,8 +957,7 @@ impl TestServer {
|
||||
/// Connect to a websocket server
|
||||
pub async fn ws(
|
||||
&mut self,
|
||||
) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError>
|
||||
{
|
||||
) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError> {
|
||||
self.ws_at("/").await
|
||||
}
|
||||
|
||||
@ -1218,10 +1189,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
let app = init_service(
|
||||
App::new().service(web::resource("/index.html").to(async_with_block)),
|
||||
)
|
||||
.await;
|
||||
let app =
|
||||
init_service(App::new().service(web::resource("/index.html").to(async_with_block)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::post().uri("/index.html").to_request();
|
||||
let res = app.call(req).await.unwrap();
|
||||
|
@ -276,13 +276,12 @@ 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"!@$%^&*()");
|
||||
}
|
||||
|
||||
@ -294,15 +293,14 @@ 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");
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ use serde::{de::DeserializeOwned, Serialize};
|
||||
#[cfg(feature = "compress")]
|
||||
use crate::dev::Decompress;
|
||||
use crate::{
|
||||
error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH, web,
|
||||
Error, HttpMessage, HttpRequest, HttpResponse, Responder,
|
||||
error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH, web, Error,
|
||||
HttpMessage, HttpRequest, HttpResponse, Responder,
|
||||
};
|
||||
|
||||
/// URL encoded payload extractor and responder.
|
||||
@ -342,16 +342,14 @@ where
|
||||
}
|
||||
|
||||
if encoding == UTF_8 {
|
||||
serde_urlencoded::from_bytes::<T>(&body)
|
||||
.map_err(|_| UrlencodedError::Parse)
|
||||
serde_urlencoded::from_bytes::<T>(&body).map_err(|_| UrlencodedError::Parse)
|
||||
} else {
|
||||
let body = encoding
|
||||
.decode_without_bom_handling_and_without_replacement(&body)
|
||||
.map(|s| s.into_owned())
|
||||
.ok_or(UrlencodedError::Parse)?;
|
||||
|
||||
serde_urlencoded::from_str::<T>(&body)
|
||||
.map_err(|_| UrlencodedError::Parse)
|
||||
serde_urlencoded::from_str::<T>(&body).map_err(|_| UrlencodedError::Parse)
|
||||
}
|
||||
}
|
||||
.boxed_local(),
|
||||
|
@ -482,8 +482,8 @@ 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();
|
||||
|
@ -235,11 +235,9 @@ mod tests {
|
||||
assert_eq!(res.1, "user1");
|
||||
|
||||
let (Path(a), Path(b)) =
|
||||
<(Path<(String, String)>, Path<(String, String)>)>::from_request(
|
||||
&req, &mut pl,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
<(Path<(String, String)>, Path<(String, String)>)>::from_request(&req, &mut pl)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(a.0, "name");
|
||||
assert_eq!(a.1, "user1");
|
||||
assert_eq!(b.0, "name");
|
||||
@ -300,11 +298,8 @@ 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();
|
||||
|
||||
|
@ -55,10 +55,7 @@ impl Stream for Payload {
|
||||
type Item = Result<Bytes, PayloadError>;
|
||||
|
||||
#[inline]
|
||||
fn poll_next(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
Pin::new(&mut self.0).poll_next(cx)
|
||||
}
|
||||
}
|
||||
@ -396,9 +393,7 @@ mod tests {
|
||||
App::new()
|
||||
.service(
|
||||
web::resource("/bytes-app-data")
|
||||
.app_data(
|
||||
PayloadConfig::default().mimetype(mime::APPLICATION_JSON),
|
||||
)
|
||||
.app_data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON))
|
||||
.route(web::get().to(bytes_handler)),
|
||||
)
|
||||
.service(
|
||||
@ -408,9 +403,7 @@ mod tests {
|
||||
)
|
||||
.service(
|
||||
web::resource("/string-app-data")
|
||||
.app_data(
|
||||
PayloadConfig::default().mimetype(mime::APPLICATION_JSON),
|
||||
)
|
||||
.app_data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON))
|
||||
.route(web::get().to(string_handler)),
|
||||
)
|
||||
.service(
|
||||
|
@ -167,8 +167,7 @@ where
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
pub struct QueryConfig {
|
||||
err_handler:
|
||||
Option<Arc<dyn Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync>>,
|
||||
err_handler: Option<Arc<dyn Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl QueryConfig {
|
||||
|
@ -74,10 +74,7 @@ where
|
||||
{
|
||||
type Item = Result<String, ReadlinesError>;
|
||||
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
let this = self.get_mut();
|
||||
|
||||
if let Some(err) = this.err.take() {
|
||||
|
Reference in New Issue
Block a user