1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-07-05 18:35:22 +02:00

Compare commits

...

18 Commits

Author SHA1 Message Date
eb10b74751 Merge branch 'master' into error-response-mapping 2024-06-10 01:31:51 +01:00
a2b9823d9d Strip non-address characters from Forwarded for= (#3343)
* Strip non-address characters from Forwarded for=

This is something of a followup to #2528, which asked for port information to not be included in  when it was taken from the local socket.

The  header's  element may optionally contain port information (https://datatracker.ietf.org/doc/html/rfc7239#section-6).
However, as I understand it,  is *supposed* to only contain an IP address, without port (per #2528).

This PR corrects that discrepancy, making it easier to parse the result of this method in application code.

There should not be any compatibility concerns, as anyone parsing the output of  would already need to handle both port and portless cases anyway.

* Update CHANGES.md

---------

Co-authored-by: Rob Ede <robjtede@icloud.com>
2024-06-09 23:40:09 +00:00
da56de4556 chore(actix-test): prepare release 0.1.5 2024-06-10 00:01:17 +01:00
758ae1dac1 actix-test: allow the configuration of the TestServer address (#3351)
* actix-test: allow the configuration of the TestServer address

This is useful if you're running (say) Selenium tests against a running TestServer, and the Selenium workers are Docker containers elsewhere in the network.
Not a *particularly* common use case, perhaps, but one that I can attest happens every now and then.

* Update CHANGES.md

* Adjust default listen address to avoid test failures

---------

Co-authored-by: Rob Ede <robjtede@icloud.com>
2024-06-09 19:07:08 +00:00
37577dcb89 chore(actix-files): prepare release 0.6.6 2024-06-09 19:45:14 +01:00
8b8eb4eae1 build(deps): update tokio-uring requirement from 0.4 to 0.5 (#3385)
* build(deps): update tokio-uring requirement from 0.4 to 0.5

Updates the requirements on [tokio-uring](https://github.com/tokio-rs/tokio-uring) to permit the latest version.
- [Release notes](https://github.com/tokio-rs/tokio-uring/releases)
- [Changelog](https://github.com/tokio-rs/tokio-uring/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/tokio-uring/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: tokio-uring
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: narrow actix-server requirement

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rob Ede <robjtede@icloud.com>
2024-06-09 17:37:42 +00:00
22593a1532 Re-export http::status::InvalidStatusCode (#3393)
* [actix-http/src/lib.rs] Expose/re-export `http::status::InvalidStatusCode`

* [actix-http/src/error.rs] Re-export `http::status::InvalidStatusCode` ; [actix-http/src/lib.rs] Revert
2024-06-09 05:07:56 +00:00
f7646bcc48 actix-web-actors: take the internal buffer when yielding (#3369)
* actix-web-actors: take the internal buffer when yielding

* actix-web-actors: Add CHANGES entry re: taking buffer
2024-06-09 05:04:42 +00:00
8018983a68 docs: update changelog for #3393 2024-06-09 06:08:21 +01:00
266834cf7c chore: narrow h2 version 2024-06-09 04:51:53 +01:00
40e1034566 docs: update changelog 2024-06-09 00:38:49 +01:00
a5c78483f9 chore(actix-web): prepare release 4.7.0 2024-06-09 00:22:03 +01:00
12a0521ef8 chore(actix-multipart): prepare release 0.6.2 2024-06-09 00:20:36 +01:00
b4faf8820c chore(actix-web-codegen): prepare release 4.3.0 2024-06-09 00:19:09 +01:00
d6f885127d chore(actix-test): prepare release 0.1.4 2024-06-09 00:16:36 +01:00
ebc43dcf1b feat: forwards-compatibility for handler visibility inheritance fix (#3391) 2024-06-09 00:10:15 +01:00
7c4c26d2df feat: expose Identity middleware (#3390) 2024-06-08 05:26:26 +01:00
98c99f3bc2 add methods for mapping error responses 2023-02-13 23:40:23 +00:00
30 changed files with 162 additions and 66 deletions

View File

@ -89,5 +89,5 @@ jobs:
- name: Generate API diff
run: |
for f in $(find -mindepth 2 -maxdepth 2 -name Cargo.toml); do
cargo public-api --manifest-path "$f" diff ${{ github.event.pull_request.base.sha }}..${{ github.sha }}
cargo public-api --manifest-path "$f" --simplified diff ${{ github.event.pull_request.base.sha }}..${{ github.sha }}
done

View File

@ -2,6 +2,9 @@
## Unreleased
## 0.6.6
- Update `tokio-uring` dependency to `0.4`.
- Minimum supported Rust version (MSRV) is now 1.72.
## 0.6.5

View File

@ -1,6 +1,6 @@
[package]
name = "actix-files"
version = "0.6.5"
version = "0.6.6"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@ -40,8 +40,8 @@ v_htmlescape = "0.15.5"
# experimental-io-uring
[target.'cfg(target_os = "linux")'.dependencies]
tokio-uring = { version = "0.4", optional = true, features = ["bytes"] }
actix-server = { version = "2.2", optional = true } # ensure matching tokio-uring versions
tokio-uring = { version = "0.5", optional = true, features = ["bytes"] }
actix-server = { version = "2.4", optional = true } # ensure matching tokio-uring versions
[dev-dependencies]
actix-rt = "2.7"

View File

@ -3,11 +3,11 @@
<!-- prettier-ignore-start -->
[![crates.io](https://img.shields.io/crates/v/actix-files?label=latest)](https://crates.io/crates/actix-files)
[![Documentation](https://docs.rs/actix-files/badge.svg?version=0.6.5)](https://docs.rs/actix-files/0.6.5)
[![Documentation](https://docs.rs/actix-files/badge.svg?version=0.6.6)](https://docs.rs/actix-files/0.6.6)
![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-files.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-files/0.6.5/status.svg)](https://deps.rs/crate/actix-files/0.6.5)
[![dependency status](https://deps.rs/crate/actix-files/0.6.6/status.svg)](https://deps.rs/crate/actix-files/0.6.6)
[![Download](https://img.shields.io/crates/d/actix-files.svg)](https://crates.io/crates/actix-files)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -2,6 +2,10 @@
## Unreleased
### Added
- Add `error::InvalidStatusCode` re-export.
## 3.7.0
### Added

View File

@ -106,7 +106,7 @@ tokio-util = { version = "0.7", features = ["io", "codec"] }
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
# http2
h2 = { version = "0.3.24", optional = true }
h2 = { version = "0.3.26", optional = true }
# websockets
local-channel = { version = "0.1", optional = true }

View File

@ -3,7 +3,7 @@
use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};
use derive_more::{Display, Error, From};
pub use http::Error as HttpError;
pub use http::{status::InvalidStatusCode, Error as HttpError};
use http::{uri::InvalidUri, StatusCode};
use crate::{body::BoxBody, Response};

View File

@ -2,6 +2,8 @@
## Unreleased
## 0.6.2
- Add testing utilities under new module `test`.
- Minimum supported Rust version (MSRV) is now 1.72.

View File

@ -1,6 +1,6 @@
[package]
name = "actix-multipart"
version = "0.6.1"
version = "0.6.2"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Jacob Halsey <jacob@jhalsey.com>",

View File

@ -5,11 +5,11 @@
<!-- prettier-ignore-start -->
[![crates.io](https://img.shields.io/crates/v/actix-multipart?label=latest)](https://crates.io/crates/actix-multipart)
[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.6.1)](https://docs.rs/actix-multipart/0.6.1)
[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.6.2)](https://docs.rs/actix-multipart/0.6.2)
![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-multipart.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-multipart/0.6.1/status.svg)](https://deps.rs/crate/actix-multipart/0.6.1)
[![dependency status](https://deps.rs/crate/actix-multipart/0.6.2/status.svg)](https://deps.rs/crate/actix-multipart/0.6.2)
[![Download](https://img.shields.io/crates/d/actix-multipart.svg)](https://crates.io/crates/actix-multipart)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -2,6 +2,12 @@
## Unreleased
## 0.1.5
- Add `TestServerConfig::listen_address()` method.
## 0.1.4
- Add `TestServerConfig::rustls_0_23()` method for Rustls v0.23 support behind new `rustls-0_23` crate feature.
- Add `TestServerConfig::disable_redirects()` method.
- Various types from `awc`, such as `ClientRequest` and `ClientResponse`, are now re-exported.

View File

@ -1,6 +1,6 @@
[package]
name = "actix-test"
version = "0.1.3"
version = "0.1.5"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",

View File

@ -154,7 +154,7 @@ where
// run server in separate orphaned thread
thread::spawn(move || {
rt::System::new().block_on(async move {
let tcp = net::TcpListener::bind(("127.0.0.1", cfg.port)).unwrap();
let tcp = net::TcpListener::bind((cfg.listen_address.clone(), cfg.port)).unwrap();
let local_addr = tcp.local_addr().unwrap();
let factory = factory.clone();
let srv_cfg = cfg.clone();
@ -514,6 +514,7 @@ pub struct TestServerConfig {
tp: HttpVer,
stream: StreamType,
client_request_timeout: Duration,
listen_address: String,
port: u16,
workers: usize,
disable_redirects: bool,
@ -532,6 +533,7 @@ impl TestServerConfig {
tp: HttpVer::Both,
stream: StreamType::Tcp,
client_request_timeout: Duration::from_secs(5),
listen_address: "127.0.0.1".to_string(),
port: 0,
workers: 1,
disable_redirects: false,
@ -607,6 +609,14 @@ impl TestServerConfig {
self
}
/// Sets the address the server will listen on.
///
/// By default, only listens on `127.0.0.1`.
pub fn listen_address(mut self, addr: impl Into<String>) -> Self {
self.listen_address = addr.into();
self
}
/// Sets test server port.
///
/// By default, a random free port is determined by the OS.
@ -657,9 +667,9 @@ impl TestServer {
let scheme = if self.tls { "https" } else { "http" };
if uri.starts_with('/') {
format!("{}://localhost:{}{}", scheme, self.addr.port(), uri)
format!("{}://{}{}", scheme, self.addr, uri)
} else {
format!("{}://localhost:{}/{}", scheme, self.addr.port(), uri)
format!("{}://{}/{}", scheme, self.addr, uri)
}
}

View File

@ -2,6 +2,7 @@
## Unreleased
- Take the encoded buffer when yielding bytes in the response stream rather than splitting the buffer, reducing memory use
- Minimum supported Rust version (MSRV) is now 1.72.
## 4.3.0

View File

@ -710,7 +710,7 @@ where
}
if !this.buf.is_empty() {
Poll::Ready(Some(Ok(this.buf.split().freeze())))
Poll::Ready(Some(Ok(std::mem::take(&mut this.buf).freeze())))
} else if this.fut.alive() && !this.closed {
Poll::Pending
} else {

View File

@ -2,7 +2,10 @@
## Unreleased
## 4.3.0
- Add `#[scope]` macro.
- Add `compat-routing-macros-force-pub` crate feature which, on-by-default, which when disabled causes handlers to inherit their attached function's visibility.
- Prevent inclusion of default `actix-router` features.
- Minimum supported Rust version (MSRV) is now 1.72.

View File

@ -1,6 +1,6 @@
[package]
name = "actix-web-codegen"
version = "4.2.2"
version = "4.3.0"
description = "Routing and runtime macros for Actix Web"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
@ -15,6 +15,10 @@ rust-version.workspace = true
[lib]
proc-macro = true
[features]
default = ["compat-routing-macros-force-pub"]
compat-routing-macros-force-pub = []
[dependencies]
actix-router = { version = "0.5", default-features = false }
proc-macro2 = "1"

View File

@ -5,11 +5,11 @@
<!-- prettier-ignore-start -->
[![crates.io](https://img.shields.io/crates/v/actix-web-codegen?label=latest)](https://crates.io/crates/actix-web-codegen)
[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.2)](https://docs.rs/actix-web-codegen/4.2.2)
[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.3.0)](https://docs.rs/actix-web-codegen/4.3.0)
![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-web-codegen.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.2/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.2)
[![dependency status](https://deps.rs/crate/actix-web-codegen/4.3.0/status.svg)](https://deps.rs/crate/actix-web-codegen/4.3.0)
[![Download](https://img.shields.io/crates/d/actix-web-codegen.svg)](https://crates.io/crates/actix-web-codegen)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -413,6 +413,13 @@ impl ToTokens for Route {
doc_attributes,
} = self;
#[allow(unused_variables)] // used when force-pub feature is disabled
let vis = &ast.vis;
// TODO(breaking): remove this force-pub forwards-compatibility feature
#[cfg(feature = "compat-routing-macros-force-pub")]
let vis = syn::Visibility::Public(<Token![pub]>::default());
let registrations: TokenStream2 = args
.iter()
.map(|args| {
@ -460,7 +467,7 @@ impl ToTokens for Route {
let stream = quote! {
#(#doc_attributes)*
#[allow(non_camel_case_types, missing_docs)]
pub struct #name;
#vis struct #name;
impl ::actix_web::dev::HttpServiceFactory for #name {
fn register(self, __config: &mut actix_web::dev::AppService) {

View File

@ -49,7 +49,7 @@ mod scope_module {
#[connect("/test2")]
#[options("/test3")]
#[trace("/test4")]
async fn multiple_separate_paths() -> impl Responder {
pub async fn multiple_separate_paths() -> impl Responder {
HttpResponse::Ok().finish()
}

View File

@ -2,10 +2,20 @@
## Unreleased
### Fixed
- `ConnectionInfo::realip_remote_addr()` now handles IPv6 addresses from `Forwarded` header correctly. Previously, it sometimes returned the forwarded port as well.
## 4.7.0
### Added
- Add `#[scope]` macro.
- Add `middleware::Identity` type.
- Add `CustomizeResponder::add_cookie()` method.
- Add `guard::GuardContext::app_data()` method.
- Add `compat-routing-macros-force-pub` crate feature which (on-by-default) which, when disabled, causes handlers to inherit their attached function's visibility.
- Add `compat` crate feature group (on-by-default) which, when disabled, helps with transitioning to some planned v5.0 breaking changes, starting only with `compat-routing-macros-force-pub`.
- Implement `From<Box<dyn ResponseError>>` for `Error`.
## 4.6.0

View File

@ -1,6 +1,6 @@
[package]
name = "actix-web"
version = "4.6.0"
version = "4.7.0"
description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
@ -40,7 +40,16 @@ name = "actix_web"
path = "src/lib.rs"
[features]
default = ["macros", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "http2", "unicode"]
default = [
"macros",
"compress-brotli",
"compress-gzip",
"compress-zstd",
"cookies",
"http2",
"unicode",
"compat",
]
# Brotli algorithm content-encoding support
compress-brotli = ["actix-http/compress-brotli", "__compress"]
@ -50,14 +59,15 @@ compress-gzip = ["actix-http/compress-gzip", "__compress"]
compress-zstd = ["actix-http/compress-zstd", "__compress"]
# Routing and runtime proc macros
macros = ["actix-macros", "actix-web-codegen"]
macros = ["dep:actix-macros", "dep:actix-web-codegen"]
# Cookies support
cookies = ["cookie"]
cookies = ["dep:cookie"]
# Secure & signed cookies
secure-cookies = ["cookies", "cookie/secure"]
# HTTP/2 support (including h2c).
http2 = ["actix-http/http2"]
# TLS via OpenSSL
@ -84,6 +94,14 @@ __compress = []
# io-uring feature only available for Linux OSes.
experimental-io-uring = ["actix-server/io-uring"]
# Feature group which, when disabled, helps migrate code to v5.0.
compat = [
"compat-routing-macros-force-pub",
]
# Opt-out forwards-compatibility for handler visibility inheritance fix.
compat-routing-macros-force-pub = ["actix-web-codegen?/compat-routing-macros-force-pub"]
[dependencies]
actix-codec = "0.5"
actix-macros = { version = "0.2.3", optional = true }
@ -95,7 +113,7 @@ actix-tls = { version = "3.4", default-features = false, optional = true }
actix-http = { version = "3.7", features = ["ws"] }
actix-router = { version = "0.5.3", default-features = false, features = ["http"] }
actix-web-codegen = { version = "4.2", optional = true }
actix-web-codegen = { version = "4.3", optional = true, default-features = false }
ahash = "0.8"
bytes = "1"

View File

@ -8,10 +8,10 @@
<!-- prettier-ignore-start -->
[![crates.io](https://img.shields.io/crates/v/actix-web?label=latest)](https://crates.io/crates/actix-web)
[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.6.0)](https://docs.rs/actix-web/4.6.0)
[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.7.0)](https://docs.rs/actix-web/4.7.0)
![MSRV](https://img.shields.io/badge/rustc-1.72+-ab6000.svg)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg)
[![Dependency Status](https://deps.rs/crate/actix-web/4.6.0/status.svg)](https://deps.rs/crate/actix-web/4.6.0)
[![Dependency Status](https://deps.rs/crate/actix-web/4.7.0/status.svg)](https://deps.rs/crate/actix-web/4.7.0)
<br />
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web)

View File

@ -6,7 +6,7 @@ use crate::{HttpResponse, ResponseError};
/// General purpose Actix Web error.
///
/// An Actix Web error is used to carry errors from `std::error` through actix in a convenient way.
/// An Actix Web error is used to carry errors from `std::error` through Actix in a convenient way.
/// It can be created through converting errors with `into()`.
///
/// Whenever it is created from an external object a response error is created for it that can be
@ -14,6 +14,7 @@ use crate::{HttpResponse, ResponseError};
/// you can always get a `ResponseError` reference from it.
pub struct Error {
cause: Box<dyn ResponseError>,
response_mappers: Vec<Box<dyn Fn(HttpResponse) -> HttpResponse>>,
}
impl Error {
@ -29,7 +30,20 @@ impl Error {
/// Shortcut for creating an `HttpResponse`.
pub fn error_response(&self) -> HttpResponse {
self.cause.error_response()
let mut res = self.cause.error_response();
for mapper in &self.response_mappers {
res = (mapper)(res);
}
res
}
pub fn add_mapper<F, B>(&mut self, mapper: F)
where
F: Fn(HttpResponse) -> HttpResponse + 'static,
{
self.response_mappers.push(Box::new(mapper))
}
}
@ -56,6 +70,7 @@ impl<T: ResponseError + 'static> From<T> for Error {
fn from(err: T) -> Error {
Error {
cause: Box::new(err),
response_mappers: Vec::new(),
}
}
}

View File

@ -21,6 +21,19 @@ fn unquote(val: &str) -> &str {
val.trim().trim_start_matches('"').trim_end_matches('"')
}
/// Remove port and IPv6 square brackets from a peer specification.
fn bare_address(val: &str) -> &str {
if val.starts_with('[') {
val.split("]:")
.next()
.map(|s| s.trim_start_matches('[').trim_end_matches(']'))
// This shouldn't *actually* ever happen
.unwrap_or(val)
} else {
val.split(':').next().unwrap_or(val)
}
}
/// Extracts and trims first value for given header name.
fn first_header_value<'a>(req: &'a RequestHead, name: &'_ HeaderName) -> Option<&'a str> {
let hdr = req.headers.get(name)?.to_str().ok()?;
@ -100,7 +113,7 @@ impl ConnectionInfo {
// --- https://datatracker.ietf.org/doc/html/rfc7239#section-5.2
match name.trim().to_lowercase().as_str() {
"for" => realip_remote_addr.get_or_insert_with(|| unquote(val)),
"for" => realip_remote_addr.get_or_insert_with(|| bare_address(unquote(val))),
"proto" => scheme.get_or_insert_with(|| unquote(val)),
"host" => host.get_or_insert_with(|| unquote(val)),
"by" => {
@ -368,16 +381,25 @@ mod tests {
.insert_header((header::FORWARDED, r#"for="192.0.2.60:8080""#))
.to_http_request();
let info = req.connection_info();
assert_eq!(info.realip_remote_addr(), Some("192.0.2.60:8080"));
assert_eq!(info.realip_remote_addr(), Some("192.0.2.60"));
}
#[test]
fn forwarded_for_ipv6() {
let req = TestRequest::default()
.insert_header((header::FORWARDED, r#"for="[2001:db8:cafe::17]""#))
.to_http_request();
let info = req.connection_info();
assert_eq!(info.realip_remote_addr(), Some("2001:db8:cafe::17"));
}
#[test]
fn forwarded_for_ipv6_with_port() {
let req = TestRequest::default()
.insert_header((header::FORWARDED, r#"for="[2001:db8:cafe::17]:4711""#))
.to_http_request();
let info = req.connection_info();
assert_eq!(info.realip_remote_addr(), Some("[2001:db8:cafe::17]:4711"));
assert_eq!(info.realip_remote_addr(), Some("2001:db8:cafe::17"));
}
#[test]

View File

@ -38,15 +38,6 @@ pub struct Compat<T> {
transform: T,
}
#[cfg(test)]
impl Compat<super::Noop> {
pub(crate) fn noop() -> Self {
Self {
transform: super::Noop,
}
}
}
impl<T> Compat<T> {
/// Wrap a middleware to give it broader compatibility.
pub fn new(middleware: T) -> Self {
@ -152,7 +143,7 @@ mod tests {
use crate::{
dev::ServiceRequest,
http::StatusCode,
middleware::{self, Condition, Logger},
middleware::{self, Condition, Identity, Logger},
test::{self, call_service, init_service, TestRequest},
web, App, HttpResponse,
};
@ -225,7 +216,7 @@ mod tests {
async fn compat_noop_is_noop() {
let srv = test::ok_service();
let mw = Compat::noop()
let mw = Compat::new(Identity)
.new_transform(srv.into_service())
.await
.unwrap();

View File

@ -141,7 +141,7 @@ mod tests {
header::{HeaderValue, CONTENT_TYPE},
StatusCode,
},
middleware::{self, ErrorHandlerResponse, ErrorHandlers},
middleware::{self, ErrorHandlerResponse, ErrorHandlers, Identity},
test::{self, TestRequest},
web::Bytes,
HttpResponse,
@ -158,7 +158,7 @@ mod tests {
#[test]
fn compat_with_builtin_middleware() {
let _ = Condition::new(true, middleware::Compat::noop());
let _ = Condition::new(true, middleware::Compat::new(Identity));
let _ = Condition::new(true, middleware::Logger::default());
let _ = Condition::new(true, middleware::Compress::default());
let _ = Condition::new(true, middleware::NormalizePath::trim());

View File

@ -2,35 +2,39 @@
use actix_utils::future::{ready, Ready};
use crate::dev::{Service, Transform};
use crate::dev::{forward_ready, Service, Transform};
/// A no-op middleware that passes through request and response untouched.
pub(crate) struct Noop;
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct Identity;
impl<S: Service<Req>, Req> Transform<S, Req> for Noop {
impl<S: Service<Req>, Req> Transform<S, Req> for Identity {
type Response = S::Response;
type Error = S::Error;
type Transform = NoopService<S>;
type Transform = IdentityMiddleware<S>;
type InitError = ();
type Future = Ready<Result<Self::Transform, Self::InitError>>;
#[inline]
fn new_transform(&self, service: S) -> Self::Future {
ready(Ok(NoopService { service }))
ready(Ok(IdentityMiddleware { service }))
}
}
#[doc(hidden)]
pub(crate) struct NoopService<S> {
pub struct IdentityMiddleware<S> {
service: S,
}
impl<S: Service<Req>, Req> Service<Req> for NoopService<S> {
impl<S: Service<Req>, Req> Service<Req> for IdentityMiddleware<S> {
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
crate::dev::forward_ready!(service);
forward_ready!(service);
#[inline]
fn call(&self, req: Req) -> Self::Future {
self.service.call(req)
}

View File

@ -218,31 +218,27 @@
//! [lab_from_fn]: https://docs.rs/actix-web-lab/latest/actix_web_lab/middleware/fn.from_fn.html
mod compat;
#[cfg(feature = "__compress")]
mod compress;
mod condition;
mod default_headers;
mod err_handlers;
mod identity;
mod logger;
#[cfg(test)]
mod noop;
mod normalize;
#[cfg(test)]
pub(crate) use self::noop::Noop;
#[cfg(feature = "__compress")]
pub use self::compress::Compress;
pub use self::{
compat::Compat,
condition::Condition,
default_headers::DefaultHeaders,
err_handlers::{ErrorHandlerResponse, ErrorHandlers},
identity::Identity,
logger::Logger,
normalize::{NormalizePath, TrailingSlash},
};
#[cfg(feature = "__compress")]
mod compress;
#[cfg(feature = "__compress")]
pub use self::compress::Compress;
#[cfg(test)]
mod tests {
use super::*;

View File

@ -64,7 +64,7 @@ compress-gzip = ["actix-http/compress-gzip", "__compress"]
compress-zstd = ["actix-http/compress-zstd", "__compress"]
# Cookie parsing and cookie jar
cookies = ["cookie"]
cookies = ["dep:cookie"]
# Use `trust-dns-resolver` crate as DNS resolver
trust-dns = ["trust-dns-resolver"]
@ -92,7 +92,7 @@ cfg-if = "1"
derive_more = "0.99.5"
futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] }
futures-util = { version = "0.3.17", default-features = false, features = ["alloc", "sink"] }
h2 = "0.3.24"
h2 = "0.3.26"
http = "0.2.7"
itoa = "1"
log =" 0.4"