mirror of https://github.com/fafhrd91/actix-web
fix tests and add docs
This commit is contained in:
parent
b1dfec2e87
commit
afc9aa4c92
|
@ -333,7 +333,7 @@ impl HeaderMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts a name-value pair into the map.
|
/// Inserts (overrides) a name-value pair in the map.
|
||||||
///
|
///
|
||||||
/// If the map already contained this key, the new value is associated with the key and all
|
/// If the map already contained this key, the new value is associated with the key and all
|
||||||
/// previous values are removed and returned as a `Removed` iterator. The key is not updated;
|
/// previous values are removed and returned as a `Removed` iterator. The key is not updated;
|
||||||
|
@ -372,7 +372,7 @@ impl HeaderMap {
|
||||||
Removed::new(value)
|
Removed::new(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts a name-value pair into the map.
|
/// Appends a name-value pair to the map.
|
||||||
///
|
///
|
||||||
/// If the map already contained this key, the new value is added to the list of values
|
/// If the map already contained this key, the new value is added to the list of values
|
||||||
/// currently associated with the key. The key is not updated; this matters for types that can
|
/// currently associated with the key. The key is not updated; this matters for types that can
|
||||||
|
|
|
@ -22,14 +22,14 @@ async fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(middleware::DefaultHeaders::new().insert(("X-Version", "0.2")))
|
.wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
|
||||||
.wrap(middleware::Compress::default())
|
.wrap(middleware::Compress::default())
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
.service(index)
|
.service(index)
|
||||||
.service(no_params)
|
.service(no_params)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/resource2/index.html")
|
web::resource("/resource2/index.html")
|
||||||
.wrap(middleware::DefaultHeaders::new().insert(("X-Version-R2", "0.3")))
|
.wrap(middleware::DefaultHeaders::new().add(("X-Version-R2", "0.3")))
|
||||||
.default_service(web::route().to(HttpResponse::MethodNotAllowed))
|
.default_service(web::route().to(HttpResponse::MethodNotAllowed))
|
||||||
.route(web::get().to(index_async)),
|
.route(web::get().to(index_async)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,14 +26,14 @@ async fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(middleware::DefaultHeaders::new().insert(("X-Version", "0.2")))
|
.wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
|
||||||
.wrap(middleware::Compress::default())
|
.wrap(middleware::Compress::default())
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
.service(index)
|
.service(index)
|
||||||
.service(no_params)
|
.service(no_params)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/resource2/index.html")
|
web::resource("/resource2/index.html")
|
||||||
.wrap(middleware::DefaultHeaders::new().insert(("X-Version-R2", "0.3")))
|
.wrap(middleware::DefaultHeaders::new().add(("X-Version-R2", "0.3")))
|
||||||
.default_service(web::route().to(HttpResponse::MethodNotAllowed))
|
.default_service(web::route().to(HttpResponse::MethodNotAllowed))
|
||||||
.route(web::get().to(index_async)),
|
.route(web::get().to(index_async)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -602,7 +602,7 @@ mod tests {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(
|
.wrap(
|
||||||
DefaultHeaders::new()
|
DefaultHeaders::new()
|
||||||
.insert((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
.add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
||||||
)
|
)
|
||||||
.route("/test", web::get().to(HttpResponse::Ok)),
|
.route("/test", web::get().to(HttpResponse::Ok)),
|
||||||
)
|
)
|
||||||
|
@ -623,7 +623,7 @@ mod tests {
|
||||||
.route("/test", web::get().to(HttpResponse::Ok))
|
.route("/test", web::get().to(HttpResponse::Ok))
|
||||||
.wrap(
|
.wrap(
|
||||||
DefaultHeaders::new()
|
DefaultHeaders::new()
|
||||||
.insert((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
.add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
|
@ -30,7 +30,7 @@ use crate::{
|
||||||
/// use actix_web::{web, http, middleware, App, HttpResponse};
|
/// use actix_web::{web, http, middleware, App, HttpResponse};
|
||||||
///
|
///
|
||||||
/// let app = App::new()
|
/// let app = App::new()
|
||||||
/// .wrap(middleware::DefaultHeaders::new().insert("X-Version", "0.2"))
|
/// .wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
|
||||||
/// .service(
|
/// .service(
|
||||||
/// web::resource("/test")
|
/// web::resource("/test")
|
||||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||||
|
@ -58,12 +58,14 @@ impl DefaultHeaders {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// Panics when resolved header name or value is invalid.
|
/// Panics when resolved header name or value is invalid.
|
||||||
pub fn insert(mut self, header: impl TryIntoHeaderPair) -> Self {
|
#[allow(clippy::should_implement_trait)]
|
||||||
|
pub fn add(mut self, header: impl TryIntoHeaderPair) -> Self {
|
||||||
|
// standard header terminology `insert` or `append` for this method would make the behavior
|
||||||
|
// of this middleware less obvious since it only adds the headers if they are not present
|
||||||
|
|
||||||
match header.try_into_header_pair() {
|
match header.try_into_header_pair() {
|
||||||
Ok((key, value)) => Rc::get_mut(&mut self.inner)
|
Ok((key, value)) => Rc::get_mut(&mut self.inner)
|
||||||
.expect(
|
.expect("All default headers must be added before cloning.")
|
||||||
"DefaultHeaders has been cloned. Add all default headers before cloning.",
|
|
||||||
)
|
|
||||||
.headers
|
.headers
|
||||||
.append(key, value),
|
.append(key, value),
|
||||||
Err(err) => panic!("Invalid header: {}", err.into()),
|
Err(err) => panic!("Invalid header: {}", err.into()),
|
||||||
|
@ -73,7 +75,7 @@ impl DefaultHeaders {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[deprecated(since = "4.0.0", note = "Prefer `insert`.")]
|
#[deprecated(since = "4.0.0", note = "Prefer `add`.")]
|
||||||
pub fn header<K, V>(self, key: K, value: V) -> Self
|
pub fn header<K, V>(self, key: K, value: V) -> Self
|
||||||
where
|
where
|
||||||
HeaderName: TryFrom<K>,
|
HeaderName: TryFrom<K>,
|
||||||
|
@ -81,7 +83,7 @@ impl DefaultHeaders {
|
||||||
HeaderValue: TryFrom<V>,
|
HeaderValue: TryFrom<V>,
|
||||||
<HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
|
<HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
|
||||||
{
|
{
|
||||||
self.insert((
|
self.add((
|
||||||
HeaderName::try_from(key)
|
HeaderName::try_from(key)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
.expect("Invalid header name"),
|
.expect("Invalid header name"),
|
||||||
|
@ -94,18 +96,12 @@ impl DefaultHeaders {
|
||||||
/// Adds a default *Content-Type* header if response does not contain one.
|
/// Adds a default *Content-Type* header if response does not contain one.
|
||||||
///
|
///
|
||||||
/// Default is `application/octet-stream`.
|
/// Default is `application/octet-stream`.
|
||||||
pub fn insert_content_type(self) -> Self {
|
pub fn add_content_type(self) -> Self {
|
||||||
self.insert((
|
self.add((
|
||||||
CONTENT_TYPE,
|
CONTENT_TYPE,
|
||||||
HeaderValue::from_static("application/octet-stream"),
|
HeaderValue::from_static("application/octet-stream"),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[deprecated(since = "4.0.0", note = "Renamed to `insert_content_type`.")]
|
|
||||||
pub fn add_content_type(self) -> Self {
|
|
||||||
self.insert_content_type()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
|
impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
|
||||||
|
@ -202,8 +198,8 @@ mod tests {
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn adding_default_headers() {
|
async fn adding_default_headers() {
|
||||||
let mw = DefaultHeaders::new()
|
let mw = DefaultHeaders::new()
|
||||||
.insert(("X-TEST", "0001"))
|
.add(("X-TEST", "0001"))
|
||||||
.insert(("X-TEST-TWO", HeaderValue::from_static("123")))
|
.add(("X-TEST-TWO", HeaderValue::from_static("123")))
|
||||||
.new_transform(ok_service())
|
.new_transform(ok_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -225,7 +221,7 @@ mod tests {
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
let mw = DefaultHeaders::new()
|
let mw = DefaultHeaders::new()
|
||||||
.insert((CONTENT_TYPE, "0001"))
|
.add((CONTENT_TYPE, "0001"))
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -237,7 +233,7 @@ mod tests {
|
||||||
async fn adding_content_type() {
|
async fn adding_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()
|
let mw = DefaultHeaders::new()
|
||||||
.insert_content_type()
|
.add_content_type()
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -253,12 +249,12 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn invalid_header_name() {
|
fn invalid_header_name() {
|
||||||
DefaultHeaders::new().insert((":", "hello"));
|
DefaultHeaders::new().add((":", "hello"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn invalid_header_value() {
|
fn invalid_header_value() {
|
||||||
DefaultHeaders::new().insert(("x-test", "\n"));
|
DefaultHeaders::new().add(("x-test", "\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ mod tests {
|
||||||
let _ = App::new()
|
let _ = App::new()
|
||||||
.wrap(Compat::new(Logger::default()))
|
.wrap(Compat::new(Logger::default()))
|
||||||
.wrap(Condition::new(true, DefaultHeaders::new()))
|
.wrap(Condition::new(true, DefaultHeaders::new()))
|
||||||
.wrap(DefaultHeaders::new().insert(("X-Test2", "X-Value2")))
|
.wrap(DefaultHeaders::new().add(("X-Test2", "X-Value2")))
|
||||||
.wrap(ErrorHandlers::new().handler(StatusCode::FORBIDDEN, |res| {
|
.wrap(ErrorHandlers::new().handler(StatusCode::FORBIDDEN, |res| {
|
||||||
Ok(ErrorHandlerResponse::Response(res))
|
Ok(ErrorHandlerResponse::Response(res))
|
||||||
}))
|
}))
|
||||||
|
@ -46,7 +46,7 @@ mod tests {
|
||||||
.wrap(ErrorHandlers::new().handler(StatusCode::FORBIDDEN, |res| {
|
.wrap(ErrorHandlers::new().handler(StatusCode::FORBIDDEN, |res| {
|
||||||
Ok(ErrorHandlerResponse::Response(res))
|
Ok(ErrorHandlerResponse::Response(res))
|
||||||
}))
|
}))
|
||||||
.wrap(DefaultHeaders::new().insert(("X-Test2", "X-Value2")))
|
.wrap(DefaultHeaders::new().add(("X-Test2", "X-Value2")))
|
||||||
.wrap(Condition::new(true, DefaultHeaders::new()))
|
.wrap(Condition::new(true, DefaultHeaders::new()))
|
||||||
.wrap(Compat::new(Logger::default()));
|
.wrap(Compat::new(Logger::default()));
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::{dev::Payload, error::ErrorInternalServerError, Error, FromRequest, H
|
||||||
/// # Mutating Request Data
|
/// # Mutating Request Data
|
||||||
/// Note that since extractors must output owned data, only types that `impl Clone` can use this
|
/// Note that since extractors must output owned data, only types that `impl Clone` can use this
|
||||||
/// extractor. A clone is taken of the required request data and can, therefore, not be directly
|
/// extractor. A clone is taken of the required request data and can, therefore, not be directly
|
||||||
/// mutated in-place. To mutate request data, continue to use [`HttpRequest::extensions_mut`] or
|
/// mutated in-place. To mutate request data, continue to use [`HttpRequest::req_data_mut`] or
|
||||||
/// re-insert the cloned data back into the extensions map. A `DerefMut` impl is intentionally not
|
/// re-insert the cloned data back into the extensions map. A `DerefMut` impl is intentionally not
|
||||||
/// provided to make this potential foot-gun more obvious.
|
/// provided to make this potential foot-gun more obvious.
|
||||||
///
|
///
|
||||||
|
|
|
@ -525,7 +525,7 @@ mod tests {
|
||||||
.name("test")
|
.name("test")
|
||||||
.wrap(
|
.wrap(
|
||||||
DefaultHeaders::new()
|
DefaultHeaders::new()
|
||||||
.insert((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
.add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
||||||
)
|
)
|
||||||
.route(web::get().to(HttpResponse::Ok)),
|
.route(web::get().to(HttpResponse::Ok)),
|
||||||
),
|
),
|
||||||
|
|
|
@ -8,7 +8,9 @@ use actix_http::{
|
||||||
|
|
||||||
use crate::{BoxError, HttpRequest, HttpResponse, Responder};
|
use crate::{BoxError, HttpRequest, HttpResponse, Responder};
|
||||||
|
|
||||||
/// Allows overriding status code and headers for a responder.
|
/// Allows overriding status code and headers for a [`Responder`].
|
||||||
|
///
|
||||||
|
/// Created by the [`Responder::customize`] method.
|
||||||
pub struct CustomizeResponder<R> {
|
pub struct CustomizeResponder<R> {
|
||||||
inner: CustomizeResponderInner<R>,
|
inner: CustomizeResponderInner<R>,
|
||||||
error: Option<HttpError>,
|
error: Option<HttpError>,
|
||||||
|
@ -36,12 +38,15 @@ impl<R: Responder> CustomizeResponder<R> {
|
||||||
|
|
||||||
/// Override a status code for the Responder's response.
|
/// Override a status code for the Responder's response.
|
||||||
///
|
///
|
||||||
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use actix_web::{HttpRequest, Responder, http::StatusCode};
|
/// use actix_web::{Responder, http::StatusCode, test::TestRequest};
|
||||||
///
|
///
|
||||||
/// fn index(req: HttpRequest) -> impl Responder {
|
/// let responder = "Welcome!".customize().with_status(StatusCode::ACCEPTED);
|
||||||
/// "Welcome!".with_status(StatusCode::OK)
|
///
|
||||||
/// }
|
/// let request = TestRequest::default().to_http_request();
|
||||||
|
/// let response = responder.respond_to(&request);
|
||||||
|
/// assert_eq!(response.status(), StatusCode::ACCEPTED);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn with_status(mut self, status: StatusCode) -> Self {
|
pub fn with_status(mut self, status: StatusCode) -> Self {
|
||||||
if let Some(inner) = self.inner() {
|
if let Some(inner) = self.inner() {
|
||||||
|
@ -51,24 +56,26 @@ impl<R: Responder> CustomizeResponder<R> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert header to the final response.
|
/// Insert (override) header in the final response.
|
||||||
///
|
///
|
||||||
/// Overrides other headers with the same name.
|
/// Overrides other headers with the same name.
|
||||||
|
/// See [`HeaderMap::insert`](crate::http::header::HeaderMap::insert).
|
||||||
///
|
///
|
||||||
|
/// Headers added with this method will be inserted before those added
|
||||||
|
/// with [`append_header`](Self::append_header). As such, header(s) can be overridden with more
|
||||||
|
/// than one new header by first calling `insert_header` followed by `append_header`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use actix_web::{web, HttpRequest, Responder};
|
/// use actix_web::{Responder, test::TestRequest};
|
||||||
/// use serde::Serialize;
|
|
||||||
///
|
///
|
||||||
/// #[derive(Serialize)]
|
/// let responder = "Hello world!"
|
||||||
/// struct MyObj {
|
/// .customize()
|
||||||
/// name: String,
|
/// .insert_header(("x-version", "1.2.3"));
|
||||||
/// }
|
|
||||||
///
|
///
|
||||||
/// fn index(req: HttpRequest) -> impl Responder {
|
/// let request = TestRequest::default().to_http_request();
|
||||||
/// web::Json(MyObj { name: "Name".to_string() })
|
/// let response = responder.respond_to(&request);
|
||||||
/// .with_header(("x-version", "1.2.3"))
|
/// assert_eq!(response.headers().get("x-version").unwrap(), "1.2.3");
|
||||||
/// .with_header(("x-version", "1.2.3"))
|
|
||||||
/// }
|
|
||||||
/// ```
|
/// ```
|
||||||
pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
|
pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
|
||||||
if let Some(inner) = self.inner() {
|
if let Some(inner) = self.inner() {
|
||||||
|
@ -83,6 +90,25 @@ impl<R: Responder> CustomizeResponder<R> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Append header to the final response.
|
||||||
|
///
|
||||||
|
/// Unlike [`insert_header`](Self::insert_header), this will not override existing headers.
|
||||||
|
/// See [`HeaderMap::append`](crate::http::header::HeaderMap::append).
|
||||||
|
///
|
||||||
|
/// Headers added here are appended _after_ additions/overrides from `insert_header`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use actix_web::{Responder, test::TestRequest};
|
||||||
|
///
|
||||||
|
/// let responder = "Hello world!"
|
||||||
|
/// .customize()
|
||||||
|
/// .append_header(("x-version", "1.2.3"));
|
||||||
|
///
|
||||||
|
/// let request = TestRequest::default().to_http_request();
|
||||||
|
/// let response = responder.respond_to(&request);
|
||||||
|
/// assert_eq!(response.headers().get("x-version").unwrap(), "1.2.3");
|
||||||
|
/// ```
|
||||||
pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
|
pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
|
||||||
if let Some(inner) = self.inner() {
|
if let Some(inner) = self.inner() {
|
||||||
match header.try_into_header_pair() {
|
match header.try_into_header_pair() {
|
||||||
|
|
|
@ -21,24 +21,23 @@ pub trait Responder {
|
||||||
/// Convert self to `HttpResponse`.
|
/// Convert self to `HttpResponse`.
|
||||||
fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>;
|
fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>;
|
||||||
|
|
||||||
/// Wraps responder in [`CustomizeResponder`] that allows modification of response details.
|
/// Wraps responder to allow alteration of its response.
|
||||||
///
|
///
|
||||||
/// See [`CustomizeResponder`] docs for more.
|
/// See [`CustomizeResponder`] docs for its capabilities.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use actix_web::{Responder, test};
|
/// use actix_web::{Responder, http::StatusCode, test::TestRequest};
|
||||||
///
|
|
||||||
/// let request = test::TestRequest::default().to_http_request();
|
|
||||||
///
|
///
|
||||||
/// let responder = "Hello world!"
|
/// let responder = "Hello world!"
|
||||||
/// .customize()
|
/// .customize()
|
||||||
/// .with_status(400)
|
/// .with_status(StatusCode::BAD_REQUEST)
|
||||||
/// .insert_header(("x-hello", "world"))
|
/// .insert_header(("x-hello", "world"));
|
||||||
///
|
///
|
||||||
/// let response = res.respond_to(&req);
|
/// let request = TestRequest::default().to_http_request();
|
||||||
/// assert_eq!(res.status(), 400);
|
/// let response = responder.respond_to(&request);
|
||||||
/// assert_eq!(res.headers().get("x-hello").unwrap(), "world");
|
/// assert_eq!(response.status(), StatusCode::BAD_REQUEST);
|
||||||
|
/// assert_eq!(response.headers().get("x-hello").unwrap(), "world");
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn customize(self) -> CustomizeResponder<Self>
|
fn customize(self) -> CustomizeResponder<Self>
|
||||||
|
|
|
@ -935,7 +935,7 @@ mod tests {
|
||||||
web::scope("app")
|
web::scope("app")
|
||||||
.wrap(
|
.wrap(
|
||||||
DefaultHeaders::new()
|
DefaultHeaders::new()
|
||||||
.insert((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
|
.add((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))),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue