Compare commits

..

No commits in common. "5be53820f0718260f6f3573d2edff49f09653206" and "9aa62112aab8249b7cc90180d5102221ebac3d42" have entirely different histories.

15 changed files with 74 additions and 37 deletions

View File

@ -49,7 +49,7 @@ jobs:
toolchain: ${{ matrix.version.version }} toolchain: ${{ matrix.version.version }}
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
@ -83,7 +83,7 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 uses: actions-rust-lang/setup-rust-toolchain@v1.9.0
- name: Install just, cargo-hack - name: Install just, cargo-hack
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: just,cargo-hack tool: just,cargo-hack

View File

@ -64,7 +64,7 @@ jobs:
toolchain: ${{ matrix.version.version }} toolchain: ${{ matrix.version.version }}
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
@ -113,7 +113,7 @@ jobs:
toolchain: nightly toolchain: nightly
- name: Install just - name: Install just
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: just tool: just

View File

@ -24,7 +24,7 @@ jobs:
components: llvm-tools components: llvm-tools
- name: Install just, cargo-llvm-cov, cargo-nextest - name: Install just, cargo-llvm-cov, cargo-nextest
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: just,cargo-llvm-cov,cargo-nextest tool: just,cargo-llvm-cov,cargo-nextest

View File

@ -76,7 +76,7 @@ jobs:
toolchain: nightly-2024-05-01 toolchain: nightly-2024-05-01
- name: Install just - name: Install just
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: just tool: just
@ -105,7 +105,7 @@ jobs:
toolchain: nightly-2024-06-07 toolchain: nightly-2024-06-07
- name: Install cargo-public-api - name: Install cargo-public-api
uses: taiki-e/install-action@v2.42.17 uses: taiki-e/install-action@v2.42.9
with: with:
tool: cargo-public-api tool: cargo-public-api

View File

@ -511,6 +511,11 @@ mod tests {
value: String, value: String,
} }
#[derive(Deserialize)]
struct Id {
_id: String,
}
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct Test1(String, u32); struct Test1(String, u32);

View File

@ -2,10 +2,7 @@
## Unreleased ## Unreleased
## 4.3.1 - Take the encoded buffer when yielding bytes in the response stream rather than splitting the buffer, reducing memory use
- Reduce memory usage by `take`-ing (rather than `split`-ing) the encoded buffer when yielding bytes in the response stream.
- Mark crate as deprecated.
- Minimum supported Rust version (MSRV) is now 1.72. - Minimum supported Rust version (MSRV) is now 1.72.
## 4.3.0 ## 4.3.0

View File

@ -1,14 +1,13 @@
[package] [package]
name = "actix-web-actors" name = "actix-web-actors"
version = "4.3.1+deprecated" version = "4.3.0"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix actors support for Actix Web" description = "Actix actors support for Actix Web"
keywords = ["actix", "http", "web", "framework", "async"] keywords = ["actix", "http", "web", "framework", "async"]
homepage.workspace = true homepage = "https://actix.rs"
repository.workspace = true repository = "https://github.com/actix/actix-web"
license.workspace = true license = "MIT OR Apache-2.0"
edition.workspace = true edition = "2021"
rust-version.workspace = true
[package.metadata.cargo_check_external_types] [package.metadata.cargo_check_external_types]
allowed_external_types = [ allowed_external_types = [

View File

@ -1,17 +1,15 @@
# `actix-web-actors` # `actix-web-actors`
> Actix actors support for Actix Web. > Actix actors support for Actix Web.
>
> This crate is deprecated. Migrate to [`actix-ws`](https://crates.io/crates/actix-ws).
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
[![crates.io](https://img.shields.io/crates/v/actix-web-actors?label=latest)](https://crates.io/crates/actix-web-actors) [![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.3.1)](https://docs.rs/actix-web-actors/4.3.1) [![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.3.0)](https://docs.rs/actix-web-actors/4.3.0)
![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg) ![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix-web-actors.svg) ![License](https://img.shields.io/crates/l/actix-web-actors.svg)
<br /> <br />
![maintenance-status](https://img.shields.io/badge/maintenance-deprecated-red.svg) [![dependency status](https://deps.rs/crate/actix-web-actors/4.3.0/status.svg)](https://deps.rs/crate/actix-web-actors/4.3.0)
[![Download](https://img.shields.io/crates/d/actix-web-actors.svg)](https://crates.io/crates/actix-web-actors) [![Download](https://img.shields.io/crates/d/actix-web-actors.svg)](https://crates.io/crates/actix-web-actors)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -1,7 +1,5 @@
//! Actix actors support for Actix Web. //! Actix actors support for Actix Web.
//! //!
//! This crate is deprecated. Migrate to [`actix-ws`](https://crates.io/crates/actix-ws).
//!
//! # Examples //! # Examples
//! //!
//! ```no_run //! ```no_run

View File

@ -2,9 +2,11 @@ use std::{future::Future, time::Instant};
use actix_http::body::BoxBody; use actix_http::body::BoxBody;
use actix_utils::future::{ready, Ready}; use actix_utils::future::{ready, Ready};
use actix_web::{http::StatusCode, test::TestRequest, Error, HttpRequest, HttpResponse, Responder}; use actix_web::{
error, http::StatusCode, test::TestRequest, Error, HttpRequest, HttpResponse, Responder,
};
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{criterion_group, criterion_main, Criterion};
use futures_util::future::join_all; use futures_util::future::{join_all, Either};
// responder simulate the old responder trait. // responder simulate the old responder trait.
trait FutureResponder { trait FutureResponder {
@ -14,6 +16,9 @@ trait FutureResponder {
fn future_respond_to(self, req: &HttpRequest) -> Self::Future; fn future_respond_to(self, req: &HttpRequest) -> Self::Future;
} }
// a simple option responder type.
struct OptionResponder<T>(Option<T>);
// a simple wrapper type around string // a simple wrapper type around string
struct StringResponder(String); struct StringResponder(String);
@ -29,6 +34,22 @@ impl FutureResponder for StringResponder {
} }
} }
impl<T> FutureResponder for OptionResponder<T>
where
T: FutureResponder,
T::Future: Future<Output = Result<HttpResponse, Error>>,
{
type Error = Error;
type Future = Either<T::Future, Ready<Result<HttpResponse, Self::Error>>>;
fn future_respond_to(self, req: &HttpRequest) -> Self::Future {
match self.0 {
Some(t) => Either::Left(t.future_respond_to(req)),
None => Either::Right(ready(Err(error::ErrorInternalServerError("err")))),
}
}
}
impl Responder for StringResponder { impl Responder for StringResponder {
type Body = BoxBody; type Body = BoxBody;
@ -39,6 +60,17 @@ impl Responder for StringResponder {
} }
} }
impl<T: Responder> Responder for OptionResponder<T> {
type Body = BoxBody;
fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
match self.0 {
Some(t) => t.respond_to(req).map_into_boxed_body(),
None => HttpResponse::from_error(error::ErrorInternalServerError("err")),
}
}
}
fn future_responder(c: &mut Criterion) { fn future_responder(c: &mut Criterion) {
let rt = actix_rt::System::new(); let rt = actix_rt::System::new();
let req = TestRequest::default().to_http_request(); let req = TestRequest::default().to_http_request();

View File

@ -19,7 +19,7 @@ use crate::{
/// 1. It is an async function (or a function/closure that returns an appropriate future); /// 1. It is an async function (or a function/closure that returns an appropriate future);
/// 1. The function parameters (up to 12) implement [`FromRequest`]; /// 1. The function parameters (up to 12) implement [`FromRequest`];
/// 1. The async function (or future) resolves to a type that can be converted into an /// 1. The async function (or future) resolves to a type that can be converted into an
/// [`HttpResponse`] (i.e., it implements the [`Responder`] trait). /// [`HttpResponse`] (i.e., it implements the [`Responder`] trait).
/// ///
/// ///
/// # Compiler Errors /// # Compiler Errors

View File

@ -493,7 +493,7 @@ impl Header for ContentDisposition {
} }
fn parse<T: crate::HttpMessage>(msg: &T) -> Result<Self, crate::error::ParseError> { fn parse<T: crate::HttpMessage>(msg: &T) -> Result<Self, crate::error::ParseError> {
if let Some(h) = msg.headers().get(Self::name()) { if let Some(h) = msg.headers().get(&Self::name()) {
Self::from_raw(h) Self::from_raw(h)
} else { } else {
Err(crate::error::ParseError::Header) Err(crate::error::ParseError::Header)

View File

@ -107,16 +107,16 @@ impl ByteRangeSpec {
/// satisfiable if they meet the following conditions: /// satisfiable if they meet the following conditions:
/// ///
/// > If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that /// > If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that
/// > is less than the current length of the representation, or at least one /// is less than the current length of the representation, or at least one
/// > suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set is /// suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set
/// > satisfiable. Otherwise, the byte-range-set is unsatisfiable. /// is satisfiable. Otherwise, the byte-range-set is unsatisfiable.
/// ///
/// The function also computes remainder ranges based on the RFC: /// The function also computes remainder ranges based on the RFC:
/// ///
/// > If the last-byte-pos value is absent, or if the value is greater than or equal to the /// > If the last-byte-pos value is absent, or if the value is greater than or equal to the
/// > current length of the representation data, the byte range is interpreted as the remainder /// current length of the representation data, the byte range is interpreted as the remainder
/// > of the representation (i.e., the server replaces the value of last-byte-pos with a value /// of the representation (i.e., the server replaces the value of last-byte-pos with a value
/// > that is one less than the current length of the selected representation). /// that is one less than the current length of the selected representation).
/// ///
/// [RFC 7233 §2.1]: https://datatracker.ietf.org/doc/html/rfc7233 /// [RFC 7233 §2.1]: https://datatracker.ietf.org/doc/html/rfc7233
pub fn to_satisfiable_range(&self, full_length: u64) -> Option<(u64, u64)> { pub fn to_satisfiable_range(&self, full_length: u64) -> Option<(u64, u64)> {
@ -270,7 +270,7 @@ impl Header for Range {
#[inline] #[inline]
fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> { fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {
header::from_one_raw_str(msg.headers().get(Self::name())) header::from_one_raw_str(msg.headers().get(&Self::name()))
} }
} }

View File

@ -622,7 +622,11 @@ impl FormatText {
FormatText::ResponseHeader(ref name) => { FormatText::ResponseHeader(ref name) => {
let s = if let Some(val) = res.headers().get(name) { let s = if let Some(val) = res.headers().get(name) {
val.to_str().unwrap_or("-") if let Ok(s) = val.to_str() {
s
} else {
"-"
}
} else { } else {
"-" "-"
}; };
@ -666,7 +670,11 @@ impl FormatText {
FormatText::RequestTime => *self = FormatText::Str(now.format(&Rfc3339).unwrap()), FormatText::RequestTime => *self = FormatText::Str(now.format(&Rfc3339).unwrap()),
FormatText::RequestHeader(ref name) => { FormatText::RequestHeader(ref name) => {
let s = if let Some(val) = req.headers().get(name) { let s = if let Some(val) = req.headers().get(name) {
val.to_str().unwrap_or("-") if let Ok(s) = val.to_str() {
s
} else {
"-"
}
} else { } else {
"-" "-"
}; };

View File

@ -463,7 +463,7 @@ mod tests {
// content type override // content type override
let res = HttpResponse::Ok() let res = HttpResponse::Ok()
.insert_header((CONTENT_TYPE, "text/json")) .insert_header((CONTENT_TYPE, "text/json"))
.json(["v1", "v2", "v3"]); .json(&vec!["v1", "v2", "v3"]);
let ct = res.headers().get(CONTENT_TYPE).unwrap(); let ct = res.headers().get(CONTENT_TYPE).unwrap();
assert_eq!(ct, HeaderValue::from_static("text/json")); assert_eq!(ct, HeaderValue::from_static("text/json"));
assert_body_eq!(res, br#"["v1","v2","v3"]"#); assert_body_eq!(res, br#"["v1","v2","v3"]"#);