mirror of https://github.com/fafhrd91/actix-web
Compare commits
No commits in common. "856480cd902923049cca066509d44486c6a391db" and "d8566da66f25ece1c176ad9dc52002c0451a1176" have entirely different histories.
856480cd90
...
d8566da66f
|
@ -88,3 +88,30 @@ jobs:
|
||||||
|
|
||||||
- name: check external types
|
- name: check external types
|
||||||
run: just check-external-types-all +${{ vars.RUST_VERSION_EXTERNAL_TYPES }}
|
run: just check-external-types-all +${{ vars.RUST_VERSION_EXTERNAL_TYPES }}
|
||||||
|
|
||||||
|
public-api-diff:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout main branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.base_ref }}
|
||||||
|
|
||||||
|
- name: Checkout PR branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust (${{ vars.RUST_VERSION_API_DIFF }})
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1.10.1
|
||||||
|
with:
|
||||||
|
toolchain: ${{ vars.RUST_VERSION_API_DIFF }}
|
||||||
|
|
||||||
|
- name: Install cargo-public-api
|
||||||
|
uses: taiki-e/install-action@v2.46.20
|
||||||
|
with:
|
||||||
|
tool: cargo-public-api
|
||||||
|
|
||||||
|
- name: Generate API diff
|
||||||
|
run: |
|
||||||
|
for f in $(find -mindepth 2 -maxdepth 2 -name Cargo.toml); do
|
||||||
|
cargo public-api --manifest-path "$f" --simplified diff ${{ github.event.pull_request.base.sha }}..${{ github.sha }}
|
||||||
|
done
|
||||||
|
|
|
@ -106,12 +106,12 @@ actix-codec = "0.5"
|
||||||
actix-utils = "3"
|
actix-utils = "3"
|
||||||
actix-rt = { version = "2.2", default-features = false }
|
actix-rt = { version = "2.2", default-features = false }
|
||||||
|
|
||||||
|
ahash = "0.8"
|
||||||
bitflags = "2"
|
bitflags = "2"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
bytestring = "1"
|
bytestring = "1"
|
||||||
derive_more = { version = "1", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] }
|
derive_more = { version = "1", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] }
|
||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
foldhash = "0.1"
|
|
||||||
futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] }
|
futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] }
|
||||||
http = "0.2.7"
|
http = "0.2.7"
|
||||||
httparse = "1.5.1"
|
httparse = "1.5.1"
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl Hasher for NoOpHasher {
|
||||||
/// All entries into this map must be owned types (or static references).
|
/// All entries into this map must be owned types (or static references).
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Extensions {
|
pub struct Extensions {
|
||||||
// use no-op hasher with a std HashMap with for faster lookups on the small `TypeId` keys
|
/// Use AHasher with a std HashMap with for faster lookups on the small `TypeId` keys.
|
||||||
map: HashMap<TypeId, Box<dyn Any>, BuildHasherDefault<NoOpHasher>>,
|
map: HashMap<TypeId, Box<dyn Any>, BuildHasherDefault<NoOpHasher>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::{borrow::Cow, collections::hash_map, iter, ops};
|
use std::{borrow::Cow, collections::hash_map, iter, ops};
|
||||||
|
|
||||||
use foldhash::{HashMap as FoldHashMap, HashMapExt as _};
|
use ahash::AHashMap;
|
||||||
use http::header::{HeaderName, HeaderValue};
|
use http::header::{HeaderName, HeaderValue};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ use super::AsHeaderName;
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct HeaderMap {
|
pub struct HeaderMap {
|
||||||
pub(crate) inner: FoldHashMap<HeaderName, Value>,
|
pub(crate) inner: AHashMap<HeaderName, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A bespoke non-empty list for HeaderMap values.
|
/// A bespoke non-empty list for HeaderMap values.
|
||||||
|
@ -116,7 +116,7 @@ impl HeaderMap {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
HeaderMap {
|
HeaderMap {
|
||||||
inner: FoldHashMap::with_capacity(capacity),
|
inner: AHashMap::with_capacity(capacity),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +830,7 @@ impl<'a> Drain<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for Drain<'_> {
|
impl<'a> Iterator for Drain<'a> {
|
||||||
type Item = (Option<HeaderName>, HeaderValue);
|
type Item = (Option<HeaderName>, HeaderValue);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub fn write_content_length<B: BufMut>(n: u64, buf: &mut B, camel_case: bool) {
|
||||||
/// perform a remaining length check before writing.
|
/// perform a remaining length check before writing.
|
||||||
pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
|
pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
|
||||||
|
|
||||||
impl<B> io::Write for MutWriter<'_, B>
|
impl<'a, B> io::Write for MutWriter<'a, B>
|
||||||
where
|
where
|
||||||
B: BufMut,
|
B: BufMut,
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,7 +103,7 @@ pub trait HttpMessage: Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> HttpMessage for &mut T
|
impl<'a, T> HttpMessage for &'a mut T
|
||||||
where
|
where
|
||||||
T: HttpMessage,
|
T: HttpMessage,
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,7 +59,7 @@ tokio = { version = "1.24.2", features = ["sync", "io-util"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-http = "3"
|
actix-http = "3"
|
||||||
actix-multipart-rfc7578 = "0.11"
|
actix-multipart-rfc7578 = "0.10"
|
||||||
actix-rt = "2.2"
|
actix-rt = "2.2"
|
||||||
actix-test = "0.1"
|
actix-test = "0.1"
|
||||||
actix-web = "4"
|
actix-web = "4"
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl ResourcePath for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResourcePath for &str {
|
impl<'a> ResourcePath for &'a str {
|
||||||
fn path(&self) -> &str {
|
fn path(&self) -> &str {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ async fn routes_overlapping_inaccessible_test(req: HttpRequest) -> impl Responde
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/custom_resource_name", name = "custom")]
|
#[get("/custom_resource_name", name = "custom")]
|
||||||
async fn custom_resource_name_test(req: HttpRequest) -> impl Responder {
|
async fn custom_resource_name_test<'a>(req: HttpRequest) -> impl Responder {
|
||||||
assert!(req.url_for_static("custom").is_ok());
|
assert!(req.url_for_static("custom").is_ok());
|
||||||
assert!(req.url_for_static("custom_resource_name_test").is_err());
|
assert!(req.url_for_static("custom_resource_name_test").is_err());
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
|
|
|
@ -141,13 +141,13 @@ actix-http = { version = "3.7", features = ["ws"] }
|
||||||
actix-router = { version = "0.5.3", default-features = false, features = ["http"] }
|
actix-router = { version = "0.5.3", default-features = false, features = ["http"] }
|
||||||
actix-web-codegen = { version = "4.3", optional = true, default-features = false }
|
actix-web-codegen = { version = "4.3", optional = true, default-features = false }
|
||||||
|
|
||||||
|
ahash = "0.8"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
bytestring = "1"
|
bytestring = "1"
|
||||||
cfg-if = "1"
|
cfg-if = "1"
|
||||||
cookie = { version = "0.16", features = ["percent-encode"], optional = true }
|
cookie = { version = "0.16", features = ["percent-encode"], optional = true }
|
||||||
derive_more = { version = "1", features = ["display", "error", "from"] }
|
derive_more = { version = "1", features = ["display", "error", "from"] }
|
||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
foldhash = "0.1"
|
|
||||||
futures-core = { version = "0.3.17", default-features = false }
|
futures-core = { version = "0.3.17", default-features = false }
|
||||||
futures-util = { version = "0.3.17", default-features = false }
|
futures-util = { version = "0.3.17", default-features = false }
|
||||||
itoa = "1"
|
itoa = "1"
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
[](https://deps.rs/crate/actix-web/4.9.0)
|
[](https://deps.rs/crate/actix-web/4.9.0)
|
||||||
<br />
|
<br />
|
||||||
[](https://github.com/actix/actix-web/actions/workflows/ci.yml)
|
[](https://github.com/actix/actix-web/actions/workflows/ci.yml)
|
||||||
[](https://codecov.io/gh/actix/actix-web)
|
[](https://codecov.io/gh/actix/actix-web)
|
||||||

|

|
||||||
[](https://discord.gg/NWpN5mmg3x)
|
[](https://discord.gg/NWpN5mmg3x)
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use bytes::BufMut;
|
||||||
/// perform a remaining length check before writing.
|
/// perform a remaining length check before writing.
|
||||||
pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
|
pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
|
||||||
|
|
||||||
impl<B> io::Write for MutWriter<'_, B>
|
impl<'a, B> io::Write for MutWriter<'a, B>
|
||||||
where
|
where
|
||||||
B: BufMut,
|
B: BufMut,
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use actix_service::{Service, Transform};
|
use actix_service::{Service, Transform};
|
||||||
use foldhash::HashMap as FoldHashMap;
|
use ahash::AHashMap;
|
||||||
use futures_core::{future::LocalBoxFuture, ready};
|
use futures_core::{future::LocalBoxFuture, ready};
|
||||||
use pin_project_lite::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ pub struct ErrorHandlers<B> {
|
||||||
handlers: Handlers<B>,
|
handlers: Handlers<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handlers<B> = Rc<FoldHashMap<StatusCode, Box<ErrorHandler<B>>>>;
|
type Handlers<B> = Rc<AHashMap<StatusCode, Box<ErrorHandler<B>>>>;
|
||||||
|
|
||||||
impl<B> Default for ErrorHandlers<B> {
|
impl<B> Default for ErrorHandlers<B> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|
|
@ -704,7 +704,7 @@ impl FormatText {
|
||||||
/// Converter to get a String from something that writes to a Formatter.
|
/// Converter to get a String from something that writes to a Formatter.
|
||||||
pub(crate) struct FormatDisplay<'a>(&'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>);
|
pub(crate) struct FormatDisplay<'a>(&'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>);
|
||||||
|
|
||||||
impl fmt::Display for FormatDisplay<'_> {
|
impl<'a> fmt::Display for FormatDisplay<'a> {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
(self.0)(fmt)
|
(self.0)(fmt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,9 @@ use crate::{
|
||||||
///
|
///
|
||||||
/// Resource in turn has at least one route. Route consists of an handlers objects and list of
|
/// Resource in turn has at least one route. Route consists of an handlers objects and list of
|
||||||
/// guards (objects that implement `Guard` trait). Resources and routes uses builder-like pattern
|
/// guards (objects that implement `Guard` trait). Resources and routes uses builder-like pattern
|
||||||
/// for configuration. During request handling, the resource object iterates through all routes
|
/// for configuration. During request handling, resource object iterate through all routes and check
|
||||||
/// and checks guards for the specific route, if the request matches all the guards, then the route
|
/// guards for specific route, if request matches all guards, route considered matched and route
|
||||||
/// is considered matched and the route handler gets called.
|
/// handler get called.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use actix_router::ResourceDef;
|
use actix_router::ResourceDef;
|
||||||
use foldhash::HashMap as FoldHashMap;
|
use ahash::AHashMap;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{error::UrlGenerationError, request::HttpRequest};
|
use crate::{error::UrlGenerationError, request::HttpRequest};
|
||||||
|
@ -19,7 +19,7 @@ pub struct ResourceMap {
|
||||||
|
|
||||||
/// Named resources within the tree or, for external resources, it points to isolated nodes
|
/// Named resources within the tree or, for external resources, it points to isolated nodes
|
||||||
/// outside the tree.
|
/// outside the tree.
|
||||||
named: FoldHashMap<String, Rc<ResourceMap>>,
|
named: AHashMap<String, Rc<ResourceMap>>,
|
||||||
|
|
||||||
parent: RefCell<Weak<ResourceMap>>,
|
parent: RefCell<Weak<ResourceMap>>,
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ impl ResourceMap {
|
||||||
pub fn new(root: ResourceDef) -> Self {
|
pub fn new(root: ResourceDef) -> Self {
|
||||||
ResourceMap {
|
ResourceMap {
|
||||||
pattern: root,
|
pattern: root,
|
||||||
named: FoldHashMap::default(),
|
named: AHashMap::default(),
|
||||||
parent: RefCell::new(Weak::new()),
|
parent: RefCell::new(Weak::new()),
|
||||||
nodes: Some(Vec::new()),
|
nodes: Some(Vec::new()),
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ impl ResourceMap {
|
||||||
} else {
|
} else {
|
||||||
let new_node = Rc::new(ResourceMap {
|
let new_node = Rc::new(ResourceMap {
|
||||||
pattern: pattern.clone(),
|
pattern: pattern.clone(),
|
||||||
named: FoldHashMap::default(),
|
named: AHashMap::default(),
|
||||||
parent: RefCell::new(Weak::new()),
|
parent: RefCell::new(Weak::new()),
|
||||||
nodes: None,
|
nodes: None,
|
||||||
});
|
});
|
||||||
|
|
|
@ -332,7 +332,7 @@ impl<T: DeserializeOwned> JsonBody<T> {
|
||||||
(true, Ok(Some(mime))) => {
|
(true, Ok(Some(mime))) => {
|
||||||
mime.subtype() == mime::JSON
|
mime.subtype() == mime::JSON
|
||||||
|| mime.suffix() == Some(mime::JSON)
|
|| mime.suffix() == Some(mime::JSON)
|
||||||
|| ctype_fn.is_some_and(|predicate| predicate(mime))
|
|| ctype_fn.map_or(false, |predicate| predicate(mime))
|
||||||
}
|
}
|
||||||
|
|
||||||
// if content-type is expected but not parsable as mime type, bail
|
// if content-type is expected but not parsable as mime type, bail
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
- Update `brotli` dependency to `7`.
|
- Update `brotli` dependency to `7`.
|
||||||
- Prevent panics on connection pool drop when Tokio runtime is shutdown early.
|
- Prevent panics on connection pool drop when Tokio runtime is shutdown early.
|
||||||
- Minimum supported Rust version (MSRV) is now 1.75.
|
- Minimum supported Rust version (MSRV) is now 1.75.
|
||||||
- Do not send `Host` header on HTTP/2 requests, as it is not required, and some web servers may reject it.
|
|
||||||
|
|
||||||
## 3.5.1
|
## 3.5.1
|
||||||
|
|
||||||
|
|
|
@ -153,9 +153,9 @@ tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] }
|
||||||
zstd = "0.13"
|
zstd = "0.13"
|
||||||
tls-rustls-0_23 = { package = "rustls", version = "0.23" } # add rustls 0.23 with default features to make aws_lc_rs work in tests
|
tls-rustls-0_23 = { package = "rustls", version = "0.23" } # add rustls 0.23 with default features to make aws_lc_rs work in tests
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "client"
|
name = "client"
|
||||||
required-features = ["rustls-0_23-webpki-roots"]
|
required-features = ["rustls-0_23-webpki-roots"]
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
|
|
|
@ -1,39 +1,25 @@
|
||||||
//! Demonstrates construction and usage of a TLS-capable HTTP client.
|
use std::error::Error as StdError;
|
||||||
|
|
||||||
extern crate tls_rustls_0_23 as rustls;
|
|
||||||
|
|
||||||
use std::{error::Error as StdError, sync::Arc};
|
|
||||||
|
|
||||||
use actix_tls::connect::rustls_0_23::webpki_roots_cert_store;
|
|
||||||
use rustls::ClientConfig;
|
|
||||||
|
|
||||||
|
/// If we want to make requests to addresses starting with `https`, we need to enable the rustls feature of awc
|
||||||
|
/// `awc = { version = "3.5.0", features = ["rustls"] }`
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> Result<(), Box<dyn StdError>> {
|
async fn main() -> Result<(), Box<dyn StdError>> {
|
||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
|
|
||||||
let mut config = ClientConfig::builder()
|
// construct request builder
|
||||||
.with_root_certificates(webpki_roots_cert_store())
|
let client = awc::Client::new();
|
||||||
.with_no_client_auth();
|
|
||||||
|
|
||||||
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
|
||||||
config.alpn_protocols = protos;
|
|
||||||
|
|
||||||
// construct request builder with TLS support
|
|
||||||
let client = awc::Client::builder()
|
|
||||||
.connector(awc::Connector::new().rustls_0_23(Arc::new(config)))
|
|
||||||
.finish();
|
|
||||||
|
|
||||||
// configure request
|
// configure request
|
||||||
let request = client
|
let request = client
|
||||||
.get("https://www.rust-lang.org/")
|
.get("https://www.rust-lang.org/")
|
||||||
.append_header(("User-Agent", "awc/3.0"));
|
.append_header(("User-Agent", "Actix-web"));
|
||||||
|
|
||||||
println!("Request: {request:?}");
|
println!("Request: {:?}", request);
|
||||||
|
|
||||||
let mut response = request.send().await?;
|
let mut response = request.send().await?;
|
||||||
|
|
||||||
// server response head
|
// server response head
|
||||||
println!("Response: {response:?}");
|
println!("Response: {:?}", response);
|
||||||
|
|
||||||
// read response body
|
// read response body
|
||||||
let body = response.body().await?;
|
let body = response.body().await?;
|
||||||
|
|
|
@ -511,8 +511,7 @@ where
|
||||||
let h2 = sock
|
let h2 = sock
|
||||||
.ssl()
|
.ssl()
|
||||||
.selected_alpn_protocol()
|
.selected_alpn_protocol()
|
||||||
.is_some_and(|protos| protos.windows(2).any(|w| w == H2));
|
.map_or(false, |protos| protos.windows(2).any(|w| w == H2));
|
||||||
|
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock), Protocol::Http2)
|
(Box::new(sock), Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
|
@ -551,8 +550,7 @@ where
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
.alpn_protocol()
|
.alpn_protocol()
|
||||||
.is_some_and(|protos| protos.windows(2).any(|w| w == H2));
|
.map_or(false, |protos| protos.windows(2).any(|w| w == H2));
|
||||||
|
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock), Protocol::Http2)
|
(Box::new(sock), Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
|
@ -586,8 +584,7 @@ where
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
.alpn_protocol()
|
.alpn_protocol()
|
||||||
.is_some_and(|protos| protos.windows(2).any(|w| w == H2));
|
.map_or(false, |protos| protos.windows(2).any(|w| w == H2));
|
||||||
|
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock), Protocol::Http2)
|
(Box::new(sock), Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
|
@ -624,8 +621,7 @@ where
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
.alpn_protocol()
|
.alpn_protocol()
|
||||||
.is_some_and(|protos| protos.windows(2).any(|w| w == H2));
|
.map_or(false, |protos| protos.windows(2).any(|w| w == H2));
|
||||||
|
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock), Protocol::Http2)
|
(Box::new(sock), Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
|
@ -659,8 +655,7 @@ where
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
.alpn_protocol()
|
.alpn_protocol()
|
||||||
.is_some_and(|protos| protos.windows(2).any(|w| w == H2));
|
.map_or(false, |protos| protos.windows(2).any(|w| w == H2));
|
||||||
|
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock), Protocol::Http2)
|
(Box::new(sock), Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use h2::{
|
||||||
SendStream,
|
SendStream,
|
||||||
};
|
};
|
||||||
use http::{
|
use http::{
|
||||||
header::{HeaderValue, CONNECTION, CONTENT_LENGTH, HOST, TRANSFER_ENCODING},
|
header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING},
|
||||||
request::Request,
|
request::Request,
|
||||||
Method, Version,
|
Method, Version,
|
||||||
};
|
};
|
||||||
|
@ -97,7 +97,7 @@ where
|
||||||
// TODO: consider skipping other headers according to:
|
// TODO: consider skipping other headers according to:
|
||||||
// https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2
|
// https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2
|
||||||
// omit HTTP/1.x only headers
|
// omit HTTP/1.x only headers
|
||||||
CONNECTION | TRANSFER_ENCODING | HOST => continue,
|
CONNECTION | TRANSFER_ENCODING => continue,
|
||||||
CONTENT_LENGTH if skip_len => continue,
|
CONTENT_LENGTH if skip_len => continue,
|
||||||
// DATE => has_date = true,
|
// DATE => has_date = true,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -444,7 +444,7 @@ struct Host<'a> {
|
||||||
port: Option<http::uri::Port<&'a str>>,
|
port: Option<http::uri::Port<&'a str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Host<'_> {
|
impl<'a> fmt::Display for Host<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str(self.hostname)?;
|
f.write_str(self.hostname)?;
|
||||||
|
|
||||||
|
|
6
justfile
6
justfile
|
@ -51,8 +51,8 @@ test-msrv: downgrade-for-msrv (test msrv_rustup)
|
||||||
test toolchain="":
|
test toolchain="":
|
||||||
cargo {{ toolchain }} test --lib --tests -p=actix-web-codegen --all-features
|
cargo {{ toolchain }} test --lib --tests -p=actix-web-codegen --all-features
|
||||||
cargo {{ toolchain }} test --lib --tests -p=actix-multipart-derive --all-features
|
cargo {{ toolchain }} test --lib --tests -p=actix-multipart-derive --all-features
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn -p=actix-router --no-default-features
|
cargo {{ toolchain }} nextest run -p=actix-router --no-default-features
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-web-codegen --exclude=actix-multipart-derive {{ all_crate_features }} --filter-expr="not test(test_reading_deflate_encoding_large_random_rustls)"
|
cargo {{ toolchain }} nextest run --workspace --exclude=actix-web-codegen --exclude=actix-multipart-derive {{ all_crate_features }} --filter-expr="not test(test_reading_deflate_encoding_large_random_rustls)"
|
||||||
|
|
||||||
# Test workspace docs.
|
# Test workspace docs.
|
||||||
test-docs toolchain="": && doc
|
test-docs toolchain="": && doc
|
||||||
|
@ -64,7 +64,7 @@ test-all toolchain="": (test toolchain) (test-docs toolchain)
|
||||||
# Test workspace and collect coverage info.
|
# Test workspace and collect coverage info.
|
||||||
[private]
|
[private]
|
||||||
test-coverage toolchain="":
|
test-coverage toolchain="":
|
||||||
cargo {{ toolchain }} llvm-cov nextest --no-tests=warn --no-report {{ all_crate_features }}
|
cargo {{ toolchain }} llvm-cov nextest --no-report {{ all_crate_features }}
|
||||||
cargo {{ toolchain }} llvm-cov --doc --no-report {{ all_crate_features }}
|
cargo {{ toolchain }} llvm-cov --doc --no-report {{ all_crate_features }}
|
||||||
|
|
||||||
# Test workspace and generate Codecov report.
|
# Test workspace and generate Codecov report.
|
||||||
|
|
Loading…
Reference in New Issue