mirror of
https://github.com/actix/actix-web.git
synced 2024-12-23 00:26:34 +00:00
refactor web module (#2379)
This commit is contained in:
parent
53ec66caf4
commit
d8a0f46f26
8 changed files with 103 additions and 181 deletions
|
@ -6,4 +6,4 @@ ci-min-test = "hack check --workspace --no-default-features --tests --examples"
|
|||
ci-default = "check --workspace --bins --tests --examples"
|
||||
ci-full = "check --workspace --all-features --bins --tests --examples"
|
||||
ci-test = "test --workspace --all-features --lib --tests --no-fail-fast -- --nocapture"
|
||||
ci-doctest = "hack test --workspace --all-features --doc --no-fail-fast -- --nocapture"
|
||||
ci-doctest = "test --workspace --all-features --doc --no-fail-fast -- --nocapture"
|
||||
|
|
40
.github/workflows/ci.yml
vendored
40
.github/workflows/ci.yml
vendored
|
@ -80,13 +80,6 @@ jobs:
|
|||
command: ci-test
|
||||
args: --skip=test_reading_deflate_encoding_large_random_rustls
|
||||
|
||||
- name: doc tests
|
||||
# due to unknown issue with running doc tests on macOS
|
||||
if: matrix.target.os == 'ubuntu-latest'
|
||||
uses: actions-rs/cargo@v1
|
||||
timeout-minutes: 40
|
||||
with: { command: ci-doctest }
|
||||
|
||||
- name: Generate coverage file
|
||||
if: >
|
||||
matrix.target.os == 'ubuntu-latest'
|
||||
|
@ -106,5 +99,36 @@ jobs:
|
|||
|
||||
- name: Clear the cargo caches
|
||||
run: |
|
||||
cargo install cargo-cache --version 0.6.2 --no-default-features --features ci-autoclean
|
||||
cargo install cargo-cache --version 0.6.3 --no-default-features --features ci-autoclean
|
||||
cargo-cache
|
||||
|
||||
rustdoc:
|
||||
name: rustdoc
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust (nightly)
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-x86_64-unknown-linux-gnu
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Generate Cargo.lock
|
||||
uses: actions-rs/cargo@v1
|
||||
with: { command: generate-lockfile }
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v1.3.0
|
||||
|
||||
- name: Install cargo-hack
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
args: cargo-hack
|
||||
|
||||
- name: doc tests
|
||||
uses: actions-rs/cargo@v1
|
||||
timeout-minutes: 40
|
||||
with: { command: ci-doctest }
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
* Re-export actix-service `ServiceFactory` in `dev` module. [#2325]
|
||||
|
||||
### Changed
|
||||
* Minimum supported Rust version (MSRV) is now 1.51.
|
||||
* Compress middleware will return 406 Not Acceptable when no content encoding is acceptable to the client. [#2344]
|
||||
* Move `BaseHttpResponse` to `dev::Response`. [#2379]
|
||||
* Minimum supported Rust version (MSRV) is now 1.51.
|
||||
|
||||
### Fixed
|
||||
* Fix quality parse error in Accept-Encoding header. [#2344]
|
||||
* Re-export correct type at `web::HttpResponse`. [#2379]
|
||||
|
||||
[#2325]: https://github.com/actix/actix-web/pull/2325
|
||||
[#2344]: https://github.com/actix/actix-web/pull/2344
|
||||
[#2379]: https://github.com/actix/actix-web/pull/2379
|
||||
|
||||
|
||||
## 4.0.0-beta.8 - 2021-06-26
|
||||
|
|
|
@ -18,7 +18,7 @@ pub use actix_http::body::{AnyBody, Body, BodySize, MessageBody, ResponseBody, S
|
|||
|
||||
#[cfg(feature = "__compress")]
|
||||
pub use actix_http::encoding::Decoder as Decompress;
|
||||
pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, ResponseHead};
|
||||
pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, Response, ResponseHead};
|
||||
pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
|
||||
pub use actix_server::Server;
|
||||
pub use actix_service::{
|
||||
|
@ -26,7 +26,7 @@ pub use actix_service::{
|
|||
};
|
||||
|
||||
use crate::http::header::ContentEncoding;
|
||||
use actix_http::{Response, ResponseBuilder};
|
||||
use actix_http::ResponseBuilder;
|
||||
|
||||
use actix_router::Patterns;
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! # References
|
||||
//!
|
||||
//! "The Content-Disposition Header Field" https://www.ietf.org/rfc/rfc2183.txt
|
||||
//! "The Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)" https://www.ietf.org/rfc/rfc6266.txt
|
||||
//! "Returning Values from Forms: multipart/form-data" https://www.ietf.org/rfc/rfc7578.txt
|
||||
//! Browser conformance tests at: http://greenbytes.de/tech/tc2231/
|
||||
//! IANA assignment: http://www.iana.org/assignments/cont-disp/cont-disp.xhtml
|
||||
//! "The Content-Disposition Header Field" <https://www.ietf.org/rfc/rfc2183.txt>
|
||||
//! "The Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)" <https://www.ietf.org/rfc/rfc6266.txt>
|
||||
//! "Returning Values from Forms: multipart/form-data" <https://www.ietf.org/rfc/rfc7578.txt>
|
||||
//! Browser conformance tests at: <http://greenbytes.de/tech/tc2231/>
|
||||
//! IANA assignment: <http://www.iana.org/assignments/cont-disp/cont-disp.xhtml>
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
|
|
@ -96,7 +96,6 @@ pub mod test;
|
|||
pub(crate) mod types;
|
||||
pub mod web;
|
||||
|
||||
pub use actix_http::Response as BaseHttpResponse;
|
||||
pub use actix_http::{body, HttpMessage};
|
||||
#[doc(inline)]
|
||||
pub use actix_rt as rt;
|
||||
|
|
|
@ -476,7 +476,7 @@ impl WebService {
|
|||
|
||||
/// Set service name.
|
||||
///
|
||||
/// Name is used for url generation.
|
||||
/// Name is used for URL generation.
|
||||
pub fn name(mut self, name: &str) -> Self {
|
||||
self.name = Some(name.to_string());
|
||||
self
|
||||
|
|
220
src/web.rs
220
src/web.rs
|
@ -3,44 +3,36 @@
|
|||
use std::future::Future;
|
||||
|
||||
use actix_http::http::Method;
|
||||
pub use actix_http::Response as HttpResponse;
|
||||
use actix_router::IntoPatterns;
|
||||
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
|
||||
|
||||
use crate::error::BlockingError;
|
||||
use crate::extract::FromRequest;
|
||||
use crate::handler::Handler;
|
||||
use crate::resource::Resource;
|
||||
use crate::responder::Responder;
|
||||
use crate::route::Route;
|
||||
use crate::scope::Scope;
|
||||
use crate::service::WebService;
|
||||
use crate::{
|
||||
error::BlockingError, extract::FromRequest, handler::Handler, resource::Resource,
|
||||
responder::Responder, route::Route, scope::Scope, service::WebService,
|
||||
};
|
||||
|
||||
pub use crate::config::ServiceConfig;
|
||||
pub use crate::data::Data;
|
||||
pub use crate::request::HttpRequest;
|
||||
pub use crate::request_data::ReqData;
|
||||
pub use crate::response::HttpResponse;
|
||||
pub use crate::types::*;
|
||||
|
||||
/// Create resource for a specific path.
|
||||
/// Creates a new resource for a specific path.
|
||||
///
|
||||
/// Resources may have variable path segments. For example, a
|
||||
/// resource with the path `/a/{name}/c` would match all incoming
|
||||
/// requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
|
||||
/// Resources may have dynamic path segments. For example, a resource with the path `/a/{name}/c`
|
||||
/// would match all incoming requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
|
||||
///
|
||||
/// A variable segment is specified in the form `{identifier}`,
|
||||
/// where the identifier can be used later in a request handler to
|
||||
/// access the matched value for that segment. This is done by
|
||||
/// looking up the identifier in the `Params` object returned by
|
||||
/// `HttpRequest.match_info()` method.
|
||||
/// A dynamic segment is specified in the form `{identifier}`, where the identifier can be used
|
||||
/// later in a request handler to access the matched value for that segment. This is done by looking
|
||||
/// up the identifier in the `Path` object returned by [`HttpRequest.match_info()`] method.
|
||||
///
|
||||
/// By default, each segment matches the regular expression `[^{}/]+`.
|
||||
///
|
||||
/// You can also specify a custom regex in the form `{identifier:regex}`:
|
||||
///
|
||||
/// For instance, to route `GET`-requests on any route matching
|
||||
/// `/users/{userid}/{friend}` and store `userid` and `friend` in
|
||||
/// the exposed `Params` object:
|
||||
/// For instance, to route `GET`-requests on any route matching `/users/{userid}/{friend}` and store
|
||||
/// `userid` and `friend` in the exposed `Path` object:
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
|
@ -55,10 +47,16 @@ pub fn resource<T: IntoPatterns>(path: T) -> Resource {
|
|||
Resource::new(path)
|
||||
}
|
||||
|
||||
/// Configure scope for common root path.
|
||||
/// Creates scope for common path prefix.
|
||||
///
|
||||
/// Scopes collect multiple paths under a common path prefix.
|
||||
/// Scope path can contain variable path segments as resources.
|
||||
/// Scopes collect multiple paths under a common path prefix. The scope's path can contain dynamic
|
||||
/// path segments.
|
||||
///
|
||||
/// # Examples
|
||||
/// In this example, three routes are set up (and will handle any method):
|
||||
/// * `/{project_id}/path1`
|
||||
/// * `/{project_id}/path2`
|
||||
/// * `/{project_id}/path3`
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
|
@ -70,148 +68,50 @@ pub fn resource<T: IntoPatterns>(path: T) -> Resource {
|
|||
/// .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, three routes get added:
|
||||
/// * /{project_id}/path1
|
||||
/// * /{project_id}/path2
|
||||
/// * /{project_id}/path3
|
||||
///
|
||||
pub fn scope(path: &str) -> Scope {
|
||||
Scope::new(path)
|
||||
}
|
||||
|
||||
/// Create *route* without configuration.
|
||||
/// Creates a new un-configured route.
|
||||
pub fn route() -> Route {
|
||||
Route::new()
|
||||
}
|
||||
|
||||
/// Create *route* with `GET` method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `GET` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn get() -> Route {
|
||||
method(Method::GET)
|
||||
macro_rules! method_route {
|
||||
($method_fn:ident, $method_const:ident) => {
|
||||
paste::paste! {
|
||||
#[doc = "Creates a new route with `" $method_const "` method guard."]
|
||||
///
|
||||
/// # Examples
|
||||
#[doc = "In this example, one `" $method_const " /{project_id}` route is set up:"]
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
#[doc = " .route(web::" $method_fn "().to(|| HttpResponse::Ok()))"]
|
||||
///
|
||||
/// );
|
||||
/// ```
|
||||
pub fn $method_fn() -> Route {
|
||||
method(Method::$method_const)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create *route* with `POST` method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::post().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `POST` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn post() -> Route {
|
||||
method(Method::POST)
|
||||
}
|
||||
method_route!(get, GET);
|
||||
method_route!(post, POST);
|
||||
method_route!(put, PUT);
|
||||
method_route!(patch, PATCH);
|
||||
method_route!(delete, DELETE);
|
||||
method_route!(head, HEAD);
|
||||
method_route!(trace, TRACE);
|
||||
|
||||
/// Create *route* with `PUT` method guard.
|
||||
/// Creates a new route with specified method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::put().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `PUT` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn put() -> Route {
|
||||
method(Method::PUT)
|
||||
}
|
||||
|
||||
/// Create *route* with `PATCH` method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::patch().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `PATCH` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn patch() -> Route {
|
||||
method(Method::PATCH)
|
||||
}
|
||||
|
||||
/// Create *route* with `DELETE` method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::delete().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `DELETE` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn delete() -> Route {
|
||||
method(Method::DELETE)
|
||||
}
|
||||
|
||||
/// Create *route* with `HEAD` method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::head().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `HEAD` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn head() -> Route {
|
||||
method(Method::HEAD)
|
||||
}
|
||||
|
||||
/// Create *route* with `TRACE` method guard.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::trace().to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `HEAD` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn trace() -> Route {
|
||||
method(Method::TRACE)
|
||||
}
|
||||
|
||||
/// Create *route* and add method guard.
|
||||
/// # Examples
|
||||
/// In this example, one `GET /{project_id}` route is set up:
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, http, App, HttpResponse};
|
||||
|
@ -221,15 +121,11 @@ pub fn trace() -> Route {
|
|||
/// .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// In the above example, one `GET` route gets added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn method(method: Method) -> Route {
|
||||
Route::new().method(method)
|
||||
}
|
||||
|
||||
/// Create a new route and add handler.
|
||||
/// Creates a new any-method route with handler.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
||||
|
@ -253,7 +149,7 @@ where
|
|||
Route::new().to(handler)
|
||||
}
|
||||
|
||||
/// Create raw service for a specific path.
|
||||
/// Creates a raw service for a specific path.
|
||||
///
|
||||
/// ```
|
||||
/// use actix_web::{dev, web, guard, App, Error, HttpResponse};
|
||||
|
@ -272,8 +168,8 @@ pub fn service<T: IntoPatterns>(path: T) -> WebService {
|
|||
WebService::new(path)
|
||||
}
|
||||
|
||||
/// Execute blocking function on a thread pool, returns future that resolves
|
||||
/// to result of the function execution.
|
||||
/// Executes blocking function on a thread pool, returns future that resolves to result of the
|
||||
/// function execution.
|
||||
pub fn block<F, R>(f: F) -> impl Future<Output = Result<R, BlockingError>>
|
||||
where
|
||||
F: FnOnce() -> R + Send + 'static,
|
||||
|
|
Loading…
Reference in a new issue