Merge branch 'master' into default_error_handler

This commit is contained in:
Rob Ede 2022-09-13 02:28:43 +01:00 committed by GitHub
commit d8198785ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 212 additions and 80 deletions

View File

@ -16,7 +16,7 @@ jobs:
- { name: macOS, os: macos-latest, triple: x86_64-apple-darwin }
- { name: Windows, os: windows-2022, triple: x86_64-pc-windows-msvc }
version:
- 1.57.0 # MSRV
- 1.59.0 # MSRV
- stable
name: ${{ matrix.target.name }} / ${{ matrix.version }}

View File

@ -28,8 +28,7 @@ jobs:
run: echo '<meta http-equiv="refresh" content="0;url=actix_web/index.html">' > target/doc/index.html
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@3.7.1
uses: JamesIves/github-pages-deploy-action@v4.4.0
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages
FOLDER: target/doc
folder: target/doc
single-commit: true

View File

@ -1,6 +1,7 @@
# Changes
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
## 0.6.2 - 2022-07-23

View File

@ -27,7 +27,6 @@ actix-service = "2"
actix-utils = "3"
actix-web = { version = "4", default-features = false }
askama_escape = "0.10"
bitflags = "1"
bytes = "1"
derive_more = "0.99.5"
@ -38,6 +37,7 @@ mime = "0.3"
mime_guess = "2.0.1"
percent-encoding = "2.1"
pin-project-lite = "0.2.7"
v_htmlescape= "0.15"
# experimental-io-uring
[target.'cfg(target_os = "linux")'.dependencies]

View File

@ -4,7 +4,7 @@
[![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.2)](https://docs.rs/actix-files/0.6.2)
![Version](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-files.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-files/0.6.2/status.svg)](https://deps.rs/crate/actix-files/0.6.2)

View File

@ -1,8 +1,8 @@
use std::{fmt::Write, fs::DirEntry, io, path::Path, path::PathBuf};
use actix_web::{dev::ServiceResponse, HttpRequest, HttpResponse};
use askama_escape::{escape as escape_html_entity, Html};
use percent_encoding::{utf8_percent_encode, CONTROLS};
use v_htmlescape::escape as escape_html_entity;
/// A directory; responds with the generated directory listing.
#[derive(Debug)]
@ -59,7 +59,7 @@ macro_rules! encode_file_url {
/// ```
macro_rules! encode_file_name {
($entry:ident) => {
escape_html_entity(&$entry.file_name().to_string_lossy(), Html)
escape_html_entity(&$entry.file_name().to_string_lossy())
};
}

View File

@ -1,6 +1,7 @@
# Changes
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.59.
## 3.0.0 - 2022-07-24

View File

@ -4,7 +4,7 @@
[![crates.io](https://img.shields.io/crates/v/actix-http-test?label=latest)](https://crates.io/crates/actix-http-test)
[![Documentation](https://docs.rs/actix-http-test/badge.svg?version=3.0.0)](https://docs.rs/actix-http-test/3.0.0)
![Version](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http-test)
<br>
[![Dependency Status](https://deps.rs/crate/actix-http-test/3.0.0/status.svg)](https://deps.rs/crate/actix-http-test/3.0.0)

View File

@ -1,6 +1,12 @@
# Changes
## Unreleased - 2022-xx-xx
## 3.2.2 - 2022-09-11
### Changed
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
### Fixed
- Avoid possibility of dispatcher getting stuck while back-pressuring I/O. [#2369]

View File

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

View File

@ -3,11 +3,11 @@
> HTTP primitives for the Actix ecosystem.
[![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http)
[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.2.1)](https://docs.rs/actix-http/3.2.1)
![Version](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.2.2)](https://docs.rs/actix-http/3.2.2)
![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-http/3.2.1/status.svg)](https://deps.rs/crate/actix-http/3.2.1)
[![dependency status](https://deps.rs/crate/actix-http/3.2.2/status.svg)](https://deps.rs/crate/actix-http/3.2.2)
[![Download](https://img.shields.io/crates/d/actix-http.svg)](https://crates.io/crates/actix-http)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -1,7 +1,7 @@
# Changes
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
## 0.4.0 - 2022-02-25

View File

@ -28,7 +28,7 @@ twoway = "0.2"
[dev-dependencies]
actix-rt = "2.2"
actix-http = "3.0.0"
actix-http = "3"
futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] }
tokio = { version = "1.8.4", features = ["sync"] }
tokio-stream = "0.1"

View File

@ -4,7 +4,7 @@
[![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.4.0)](https://docs.rs/actix-multipart/0.4.0)
![Version](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
![Version](https://img.shields.io/badge/rustc-1.59+-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.4.0/status.svg)](https://deps.rs/crate/actix-multipart/0.4.0)

View File

@ -1,7 +1,7 @@
# Changes
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
## 0.5.0 - 2022-02-22

View File

@ -1,6 +1,7 @@
# Changes
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
## 0.1.0 - 2022-07-24

View File

@ -4,7 +4,7 @@
[![crates.io](https://img.shields.io/crates/v/actix-web-actors?label=latest)](https://crates.io/crates/actix-web-actors)
[![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.1.0)](https://docs.rs/actix-web-actors/4.1.0)
![Version](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-web-actors.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-web-actors/4.1.0/status.svg)](https://deps.rs/crate/actix-web-actors/4.1.0)

View File

@ -1,8 +1,11 @@
# Changes
## Unreleased - 2022-xx-xx
## 4.1.0 - 2022-09-11
- Add `#[routes]` macro to support multiple paths for one handler. [#2718]
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
[#2718]: https://github.com/actix/actix-web/pull/2718

View File

@ -1,6 +1,6 @@
[package]
name = "actix-web-codegen"
version = "4.0.1"
version = "4.1.0"
description = "Routing and runtime macros for Actix Web"
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web.git"
@ -24,8 +24,8 @@ syn = { version = "1", features = ["full", "extra-traits"] }
actix-macros = "0.2.3"
actix-rt = "2.2"
actix-test = "0.1"
actix-utils = "3.0.0"
actix-web = "4.0.0"
actix-utils = "3"
actix-web = "4"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
trybuild = "1"

View File

@ -3,11 +3,11 @@
> Routing and runtime macros for Actix Web.
[![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.0.1)](https://docs.rs/actix-web-codegen/4.0.1)
![Version](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.1.0)](https://docs.rs/actix-web-codegen/4.1.0)
![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-web-codegen.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-web-codegen/4.0.1/status.svg)](https://deps.rs/crate/actix-web-codegen/4.0.1)
[![dependency status](https://deps.rs/crate/actix-web-codegen/4.1.0/status.svg)](https://deps.rs/crate/actix-web-codegen/4.1.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

@ -1,4 +1,4 @@
#[rustversion::stable(1.57)] // MSRV
#[rustversion::stable(1.59)] // MSRV
#[test]
fn compile_macros() {
let t = trybuild::TestCases::new();

View File

@ -4,10 +4,16 @@ error: HTTP method defined more than once: `GET`
3 | #[route("/", method="GET", method="GET")]
| ^^^^^
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
error[E0277]: the trait bound `fn() -> impl std::future::Future<Output = String> {index}: HttpServiceFactory` is not satisfied
--> tests/trybuild/route-duplicate-method-fail.rs:12:55
|
12 | let srv = actix_test::start(|| App::new().service(index));
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future<Output = String> {index}`
| |
| required by a bound introduced by this call
|
note: required by a bound in `App::<T>::service`
--> $WORKSPACE/actix-web/src/app.rs
|
| F: HttpServiceFactory + 'static,
| ^^^^^^^^^^^^^^^^^^ required by this bound in `App::<T>::service`

View File

@ -6,10 +6,16 @@ error: The #[route(..)] macro requires at least one `method` attribute
|
= note: this error originates in the attribute macro `route` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
error[E0277]: the trait bound `fn() -> impl std::future::Future<Output = String> {index}: HttpServiceFactory` is not satisfied
--> tests/trybuild/route-missing-method-fail.rs:12:55
|
12 | let srv = actix_test::start(|| App::new().service(index));
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future<Output = String> {index}`
| |
| required by a bound introduced by this call
|
note: required by a bound in `App::<T>::service`
--> $WORKSPACE/actix-web/src/app.rs
|
| F: HttpServiceFactory + 'static,
| ^^^^^^^^^^^^^^^^^^ required by this bound in `App::<T>::service`

View File

@ -4,10 +4,16 @@ error: Unexpected HTTP method: `UNEXPECTED`
3 | #[route("/", method="UNEXPECTED")]
| ^^^^^^^^^^^^
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
error[E0277]: the trait bound `fn() -> impl std::future::Future<Output = String> {index}: HttpServiceFactory` is not satisfied
--> tests/trybuild/route-unexpected-method-fail.rs:12:55
|
12 | let srv = actix_test::start(|| App::new().service(index));
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future<Output = String> {index}`
| |
| required by a bound introduced by this call
|
note: required by a bound in `App::<T>::service`
--> $WORKSPACE/actix-web/src/app.rs
|
| F: HttpServiceFactory + 'static,
| ^^^^^^^^^^^^^^^^^^ required by this bound in `App::<T>::service`

View File

@ -12,10 +12,16 @@ error: Invalid input for macro
4 | #[get]
| ^^^^^^
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
error[E0277]: the trait bound `fn() -> impl std::future::Future<Output = String> {index}: HttpServiceFactory` is not satisfied
--> tests/trybuild/routes-missing-args-fail.rs:13:55
|
13 | let srv = actix_test::start(|| App::new().service(index));
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future<Output = String> {index}`
| |
| required by a bound introduced by this call
|
note: required by a bound in `App::<T>::service`
--> $WORKSPACE/actix-web/src/app.rs
|
| F: HttpServiceFactory + 'static,
| ^^^^^^^^^^^^^^^^^^ required by this bound in `App::<T>::service`

View File

@ -6,10 +6,16 @@ error: The #[routes] macro requires at least one `#[<method>(..)]` attribute.
|
= note: this error originates in the attribute macro `routes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
error[E0277]: the trait bound `fn() -> impl std::future::Future<Output = String> {index}: HttpServiceFactory` is not satisfied
--> tests/trybuild/routes-missing-method-fail.rs:12:55
|
12 | let srv = actix_test::start(|| App::new().service(index));
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
| ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future<Output = String> {index}`
| |
| required by a bound introduced by this call
|
note: required by a bound in `App::<T>::service`
--> $WORKSPACE/actix-web/src/app.rs
|
| F: HttpServiceFactory + 'static,
| ^^^^^^^^^^^^^^^^^^ required by this bound in `App::<T>::service`

View File

@ -2,13 +2,27 @@
## Unreleased - 2022-xx-xx
### Added
- Add `ContentDisposition::attachment` constructor. [#2867]
[#2867]: https://github.com/actix/actix-web/pull/2867
## 4.2.1 - 2022-09-12
### Fixed
- Bump minimum version of `actix-http` dependency to fix compatibility issue. [#2871]
[#2871]: https://github.com/actix/actix-web/pull/2871
## 4.2.0 - 2022-09-11
### Added
- Add `#[routes]` macro to support multiple paths for one handler. [#2718]
- Add configuration options for TLS handshake timeout via `HttpServer::{rustls, openssl}_with_config` methods. [#2752]
- Add `ErrorHandlers::default_handler()` (as well as `default_handler_{server, client}()`) to make registering handlers with the `ErrorHandlers` middleware easier. [#2784]
- Add `ServiceRequest::{parts, request}()` getter methods. [#2786]
### Changed
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
[#2718]: https://github.com/actix/actix-web/pull/2718
[#2752]: https://github.com/actix/actix-web/pull/2752

View File

@ -1,6 +1,6 @@
[package]
name = "actix-web"
version = "4.1.0"
version = "4.2.1"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@ -71,9 +71,9 @@ actix-service = "2"
actix-utils = "3"
actix-tls = { version = "3", default-features = false, optional = true }
actix-http = { version = "3", features = ["http2", "ws"] }
actix-http = { version = "3.2.2", features = ["http2", "ws"] }
actix-router = "0.5"
actix-web-codegen = { version = "4", optional = true }
actix-web-codegen = { version = "4.1", optional = true }
ahash = "0.7"
bytes = "1"

View File

@ -6,10 +6,10 @@
<p>
[![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.1.0)](https://docs.rs/actix-web/4.1.0)
![MSRV](https://img.shields.io/badge/rustc-1.57+-ab6000.svg)
[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.2.1)](https://docs.rs/actix-web/4.2.1)
![MSRV](https://img.shields.io/badge/rustc-1.59+-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.1.0/status.svg)](https://deps.rs/crate/actix-web/4.1.0)
[![Dependency Status](https://deps.rs/crate/actix-web/4.2.1/status.svg)](https://deps.rs/crate/actix-web/4.2.1)
<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)
@ -33,7 +33,7 @@
- SSL support using OpenSSL or Rustls
- Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
- Integrates with the [`awc` HTTP client](https://docs.rs/awc/)
- Runs on stable Rust 1.57+
- Runs on stable Rust 1.59+
## Documentation

View File

@ -79,7 +79,7 @@ impl<'a> From<&'a str> for DispositionType {
/// assert!(param.is_filename());
/// assert_eq!(param.as_filename().unwrap(), "sample.txt");
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[allow(clippy::large_enum_variant)]
pub enum DispositionParam {
/// For [`DispositionType::FormData`] (i.e. *multipart/form-data*), the name of an field from
@ -302,7 +302,7 @@ impl DispositionParam {
/// change to match local file system conventions if applicable, and do not use directory path
/// information that may be present.
/// See [RFC 2183 §2.3](https://datatracker.ietf.org/doc/html/rfc2183#section-2.3).
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContentDisposition {
/// The disposition type
pub disposition: DispositionType,
@ -312,16 +312,36 @@ pub struct ContentDisposition {
}
impl ContentDisposition {
/// Constructs a Content-Disposition header suitable for downloads.
///
/// # Examples
/// ```
/// use actix_web::http::header::{ContentDisposition, TryIntoHeaderValue as _};
///
/// let cd = ContentDisposition::attachment("files.zip");
///
/// let cd_val = cd.try_into_value().unwrap();
/// assert_eq!(cd_val, "attachment; filename=\"files.zip\"");
/// ```
pub fn attachment(filename: impl Into<String>) -> Self {
Self {
disposition: DispositionType::Attachment,
parameters: vec![DispositionParam::Filename(filename.into())],
}
}
/// Parse a raw Content-Disposition header value.
pub fn from_raw(hv: &header::HeaderValue) -> Result<Self, crate::error::ParseError> {
// `header::from_one_raw_str` invokes `hv.to_str` which assumes `hv` contains only visible
// ASCII characters. So `hv.as_bytes` is necessary here.
let hv = String::from_utf8(hv.as_bytes().to_vec())
.map_err(|_| crate::error::ParseError::Header)?;
let (disp_type, mut left) = split_once_and_trim(hv.as_str().trim(), ';');
if disp_type.is_empty() {
return Err(crate::error::ParseError::Header);
}
let mut cd = ContentDisposition {
disposition: disp_type.into(),
parameters: Vec::new(),

View File

@ -40,7 +40,7 @@ type Guards = Vec<Box<dyn Guard>>;
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
/// web::scope("/{project_id}/")
/// web::scope("/{project_id}")
/// .service(web::resource("/path1").to(|| async { "OK" }))
/// .service(web::resource("/path2").route(web::get().to(|| HttpResponse::Ok())))
/// .service(web::resource("/path3").route(web::head().to(HttpResponse::MethodNotAllowed)))

View File

@ -172,7 +172,7 @@ where
///
/// One thread pool is set up **per worker**; not shared across workers.
///
/// By default set to 512 / workers.
/// By default set to 512 divided by the number of workers.
pub fn worker_max_blocking_threads(mut self, num: usize) -> Self {
self.builder = self.builder.worker_max_blocking_threads(num);
self

View File

@ -2,8 +2,18 @@
## Unreleased - 2022-xx-xx
### Changed
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
## 3.0.1 - 2022-08-25
### Changed
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
### Fixed
- Fixed handling of redirection requests that begin with `//`. [#2840]
[#2840]: https://github.com/actix/actix-web/pull/2840
## 3.0.0 - 2022-03-07
### Dependencies

View File

@ -1,6 +1,6 @@
[package]
name = "awc"
version = "3.0.0"
version = "3.0.1"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"fakeshadow <24548779@qq.com>",

View File

@ -3,9 +3,9 @@
> Async HTTP and WebSocket client library.
[![crates.io](https://img.shields.io/crates/v/awc?label=latest)](https://crates.io/crates/awc)
[![Documentation](https://docs.rs/awc/badge.svg?version=3.0.0)](https://docs.rs/awc/3.0.0)
[![Documentation](https://docs.rs/awc/badge.svg?version=3.0.1)](https://docs.rs/awc/3.0.1)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc)
[![Dependency Status](https://deps.rs/crate/awc/3.0.0/status.svg)](https://deps.rs/crate/awc/3.0.0)
[![Dependency Status](https://deps.rs/crate/awc/3.0.1/status.svg)](https://deps.rs/crate/awc/3.0.1)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)
## Documentation & Resources

View File

@ -257,6 +257,16 @@ fn build_next_uri(res: &ClientResponse, prev_uri: &Uri) -> Result<Uri, SendReque
.scheme(prev_uri.scheme().cloned().unwrap())
.authority(prev_uri.authority().cloned().unwrap());
// scheme-relative address
if location.as_bytes().starts_with(b"//") {
let scheme = prev_uri.scheme_str().unwrap();
let mut full_url: Vec<u8> = scheme.as_bytes().to_vec();
full_url.push(b':');
full_url.extend(location.as_bytes());
return Uri::try_from(full_url)
.map_err(|_| SendRequestError::Url(InvalidUrl::MissingScheme));
}
// when scheme or authority is missing treat the location value as path and query
// recover error where location does not have leading slash
let path = if location.as_bytes().starts_with(b"/") {
@ -588,6 +598,41 @@ mod tests {
assert_eq!(res.status().as_u16(), 200);
}
#[actix_rt::test]
async fn test_double_slash_redirect() {
let client = ClientBuilder::new()
.disable_redirects()
.wrap(Redirect::new().max_redirect_times(10))
.finish();
let srv = actix_test::start(|| {
App::new()
.service(web::resource("/test").route(web::to(|| async {
Ok::<_, Error>(HttpResponse::BadRequest())
})))
.service(
web::resource("/").route(web::to(|req: HttpRequest| async move {
Ok::<_, Error>(
HttpResponse::Found()
.append_header((
"location",
format!(
"//localhost:{}/test",
req.app_config().local_addr().port()
)
.as_str(),
))
.finish(),
)
})),
)
});
let res = client.get(srv.url("/")).send().await.unwrap();
assert_eq!(res.status().as_u16(), 400);
}
#[actix_rt::test]
async fn test_remove_sensitive_headers() {
fn gen_headers() -> header::HeaderMap {

View File

@ -1 +1 @@
msrv = "1.57"
msrv = "1.59"

View File

@ -45,6 +45,8 @@ unreleased_for() {
cat "$CHANGE_CHUNK_FILE"
}
for f in $(fd --absolute-path 'CHANGE\w+.md'); do
unreleased_for $(dirname $f)
files=$(fd --threads=1 --min-depth=2 --absolute-path 'CHANGE\w+.md')
for f in $files; do
unreleased_for $(dirname $f) || true
done