{
srv: S,
diff --git a/actix-http/src/header/into_pair.rs b/actix-http/src/header/into_pair.rs
index 91c3e6640..0a71f857a 100644
--- a/actix-http/src/header/into_pair.rs
+++ b/actix-http/src/header/into_pair.rs
@@ -1,7 +1,5 @@
//! [`TryIntoHeaderPair`] trait and implementations.
-use std::convert::TryFrom as _;
-
use super::{
Header, HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, TryIntoHeaderValue,
};
diff --git a/actix-http/src/header/into_value.rs b/actix-http/src/header/into_value.rs
index 6d369ee65..253900633 100644
--- a/actix-http/src/header/into_value.rs
+++ b/actix-http/src/header/into_value.rs
@@ -1,7 +1,5 @@
//! [`TryIntoHeaderValue`] trait and implementations.
-use std::convert::TryFrom as _;
-
use bytes::Bytes;
use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue};
use mime::Mime;
diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs
index d7b4e6dde..e8118be93 100644
--- a/actix-http/src/header/map.rs
+++ b/actix-http/src/header/map.rs
@@ -1120,9 +1120,7 @@ mod tests {
assert!(vals.next().is_none());
}
- fn owned_pair<'a>(
- (name, val): (&'a HeaderName, &'a HeaderValue),
- ) -> (HeaderName, HeaderValue) {
+ fn owned_pair<'a>((name, val): (&'a HeaderName, &'a HeaderValue)) -> (HeaderName, HeaderValue) {
(name.clone(), val.clone())
}
}
diff --git a/actix-http/src/header/mod.rs b/actix-http/src/header/mod.rs
index a63174a92..79f91afef 100644
--- a/actix-http/src/header/mod.rs
+++ b/actix-http/src/header/mod.rs
@@ -3,33 +3,30 @@
// declaring new header consts will yield this error
#![allow(clippy::declare_interior_mutable_const)]
-use percent_encoding::{AsciiSet, CONTROLS};
-
// re-export from http except header map related items
pub use ::http::header::{
HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, ToStrError,
};
-
// re-export const header names, list is explicit so that any updates to `common` module do not
// conflict with this set
pub use ::http::header::{
ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES,
- ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS,
- ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS,
- ACCESS_CONTROL_MAX_AGE, ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE,
- ALLOW, ALT_SVC, AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION,
- CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE,
- CONTENT_SECURITY_POLICY, CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE,
- DNT, ETAG, EXPECT, EXPIRES, FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE,
- IF_NONE_MATCH, IF_RANGE, IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS,
- ORIGIN, PRAGMA, PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS,
- PUBLIC_KEY_PINS_REPORT_ONLY, RANGE, REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER,
- SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_EXTENSIONS, SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL,
- SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE, STRICT_TRANSPORT_SECURITY, TE, TRAILER,
- TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS, USER_AGENT, VARY, VIA, WARNING,
- WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS, X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS,
- X_XSS_PROTECTION,
+ ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS,
+ ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE,
+ ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE, ALLOW, ALT_SVC,
+ AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING,
+ CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE, CONTENT_SECURITY_POLICY,
+ CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE, DNT, ETAG, EXPECT, EXPIRES,
+ FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE,
+ IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS, ORIGIN, PRAGMA,
+ PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, PUBLIC_KEY_PINS_REPORT_ONLY, RANGE,
+ REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER, SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_EXTENSIONS,
+ SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE,
+ STRICT_TRANSPORT_SECURITY, TE, TRAILER, TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS,
+ USER_AGENT, VARY, VIA, WARNING, WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS,
+ X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS, X_XSS_PROTECTION,
};
+use percent_encoding::{AsciiSet, CONTROLS};
use crate::{error::ParseError, HttpMessage};
@@ -43,23 +40,22 @@ mod utils;
pub use self::{
as_name::AsHeaderName,
+ // re-export list is explicit so that any updates to `http` do not conflict with this set
+ common::{
+ CACHE_STATUS, CDN_CACHE_CONTROL, CROSS_ORIGIN_EMBEDDER_POLICY, CROSS_ORIGIN_OPENER_POLICY,
+ CROSS_ORIGIN_RESOURCE_POLICY, PERMISSIONS_POLICY, X_FORWARDED_FOR, X_FORWARDED_HOST,
+ X_FORWARDED_PROTO,
+ },
into_pair::TryIntoHeaderPair,
into_value::TryIntoHeaderValue,
map::HeaderMap,
shared::{
- parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate,
- LanguageTag, Quality, QualityItem,
+ parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate, LanguageTag,
+ Quality, QualityItem,
},
utils::{fmt_comma_delimited, from_comma_delimited, from_one_raw_str, http_percent_encode},
};
-// re-export list is explicit so that any updates to `http` do not conflict with this set
-pub use self::common::{
- CACHE_STATUS, CDN_CACHE_CONTROL, CROSS_ORIGIN_EMBEDDER_POLICY, CROSS_ORIGIN_OPENER_POLICY,
- CROSS_ORIGIN_RESOURCE_POLICY, PERMISSIONS_POLICY, X_FORWARDED_FOR, X_FORWARDED_HOST,
- X_FORWARDED_PROTO,
-};
-
/// An interface for types that already represent a valid header.
pub trait Header: TryIntoHeaderValue {
/// Returns the name of the header field.
diff --git a/actix-http/src/header/shared/content_encoding.rs b/actix-http/src/header/shared/content_encoding.rs
index bd25de704..c3b4bc4c2 100644
--- a/actix-http/src/header/shared/content_encoding.rs
+++ b/actix-http/src/header/shared/content_encoding.rs
@@ -1,4 +1,4 @@
-use std::{convert::TryFrom, str::FromStr};
+use std::str::FromStr;
use derive_more::{Display, Error};
use http::header::InvalidHeaderValue;
diff --git a/actix-http/src/header/shared/mod.rs b/actix-http/src/header/shared/mod.rs
index 257e54d7a..889c73c45 100644
--- a/actix-http/src/header/shared/mod.rs
+++ b/actix-http/src/header/shared/mod.rs
@@ -1,5 +1,7 @@
//! Originally taken from `hyper::header::shared`.
+pub use language_tags::LanguageTag;
+
mod charset;
mod content_encoding;
mod extended;
@@ -7,10 +9,11 @@ mod http_date;
mod quality;
mod quality_item;
-pub use self::charset::Charset;
-pub use self::content_encoding::ContentEncoding;
-pub use self::extended::{parse_extended_value, ExtendedValue};
-pub use self::http_date::HttpDate;
-pub use self::quality::{q, Quality};
-pub use self::quality_item::QualityItem;
-pub use language_tags::LanguageTag;
+pub use self::{
+ charset::Charset,
+ content_encoding::ContentEncoding,
+ extended::{parse_extended_value, ExtendedValue},
+ http_date::HttpDate,
+ quality::{q, Quality},
+ quality_item::QualityItem,
+};
diff --git a/actix-http/src/header/shared/quality.rs b/actix-http/src/header/shared/quality.rs
index c80dd0a8e..c2276cf1b 100644
--- a/actix-http/src/header/shared/quality.rs
+++ b/actix-http/src/header/shared/quality.rs
@@ -1,7 +1,4 @@
-use std::{
- convert::{TryFrom, TryInto},
- fmt,
-};
+use std::fmt;
use derive_more::{Display, Error};
diff --git a/actix-http/src/header/shared/quality_item.rs b/actix-http/src/header/shared/quality_item.rs
index 0b35b5401..a41369c20 100644
--- a/actix-http/src/header/shared/quality_item.rs
+++ b/actix-http/src/header/shared/quality_item.rs
@@ -1,8 +1,7 @@
-use std::{cmp, convert::TryFrom as _, fmt, str};
-
-use crate::error::ParseError;
+use std::{cmp, fmt, str};
use super::Quality;
+use crate::error::ParseError;
/// Represents an item with a quality value as defined
/// in [RFC 7231 §5.3.1](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.1).
diff --git a/actix-http/src/http_message.rs b/actix-http/src/http_message.rs
index 198254e02..3ba9ef752 100644
--- a/actix-http/src/http_message.rs
+++ b/actix-http/src/http_message.rs
@@ -61,9 +61,7 @@ pub trait HttpMessage: Sized {
fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> {
if let Some(mime_type) = self.mime_type()? {
if let Some(charset) = mime_type.get_param("charset") {
- if let Some(enc) =
- Encoding::for_label_no_replacement(charset.as_str().as_bytes())
- {
+ if let Some(enc) = Encoding::for_label_no_replacement(charset.as_str().as_bytes()) {
Ok(enc)
} else {
Err(ContentTypeError::UnknownEncoding)
@@ -146,7 +144,7 @@ mod tests {
.finish();
assert_eq!(req.content_type(), "text/plain");
let req = TestRequest::default()
- .insert_header(("content-type", "application/json; charset=utf=8"))
+ .insert_header(("content-type", "application/json; charset=utf-8"))
.finish();
assert_eq!(req.content_type(), "application/json");
let req = TestRequest::default().finish();
diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs
index 8bf834f73..8b755f2f4 100644
--- a/actix-http/src/lib.rs
+++ b/actix-http/src/lib.rs
@@ -28,8 +28,7 @@
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
-pub use ::http::{uri, uri::Uri};
-pub use ::http::{Method, StatusCode, Version};
+pub use ::http::{uri, uri::Uri, Method, StatusCode, Version};
pub mod body;
mod builder;
@@ -57,22 +56,24 @@ pub mod test;
#[cfg(feature = "ws")]
pub mod ws;
-pub use self::builder::HttpServiceBuilder;
-pub use self::config::ServiceConfig;
-pub use self::error::Error;
-pub use self::extensions::Extensions;
-pub use self::header::ContentEncoding;
-pub use self::http_message::HttpMessage;
-pub use self::keep_alive::KeepAlive;
-pub use self::message::ConnectionType;
-pub use self::message::Message;
#[allow(deprecated)]
-pub use self::payload::{BoxedPayloadStream, Payload, PayloadStream};
-pub use self::requests::{Request, RequestHead, RequestHeadType};
-pub use self::responses::{Response, ResponseBuilder, ResponseHead};
-pub use self::service::HttpService;
+pub use self::payload::PayloadStream;
#[cfg(any(feature = "openssl", feature = "rustls"))]
pub use self::service::TlsAcceptorConfig;
+pub use self::{
+ builder::HttpServiceBuilder,
+ config::ServiceConfig,
+ error::Error,
+ extensions::Extensions,
+ header::ContentEncoding,
+ http_message::HttpMessage,
+ keep_alive::KeepAlive,
+ message::{ConnectionType, Message},
+ payload::{BoxedPayloadStream, Payload},
+ requests::{Request, RequestHead, RequestHeadType},
+ responses::{Response, ResponseBuilder, ResponseHead},
+ service::HttpService,
+};
/// A major HTTP protocol version.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/actix-http/src/requests/mod.rs b/actix-http/src/requests/mod.rs
index fc35da65a..4a27818a5 100644
--- a/actix-http/src/requests/mod.rs
+++ b/actix-http/src/requests/mod.rs
@@ -3,5 +3,7 @@
mod head;
mod request;
-pub use self::head::{RequestHead, RequestHeadType};
-pub use self::request::Request;
+pub use self::{
+ head::{RequestHead, RequestHeadType},
+ request::Request,
+};
diff --git a/actix-http/src/requests/request.rs b/actix-http/src/requests/request.rs
index ac358e8df..1750fb2f7 100644
--- a/actix-http/src/requests/request.rs
+++ b/actix-http/src/requests/request.rs
@@ -10,8 +10,7 @@ use std::{
use http::{header, Method, Uri, Version};
use crate::{
- header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Message, Payload,
- RequestHead,
+ header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Message, Payload, RequestHead,
};
/// An HTTP request.
@@ -234,7 +233,6 @@ impl fmt::Debug for Request
{
#[cfg(test)]
mod tests {
use super::*;
- use std::convert::TryFrom;
#[test]
fn test_basics() {
diff --git a/actix-http/src/responses/mod.rs b/actix-http/src/responses/mod.rs
index 899232b9f..d99628232 100644
--- a/actix-http/src/responses/mod.rs
+++ b/actix-http/src/responses/mod.rs
@@ -5,7 +5,5 @@ mod head;
#[allow(clippy::module_inception)]
mod response;
-pub use self::builder::ResponseBuilder;
pub(crate) use self::head::BoxedResponseHead;
-pub use self::head::ResponseHead;
-pub use self::response::Response;
+pub use self::{builder::ResponseBuilder, head::ResponseHead, response::Response};
diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs
index 22177b849..e118d8361 100644
--- a/actix-http/src/service.rs
+++ b/actix-http/src/service.rs
@@ -30,9 +30,9 @@ use crate::{
///
/// # Automatic HTTP Version Selection
/// There are two ways to select the HTTP version of an incoming connection:
-/// - One is to rely on the ALPN information that is provided when using a TLS (HTTPS); both
-/// versions are supported automatically when using either of the `.rustls()` or `.openssl()`
-/// finalizing methods.
+/// - One is to rely on the ALPN information that is provided when using TLS (HTTPS); both versions
+/// are supported automatically when using either of the `.rustls()` or `.openssl()` finalizing
+/// methods.
/// - The other is to read the first few bytes of the TCP stream. This is the only viable approach
/// for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use
/// the `.tcp_auto_h2c()` finalizing method to enable this behavior.
@@ -200,13 +200,8 @@ where
/// The resulting service only supports HTTP/1.x.
pub fn tcp(
self,
- ) -> impl ServiceFactory<
- TcpStream,
- Config = (),
- Response = (),
- Error = DispatchError,
- InitError = (),
- > {
+ ) -> impl ServiceFactory
+ {
fn_service(|io: TcpStream| async {
let peer_addr = io.peer_addr().ok();
Ok((io, Protocol::Http1, peer_addr))
@@ -219,13 +214,8 @@ where
#[cfg(feature = "http2")]
pub fn tcp_auto_h2c(
self,
- ) -> impl ServiceFactory<
- TcpStream,
- Config = (),
- Response = (),
- Error = DispatchError,
- InitError = (),
- > {
+ ) -> impl ServiceFactory
+ {
fn_service(move |io: TcpStream| async move {
// subset of HTTP/2 preface defined by RFC 9113 §3.4
// this subset was chosen to maximize likelihood that peeking only once will allow us to
@@ -563,10 +553,7 @@ where
}
}
- pub(super) fn _poll_ready(
- &self,
- cx: &mut Context<'_>,
- ) -> Poll>> {
+ pub(super) fn _poll_ready(&self, cx: &mut Context<'_>) -> Poll>> {
ready!(self.flow.expect.poll_ready(cx).map_err(Into::into))?;
ready!(self.flow.service.poll_ready(cx).map_err(Into::into))?;
@@ -625,10 +612,7 @@ where
})
}
- fn call(
- &self,
- (io, proto, peer_addr): (T, Protocol, Option),
- ) -> Self::Future {
+ fn call(&self, (io, proto, peer_addr): (T, Protocol, Option)) -> Self::Future {
let conn_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
match proto {
diff --git a/actix-http/src/ws/dispatcher.rs b/actix-http/src/ws/dispatcher.rs
index 396f1e86c..1354d5ae1 100644
--- a/actix-http/src/ws/dispatcher.rs
+++ b/actix-http/src/ws/dispatcher.rs
@@ -70,15 +70,14 @@ mod inner {
task::{Context, Poll},
};
+ use actix_codec::Framed;
use actix_service::{IntoService, Service};
use futures_core::stream::Stream;
use local_channel::mpsc;
use pin_project_lite::pin_project;
- use tracing::debug;
-
- use actix_codec::Framed;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_util::codec::{Decoder, Encoder};
+ use tracing::debug;
use crate::{body::BoxBody, Response};
@@ -413,9 +412,7 @@ mod inner {
}
State::Error(_) => {
// flush write buffer
- if !this.framed.is_write_buf_empty()
- && this.framed.flush(cx).is_pending()
- {
+ if !this.framed.is_write_buf_empty() && this.framed.flush(cx).is_pending() {
return Poll::Pending;
}
Poll::Ready(Err(this.state.take_error()))
diff --git a/actix-http/src/ws/frame.rs b/actix-http/src/ws/frame.rs
index dddb03d18..c9fb0cde9 100644
--- a/actix-http/src/ws/frame.rs
+++ b/actix-http/src/ws/frame.rs
@@ -1,5 +1,4 @@
use std::cmp::min;
-use std::convert::TryFrom;
use bytes::{Buf, BufMut, BytesMut};
use tracing::debug;
@@ -222,9 +221,10 @@ impl Parser {
#[cfg(test)]
mod tests {
- use super::*;
use bytes::Bytes;
+ use super::*;
+
struct F {
finished: bool,
opcode: OpCode,
diff --git a/actix-http/src/ws/mod.rs b/actix-http/src/ws/mod.rs
index 2a0b0a99c..87f9b38f3 100644
--- a/actix-http/src/ws/mod.rs
+++ b/actix-http/src/ws/mod.rs
@@ -8,8 +8,7 @@ use std::io;
use derive_more::{Display, Error, From};
use http::{header, Method, StatusCode};
-use crate::body::BoxBody;
-use crate::{header::HeaderValue, RequestHead, Response, ResponseBuilder};
+use crate::{body::BoxBody, header::HeaderValue, RequestHead, Response, ResponseBuilder};
mod codec;
mod dispatcher;
@@ -17,10 +16,12 @@ mod frame;
mod mask;
mod proto;
-pub use self::codec::{Codec, Frame, Item, Message};
-pub use self::dispatcher::Dispatcher;
-pub use self::frame::Parser;
-pub use self::proto::{hash_key, CloseCode, CloseReason, OpCode};
+pub use self::{
+ codec::{Codec, Frame, Item, Message},
+ dispatcher::Dispatcher,
+ frame::Parser,
+ proto::{hash_key, CloseCode, CloseReason, OpCode},
+};
/// WebSocket protocol errors.
#[derive(Debug, Display, Error, From)]
@@ -219,10 +220,8 @@ pub fn handshake_response(req: &RequestHead) -> ResponseBuilder {
#[cfg(test)]
mod tests {
- use crate::{header, Method};
-
use super::*;
- use crate::test::TestRequest;
+ use crate::{header, test::TestRequest, Method};
#[test]
fn test_handshake() {
diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs
index 7464bee4e..b4d8ed1a5 100644
--- a/actix-http/tests/test_openssl.rs
+++ b/actix-http/tests/test_openssl.rs
@@ -321,8 +321,7 @@ async fn h2_body_length() {
let mut srv = test_server(move || {
HttpService::build()
.h2(|_| async {
- let body =
- once(async { Ok::<_, Infallible>(Bytes::from_static(STR.as_ref())) });
+ let body = once(async { Ok::<_, Infallible>(Bytes::from_static(STR.as_ref())) });
Ok::<_, Infallible>(
Response::ok().set_body(SizedStream::new(STR.len() as u64, body)),
diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs
index 0b8197a69..3d9a39cbd 100644
--- a/actix-http/tests/test_rustls.rs
+++ b/actix-http/tests/test_rustls.rs
@@ -4,7 +4,7 @@
extern crate tls_rustls as rustls;
use std::{
- convert::{Infallible, TryFrom},
+ convert::Infallible,
io::{self, BufReader, Write},
net::{SocketAddr, TcpStream as StdTcpStream},
sync::Arc,
@@ -90,11 +90,9 @@ pub fn get_negotiated_alpn_protocol(
config.alpn_protocols.push(client_alpn_protocol.to_vec());
- let mut sess = rustls::ClientConnection::new(
- Arc::new(config),
- ServerName::try_from("localhost").unwrap(),
- )
- .unwrap();
+ let mut sess =
+ rustls::ClientConnection::new(Arc::new(config), ServerName::try_from("localhost").unwrap())
+ .unwrap();
let mut sock = StdTcpStream::connect(addr).unwrap();
let mut stream = rustls::Stream::new(&mut sess, &mut sock);
diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs
index 2efb336ae..cfb4d17b8 100644
--- a/actix-http/tests/test_server.rs
+++ b/actix-http/tests/test_server.rs
@@ -166,8 +166,7 @@ async fn chunked_payload() {
for chunk_size in chunk_sizes.iter() {
let mut bytes = Vec::new();
- let random_bytes: Vec =
- (0..*chunk_size).map(|_| rand::random::()).collect();
+ let random_bytes: Vec = (0..*chunk_size).map(|_| rand::random::()).collect();
bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes());
bytes.extend(&random_bytes[..]);
@@ -352,8 +351,7 @@ async fn http10_keepalive() {
.await;
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
- let _ =
- stream.write_all(b"GET /test/tests/test HTTP/1.0\r\nconnection: keep-alive\r\n\r\n");
+ let _ = stream.write_all(b"GET /test/tests/test HTTP/1.0\r\nconnection: keep-alive\r\n\r\n");
let mut data = vec![0; 1024];
let _ = stream.read(&mut data);
assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n");
@@ -795,8 +793,9 @@ async fn not_modified_spec_h1() {
.map_into_boxed_body(),
// with no content-length
- "/body" => Response::with_body(StatusCode::NOT_MODIFIED, "1234")
- .map_into_boxed_body(),
+ "/body" => {
+ Response::with_body(StatusCode::NOT_MODIFIED, "1234").map_into_boxed_body()
+ }
// with manual content-length header and specific None body
"/cl-none" => {
diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md
index 8dd7aa4d0..caf75aeb3 100644
--- a/actix-multipart-derive/CHANGES.md
+++ b/actix-multipart-derive/CHANGES.md
@@ -1,5 +1,9 @@
# Changes
+## Unreleased
+
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 0.6.0 - 2023-02-26
- Add `MultipartForm` derive macro.
diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml
index e0b78fa26..aca6de84a 100644
--- a/actix-multipart-derive/Cargo.toml
+++ b/actix-multipart-derive/Cargo.toml
@@ -7,7 +7,7 @@ keywords = ["http", "web", "framework", "async", "futures"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web.git"
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
diff --git a/actix-multipart-derive/README.md b/actix-multipart-derive/README.md
index 44f08c7bd..b077d355c 100644
--- a/actix-multipart-derive/README.md
+++ b/actix-multipart-derive/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-multipart-derive)
[](https://docs.rs/actix-multipart-derive/0.5.0)
-
+

[](https://deps.rs/crate/actix-multipart-derive/0.5.0)
@@ -14,4 +14,4 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-multipart-derive)
-- Minimum Supported Rust Version (MSRV): 1.59
+- Minimum Supported Rust Version (MSRV): 1.65
diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs
index 2af023aec..9552ad2d9 100644
--- a/actix-multipart-derive/src/lib.rs
+++ b/actix-multipart-derive/src/lib.rs
@@ -8,7 +8,7 @@
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
-use std::{collections::HashSet, convert::TryFrom as _};
+use std::collections::HashSet;
use darling::{FromDeriveInput, FromField, FromMeta};
use parse_size::parse_size;
diff --git a/actix-multipart-derive/tests/trybuild.rs b/actix-multipart-derive/tests/trybuild.rs
index 7b9f14ed7..829c1d771 100644
--- a/actix-multipart-derive/tests/trybuild.rs
+++ b/actix-multipart-derive/tests/trybuild.rs
@@ -1,4 +1,4 @@
-#[rustversion::stable(1.59)] // MSRV
+#[rustversion::stable(1.65)] // MSRV
#[test]
fn compile_macros() {
let t = trybuild::TestCases::new();
diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md
index 4bb120c61..410c8af17 100644
--- a/actix-multipart/CHANGES.md
+++ b/actix-multipart/CHANGES.md
@@ -2,6 +2,8 @@
## Unreleased - 2023-xx-xx
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 0.6.0 - 2023-02-26
- Added `MultipartForm` typed data extractor. [#2883]
diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml
index a36fbffc0..9220e793c 100644
--- a/actix-multipart/Cargo.toml
+++ b/actix-multipart/Cargo.toml
@@ -10,7 +10,7 @@ keywords = ["http", "web", "framework", "async", "futures"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web.git"
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
@@ -19,7 +19,7 @@ all-features = true
[features]
default = ["tempfile", "derive"]
derive = ["actix-multipart-derive"]
-tempfile = ["tempfile-dep", "tokio/fs"]
+tempfile = ["dep:tempfile", "tokio/fs"]
[dependencies]
actix-multipart-derive = { version = "=0.6.0", optional = true }
@@ -38,9 +38,8 @@ mime = "0.3"
serde = "1"
serde_json = "1"
serde_plain = "1"
-# TODO(MSRV 1.60): replace with dep: prefix
-tempfile-dep = { package = "tempfile", version = "3.4", optional = true }
-tokio = { version = "1.24.2", features = ["sync"] }
+tempfile = { version = "3.4", optional = true }
+tokio = { version = "1.24.2", features = ["sync", "io-util"] }
[dev-dependencies]
actix-http = "3"
diff --git a/actix-multipart/README.md b/actix-multipart/README.md
index c4101e1ce..3e2a7a127 100644
--- a/actix-multipart/README.md
+++ b/actix-multipart/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-multipart)
[](https://docs.rs/actix-multipart/0.6.0)
-
+

[](https://deps.rs/crate/actix-multipart/0.6.0)
@@ -14,4 +14,4 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-multipart)
-- Minimum Supported Rust Version (MSRV): 1.59
+- Minimum Supported Rust Version (MSRV): 1.65
diff --git a/actix-multipart/src/form/bytes.rs b/actix-multipart/src/form/bytes.rs
index 7d64fffce..3c5e2eb10 100644
--- a/actix-multipart/src/form/bytes.rs
+++ b/actix-multipart/src/form/bytes.rs
@@ -27,11 +27,7 @@ pub struct Bytes {
impl<'t> FieldReader<'t> for Bytes {
type Future = LocalBoxFuture<'t, Result>;
- fn read_field(
- _: &'t HttpRequest,
- mut field: Field,
- limits: &'t mut Limits,
- ) -> Self::Future {
+ fn read_field(_: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future {
Box::pin(async move {
let mut buf = BytesMut::with_capacity(131_072);
diff --git a/actix-multipart/src/form/json.rs b/actix-multipart/src/form/json.rs
index 9951eaaaf..fb90a82b9 100644
--- a/actix-multipart/src/form/json.rs
+++ b/actix-multipart/src/form/json.rs
@@ -7,13 +7,12 @@ use derive_more::{Deref, DerefMut, Display, Error};
use futures_core::future::LocalBoxFuture;
use serde::de::DeserializeOwned;
+use super::FieldErrorHandler;
use crate::{
form::{bytes::Bytes, FieldReader, Limits},
Field, MultipartError,
};
-use super::FieldErrorHandler;
-
/// Deserialize from JSON.
#[derive(Debug, Deref, DerefMut)]
pub struct Json(pub T);
diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs
index 711d4aeb6..67adfd4b2 100644
--- a/actix-multipart/src/form/mod.rs
+++ b/actix-multipart/src/form/mod.rs
@@ -429,8 +429,7 @@ mod tests {
#[actix_rt::test]
async fn test_options() {
- let srv =
- actix_test::start(|| App::new().route("/", web::post().to(test_options_route)));
+ let srv = actix_test::start(|| App::new().route("/", web::post().to(test_options_route)));
let mut form = multipart::Form::default();
form.add_text("field1", "value");
@@ -481,9 +480,7 @@ mod tests {
field3: Text,
}
- async fn test_field_renaming_route(
- form: MultipartForm,
- ) -> impl Responder {
+ async fn test_field_renaming_route(form: MultipartForm) -> impl Responder {
assert_eq!(&*form.field1, "renamed");
assert_eq!(&*form.field2, "field1");
assert_eq!(&*form.field3, "field3");
@@ -492,9 +489,8 @@ mod tests {
#[actix_rt::test]
async fn test_field_renaming() {
- let srv = actix_test::start(|| {
- App::new().route("/", web::post().to(test_field_renaming_route))
- });
+ let srv =
+ actix_test::start(|| App::new().route("/", web::post().to(test_field_renaming_route)));
let mut form = multipart::Form::default();
form.add_text("renamed", "renamed");
@@ -623,9 +619,7 @@ mod tests {
HttpResponse::Ok().finish()
}
- async fn test_upload_limits_file(
- form: MultipartForm,
- ) -> impl Responder {
+ async fn test_upload_limits_file(form: MultipartForm) -> impl Responder {
assert!(form.field.size > 0);
HttpResponse::Ok().finish()
}
diff --git a/actix-multipart/src/form/tempfile.rs b/actix-multipart/src/form/tempfile.rs
index 3c637e717..9371a026b 100644
--- a/actix-multipart/src/form/tempfile.rs
+++ b/actix-multipart/src/form/tempfile.rs
@@ -11,7 +11,7 @@ use derive_more::{Display, Error};
use futures_core::future::LocalBoxFuture;
use futures_util::TryStreamExt as _;
use mime::Mime;
-use tempfile_dep::NamedTempFile;
+use tempfile::NamedTempFile;
use tokio::io::AsyncWriteExt;
use super::FieldErrorHandler;
@@ -39,23 +39,20 @@ pub struct TempFile {
impl<'t> FieldReader<'t> for TempFile {
type Future = LocalBoxFuture<'t, Result>;
- fn read_field(
- req: &'t HttpRequest,
- mut field: Field,
- limits: &'t mut Limits,
- ) -> Self::Future {
+ fn read_field(req: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future {
Box::pin(async move {
let config = TempFileConfig::from_req(req);
let field_name = field.name().to_owned();
let mut size = 0;
- let file = config.create_tempfile().map_err(|err| {
- config.map_error(req, &field_name, TempFileError::FileIo(err))
- })?;
+ let file = config
+ .create_tempfile()
+ .map_err(|err| config.map_error(req, &field_name, TempFileError::FileIo(err)))?;
- let mut file_async = tokio::fs::File::from_std(file.reopen().map_err(|err| {
- config.map_error(req, &field_name, TempFileError::FileIo(err))
- })?);
+ let mut file_async =
+ tokio::fs::File::from_std(file.reopen().map_err(|err| {
+ config.map_error(req, &field_name, TempFileError::FileIo(err))
+ })?);
while let Some(chunk) = field.try_next().await? {
limits.try_consume_limits(chunk.len(), false)?;
@@ -65,9 +62,10 @@ impl<'t> FieldReader<'t> for TempFile {
})?;
}
- file_async.flush().await.map_err(|err| {
- config.map_error(req, &field_name, TempFileError::FileIo(err))
- })?;
+ file_async
+ .flush()
+ .await
+ .map_err(|err| config.map_error(req, &field_name, TempFileError::FileIo(err)))?;
Ok(TempFile {
file,
@@ -131,12 +129,7 @@ impl TempFileConfig {
.unwrap_or(&DEFAULT_CONFIG)
}
- fn map_error(
- &self,
- req: &HttpRequest,
- field_name: &str,
- err: TempFileError,
- ) -> MultipartError {
+ fn map_error(&self, req: &HttpRequest, field_name: &str, err: TempFileError) -> MultipartError {
let source = if let Some(ref err_handler) = self.err_handler {
(err_handler)(err, req)
} else {
diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs
index 73e10c913..615a8e6de 100644
--- a/actix-multipart/src/lib.rs
+++ b/actix-multipart/src/lib.rs
@@ -17,5 +17,7 @@ mod server;
pub mod form;
-pub use self::error::MultipartError;
-pub use self::server::{Field, Multipart};
+pub use self::{
+ error::MultipartError,
+ server::{Field, Multipart},
+};
diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs
index 6726bc9d3..b20429040 100644
--- a/actix-multipart/src/server.rs
+++ b/actix-multipart/src/server.rs
@@ -2,9 +2,7 @@
use std::{
cell::{Cell, RefCell, RefMut},
- cmp,
- convert::TryFrom,
- fmt,
+ cmp, fmt,
marker::PhantomData,
pin::Pin,
rc::Rc,
@@ -163,8 +161,8 @@ impl InnerMultipart {
for h in hdrs {
let name =
HeaderName::try_from(h.name).map_err(|_| ParseError::Header)?;
- let value = HeaderValue::try_from(h.value)
- .map_err(|_| ParseError::Header)?;
+ let value =
+ HeaderValue::try_from(h.value).map_err(|_| ParseError::Header)?;
headers.append(name, value);
}
@@ -224,8 +222,7 @@ impl InnerMultipart {
if chunk.len() < boundary.len() {
continue;
}
- if &chunk[..2] == b"--" && &chunk[2..chunk.len() - 2] == boundary.as_bytes()
- {
+ if &chunk[..2] == b"--" && &chunk[2..chunk.len() - 2] == boundary.as_bytes() {
break;
} else {
if chunk.len() < boundary.len() + 2 {
@@ -270,9 +267,7 @@ impl InnerMultipart {
match field.borrow_mut().poll(safety) {
Poll::Pending => return Poll::Pending,
Poll::Ready(Some(Ok(_))) => continue,
- Poll::Ready(Some(Err(err))) => {
- return Poll::Ready(Some(Err(err)))
- }
+ Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))),
Poll::Ready(None) => true,
}
}
@@ -291,8 +286,7 @@ impl InnerMultipart {
match self.state {
// read until first boundary
InnerState::FirstBoundary => {
- match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)?
- {
+ match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)? {
Some(eof) => {
if eof {
self.state = InnerState::Eof;
@@ -669,9 +663,7 @@ impl InnerField {
Ok(None) => Poll::Pending,
Ok(Some(line)) => {
if line.as_ref() != b"\r\n" {
- log::warn!(
- "multipart field did not read all the data or it is malformed"
- );
+ log::warn!("multipart field did not read all the data or it is malformed");
}
Poll::Ready(None)
}
diff --git a/actix-router/CHANGES.md b/actix-router/CHANGES.md
index 7ef9497dc..1f5552193 100644
--- a/actix-router/CHANGES.md
+++ b/actix-router/CHANGES.md
@@ -2,6 +2,8 @@
## Unreleased - 2023-xx-xx
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 0.5.1 - 2022-09-19
- Correct typo in error string for `i32` deserialization. [#2876]
diff --git a/actix-router/Cargo.toml b/actix-router/Cargo.toml
index f8efd5350..adf43a086 100644
--- a/actix-router/Cargo.toml
+++ b/actix-router/Cargo.toml
@@ -10,7 +10,7 @@ description = "Resource path matching and router"
keywords = ["actix", "router", "routing"]
repository = "https://github.com/actix/actix-web.git"
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[lib]
name = "actix_router"
@@ -27,7 +27,7 @@ serde = "1"
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
[dev-dependencies]
-criterion = { version = "0.4", features = ["html_reports"] }
+criterion = { version = "0.5", features = ["html_reports"] }
http = "0.2.7"
serde = { version = "1", features = ["derive"] }
percent-encoding = "2.1"
diff --git a/actix-router/benches/quoter.rs b/actix-router/benches/quoter.rs
index 9ca06da39..2065fd563 100644
--- a/actix-router/benches/quoter.rs
+++ b/actix-router/benches/quoter.rs
@@ -1,9 +1,9 @@
#![allow(clippy::uninlined_format_args)]
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
-
use std::borrow::Cow;
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
fn compare_quoters(c: &mut Criterion) {
let mut group = c.benchmark_group("Compare Quoters");
diff --git a/actix-router/src/de.rs b/actix-router/src/de.rs
index 458e08930..e8c7c658e 100644
--- a/actix-router/src/de.rs
+++ b/actix-router/src/de.rs
@@ -1,10 +1,14 @@
use std::borrow::Cow;
-use serde::de::{self, Deserializer, Error as DeError, Visitor};
-use serde::forward_to_deserialize_any;
+use serde::{
+ de::{self, Deserializer, Error as DeError, Visitor},
+ forward_to_deserialize_any,
+};
-use crate::path::{Path, PathIter};
-use crate::{Quoter, ResourcePath};
+use crate::{
+ path::{Path, PathIter},
+ Quoter, ResourcePath,
+};
thread_local! {
static FULL_QUOTER: Quoter = Quoter::new(b"", b"");
@@ -486,11 +490,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
Err(de::value::Error::custom("not supported"))
}
- fn struct_variant(
- self,
- _: &'static [&'static str],
- _: V,
- ) -> Result
+ fn struct_variant(self, _: &'static [&'static str], _: V) -> Result
where
V: Visitor<'de>,
{
@@ -503,9 +503,7 @@ mod tests {
use serde::{de, Deserialize};
use super::*;
- use crate::path::Path;
- use crate::router::Router;
- use crate::ResourceDef;
+ use crate::{path::Path, router::Router, ResourceDef};
#[derive(Deserialize)]
struct MyStruct {
@@ -572,13 +570,11 @@ mod tests {
assert_eq!(s.key, "name");
assert_eq!(s.value, 32);
- let s: (String, u8) =
- de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+ let s: (String, u8) = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(s.0, "name");
assert_eq!(s.1, 32);
- let res: Vec =
- de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+ let res: Vec = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(res[0], "name".to_owned());
assert_eq!(res[1], "32".to_owned());
}
diff --git a/actix-router/src/lib.rs b/actix-router/src/lib.rs
index a02129495..53c0ad82a 100644
--- a/actix-router/src/lib.rs
+++ b/actix-router/src/lib.rs
@@ -18,13 +18,14 @@ mod router;
#[cfg(feature = "http")]
mod url;
-pub use self::de::PathDeserializer;
-pub use self::path::Path;
-pub use self::pattern::{IntoPatterns, Patterns};
-pub use self::quoter::Quoter;
-pub use self::resource::ResourceDef;
-pub use self::resource_path::{Resource, ResourcePath};
-pub use self::router::{ResourceId, Router, RouterBuilder};
-
#[cfg(feature = "http")]
pub use self::url::Url;
+pub use self::{
+ de::PathDeserializer,
+ path::Path,
+ pattern::{IntoPatterns, Patterns},
+ quoter::Quoter,
+ resource::ResourceDef,
+ resource_path::{Resource, ResourcePath},
+ router::{ResourceId, Router, RouterBuilder},
+};
diff --git a/actix-router/src/path.rs b/actix-router/src/path.rs
index 34dabcfbe..dc4150ddc 100644
--- a/actix-router/src/path.rs
+++ b/actix-router/src/path.rs
@@ -1,5 +1,7 @@
-use std::borrow::Cow;
-use std::ops::{DerefMut, Index};
+use std::{
+ borrow::Cow,
+ ops::{DerefMut, Index},
+};
use serde::de;
diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs
index f198115ad..860993a37 100644
--- a/actix-router/src/resource.rs
+++ b/actix-router/src/resource.rs
@@ -1389,8 +1389,6 @@ mod tests {
#[cfg(feature = "http")]
#[test]
fn parse_urlencoded_param() {
- use std::convert::TryFrom;
-
let re = ResourceDef::new("/user/{id}/test");
let mut path = Path::new("/user/2345/test");
@@ -1743,9 +1741,7 @@ mod tests {
ResourceDef::new("/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}");
// panics
- ResourceDef::new(
- "/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}",
- );
+ ResourceDef::new("/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}");
}
#[test]
diff --git a/actix-router/src/router.rs b/actix-router/src/router.rs
index 064c5e904..d31d10ce8 100644
--- a/actix-router/src/router.rs
+++ b/actix-router/src/router.rs
@@ -117,11 +117,7 @@ where
U: Default,
{
/// Registers resource for specified path.
- pub fn path(
- &mut self,
- path: impl IntoPatterns,
- val: T,
- ) -> (&mut ResourceDef, &mut T, &mut U) {
+ pub fn path(&mut self, path: impl IntoPatterns, val: T) -> (&mut ResourceDef, &mut T, &mut U) {
self.push(ResourceDef::new(path), val, U::default())
}
@@ -142,8 +138,10 @@ where
#[cfg(test)]
mod tests {
- use crate::path::Path;
- use crate::router::{ResourceId, Router};
+ use crate::{
+ path::Path,
+ router::{ResourceId, Router},
+ };
#[allow(clippy::cognitive_complexity)]
#[test]
diff --git a/actix-router/src/url.rs b/actix-router/src/url.rs
index 8ac033861..2920e271d 100644
--- a/actix-router/src/url.rs
+++ b/actix-router/src/url.rs
@@ -1,6 +1,4 @@
-use crate::ResourcePath;
-
-use crate::Quoter;
+use crate::{Quoter, ResourcePath};
thread_local! {
static DEFAULT_QUOTER: Quoter = Quoter::new(b"", b"%/+");
@@ -65,7 +63,6 @@ impl ResourcePath for Url {
#[cfg(test)]
mod tests {
use http::Uri;
- use std::convert::TryFrom;
use super::*;
use crate::{Path, ResourceDef};
diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md
index 47fea4173..aba27dbfc 100644
--- a/actix-test/CHANGES.md
+++ b/actix-test/CHANGES.md
@@ -2,6 +2,9 @@
## Unreleased - 2023-xx-xx
+- Add `TestServerConfig::workers()` setter method.
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 0.1.1 - 2023-02-26
- Add `TestServerConfig::port()` setter method.
diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml
index f2cbfe5cd..9cf5aa76c 100644
--- a/actix-test/Cargo.toml
+++ b/actix-test/Cargo.toml
@@ -16,7 +16,7 @@ categories = [
"web-programming::websocket",
]
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[features]
default = []
@@ -43,6 +43,6 @@ log = "0.4"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_urlencoded = "0.7"
-tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
-tls-rustls = { package = "rustls", version = "0.20.0", optional = true }
+tls-openssl = { package = "openssl", version = "0.10.55", optional = true }
+tls-rustls = { package = "rustls", version = "0.20", optional = true }
tokio = { version = "1.24.2", features = ["sync"] }
diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs
index 2beb64dca..751ab3161 100644
--- a/actix-test/src/lib.rs
+++ b/actix-test/src/lib.rs
@@ -45,8 +45,8 @@ use actix_http::{header::HeaderMap, ws, HttpService, Method, Request, Response};
pub use actix_http_test::unused_addr;
use actix_service::{map_config, IntoServiceFactory, ServiceFactory, ServiceFactoryExt as _};
pub use actix_web::test::{
- call_and_read_body, call_and_read_body_json, call_service, init_service, ok_service,
- read_body, read_body_json, status_service, TestRequest,
+ call_and_read_body, call_and_read_body_json, call_service, init_service, ok_service, read_body,
+ read_body_json, status_service, TestRequest,
};
use actix_web::{
body::MessageBody,
@@ -154,16 +154,16 @@ where
let srv_cfg = cfg.clone();
let timeout = cfg.client_request_timeout;
- let builder = Server::build().workers(1).disable_signals().system_exit();
+ let builder = Server::build()
+ .workers(cfg.workers)
+ .disable_signals()
+ .system_exit();
let srv = match srv_cfg.stream {
StreamType::Tcp => match srv_cfg.tp {
HttpVer::Http1 => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -175,11 +175,8 @@ where
.tcp()
}),
HttpVer::Http2 => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -191,11 +188,8 @@ where
.tcp()
}),
HttpVer::Both => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -210,11 +204,8 @@ where
#[cfg(feature = "openssl")]
StreamType::Openssl(acceptor) => match cfg.tp {
HttpVer::Http1 => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -226,11 +217,8 @@ where
.openssl(acceptor.clone())
}),
HttpVer::Http2 => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -242,11 +230,8 @@ where
.openssl(acceptor.clone())
}),
HttpVer::Both => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -261,11 +246,8 @@ where
#[cfg(feature = "rustls")]
StreamType::Rustls(config) => match cfg.tp {
HttpVer::Http1 => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -277,11 +259,8 @@ where
.rustls(config.clone())
}),
HttpVer::Http2 => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -293,11 +272,8 @@ where
.rustls(config.clone())
}),
HttpVer::Both => builder.listen("test", tcp, move || {
- let app_cfg = AppConfig::__priv_test_new(
- false,
- local_addr.to_string(),
- local_addr,
- );
+ let app_cfg =
+ AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory()
.into_factory()
@@ -394,6 +370,7 @@ pub struct TestServerConfig {
stream: StreamType,
client_request_timeout: Duration,
port: u16,
+ workers: usize,
}
impl Default for TestServerConfig {
@@ -410,6 +387,7 @@ impl TestServerConfig {
stream: StreamType::Tcp,
client_request_timeout: Duration::from_secs(5),
port: 0,
+ workers: 1,
}
}
@@ -452,6 +430,14 @@ impl TestServerConfig {
self.port = port;
self
}
+
+ /// Sets number of workers for the test server.
+ ///
+ /// By default, the server uses 1 worker
+ pub fn workers(mut self, workers: usize) -> Self {
+ self.workers = workers;
+ self
+ }
}
/// A basic HTTP server controller that simplifies the process of writing integration tests for
diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md
index ea19411b5..4799c7b67 100644
--- a/actix-web-actors/CHANGES.md
+++ b/actix-web-actors/CHANGES.md
@@ -2,6 +2,8 @@
## Unreleased - 2023-xx-xx
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 4.2.0 - 2023-01-21
- Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency.
diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml
index e89baed96..c6f14554a 100644
--- a/actix-web-actors/Cargo.toml
+++ b/actix-web-actors/Cargo.toml
@@ -7,7 +7,7 @@ keywords = ["actix", "http", "web", "framework", "async"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web"
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[lib]
name = "actix_web_actors"
@@ -32,7 +32,6 @@ actix-test = "0.1"
awc = { version = "3", default-features = false }
actix-web = { version = "4", features = ["macros"] }
+env_logger = "0.10"
+futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
mime = "0.3"
-
-env_logger = "0.9"
-futures-util = { version = "0.3.17", default-features = false }
diff --git a/actix-web-actors/README.md b/actix-web-actors/README.md
index dce91f503..fe6122115 100644
--- a/actix-web-actors/README.md
+++ b/actix-web-actors/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-web-actors)
[](https://docs.rs/actix-web-actors/4.2.0)
-
+

[](https://deps.rs/crate/actix-web-actors/4.2.0)
@@ -14,4 +14,4 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-web-actors)
-- Minimum Supported Rust Version (MSRV): 1.59
+- Minimum Supported Rust Version (MSRV): 1.65
diff --git a/actix-web-actors/src/context.rs b/actix-web-actors/src/context.rs
index f7b11c780..be8fd387c 100644
--- a/actix-web-actors/src/context.rs
+++ b/actix-web-actors/src/context.rs
@@ -1,11 +1,13 @@
-use std::collections::VecDeque;
-use std::future::Future;
-use std::pin::Pin;
-use std::task::{Context, Poll};
+use std::{
+ collections::VecDeque,
+ future::Future,
+ pin::Pin,
+ task::{Context, Poll},
+};
-use actix::dev::{AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, ToEnvelope};
-use actix::fut::ActorFuture;
use actix::{
+ dev::{AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, ToEnvelope},
+ fut::ActorFuture,
Actor, ActorContext, ActorState, Addr, AsyncContext, Handler, Message, SpawnHandle,
};
use actix_web::error::Error;
@@ -247,9 +249,11 @@ mod tests {
use std::time::Duration;
use actix::Actor;
- use actix_web::http::StatusCode;
- use actix_web::test::{call_service, init_service, read_body, TestRequest};
- use actix_web::{web, App, HttpResponse};
+ use actix_web::{
+ http::StatusCode,
+ test::{call_service, init_service, read_body, TestRequest},
+ web, App, HttpResponse,
+ };
use bytes::Bytes;
use super::*;
diff --git a/actix-web-actors/src/ws.rs b/actix-web-actors/src/ws.rs
index e1110eddb..6ce3e69a1 100644
--- a/actix-web-actors/src/ws.rs
+++ b/actix-web-actors/src/ws.rs
@@ -58,7 +58,6 @@
use std::{
collections::VecDeque,
- convert::TryFrom,
future::Future,
io, mem,
pin::Pin,
@@ -67,17 +66,14 @@ use std::{
use actix::{
dev::{
- AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, StreamHandler,
- ToEnvelope,
+ AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, StreamHandler, ToEnvelope,
},
fut::ActorFuture,
Actor, ActorContext, ActorState, Addr, AsyncContext, Handler, Message as ActixMessage,
SpawnHandle,
};
use actix_http::ws::{hash_key, Codec};
-pub use actix_http::ws::{
- CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError,
-};
+pub use actix_http::ws::{CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError};
use actix_web::{
error::{Error, PayloadError},
http::{
@@ -427,16 +423,16 @@ pub fn handshake_with_protocols(
};
// check requested protocols
- let protocol =
- req.headers()
- .get(&header::SEC_WEBSOCKET_PROTOCOL)
- .and_then(|req_protocols| {
- let req_protocols = req_protocols.to_str().ok()?;
- req_protocols
- .split(',')
- .map(|req_p| req_p.trim())
- .find(|req_p| protocols.iter().any(|p| p == req_p))
- });
+ let protocol = req
+ .headers()
+ .get(&header::SEC_WEBSOCKET_PROTOCOL)
+ .and_then(|req_protocols| {
+ let req_protocols = req_protocols.to_str().ok()?;
+ req_protocols
+ .split(',')
+ .map(|req_p| req_p.trim())
+ .find(|req_p| protocols.iter().any(|p| p == req_p))
+ });
let mut response = HttpResponse::build(StatusCode::SWITCHING_PROTOCOLS)
.upgrade("websocket")
diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md
index 6e962a6ca..b9e4b0aad 100644
--- a/actix-web-codegen/CHANGES.md
+++ b/actix-web-codegen/CHANGES.md
@@ -2,6 +2,8 @@
## Unreleased - 2023-xx-xx
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 4.2.0 - 2023-02-26
- Add support for custom methods with the `#[route]` macro. [#2969]
diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml
index 51cb0dfef..4f2fdc566 100644
--- a/actix-web-codegen/Cargo.toml
+++ b/actix-web-codegen/Cargo.toml
@@ -9,7 +9,7 @@ authors = [
"Rob Ede ",
]
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[lib]
proc-macro = true
diff --git a/actix-web-codegen/README.md b/actix-web-codegen/README.md
index 8dd3e986e..531f44a5d 100644
--- a/actix-web-codegen/README.md
+++ b/actix-web-codegen/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-web-codegen)
[](https://docs.rs/actix-web-codegen/4.2.0)
-
+

[](https://deps.rs/crate/actix-web-codegen/4.2.0)
@@ -14,7 +14,7 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-web-codegen)
-- Minimum Supported Rust Version (MSRV): 1.59
+- Minimum Supported Rust Version (MSRV): 1.65
## Compile Testing
diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs
index 8b68ea16b..6d6f4f79d 100644
--- a/actix-web-codegen/src/lib.rs
+++ b/actix-web-codegen/src/lib.rs
@@ -153,37 +153,37 @@ pub fn routes(_: TokenStream, input: TokenStream) -> TokenStream {
macro_rules! method_macro {
($variant:ident, $method:ident) => {
-#[doc = concat!("Creates route handler with `actix_web::guard::", stringify!($variant), "`.")]
-///
-/// # Syntax
-/// ```plain
-#[doc = concat!("#[", stringify!($method), r#"("path"[, attributes])]"#)]
-/// ```
-///
-/// # Attributes
-/// - `"path"`: Raw literal string with path for which to register handler.
-/// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the function
-/// name of handler is used.
-/// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`.
-/// - `wrap = "Middleware"`: Registers a resource middleware.
-///
-/// # Notes
-/// Function name can be specified as any expression that is going to be accessible to the
-/// generate code, e.g `my_guard` or `my_module::my_guard`.
-///
-/// # Examples
-/// ```
-/// # use actix_web::HttpResponse;
-#[doc = concat!("# use actix_web_codegen::", stringify!($method), ";")]
-#[doc = concat!("#[", stringify!($method), r#"("/")]"#)]
-/// async fn example() -> HttpResponse {
-/// HttpResponse::Ok().finish()
-/// }
-/// ```
-#[proc_macro_attribute]
-pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream {
- route::with_method(Some(route::MethodType::$variant), args, input)
-}
+ #[doc = concat!("Creates route handler with `actix_web::guard::", stringify!($variant), "`.")]
+ ///
+ /// # Syntax
+ /// ```plain
+ #[doc = concat!("#[", stringify!($method), r#"("path"[, attributes])]"#)]
+ /// ```
+ ///
+ /// # Attributes
+ /// - `"path"`: Raw literal string with path for which to register handler.
+ /// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the
+ /// function name of handler is used.
+ /// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`.
+ /// - `wrap = "Middleware"`: Registers a resource middleware.
+ ///
+ /// # Notes
+ /// Function name can be specified as any expression that is going to be accessible to the
+ /// generate code, e.g `my_guard` or `my_module::my_guard`.
+ ///
+ /// # Examples
+ /// ```
+ /// # use actix_web::HttpResponse;
+ #[doc = concat!("# use actix_web_codegen::", stringify!($method), ";")]
+ #[doc = concat!("#[", stringify!($method), r#"("/")]"#)]
+ /// async fn example() -> HttpResponse {
+ /// HttpResponse::Ok().finish()
+ /// }
+ /// ```
+ #[proc_macro_attribute]
+ pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream {
+ route::with_method(Some(route::MethodType::$variant), args, input)
+ }
};
}
diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs
index 0772dbd94..e87d37941 100644
--- a/actix-web-codegen/src/route.rs
+++ b/actix-web-codegen/src/route.rs
@@ -1,4 +1,4 @@
-use std::{collections::HashSet, convert::TryFrom};
+use std::collections::HashSet;
use actix_router::ResourceDef;
use proc_macro::TokenStream;
@@ -488,31 +488,32 @@ pub(crate) fn with_methods(input: TokenStream) -> TokenStream {
ast.attrs = others.into_iter().map(Result::unwrap_err).collect();
- let methods =
- match methods
- .into_iter()
- .map(Result::unwrap)
- .map(|(method, attr)| {
- attr.parse_meta().and_then(|args| {
- if let Meta::List(args) = args {
- Args::new(args.nested.into_iter().collect(), Some(method))
- } else {
- Err(syn::Error::new_spanned(attr, "Invalid input for macro"))
- }
- })
+ let methods = match methods
+ .into_iter()
+ .map(Result::unwrap)
+ .map(|(method, attr)| {
+ attr.parse_meta().and_then(|args| {
+ if let Meta::List(args) = args {
+ Args::new(args.nested.into_iter().collect(), Some(method))
+ } else {
+ Err(syn::Error::new_spanned(attr, "Invalid input for macro"))
+ }
})
- .collect::, _>>()
- {
- Ok(methods) if methods.is_empty() => return input_and_compile_error(
+ })
+ .collect::, _>>()
+ {
+ Ok(methods) if methods.is_empty() => {
+ return input_and_compile_error(
input,
syn::Error::new(
Span::call_site(),
"The #[routes] macro requires at least one `#[(..)]` attribute.",
),
- ),
- Ok(methods) => methods,
- Err(err) => return input_and_compile_error(input, err),
- };
+ )
+ }
+ Ok(methods) => methods,
+ Err(err) => return input_and_compile_error(input, err),
+ };
match Route::multiple(methods, ast) {
Ok(route) => route.into_token_stream().into(),
diff --git a/actix-web-codegen/tests/trybuild.rs b/actix-web-codegen/tests/trybuild.rs
index 8839dca3d..9f0aa02f4 100644
--- a/actix-web-codegen/tests/trybuild.rs
+++ b/actix-web-codegen/tests/trybuild.rs
@@ -1,4 +1,4 @@
-#[rustversion::stable(1.59)] // MSRV
+#[rustversion::stable(1.65)] // MSRV
#[test]
fn compile_macros() {
let t = trybuild::TestCases::new();
diff --git a/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr b/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr
index 243c4dd68..88198a55d 100644
--- a/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr
+++ b/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr
@@ -8,10 +8,20 @@ error[E0277]: the trait bound `fn() -> impl std::future::Future
-[](https://crates.io/crates/actix-web) [](https://docs.rs/actix-web/4.3.1)   [](https://deps.rs/crate/actix-web/4.3.1)
[](https://github.com/actix/actix-web/actions/workflows/ci.yml) [](https://codecov.io/gh/actix/actix-web)  [](https://discord.gg/NWpN5mmg3x)
+[](https://crates.io/crates/actix-web) [](https://docs.rs/actix-web/4.3.1)   [](https://deps.rs/crate/actix-web/4.3.1)
[](https://github.com/actix/actix-web/actions/workflows/ci.yml) [](https://codecov.io/gh/actix/actix-web)  [](https://discord.gg/NWpN5mmg3x)
@@ -24,7 +24,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.59+
+- Runs on stable Rust 1.65+
## Documentation
diff --git a/actix-web/benches/responder.rs b/actix-web/benches/responder.rs
index ac4d18324..c675eadff 100644
--- a/actix-web/benches/responder.rs
+++ b/actix-web/benches/responder.rs
@@ -99,8 +99,7 @@ fn responder(c: &mut Criterion) {
let req = TestRequest::default().to_http_request();
c.bench_function("responder", move |b| {
b.iter_custom(|_| {
- let responders =
- (0..100_000).map(|_| StringResponder(String::from("Hello World!!")));
+ let responders = (0..100_000).map(|_| StringResponder(String::from("Hello World!!")));
let start = Instant::now();
let _res = rt.block_on(async {
diff --git a/actix-web/benches/service.rs b/actix-web/benches/service.rs
index 87e51f170..9b29df8e5 100644
--- a/actix-web/benches/service.rs
+++ b/actix-web/benches/service.rs
@@ -1,11 +1,12 @@
-use actix_service::Service;
-use actix_web::dev::{ServiceRequest, ServiceResponse};
-use actix_web::{web, App, Error, HttpResponse};
-use criterion::{criterion_main, Criterion};
-use std::cell::RefCell;
-use std::rc::Rc;
+use std::{cell::RefCell, rc::Rc};
-use actix_web::test::{init_service, ok_service, TestRequest};
+use actix_service::Service;
+use actix_web::{
+ dev::{ServiceRequest, ServiceResponse},
+ test::{init_service, ok_service, TestRequest},
+ web, App, Error, HttpResponse,
+};
+use criterion::{criterion_main, Criterion};
/// Criterion Benchmark for async Service
/// Should be used from within criterion group:
diff --git a/actix-web/examples/on-connect.rs b/actix-web/examples/on-connect.rs
index 0d56a8f25..dc9273b46 100644
--- a/actix-web/examples/on-connect.rs
+++ b/actix-web/examples/on-connect.rs
@@ -7,8 +7,7 @@
use std::{any::Any, io, net::SocketAddr};
use actix_web::{
- dev::Extensions, rt::net::TcpStream, web, App, HttpRequest, HttpResponse, HttpServer,
- Responder,
+ dev::Extensions, rt::net::TcpStream, web, App, HttpRequest, HttpResponse, HttpServer, Responder,
};
#[allow(dead_code)]
@@ -24,9 +23,7 @@ async fn route_whoami(req: HttpRequest) -> impl Responder {
Some(info) => HttpResponse::Ok().body(format!(
"Here is some info about your connection:\n\n{info:#?}",
)),
- None => {
- HttpResponse::InternalServerError().body("Missing expected request extension data")
- }
+ None => HttpResponse::InternalServerError().body("Missing expected request extension data"),
}
}
diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs
index 353b82b19..a4cd8d819 100644
--- a/actix-web/src/app.rs
+++ b/actix-web/src/app.rs
@@ -264,12 +264,8 @@ where
pub fn default_service(mut self, svc: F) -> Self
where
F: IntoServiceFactory,
- U: ServiceFactory<
- ServiceRequest,
- Config = (),
- Response = ServiceResponse,
- Error = Error,
- > + 'static,
+ U: ServiceFactory
+ + 'static,
U::InitError: fmt::Debug,
{
let svc = svc
@@ -323,16 +319,7 @@ where
/// Middleware can be applied similarly to individual `Scope`s and `Resource`s.
/// See [`Scope::wrap`](crate::Scope::wrap) and [`Resource::wrap`].
///
- /// # Middleware Order
- /// Notice that the keyword for registering middleware is `wrap`. As you register middleware
- /// using `wrap` in the App builder, imagine wrapping layers around an inner App. The first
- /// middleware layer exposed to a Request is the outermost layer (i.e., the *last* registered in
- /// the builder chain). Consequently, the *first* middleware registered in the builder chain is
- /// the *last* to start executing during request processing.
- ///
- /// Ordering is less obvious when wrapped services also have middleware applied. In this case,
- /// middlewares are run in reverse order for `App` _and then_ in reverse order for the
- /// wrapped service.
+ /// For more info on middleware take a look at the [`middleware` module][crate::middleware].
///
/// # Examples
/// ```
diff --git a/actix-web/src/app_service.rs b/actix-web/src/app_service.rs
index 0fc856203..513e7a8a1 100644
--- a/actix-web/src/app_service.rs
+++ b/actix-web/src/app_service.rs
@@ -348,13 +348,17 @@ impl ServiceFactory for AppEntry {
#[cfg(test)]
mod tests {
- use std::sync::atomic::{AtomicBool, Ordering};
- use std::sync::Arc;
+ use std::sync::{
+ atomic::{AtomicBool, Ordering},
+ Arc,
+ };
use actix_service::Service;
- use crate::test::{init_service, TestRequest};
- use crate::{web, App, HttpResponse};
+ use crate::{
+ test::{init_service, TestRequest},
+ web, App, HttpResponse,
+ };
struct DropData(Arc);
diff --git a/actix-web/src/config.rs b/actix-web/src/config.rs
index 11eaf8720..fba0c2717 100644
--- a/actix-web/src/config.rs
+++ b/actix-web/src/config.rs
@@ -232,12 +232,8 @@ impl ServiceConfig {
pub fn default_service(&mut self, f: F) -> &mut Self
where
F: IntoServiceFactory,
- U: ServiceFactory<
- ServiceRequest,
- Config = (),
- Response = ServiceResponse,
- Error = Error,
- > + 'static,
+ U: ServiceFactory
+ + 'static,
U::InitError: std::fmt::Debug,
{
let svc = f
@@ -308,9 +304,11 @@ mod tests {
use bytes::Bytes;
use super::*;
- use crate::http::{Method, StatusCode};
- use crate::test::{assert_body_eq, call_service, init_service, read_body, TestRequest};
- use crate::{web, App, HttpRequest, HttpResponse};
+ use crate::{
+ http::{Method, StatusCode},
+ test::{assert_body_eq, call_service, init_service, read_body, TestRequest},
+ web, App, HttpRequest, HttpResponse,
+ };
// allow deprecated `ServiceConfig::data`
#[allow(deprecated)]
diff --git a/actix-web/src/data.rs b/actix-web/src/data.rs
index 89104a1ac..423dd598c 100644
--- a/actix-web/src/data.rs
+++ b/actix-web/src/data.rs
@@ -186,12 +186,14 @@ mod tests {
#[allow(deprecated)]
#[actix_rt::test]
async fn test_data_extractor() {
- let srv = init_service(App::new().data("TEST".to_string()).service(
- web::resource("/").to(|data: web::Data| {
- assert_eq!(data.to_lowercase(), "test");
- HttpResponse::Ok()
- }),
- ))
+ let srv = init_service(
+ App::new()
+ .data("TEST".to_string())
+ .service(web::resource("/").to(|data: web::Data| {
+ assert_eq!(data.to_lowercase(), "test");
+ HttpResponse::Ok()
+ })),
+ )
.await;
let req = TestRequest::default().to_request();
@@ -286,16 +288,17 @@ mod tests {
#[allow(deprecated)]
#[actix_rt::test]
async fn test_override_data() {
- let srv =
- init_service(App::new().data(1usize).service(
- web::resource("/").data(10usize).route(web::get().to(
+ let srv = init_service(
+ App::new()
+ .data(1usize)
+ .service(web::resource("/").data(10usize).route(web::get().to(
|data: web::Data| {
assert_eq!(**data, 10);
HttpResponse::Ok()
},
- )),
- ))
- .await;
+ ))),
+ )
+ .await;
let req = TestRequest::default().to_request();
let resp = srv.call(req).await.unwrap();
diff --git a/actix-web/src/dev.rs b/actix-web/src/dev.rs
index 5c7adfdaf..2a0791a1c 100644
--- a/actix-web/src/dev.rs
+++ b/actix-web/src/dev.rs
@@ -7,26 +7,25 @@
//! - [`ConnectionInfo`]: Connection information
//! - [`PeerAddr`]: Connection information
+#[cfg(feature = "__compress")]
+pub use actix_http::encoding::Decoder as Decompress;
pub use actix_http::{Extensions, Payload, RequestHead, Response, ResponseHead};
+use actix_router::Patterns;
pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
pub use actix_server::{Server, ServerHandle};
pub use actix_service::{
always_ready, fn_factory, fn_service, forward_ready, Service, ServiceFactory, Transform,
};
-#[cfg(feature = "__compress")]
-pub use actix_http::encoding::Decoder as Decompress;
-
-pub use crate::config::{AppConfig, AppService};
#[doc(hidden)]
pub use crate::handler::Handler;
-pub use crate::info::{ConnectionInfo, PeerAddr};
-pub use crate::rmap::ResourceMap;
-pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService};
-
-pub use crate::types::{JsonBody, Readlines, UrlEncoded};
-
-use actix_router::Patterns;
+pub use crate::{
+ config::{AppConfig, AppService},
+ info::{ConnectionInfo, PeerAddr},
+ rmap::ResourceMap,
+ service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService},
+ types::{JsonBody, Readlines, UrlEncoded},
+};
pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns {
match &mut patterns {
diff --git a/actix-web/src/error/macros.rs b/actix-web/src/error/macros.rs
index 78b1ed9f6..8634557c9 100644
--- a/actix-web/src/error/macros.rs
+++ b/actix-web/src/error/macros.rs
@@ -42,8 +42,7 @@ macro_rules! downcast_dyn {
/// Downcasts generic body to a specific type.
#[allow(dead_code)]
pub fn downcast_ref(&self) -> Option<&T> {
- if self.__private_get_type_id__(PrivateHelper(())).0
- == std::any::TypeId::of::()
+ if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::()
{
// SAFETY: external crates cannot override the default
// implementation of `__private_get_type_id__`, since
@@ -59,8 +58,7 @@ macro_rules! downcast_dyn {
/// Downcasts a generic body to a mutable specific type.
#[allow(dead_code)]
pub fn downcast_mut(&mut self) -> Option<&mut T> {
- if self.__private_get_type_id__(PrivateHelper(())).0
- == std::any::TypeId::of::()
+ if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::()
{
// SAFETY: external crates cannot override the default
// implementation of `__private_get_type_id__`, since
@@ -76,7 +74,8 @@ macro_rules! downcast_dyn {
};
}
-pub(crate) use {downcast_dyn, downcast_get_type_id};
+pub(crate) use downcast_dyn;
+pub(crate) use downcast_get_type_id;
#[cfg(test)]
mod tests {
diff --git a/actix-web/src/error/mod.rs b/actix-web/src/error/mod.rs
index 604c539f3..91a6bcc3f 100644
--- a/actix-web/src/error/mod.rs
+++ b/actix-web/src/error/mod.rs
@@ -5,14 +5,10 @@
// expanded manually.
//
// See
-pub use actix_http::error::{
- ContentTypeError, DispatchError, HttpError, ParseError, PayloadError,
-};
-
+pub use actix_http::error::{ContentTypeError, DispatchError, HttpError, ParseError, PayloadError};
use derive_more::{Display, Error, From};
use serde_json::error::Error as JsonError;
-use serde_urlencoded::de::Error as FormDeError;
-use serde_urlencoded::ser::Error as FormError;
+use serde_urlencoded::{de::Error as FormDeError, ser::Error as FormError};
use url::ParseError as UrlParseError;
use crate::http::StatusCode;
@@ -23,10 +19,8 @@ mod internal;
mod macros;
mod response_error;
-pub use self::error::Error;
-pub use self::internal::*;
-pub use self::response_error::ResponseError;
-pub(crate) use macros::{downcast_dyn, downcast_get_type_id};
+pub(crate) use self::macros::{downcast_dyn, downcast_get_type_id};
+pub use self::{error::Error, internal::*, response_error::ResponseError};
/// A convenience [`Result`](std::result::Result) for Actix Web operations.
///
diff --git a/actix-web/src/extract.rs b/actix-web/src/extract.rs
index 84904a9eb..a2afd3827 100644
--- a/actix-web/src/extract.rs
+++ b/actix-web/src/extract.rs
@@ -429,8 +429,10 @@ mod tests {
use serde::Deserialize;
use super::*;
- use crate::test::TestRequest;
- use crate::types::{Form, FormConfig};
+ use crate::{
+ test::TestRequest,
+ types::{Form, FormConfig},
+ };
#[derive(Deserialize, Debug, PartialEq)]
struct Info {
diff --git a/actix-web/src/guard/mod.rs b/actix-web/src/guard/mod.rs
index a9173a9d1..35294a3c4 100644
--- a/actix-web/src/guard/mod.rs
+++ b/actix-web/src/guard/mod.rs
@@ -51,7 +51,6 @@
use std::{
cell::{Ref, RefMut},
- convert::TryFrom,
rc::Rc,
};
@@ -62,8 +61,10 @@ use crate::{http::header::Header, service::ServiceRequest, HttpMessage as _};
mod acceptable;
mod host;
-pub use self::acceptable::Acceptable;
-pub use self::host::{Host, HostGuard};
+pub use self::{
+ acceptable::Acceptable,
+ host::{Host, HostGuard},
+};
/// Provides access to request parts that are useful during routing.
#[derive(Debug)]
diff --git a/actix-web/src/http/header/accept_encoding.rs b/actix-web/src/http/header/accept_encoding.rs
index 8c35179b6..715126a03 100644
--- a/actix-web/src/http/header/accept_encoding.rs
+++ b/actix-web/src/http/header/accept_encoding.rs
@@ -94,10 +94,7 @@ impl AcceptEncoding {
/// includes the server's supported encodings in the body plus a [`Vary`] header.
///
/// [`Vary`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary
- pub fn negotiate<'a>(
- &self,
- supported: impl Iterator- ,
- ) -> Option {
+ pub fn negotiate<'a>(&self, supported: impl Iterator
- ) -> Option {
// 1. If no Accept-Encoding field is in the request, any content-coding is considered
// acceptable by the user agent.
@@ -375,9 +372,7 @@ mod tests {
Some(Encoding::deflate())
);
assert_eq!(
- test.negotiate(
- [Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()
- ),
+ test.negotiate([Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()),
Some(Encoding::gzip())
);
assert_eq!(
diff --git a/actix-web/src/http/header/content_disposition.rs b/actix-web/src/http/header/content_disposition.rs
index f743302a2..0606f5aef 100644
--- a/actix-web/src/http/header/content_disposition.rs
+++ b/actix-web/src/http/header/content_disposition.rs
@@ -592,9 +592,8 @@ mod tests {
fn test_from_raw_basic() {
assert!(ContentDisposition::from_raw(&HeaderValue::from_static("")).is_err());
- let a = HeaderValue::from_static(
- "form-data; dummy=3; name=upload; filename=\"sample.png\"",
- );
+ let a =
+ HeaderValue::from_static("form-data; dummy=3; name=upload; filename=\"sample.png\"");
let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
let b = ContentDisposition {
disposition: DispositionType::FormData,
@@ -648,8 +647,8 @@ mod tests {
charset: Charset::Ext(String::from("UTF-8")),
language_tag: None,
value: vec![
- 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r',
- b'a', b't', b'e', b's',
+ 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a',
+ b't', b'e', b's',
],
})],
};
@@ -665,8 +664,8 @@ mod tests {
charset: Charset::Ext(String::from("UTF-8")),
language_tag: None,
value: vec![
- 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r',
- b'a', b't', b'e', b's',
+ 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a',
+ b't', b'e', b's',
],
})],
};
@@ -742,8 +741,8 @@ mod tests {
};
assert_eq!(a, b);
- let a = ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param"))
- .unwrap();
+ let a =
+ ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param")).unwrap();
let b = ContentDisposition {
disposition: DispositionType::Ext(String::from("unknown-disp-param")),
parameters: vec![],
@@ -782,8 +781,7 @@ mod tests {
Mainstream browsers like Firefox (gecko) and Chrome use UTF-8 directly as above.
(And now, only UTF-8 is handled by this implementation.)
*/
- let a =
- HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap();
+ let a = HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap();
let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
let b = ContentDisposition {
disposition: DispositionType::FormData,
@@ -803,9 +801,7 @@ mod tests {
disposition: DispositionType::FormData,
parameters: vec![
DispositionParam::Name(String::from("upload")),
- DispositionParam::Filename(String::from(
- "余固知謇謇之為患兮,忍而不能舍也.pptx",
- )),
+ DispositionParam::Filename(String::from("余固知謇謇之為患兮,忍而不能舍也.pptx")),
],
};
assert_eq!(a, b);
@@ -870,8 +866,7 @@ mod tests {
};
assert_eq!(a, b);
- let a =
- HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\"");
+ let a = HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\"");
let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
let b = ContentDisposition {
disposition: DispositionType::FormData,
diff --git a/actix-web/src/http/header/content_range.rs b/actix-web/src/http/header/content_range.rs
index bcbe77e66..8befffd95 100644
--- a/actix-web/src/http/header/content_range.rs
+++ b/actix-web/src/http/header/content_range.rs
@@ -127,8 +127,7 @@ impl FromStr for ContentRangeSpec {
fn from_str(s: &str) -> Result {
let res = match split_in_two(s, ' ') {
Some(("bytes", resp)) => {
- let (range, instance_length) =
- split_in_two(resp, '/').ok_or(ParseError::Header)?;
+ let (range, instance_length) = split_in_two(resp, '/').ok_or(ParseError::Header)?;
let instance_length = if instance_length == "*" {
None
diff --git a/actix-web/src/http/header/content_type.rs b/actix-web/src/http/header/content_type.rs
index 1fc75d0e2..41c0c1fc9 100644
--- a/actix-web/src/http/header/content_type.rs
+++ b/actix-web/src/http/header/content_type.rs
@@ -1,6 +1,7 @@
-use super::CONTENT_TYPE;
use mime::Mime;
+use super::CONTENT_TYPE;
+
crate::http::header::common_header! {
/// `Content-Type` header, defined
/// in [RFC 7231 §3.1.1.5](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5)
diff --git a/actix-web/src/http/header/date.rs b/actix-web/src/http/header/date.rs
index f62740211..a8ac65660 100644
--- a/actix-web/src/http/header/date.rs
+++ b/actix-web/src/http/header/date.rs
@@ -1,6 +1,7 @@
-use super::{HttpDate, DATE};
use std::time::SystemTime;
+use super::{HttpDate, DATE};
+
crate::http::header::common_header! {
/// `Date` header, defined
/// in [RFC 7231 §7.1.1.2](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2)
diff --git a/actix-web/src/http/header/entity.rs b/actix-web/src/http/header/entity.rs
index 0eaa12b5d..a5ef3c5b7 100644
--- a/actix-web/src/http/header/entity.rs
+++ b/actix-web/src/http/header/entity.rs
@@ -152,9 +152,7 @@ impl FromStr for EntityTag {
return Err(crate::error::ParseError::Header);
}
// The etag is weak if its first char is not a DQUOTE.
- if slice.len() >= 2
- && slice.starts_with('"')
- && check_slice_validity(&slice[1..length - 1])
+ if slice.len() >= 2 && slice.starts_with('"') && check_slice_validity(&slice[1..length - 1])
{
// No need to check if the last char is a DQUOTE,
// we already did that above.
diff --git a/actix-web/src/http/header/if_range.rs b/actix-web/src/http/header/if_range.rs
index eb3632a4d..d7375c4c5 100644
--- a/actix-web/src/http/header/if_range.rs
+++ b/actix-web/src/http/header/if_range.rs
@@ -4,9 +4,7 @@ use super::{
from_one_raw_str, EntityTag, Header, HeaderName, HeaderValue, HttpDate, InvalidHeaderValue,
TryIntoHeaderValue, Writer,
};
-use crate::error::ParseError;
-use crate::http::header;
-use crate::HttpMessage;
+use crate::{error::ParseError, http::header, HttpMessage};
/// `If-Range` header, defined
/// in [RFC 7233 §3.2](https://datatracker.ietf.org/doc/html/rfc7233#section-3.2)
diff --git a/actix-web/src/http/header/macros.rs b/actix-web/src/http/header/macros.rs
index b40eca03b..d9755e15e 100644
--- a/actix-web/src/http/header/macros.rs
+++ b/actix-web/src/http/header/macros.rs
@@ -314,7 +314,7 @@ macro_rules! common_header {
};
}
-pub(crate) use {common_header, common_header_test_module};
-
+pub(crate) use common_header;
#[cfg(test)]
pub(crate) use common_header_test;
+pub(crate) use common_header_test_module;
diff --git a/actix-web/src/http/header/mod.rs b/actix-web/src/http/header/mod.rs
index 9807d5f5e..65c5c88a0 100644
--- a/actix-web/src/http/header/mod.rs
+++ b/actix-web/src/http/header/mod.rs
@@ -6,8 +6,6 @@
use std::fmt;
-use bytes::{Bytes, BytesMut};
-
// re-export from actix-http
// - header name / value types
// - relevant traits for converting to header name / value
@@ -16,6 +14,7 @@ use bytes::{Bytes, BytesMut};
// - the few typed headers from actix-http
// - header parsing utils
pub use actix_http::header::*;
+use bytes::{Bytes, BytesMut};
mod accept;
mod accept_charset;
@@ -43,32 +42,33 @@ mod preference;
mod range;
#[cfg(test)]
-pub(crate) use macros::common_header_test;
-pub(crate) use macros::{common_header, common_header_test_module};
-
-pub use self::accept::Accept;
-pub use self::accept_charset::AcceptCharset;
-pub use self::accept_encoding::AcceptEncoding;
-pub use self::accept_language::AcceptLanguage;
-pub use self::allow::Allow;
-pub use self::cache_control::{CacheControl, CacheDirective};
-pub use self::content_disposition::{ContentDisposition, DispositionParam, DispositionType};
-pub use self::content_language::ContentLanguage;
-pub use self::content_range::{ContentRange, ContentRangeSpec};
-pub use self::content_type::ContentType;
-pub use self::date::Date;
-pub use self::encoding::Encoding;
-pub use self::entity::EntityTag;
-pub use self::etag::ETag;
-pub use self::expires::Expires;
-pub use self::if_match::IfMatch;
-pub use self::if_modified_since::IfModifiedSince;
-pub use self::if_none_match::IfNoneMatch;
-pub use self::if_range::IfRange;
-pub use self::if_unmodified_since::IfUnmodifiedSince;
-pub use self::last_modified::LastModified;
-pub use self::preference::Preference;
-pub use self::range::{ByteRangeSpec, Range};
+pub(crate) use self::macros::common_header_test;
+pub(crate) use self::macros::{common_header, common_header_test_module};
+pub use self::{
+ accept::Accept,
+ accept_charset::AcceptCharset,
+ accept_encoding::AcceptEncoding,
+ accept_language::AcceptLanguage,
+ allow::Allow,
+ cache_control::{CacheControl, CacheDirective},
+ content_disposition::{ContentDisposition, DispositionParam, DispositionType},
+ content_language::ContentLanguage,
+ content_range::{ContentRange, ContentRangeSpec},
+ content_type::ContentType,
+ date::Date,
+ encoding::Encoding,
+ entity::EntityTag,
+ etag::ETag,
+ expires::Expires,
+ if_match::IfMatch,
+ if_modified_since::IfModifiedSince,
+ if_none_match::IfNoneMatch,
+ if_range::IfRange,
+ if_unmodified_since::IfUnmodifiedSince,
+ last_modified::LastModified,
+ preference::Preference,
+ range::{ByteRangeSpec, Range},
+};
/// Format writer ([`fmt::Write`]) for a [`BytesMut`].
#[derive(Debug, Default)]
diff --git a/actix-web/src/lib.rs b/actix-web/src/lib.rs
index 57cdaea69..e982a43b1 100644
--- a/actix-web/src/lib.rs
+++ b/actix-web/src/lib.rs
@@ -74,6 +74,11 @@
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+pub use actix_http::{body, HttpMessage};
+#[cfg(feature = "cookies")]
+#[doc(inline)]
+pub use cookie;
+
mod app;
mod app_service;
mod config;
@@ -102,25 +107,21 @@ pub mod test;
pub(crate) mod types;
pub mod web;
-pub use crate::app::App;
#[doc(inline)]
pub use crate::error::Result;
-pub use crate::error::{Error, ResponseError};
-pub use crate::extract::FromRequest;
-pub use crate::handler::Handler;
-pub use crate::request::HttpRequest;
-pub use crate::resource::Resource;
-pub use crate::response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder};
-pub use crate::route::Route;
-pub use crate::scope::Scope;
-pub use crate::server::HttpServer;
-pub use crate::types::Either;
-
-pub use actix_http::{body, HttpMessage};
-
-#[cfg(feature = "cookies")]
-#[doc(inline)]
-pub use cookie;
+pub use crate::{
+ app::App,
+ error::{Error, ResponseError},
+ extract::FromRequest,
+ handler::Handler,
+ request::HttpRequest,
+ resource::Resource,
+ response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder},
+ route::Route,
+ scope::Scope,
+ server::HttpServer,
+ types::Either,
+};
macro_rules! codegen_reexport {
($name:ident) => {
diff --git a/actix-web/src/middleware/compat.rs b/actix-web/src/middleware/compat.rs
index ee8b8a498..7df510a5c 100644
--- a/actix-web/src/middleware/compat.rs
+++ b/actix-web/src/middleware/compat.rs
@@ -146,10 +146,9 @@ mod tests {
// easier to code when cookies feature is disabled
#![allow(unused_imports)]
- use super::*;
-
use actix_service::IntoService;
+ use super::*;
use crate::{
dev::ServiceRequest,
http::StatusCode,
@@ -207,9 +206,9 @@ mod tests {
#[actix_rt::test]
async fn test_condition_scope_middleware() {
let srv = |req: ServiceRequest| {
- Box::pin(async move {
- Ok(req.into_response(HttpResponse::InternalServerError().finish()))
- })
+ Box::pin(
+ async move { Ok(req.into_response(HttpResponse::InternalServerError().finish())) },
+ )
};
let logger = Logger::default();
diff --git a/actix-web/src/middleware/default_headers.rs b/actix-web/src/middleware/default_headers.rs
index 003abd40d..b5a5a6998 100644
--- a/actix-web/src/middleware/default_headers.rs
+++ b/actix-web/src/middleware/default_headers.rs
@@ -1,7 +1,6 @@
//! For middleware documentation, see [`DefaultHeaders`].
use std::{
- convert::TryFrom,
future::Future,
marker::PhantomData,
pin::Pin,
diff --git a/actix-web/src/middleware/err_handlers.rs b/actix-web/src/middleware/err_handlers.rs
index 5522cc021..e640bba08 100644
--- a/actix-web/src/middleware/err_handlers.rs
+++ b/actix-web/src/middleware/err_handlers.rs
@@ -270,8 +270,8 @@ impl ErrorHandlers {
handlers
.get(status)
.map(|h| h.as_ref())
- .or_else(|| status.is_client_error().then(|| default_client).flatten())
- .or_else(|| status.is_server_error().then(|| default_server).flatten())
+ .or_else(|| status.is_client_error().then_some(default_client).flatten())
+ .or_else(|| status.is_server_error().then_some(default_server).flatten())
}
}
@@ -540,21 +540,17 @@ mod tests {
let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await;
let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
- let resp =
- test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
+ let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
- let resp =
- test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
+ let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
}
#[actix_rt::test]
async fn default_handlers_separate_client_server() {
#[allow(clippy::unnecessary_wraps)]
- fn error_handler_client(
- mut res: ServiceResponse,
- ) -> Result> {
+ fn error_handler_client(mut res: ServiceResponse) -> Result> {
res.response_mut()
.headers_mut()
.insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
@@ -562,9 +558,7 @@ mod tests {
}
#[allow(clippy::unnecessary_wraps)]
- fn error_handler_server(
- mut res: ServiceResponse,
- ) -> Result> {
+ fn error_handler_server(mut res: ServiceResponse) -> Result> {
res.response_mut()
.headers_mut()
.insert(CONTENT_TYPE, HeaderValue::from_static("0002"));
@@ -582,21 +576,17 @@ mod tests {
let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await;
let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
- let resp =
- test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
+ let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
- let resp =
- test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
+ let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
}
#[actix_rt::test]
async fn default_handlers_specialization() {
#[allow(clippy::unnecessary_wraps)]
- fn error_handler_client(
- mut res: ServiceResponse,
- ) -> Result> {
+ fn error_handler_client(mut res: ServiceResponse) -> Result> {
res.response_mut()
.headers_mut()
.insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
@@ -624,12 +614,10 @@ mod tests {
let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
let mw_specific = make_mw(StatusCode::UNPROCESSABLE_ENTITY).await;
- let resp =
- test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
+ let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
- let resp =
- test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await;
+ let resp = test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0003");
}
}
diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs
index 5fec5a013..06d26617a 100644
--- a/actix-web/src/middleware/logger.rs
+++ b/actix-web/src/middleware/logger.rs
@@ -3,7 +3,6 @@
use std::{
borrow::Cow,
collections::HashSet,
- convert::TryFrom,
env,
fmt::{self, Display as _},
future::Future,
@@ -490,12 +489,8 @@ impl Format {
unreachable!("regex and code mismatch")
}
}
- "i" => {
- FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap())
- }
- "o" => {
- FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap())
- }
+ "i" => FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap()),
+ "o" => FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap()),
"e" => FormatText::EnvironHeader(key.as_str().to_owned()),
"xi" => FormatText::CustomRequest(key.as_str().to_owned(), None),
"xo" => FormatText::CustomResponse(key.as_str().to_owned(), None),
@@ -711,9 +706,7 @@ impl FormatText {
}
/// 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<'a> fmt::Display for FormatDisplay<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
diff --git a/actix-web/src/middleware/mod.rs b/actix-web/src/middleware/mod.rs
index 0a61ad6cb..8dbd1ff2c 100644
--- a/actix-web/src/middleware/mod.rs
+++ b/actix-web/src/middleware/mod.rs
@@ -1,4 +1,221 @@
//! A collection of common middleware.
+//!
+//! # What Is Middleware?
+//!
+//! Actix Web's middleware system allows us to add additional behavior to request/response
+//! processing. Middleware can hook into incoming request and outgoing response processes, enabling
+//! us to modify requests and responses as well as halt request processing to return a response
+//! early.
+//!
+//! Typically, middleware is involved in the following actions:
+//!
+//! - Pre-process the request (e.g., [normalizing paths](NormalizePath))
+//! - Post-process a response (e.g., [logging][Logger])
+//! - Modify application state (through [`ServiceRequest`][crate::dev::ServiceRequest])
+//! - Access external services (e.g., [sessions](https://docs.rs/actix-session), etc.)
+//!
+//! Middleware is registered for each [`App`], [`Scope`](crate::Scope), or
+//! [`Resource`](crate::Resource) and executed in opposite order as registration. In general, a
+//! middleware is a pair of types that implements the [`Service`] trait and [`Transform`] trait,
+//! respectively. The [`new_transform`] and [`call`] methods must return a [`Future`], though it
+//! can often be [an immediately-ready one](actix_utils::future::Ready).
+//!
+//! # Ordering
+//!
+//! ```
+//! # use actix_web::{web, middleware, get, App, Responder};
+//! #
+//! # // some basic types to make sure this compiles
+//! # type ExtractorA = web::Json;
+//! # type ExtractorB = ExtractorA;
+//! #[get("/")]
+//! async fn service(a: ExtractorA, b: ExtractorB) -> impl Responder { "Hello, World!" }
+//!
+//! # fn main() {
+//! # // These aren't snake_case, because they are supposed to be unit structs.
+//! # let MiddlewareA = middleware::Compress::default();
+//! # let MiddlewareB = middleware::Compress::default();
+//! # let MiddlewareC = middleware::Compress::default();
+//! let app = App::new()
+//! .wrap(MiddlewareA)
+//! .wrap(MiddlewareB)
+//! .wrap(MiddlewareC)
+//! .service(service);
+//! # }
+//! ```
+//!
+//! ```plain
+//! Request
+//! ⭣
+//! ╭────────────────────┼────╮
+//! │ MiddlewareC │ │
+//! │ ╭──────────────────┼───╮│
+//! │ │ MiddlewareB │ ││
+//! │ │ ╭────────────────┼──╮││
+//! │ │ │ MiddlewareA │ │││
+//! │ │ │ ╭──────────────┼─╮│││
+//! │ │ │ │ ExtractorA │ ││││
+//! │ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││
+//! │ │ │ │ ExtractorB │ ││││
+//! │ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││
+//! │ │ │ │ service │ ││││
+//! │ │ │ ╰──────────────┼─╯│││
+//! │ │ ╰────────────────┼──╯││
+//! │ ╰──────────────────┼───╯│
+//! ╰────────────────────┼────╯
+//! ⭣
+//! Response
+//! ```
+//! The request _first_ gets processed by the middleware specified _last_ - `MiddlewareC`. It passes
+//! the request (modified a modified one) to the next middleware - `MiddlewareB` - _or_ directly
+//! responds to the request (e.g. when the request was invalid or an error occurred). `MiddlewareB`
+//! processes the request as well and passes it to `MiddlewareA`, which then passes it to the
+//! [`Service`]. In the [`Service`], the extractors will run first. They don't pass the request on,
+//! but only view it (see [`FromRequest`]). After the [`Service`] responds to the request, the
+//! response it passed back through `MiddlewareA`, `MiddlewareB`, and `MiddlewareC`.
+//!
+//! As you register middleware using [`wrap`][crate::App::wrap] and [`wrap_fn`][crate::App::wrap_fn]
+//! in the [`App`] builder, imagine wrapping layers around an inner [`App`]. The first middleware
+//! layer exposed to a Request is the outermost layer (i.e., the _last_ registered in the builder
+//! chain, in the example above: `MiddlewareC`). Consequently, the _first_ middleware registered in
+//! the builder chain is the _last_ to start executing during request processing (`MiddlewareA`).
+//! Ordering is less obvious when wrapped services also have middleware applied. In this case,
+//! middleware are run in reverse order for [`App`] _and then_ in reverse order for the wrapped
+//! service.
+//!
+//! # Middleware Traits
+//!
+//! ## `Transform
`
+//!
+//! The [`Transform`] trait is the builder for the actual [`Service`]s that handle the requests. All
+//! the middleware you pass to the `wrap` methods implement this trait. During construction, each
+//! thread assembles a chain of [`Service`]s by calling [`new_transform`] and passing the next
+//! [`Service`] (`S`) in the chain. The created [`Service`] handles requests of type `Req`.
+//!
+//! In the example from the [ordering](#ordering) section, the chain would be:
+//!
+//! ```plain
+//! MiddlewareCService {
+//! next: MiddlewareBService {
+//! next: MiddlewareAService { ... }
+//! }
+//! }
+//! ```
+//!
+//! ## `Service`
+//!
+//! A [`Service`] `S` represents an asynchronous operation that turns a request of type `Req` into a
+//! response of type [`S::Response`](crate::dev::Service::Response) or an error of type
+//! [`S::Error`](crate::dev::Service::Error). You can think of the service of being roughly:
+//!
+//! ```ignore
+//! async fn(&self, req: Req) -> Result
+//! ```
+//!
+//! In most cases the [`Service`] implementation will, at some point, call the wrapped [`Service`]
+//! in its [`call`] implementation.
+//!
+//! Note that the [`Service`]s created by [`new_transform`] don't need to be [`Send`] or [`Sync`].
+//!
+//! # Example
+//!
+//! ```
+//! use std::{future::{ready, Ready, Future}, pin::Pin};
+//!
+//! use actix_web::{
+//! dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
+//! web, Error,
+//! # App
+//! };
+//!
+//! pub struct SayHi;
+//!
+//! // `S` - type of the next service
+//! // `B` - type of response's body
+//! impl Transform for SayHi
+//! where
+//! S: Service, Error = Error>,
+//! S::Future: 'static,
+//! B: 'static,
+//! {
+//! type Response = ServiceResponse;
+//! type Error = Error;
+//! type InitError = ();
+//! type Transform = SayHiMiddleware;
+//! type Future = Ready>;
+//!
+//! fn new_transform(&self, service: S) -> Self::Future {
+//! ready(Ok(SayHiMiddleware { service }))
+//! }
+//! }
+//!
+//! pub struct SayHiMiddleware {
+//! /// The next service to call
+//! service: S,
+//! }
+//!
+//! // This future doesn't have the requirement of being `Send`.
+//! // See: futures_util::future::LocalBoxFuture
+//! type LocalBoxFuture = Pin + 'static>>;
+//!
+//! // `S`: type of the wrapped service
+//! // `B`: type of the body - try to be generic over the body where possible
+//! impl Service for SayHiMiddleware
+//! where
+//! S: Service, Error = Error>,
+//! S::Future: 'static,
+//! B: 'static,
+//! {
+//! type Response = ServiceResponse;
+//! type Error = Error;
+//! type Future = LocalBoxFuture>;
+//!
+//! // This service is ready when its next service is ready
+//! forward_ready!(service);
+//!
+//! fn call(&self, req: ServiceRequest) -> Self::Future {
+//! println!("Hi from start. You requested: {}", req.path());
+//!
+//! // A more complex middleware, could return an error or an early response here.
+//!
+//! let fut = self.service.call(req);
+//!
+//! Box::pin(async move {
+//! let res = fut.await?;
+//!
+//! println!("Hi from response");
+//! Ok(res)
+//! })
+//! }
+//! }
+//!
+//! # fn main() {
+//! let app = App::new()
+//! .wrap(SayHi)
+//! .route("/", web::get().to(|| async { "Hello, middleware!" }));
+//! # }
+//! ```
+//!
+//! # Simpler Middleware
+//!
+//! In many cases, you _can_ actually use an async function via a helper that will provide a more
+//! natural flow for your behavior.
+//!
+//! The experimental `actix_web_lab` crate provides a [`from_fn`][lab_from_fn] utility which allows
+//! an async fn to be wrapped and used in the same way as other middleware. See the
+//! [`from_fn`][lab_from_fn] docs for more info and examples of it's use.
+//!
+//! While [`from_fn`][lab_from_fn] is experimental currently, it's likely this helper will graduate
+//! to Actix Web in some form, so feedback is appreciated.
+//!
+//! [`Future`]: std::future::Future
+//! [`App`]: crate::App
+//! [`FromRequest`]: crate::FromRequest
+//! [`Service`]: crate::dev::Service
+//! [`Transform`]: crate::dev::Transform
+//! [`call`]: crate::dev::Service::call()
+//! [`new_transform`]: crate::dev::Transform::new_transform()
+//! [lab_from_fn]: https://docs.rs/actix-web-lab/latest/actix_web_lab/middleware/fn.from_fn.html
mod compat;
mod condition;
@@ -9,14 +226,16 @@ mod logger;
mod noop;
mod normalize;
-pub use self::compat::Compat;
-pub use self::condition::Condition;
-pub use self::default_headers::DefaultHeaders;
-pub use self::err_handlers::{ErrorHandlerResponse, ErrorHandlers};
-pub use self::logger::Logger;
#[cfg(test)]
pub(crate) use self::noop::Noop;
-pub use self::normalize::{NormalizePath, TrailingSlash};
+pub use self::{
+ compat::Compat,
+ condition::Condition,
+ default_headers::DefaultHeaders,
+ err_handlers::{ErrorHandlerResponse, ErrorHandlers},
+ logger::Logger,
+ normalize::{NormalizePath, TrailingSlash},
+};
#[cfg(feature = "__compress")]
mod compress;
@@ -26,9 +245,8 @@ pub use self::compress::Compress;
#[cfg(test)]
mod tests {
- use crate::{http::StatusCode, App};
-
use super::*;
+ use crate::{http::StatusCode, App};
#[test]
fn common_combinations() {
diff --git a/actix-web/src/middleware/normalize.rs b/actix-web/src/middleware/normalize.rs
index 3ab908481..afcc0faac 100644
--- a/actix-web/src/middleware/normalize.rs
+++ b/actix-web/src/middleware/normalize.rs
@@ -15,11 +15,12 @@ use crate::{
///
/// The default is `TrailingSlash::Trim`.
#[non_exhaustive]
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, Default)]
pub enum TrailingSlash {
/// Trim trailing slashes from the end of the path.
///
/// Using this will require all routes to omit trailing slashes for them to be accessible.
+ #[default]
Trim,
/// Only merge any present multiple trailing slashes.
@@ -33,12 +34,6 @@ pub enum TrailingSlash {
Always,
}
-impl Default for TrailingSlash {
- fn default() -> Self {
- TrailingSlash::Trim
- }
-}
-
/// Middleware for normalizing a request's path so that routes can be matched more flexibly.
///
/// # Normalization Steps
diff --git a/actix-web/src/redirect.rs b/actix-web/src/redirect.rs
index 5611cc368..f9e9f2d7a 100644
--- a/actix-web/src/redirect.rs
+++ b/actix-web/src/redirect.rs
@@ -181,9 +181,8 @@ impl Responder for Redirect {
#[cfg(test)]
mod tests {
- use crate::{dev::Service, http::StatusCode, test, App};
-
use super::*;
+ use crate::{dev::Service, http::StatusCode, test, App};
#[actix_rt::test]
async fn absolute_redirects() {
diff --git a/actix-web/src/request.rs b/actix-web/src/request.rs
index c5fb24857..d563afe29 100644
--- a/actix-web/src/request.rs
+++ b/actix-web/src/request.rs
@@ -661,13 +661,13 @@ mod tests {
#[actix_rt::test]
async fn test_drop_http_request_pool() {
- let srv = init_service(App::new().service(web::resource("/").to(
- |req: HttpRequest| {
+ let srv = init_service(
+ App::new().service(web::resource("/").to(|req: HttpRequest| {
HttpResponse::Ok()
.insert_header(("pool_cap", req.app_state().pool().cap))
.finish()
- },
- )))
+ })),
+ )
.await;
let req = TestRequest::default().to_request();
@@ -815,10 +815,7 @@ mod tests {
web::scope("/user/{id}")
.service(web::resource("/profile").route(web::get().to(
move |req: HttpRequest| {
- assert_eq!(
- req.match_pattern(),
- Some("/user/{id}/profile".to_owned())
- );
+ assert_eq!(req.match_pattern(), Some("/user/{id}/profile".to_owned()));
HttpResponse::Ok().finish()
},
diff --git a/actix-web/src/request_data.rs b/actix-web/src/request_data.rs
index 719e6551f..bffbf74da 100644
--- a/actix-web/src/request_data.rs
+++ b/actix-web/src/request_data.rs
@@ -27,7 +27,6 @@ use crate::{
/// # Examples
/// ```no_run
/// # use actix_web::{web, HttpResponse, HttpRequest, Responder, HttpMessage as _};
-///
/// #[derive(Debug, Clone, PartialEq)]
/// struct FlagFromMiddleware(String);
///
diff --git a/actix-web/src/resource.rs b/actix-web/src/resource.rs
index 5d2c9706a..95185b80a 100644
--- a/actix-web/src/resource.rs
+++ b/actix-web/src/resource.rs
@@ -353,12 +353,8 @@ where
pub fn default_service(mut self, f: F) -> Self
where
F: IntoServiceFactory,
- U: ServiceFactory<
- ServiceRequest,
- Config = (),
- Response = ServiceResponse,
- Error = Error,
- > + 'static,
+ U: ServiceFactory
+ + 'static,
U::InitError: fmt::Debug,
{
// create and configure default resource
@@ -625,10 +621,8 @@ mod tests {
let fut = srv.call(req);
async {
fut.await.map(|mut res| {
- res.headers_mut().insert(
- header::CONTENT_TYPE,
- HeaderValue::from_static("0001"),
- );
+ res.headers_mut()
+ .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
res
})
}
@@ -660,12 +654,9 @@ mod tests {
#[actix_rt::test]
async fn test_pattern() {
- let srv = init_service(
- App::new().service(
- web::resource(["/test", "/test2"])
- .to(|| async { Ok::<_, Error>(HttpResponse::Ok()) }),
- ),
- )
+ let srv = init_service(App::new().service(
+ web::resource(["/test", "/test2"]).to(|| async { Ok::<_, Error>(HttpResponse::Ok()) }),
+ ))
.await;
let req = TestRequest::with_uri("/test").to_request();
let resp = call_service(&srv, req).await;
@@ -804,17 +795,18 @@ mod tests {
#[allow(deprecated)]
#[actix_rt::test]
async fn test_data_default_service() {
- let srv = init_service(
- App::new().data(1usize).service(
- web::resource("/test")
- .data(10usize)
- .default_service(web::to(|data: web::Data| {
- assert_eq!(**data, 10);
- HttpResponse::Ok()
- })),
- ),
- )
- .await;
+ let srv =
+ init_service(
+ App::new().data(1usize).service(
+ web::resource("/test")
+ .data(10usize)
+ .default_service(web::to(|data: web::Data| {
+ assert_eq!(**data, 10);
+ HttpResponse::Ok()
+ })),
+ ),
+ )
+ .await;
let req = TestRequest::get().uri("/test").to_request();
let resp = call_service(&srv, req).await;
diff --git a/actix-web/src/response/builder.rs b/actix-web/src/response/builder.rs
index 120d4c358..2c06941cd 100644
--- a/actix-web/src/response/builder.rs
+++ b/actix-web/src/response/builder.rs
@@ -1,6 +1,5 @@
use std::{
cell::{Ref, RefMut},
- convert::TryInto,
future::Future,
pin::Pin,
task::{Context, Poll},
@@ -15,8 +14,10 @@ use crate::{
body::{BodyStream, BoxBody, MessageBody},
dev::Extensions,
error::{Error, JsonPayloadError},
- http::header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue},
- http::{ConnectionType, StatusCode},
+ http::{
+ header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue},
+ ConnectionType, StatusCode,
+ },
BoxError, HttpRequest, HttpResponse, Responder,
};
@@ -473,9 +474,8 @@ mod tests {
#[actix_rt::test]
async fn test_serde_json_in_body() {
- let resp = HttpResponse::Ok().body(
- serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap(),
- );
+ let resp = HttpResponse::Ok()
+ .body(serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap());
assert_eq!(
body::to_bytes(resp.into_body()).await.unwrap().as_ref(),
diff --git a/actix-web/src/response/customize_responder.rs b/actix-web/src/response/customize_responder.rs
index f6f4b9236..aad0039e0 100644
--- a/actix-web/src/response/customize_responder.rs
+++ b/actix-web/src/response/customize_responder.rs
@@ -1,5 +1,7 @@
use actix_http::{
- body::EitherBody, error::HttpError, header::HeaderMap, header::TryIntoHeaderPair,
+ body::EitherBody,
+ error::HttpError,
+ header::{HeaderMap, TryIntoHeaderPair},
StatusCode,
};
@@ -168,9 +170,8 @@ where
#[cfg(test)]
mod tests {
- use bytes::Bytes;
-
use actix_http::body::to_bytes;
+ use bytes::Bytes;
use super::*;
use crate::{
diff --git a/actix-web/src/response/http_codes.rs b/actix-web/src/response/http_codes.rs
index 986735346..2ac83046a 100644
--- a/actix-web/src/response/http_codes.rs
+++ b/actix-web/src/response/http_codes.rs
@@ -87,8 +87,7 @@ impl HttpResponse {
#[cfg(test)]
mod tests {
- use crate::http::StatusCode;
- use crate::HttpResponse;
+ use crate::{http::StatusCode, HttpResponse};
#[test]
fn test_build() {
diff --git a/actix-web/src/response/mod.rs b/actix-web/src/response/mod.rs
index 977147104..11fd28301 100644
--- a/actix-web/src/response/mod.rs
+++ b/actix-web/src/response/mod.rs
@@ -5,10 +5,9 @@ mod responder;
#[allow(clippy::module_inception)]
mod response;
-pub use self::builder::HttpResponseBuilder;
-pub use self::customize_responder::CustomizeResponder;
-pub use self::responder::Responder;
-pub use self::response::HttpResponse;
-
#[cfg(feature = "cookies")]
pub use self::response::CookieIter;
+pub use self::{
+ builder::HttpResponseBuilder, customize_responder::CustomizeResponder, responder::Responder,
+ response::HttpResponse,
+};
diff --git a/actix-web/src/response/responder.rs b/actix-web/src/response/responder.rs
index 965163a1f..7d0b0e585 100644
--- a/actix-web/src/response/responder.rs
+++ b/actix-web/src/response/responder.rs
@@ -186,11 +186,10 @@ impl_into_string_responder!(Cow<'_, str>);
#[cfg(test)]
pub(crate) mod tests {
+ use actix_http::body::to_bytes;
use actix_service::Service;
use bytes::{Bytes, BytesMut};
- use actix_http::body::to_bytes;
-
use super::*;
use crate::{
error,
diff --git a/actix-web/src/response/response.rs b/actix-web/src/response/response.rs
index ead8badba..fbd87e10c 100644
--- a/actix-web/src/response/response.rs
+++ b/actix-web/src/response/response.rs
@@ -8,7 +8,6 @@ use actix_http::{
header::HeaderMap,
Extensions, Response, ResponseHead, StatusCode,
};
-
#[cfg(feature = "cookies")]
use {
actix_http::{
diff --git a/actix-web/src/rmap.rs b/actix-web/src/rmap.rs
index 6e10717c3..462f3b313 100644
--- a/actix-web/src/rmap.rs
+++ b/actix-web/src/rmap.rs
@@ -81,7 +81,7 @@ impl ResourceMap {
"`pattern` and `nested` mismatch"
);
// parents absorb references to the named resources of children
- self.named.extend(new_node.named.clone().into_iter());
+ self.named.extend(new_node.named.clone());
self.nodes.as_mut().unwrap().push(new_node);
} else {
let new_node = Rc::new(ResourceMap {
@@ -136,7 +136,7 @@ impl ResourceMap {
.root_rmap_fn(String::with_capacity(AVG_PATH_LEN), |mut acc, node| {
node.pattern
.resource_path_from_iter(&mut acc, &mut elements)
- .then(|| acc)
+ .then_some(acc)
})
.ok_or(UrlGenerationError::NotEnoughElements)?;
@@ -149,7 +149,7 @@ impl ResourceMap {
// external resource; third slash would be the root slash in the path
let third_slash_index = path
.char_indices()
- .filter_map(|(i, c)| (c == '/').then(|| i))
+ .filter_map(|(i, c)| (c == '/').then_some(i))
.nth(2)
.unwrap_or(path.len());
diff --git a/actix-web/src/route.rs b/actix-web/src/route.rs
index b37128f2c..674d0082a 100644
--- a/actix-web/src/route.rs
+++ b/actix-web/src/route.rs
@@ -290,31 +290,32 @@ mod tests {
#[actix_rt::test]
async fn test_route() {
- let srv = init_service(
- App::new()
- .service(
- web::resource("/test")
- .route(web::get().to(HttpResponse::Ok))
- .route(web::put().to(|| async {
- Err::(error::ErrorBadRequest("err"))
- }))
- .route(web::post().to(|| async {
- sleep(Duration::from_millis(100)).await;
- Ok::<_, Infallible>(HttpResponse::Created())
- }))
- .route(web::delete().to(|| async {
- sleep(Duration::from_millis(100)).await;
- Err::(error::ErrorBadRequest("err"))
- })),
- )
- .service(web::resource("/json").route(web::get().to(|| async {
- sleep(Duration::from_millis(25)).await;
- web::Json(MyObject {
- name: "test".to_string(),
- })
- }))),
- )
- .await;
+ let srv =
+ init_service(
+ App::new()
+ .service(
+ web::resource("/test")
+ .route(web::get().to(HttpResponse::Ok))
+ .route(web::put().to(|| async {
+ Err::(error::ErrorBadRequest("err"))
+ }))
+ .route(web::post().to(|| async {
+ sleep(Duration::from_millis(100)).await;
+ Ok::<_, Infallible>(HttpResponse::Created())
+ }))
+ .route(web::delete().to(|| async {
+ sleep(Duration::from_millis(100)).await;
+ Err::(error::ErrorBadRequest("err"))
+ })),
+ )
+ .service(web::resource("/json").route(web::get().to(|| async {
+ sleep(Duration::from_millis(25)).await;
+ web::Json(MyObject {
+ name: "test".to_string(),
+ })
+ }))),
+ )
+ .await;
let req = TestRequest::with_uri("/test")
.method(Method::GET)
diff --git a/actix-web/src/rt.rs b/actix-web/src/rt.rs
index 7973da73c..629ffe3a0 100644
--- a/actix-web/src/rt.rs
+++ b/actix-web/src/rt.rs
@@ -66,8 +66,7 @@
// - Re-export but hide the runtime macros because they won't work directly but are required for
// `#[actix_web::main]` and `#[actix_web::test]` to work.
-pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner};
-
#[cfg(feature = "macros")]
#[doc(hidden)]
pub use actix_macros::{main, test};
+pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner};
diff --git a/actix-web/src/scope.rs b/actix-web/src/scope.rs
index 9af05674b..e7c4e047a 100644
--- a/actix-web/src/scope.rs
+++ b/actix-web/src/scope.rs
@@ -3,8 +3,8 @@ use std::{cell::RefCell, fmt, future::Future, mem, rc::Rc};
use actix_http::{body::MessageBody, Extensions};
use actix_router::{ResourceDef, Router};
use actix_service::{
- apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory,
- ServiceFactoryExt, Transform,
+ apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt,
+ Transform,
};
use futures_core::future::LocalBoxFuture;
use futures_util::future::join_all;
@@ -273,12 +273,8 @@ where
pub fn default_service(mut self, f: F) -> Self
where
F: IntoServiceFactory,
- U: ServiceFactory<
- ServiceRequest,
- Config = (),
- Response = ServiceResponse,
- Error = Error,
- > + 'static,
+ U: ServiceFactory
+ + 'static,
U::InitError: fmt::Debug,
{
// create and configure default resource
@@ -604,11 +600,11 @@ mod tests {
#[actix_rt::test]
async fn test_scope() {
- let srv =
- init_service(App::new().service(
- web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok)),
- ))
- .await;
+ let srv = init_service(
+ App::new()
+ .service(web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok))),
+ )
+ .await;
let req = TestRequest::with_uri("/app/path1").to_request();
let resp = srv.call(req).await.unwrap();
@@ -638,8 +634,7 @@ mod tests {
#[actix_rt::test]
async fn test_scope_root2() {
let srv = init_service(
- App::new()
- .service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))),
+ App::new().service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))),
)
.await;
@@ -784,10 +779,11 @@ mod tests {
#[actix_rt::test]
async fn test_nested_scope_no_slash() {
- let srv = init_service(App::new().service(web::scope("/app").service(
- web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)),
- )))
- .await;
+ let srv =
+ init_service(App::new().service(web::scope("/app").service(
+ web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)),
+ )))
+ .await;
let req = TestRequest::with_uri("/app/t1/path1").to_request();
let resp = srv.call(req).await.unwrap();
@@ -845,12 +841,9 @@ mod tests {
#[actix_rt::test]
async fn test_nested_scope_with_variable_segment() {
let srv = init_service(App::new().service(web::scope("/app").service(
- web::scope("/{project_id}").service(web::resource("/path1").to(
- |r: HttpRequest| {
- HttpResponse::Created()
- .body(format!("project: {}", &r.match_info()["project_id"]))
- },
- )),
+ web::scope("/{project_id}").service(web::resource("/path1").to(|r: HttpRequest| {
+ HttpResponse::Created().body(format!("project: {}", &r.match_info()["project_id"]))
+ })),
)))
.await;
@@ -1065,15 +1058,16 @@ mod tests {
#[allow(deprecated)]
#[actix_rt::test]
async fn test_override_data_default_service() {
- let srv = init_service(App::new().data(1usize).service(
- web::scope("app").data(10usize).default_service(web::to(
- |data: web::Data| {
- assert_eq!(**data, 10);
- HttpResponse::Ok()
- },
- )),
- ))
- .await;
+ let srv =
+ init_service(App::new().data(1usize).service(
+ web::scope("app").data(10usize).default_service(web::to(
+ |data: web::Data| {
+ assert_eq!(**data, 10);
+ HttpResponse::Ok()
+ },
+ )),
+ ))
+ .await;
let req = TestRequest::with_uri("/app/t").to_request();
let resp = call_service(&srv, req).await;
@@ -1150,11 +1144,11 @@ mod tests {
#[actix_rt::test]
async fn test_url_for_nested() {
let srv = init_service(App::new().service(web::scope("/a").service(
- web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(
- web::get().to(|req: HttpRequest| {
+ web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(web::get().to(
+ |req: HttpRequest| {
HttpResponse::Ok().body(format!("{}", req.url_for("c", ["12345"]).unwrap()))
- }),
- )),
+ },
+ ))),
)))
.await;
diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs
index c11d0ef53..a540da7c8 100644
--- a/actix-web/src/server.rs
+++ b/actix-web/src/server.rs
@@ -7,20 +7,18 @@ use std::{
time::Duration,
};
+#[cfg(any(feature = "openssl", feature = "rustls"))]
+use actix_http::TlsAcceptorConfig;
use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
use actix_server::{Server, ServerBuilder};
use actix_service::{
map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
};
-
#[cfg(feature = "openssl")]
use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder};
#[cfg(feature = "rustls")]
use actix_tls::accept::rustls::reexports::ServerConfig as RustlsServerConfig;
-#[cfg(any(feature = "openssl", feature = "rustls"))]
-use actix_http::TlsAcceptorConfig;
-
use crate::{config::AppConfig, Error};
struct Socket {
@@ -358,6 +356,7 @@ where
/// Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x
/// or HTTP/2 connections.
+ #[cfg(feature = "http2")]
pub fn bind_auto_h2c(mut self, addrs: A) -> io::Result {
let sockets = bind_addrs(addrs, self.backlog)?;
@@ -437,9 +436,8 @@ where
.local_addr(addr);
if let Some(handler) = on_connect_fn.clone() {
- svc = svc.on_connect_ext(move |io: &_, ext: _| {
- (handler)(io as &dyn Any, ext)
- })
+ svc =
+ svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
};
let fac = factory()
@@ -456,6 +454,7 @@ where
}
/// Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections.
+ #[cfg(feature = "http2")]
pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result {
let cfg = self.config.clone();
let factory = self.factory.clone();
@@ -481,9 +480,8 @@ where
.local_addr(addr);
if let Some(handler) = on_connect_fn.clone() {
- svc = svc.on_connect_ext(move |io: &_, ext: _| {
- (handler)(io as &dyn Any, ext)
- })
+ svc =
+ svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
};
let fac = factory()
@@ -715,8 +713,7 @@ where
.client_disconnect_timeout(c.client_disconnect_timeout);
if let Some(handler) = on_connect_fn.clone() {
- svc = svc
- .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
+ svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
}
let fac = factory()
@@ -759,10 +756,7 @@ where
}
/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
-fn bind_addrs(
- addrs: impl net::ToSocketAddrs,
- backlog: u32,
-) -> io::Result> {
+fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result> {
let mut err = None;
let mut success = false;
let mut sockets = Vec::new();
diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs
index f7692ce16..0e17c9949 100644
--- a/actix-web/src/service.rs
+++ b/actix-web/src/service.rs
@@ -696,30 +696,36 @@ service_tuple! { A B C D E F G H I J K L }
#[cfg(test)]
mod tests {
- use super::*;
- use crate::test::{self, init_service, TestRequest};
- use crate::{guard, http, web, App, HttpResponse};
use actix_service::Service;
use actix_utils::future::ok;
+ use super::*;
+ use crate::{
+ guard, http,
+ test::{self, init_service, TestRequest},
+ web, App, HttpResponse,
+ };
+
#[actix_rt::test]
async fn test_service() {
- let srv = init_service(
- App::new().service(web::service("/test").name("test").finish(
- |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
- )),
- )
- .await;
+ let srv =
+ init_service(
+ App::new().service(web::service("/test").name("test").finish(
+ |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
+ )),
+ )
+ .await;
let req = TestRequest::with_uri("/test").to_request();
let resp = srv.call(req).await.unwrap();
assert_eq!(resp.status(), http::StatusCode::OK);
- let srv = init_service(
- App::new().service(web::service("/test").guard(guard::Get()).finish(
- |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
- )),
- )
- .await;
+ let srv =
+ init_service(
+ App::new().service(web::service("/test").guard(guard::Get()).finish(
+ |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
+ )),
+ )
+ .await;
let req = TestRequest::with_uri("/test")
.method(http::Method::PUT)
.to_request();
@@ -731,18 +737,19 @@ mod tests {
#[allow(deprecated)]
#[actix_rt::test]
async fn test_service_data() {
- let srv =
- init_service(
- App::new()
- .data(42u32)
- .service(web::service("/test").name("test").finish(
- |req: ServiceRequest| {
+ let srv = init_service(
+ App::new()
+ .data(42u32)
+ .service(
+ web::service("/test")
+ .name("test")
+ .finish(|req: ServiceRequest| {
assert_eq!(req.app_data::>().unwrap().as_ref(), &42);
ok(req.into_response(HttpResponse::Ok().finish()))
- },
- )),
- )
- .await;
+ }),
+ ),
+ )
+ .await;
let req = TestRequest::with_uri("/test").to_request();
let resp = srv.call(req).await.unwrap();
assert_eq!(resp.status(), http::StatusCode::OK);
@@ -773,9 +780,7 @@ mod tests {
async fn test_services_macro() {
let scoped = services![
web::service("/scoped_test1").name("scoped_test1").finish(
- |req: ServiceRequest| async {
- Ok(req.into_response(HttpResponse::Ok().finish()))
- }
+ |req: ServiceRequest| async { Ok(req.into_response(HttpResponse::Ok().finish())) }
),
web::resource("/scoped_test2").to(|| async { "test2" }),
];
@@ -861,9 +866,7 @@ mod tests {
svc.call(req)
})
.route("/", web::get().to(|| async { "" }))
- .service(
- web::resource("/resource1/{name}/index.html").route(web::get().to(index)),
- ),
+ .service(web::resource("/resource1/{name}/index.html").route(web::get().to(index))),
)
.await;
diff --git a/actix-web/src/test/mod.rs b/actix-web/src/test/mod.rs
index 5d9367b82..5e647956b 100644
--- a/actix-web/src/test/mod.rs
+++ b/actix-web/src/test/mod.rs
@@ -29,18 +29,20 @@ mod test_request;
mod test_services;
mod test_utils;
-pub use self::test_request::TestRequest;
#[allow(deprecated)]
pub use self::test_services::{default_service, ok_service, simple_service, status_service};
-#[allow(deprecated)]
-pub use self::test_utils::{
- call_and_read_body, call_and_read_body_json, call_service, init_service, read_body,
- read_body_json, read_response, read_response_json, try_call_and_read_body_json,
- try_call_service, try_read_body, try_read_body_json,
-};
-
#[cfg(test)]
pub(crate) use self::test_utils::try_init_service;
+#[allow(deprecated)]
+pub use self::test_utils::{read_response, read_response_json};
+pub use self::{
+ test_request::TestRequest,
+ test_utils::{
+ call_and_read_body, call_and_read_body_json, call_service, init_service, read_body,
+ read_body_json, try_call_and_read_body_json, try_call_service, try_read_body,
+ try_read_body_json,
+ },
+};
/// Reduces boilerplate code when testing expected response payloads.
///
diff --git a/actix-web/src/test/test_request.rs b/actix-web/src/test/test_request.rs
index e81561d17..5491af0ac 100644
--- a/actix-web/src/test/test_request.rs
+++ b/actix-web/src/test/test_request.rs
@@ -3,13 +3,17 @@ use std::{borrow::Cow, net::SocketAddr, rc::Rc};
use actix_http::{test::TestRequest as HttpTestRequest, Request};
use serde::Serialize;
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
use crate::{
app_service::AppInitServiceState,
config::AppConfig,
data::Data,
dev::{Extensions, Path, Payload, ResourceDef, Service, Url},
- http::header::ContentType,
- http::{header::TryIntoHeaderPair, Method, Uri, Version},
+ http::{
+ header::{ContentType, TryIntoHeaderPair},
+ Method, Uri, Version,
+ },
rmap::ResourceMap,
service::{ServiceRequest, ServiceResponse},
test,
@@ -17,9 +21,6 @@ use crate::{
HttpRequest, HttpResponse,
};
-#[cfg(feature = "cookies")]
-use crate::cookie::{Cookie, CookieJar};
-
/// Test `Request` builder.
///
/// For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern.
@@ -197,8 +198,7 @@ impl TestRequest {
///
/// The `Content-Type` header is set to `application/json`.
pub fn set_json(mut self, data: impl Serialize) -> Self {
- let bytes =
- serde_json::to_string(&data).expect("Failed to serialize test data to json");
+ let bytes = serde_json::to_string(&data).expect("Failed to serialize test data to json");
self.req.set_payload(bytes);
self.req.insert_header(ContentType::json());
self
diff --git a/actix-web/src/test/test_utils.rs b/actix-web/src/test/test_utils.rs
index b985c3b36..4540d8a6b 100644
--- a/actix-web/src/test/test_utils.rs
+++ b/actix-web/src/test/test_utils.rs
@@ -201,9 +201,7 @@ where
}
/// Fallible version of [`read_body`] that allows testing MessageBody reading errors.
-pub async fn try_read_body(
- res: ServiceResponse,
-) -> Result::Error>
+pub async fn try_read_body(res: ServiceResponse) -> Result::Error>
where
B: MessageBody,
{
@@ -359,13 +357,11 @@ where
#[cfg(test)]
mod tests {
-
use serde::{Deserialize, Serialize};
use super::*;
use crate::{
- dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage,
- HttpResponse,
+ dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage, HttpResponse,
};
#[actix_rt::test]
@@ -409,10 +405,11 @@ mod tests {
#[actix_rt::test]
async fn test_response_json() {
- let app = init_service(App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
- )))
- .await;
+ let app =
+ init_service(App::new().service(web::resource("/people").route(
+ web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
+ )))
+ .await;
let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
@@ -428,10 +425,11 @@ mod tests {
#[actix_rt::test]
async fn test_try_response_json_error() {
- let app = init_service(App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
- )))
- .await;
+ let app =
+ init_service(App::new().service(web::resource("/people").route(
+ web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
+ )))
+ .await;
let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
@@ -448,10 +446,11 @@ mod tests {
#[actix_rt::test]
async fn test_body_json() {
- let app = init_service(App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
- )))
- .await;
+ let app =
+ init_service(App::new().service(web::resource("/people").route(
+ web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
+ )))
+ .await;
let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
@@ -468,10 +467,11 @@ mod tests {
#[actix_rt::test]
async fn test_try_body_json_error() {
- let app = init_service(App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
- )))
- .await;
+ let app =
+ init_service(App::new().service(web::resource("/people").route(
+ web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
+ )))
+ .await;
// Use a number for id to cause a deserialization error.
let payload = r#"{"id":12345,"name":"User name"}"#.as_bytes();
@@ -489,10 +489,11 @@ mod tests {
#[actix_rt::test]
async fn test_request_response_form() {
- let app = init_service(App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Form| HttpResponse::Ok().json(person)),
- )))
- .await;
+ let app =
+ init_service(App::new().service(web::resource("/people").route(
+ web::post().to(|person: web::Form| HttpResponse::Ok().json(person)),
+ )))
+ .await;
let payload = Person {
id: "12345".to_string(),
@@ -532,10 +533,11 @@ mod tests {
#[actix_rt::test]
async fn test_request_response_json() {
- let app = init_service(App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
- )))
- .await;
+ let app =
+ init_service(App::new().service(web::resource("/people").route(
+ web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
+ )))
+ .await;
let payload = Person {
id: "12345".to_string(),
@@ -566,9 +568,11 @@ mod tests {
InitError = (),
>,
> {
- App::new().service(web::resource("/people").route(
- web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
- ))
+ App::new().service(
+ web::resource("/people").route(
+ web::post().to(|person: web::Json| HttpResponse::Ok().json(person)),
+ ),
+ )
}
async fn test_service(
diff --git a/actix-web/src/types/either.rs b/actix-web/src/types/either.rs
index df93fb5ec..db244fd9a 100644
--- a/actix-web/src/types/either.rs
+++ b/actix-web/src/types/either.rs
@@ -238,8 +238,7 @@ where
match res {
Ok(bytes) => {
let fallback = bytes.clone();
- let left =
- L::from_request(this.req, &mut payload_from_bytes(bytes));
+ let left = L::from_request(this.req, &mut payload_from_bytes(bytes));
EitherExtractState::Left { left, fallback }
}
Err(err) => break Err(EitherExtractError::Bytes(err)),
@@ -266,10 +265,7 @@ where
match res {
Ok(data) => break Ok(Either::Right(data)),
Err(err) => {
- break Err(EitherExtractError::Extract(
- left_err.take().unwrap(),
- err,
- ));
+ break Err(EitherExtractError::Extract(left_err.take().unwrap(), err));
}
}
}
@@ -339,12 +335,11 @@ mod tests {
.set_payload(Bytes::from_static(b"!@$%^&*()"))
.to_http_parts();
- let payload = Either::, Json>, Bytes>::from_request(
- &req, &mut pl,
- )
- .await
- .unwrap()
- .unwrap_right();
+ let payload =
+ Either::, Json>, Bytes>::from_request(&req, &mut pl)
+ .await
+ .unwrap()
+ .unwrap_right();
assert_eq!(&payload.as_ref(), &b"!@$%^&*()");
}
@@ -356,14 +351,13 @@ mod tests {
})
.to_http_parts();
- let form = Either::, Json>, Bytes>::from_request(
- &req, &mut pl,
- )
- .await
- .unwrap()
- .unwrap_left()
- .unwrap_right()
- .into_inner();
+ let form =
+ Either::, Json>, Bytes>::from_request(&req, &mut pl)
+ .await
+ .unwrap()
+ .unwrap_left()
+ .unwrap_right()
+ .into_inner();
assert_eq!(&form.hello, "world");
}
}
diff --git a/actix-web/src/types/form.rs b/actix-web/src/types/form.rs
index d73f8ba74..7096b1e9c 100644
--- a/actix-web/src/types/form.rs
+++ b/actix-web/src/types/form.rs
@@ -20,9 +20,8 @@ use serde::{de::DeserializeOwned, Serialize};
#[cfg(feature = "__compress")]
use crate::dev::Decompress;
use crate::{
- body::EitherBody, error::UrlencodedError, extract::FromRequest,
- http::header::CONTENT_LENGTH, web, Error, HttpMessage, HttpRequest, HttpResponse,
- Responder,
+ body::EitherBody, error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH,
+ web, Error, HttpMessage, HttpRequest, HttpResponse, Responder,
};
/// URL encoded payload extractor and responder.
@@ -417,13 +416,12 @@ mod tests {
use serde::{Deserialize, Serialize};
use super::*;
- use crate::test::TestRequest;
use crate::{
http::{
header::{HeaderValue, CONTENT_LENGTH, CONTENT_TYPE},
StatusCode,
},
- test::assert_body_eq,
+ test::{assert_body_eq, TestRequest},
};
#[derive(Deserialize, Serialize, Debug, PartialEq)]
diff --git a/actix-web/src/types/header.rs b/actix-web/src/types/header.rs
index 6ea77faf6..8b1740e6c 100644
--- a/actix-web/src/types/header.rs
+++ b/actix-web/src/types/header.rs
@@ -75,8 +75,10 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use crate::http::{header, Method};
- use crate::test::TestRequest;
+ use crate::{
+ http::{header, Method},
+ test::TestRequest,
+ };
#[actix_rt::test]
async fn test_header_extract() {
diff --git a/actix-web/src/types/json.rs b/actix-web/src/types/json.rs
index 4eab55175..2523e55f2 100644
--- a/actix-web/src/types/json.rs
+++ b/actix-web/src/types/json.rs
@@ -10,12 +10,11 @@ use std::{
task::{Context, Poll},
};
+use actix_http::Payload;
use bytes::BytesMut;
use futures_core::{ready, Stream as _};
use serde::{de::DeserializeOwned, Serialize};
-use actix_http::Payload;
-
#[cfg(feature = "__compress")]
use crate::dev::Decompress;
use crate::{
@@ -158,8 +157,7 @@ impl FromRequest for Json {
}
}
-type JsonErrorHandler =
- Option Error + Send + Sync>>;
+type JsonErrorHandler = Option Error + Send + Sync>>;
pub struct JsonExtractFut {
req: Option,
@@ -423,9 +421,7 @@ impl Future for JsonBody {
let chunk = chunk?;
let buf_len = buf.len() + chunk.len();
if buf_len > *limit {
- return Poll::Ready(Err(JsonPayloadError::Overflow {
- limit: *limit,
- }));
+ return Poll::Ready(Err(JsonPayloadError::Overflow { limit: *limit }));
} else {
buf.extend_from_slice(&chunk);
}
@@ -508,8 +504,7 @@ mod tests {
let msg = MyObject {
name: "invalid request".to_string(),
};
- let resp =
- HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap());
+ let resp = HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap());
InternalError::from_response(err, resp).into()
}))
.to_http_parts();
@@ -747,7 +742,8 @@ mod tests {
assert!(s.is_err());
let err_str = s.err().unwrap().to_string();
- assert!(err_str
- .contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes)."));
+ assert!(
+ err_str.contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes).")
+ );
}
}
diff --git a/actix-web/src/types/mod.rs b/actix-web/src/types/mod.rs
index bab7c3bc0..792edd650 100644
--- a/actix-web/src/types/mod.rs
+++ b/actix-web/src/types/mod.rs
@@ -9,11 +9,13 @@ mod payload;
mod query;
mod readlines;
-pub use self::either::Either;
-pub use self::form::{Form, FormConfig, UrlEncoded};
-pub use self::header::Header;
-pub use self::json::{Json, JsonBody, JsonConfig};
-pub use self::path::{Path, PathConfig};
-pub use self::payload::{Payload, PayloadConfig};
-pub use self::query::{Query, QueryConfig};
-pub use self::readlines::Readlines;
+pub use self::{
+ either::Either,
+ form::{Form, FormConfig, UrlEncoded},
+ header::Header,
+ json::{Json, JsonBody, JsonConfig},
+ path::{Path, PathConfig},
+ payload::{Payload, PayloadConfig},
+ query::{Query, QueryConfig},
+ readlines::Readlines,
+};
diff --git a/actix-web/src/types/path.rs b/actix-web/src/types/path.rs
index a90c912f6..cc87bb80f 100644
--- a/actix-web/src/types/path.rs
+++ b/actix-web/src/types/path.rs
@@ -156,8 +156,7 @@ mod tests {
use serde::Deserialize;
use super::*;
- use crate::test::TestRequest;
- use crate::{error, http, HttpResponse};
+ use crate::{error, http, test::TestRequest, HttpResponse};
#[derive(Deserialize, Debug, Display)]
#[display(fmt = "MyStruct({}, {})", key, value)]
@@ -276,8 +275,7 @@ mod tests {
async fn test_custom_err_handler() {
let (req, mut pl) = TestRequest::with_uri("/name/user1/")
.app_data(PathConfig::default().error_handler(|err, _| {
- error::InternalError::from_response(err, HttpResponse::Conflict().finish())
- .into()
+ error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
}))
.to_http_parts();
diff --git a/actix-web/src/types/payload.rs b/actix-web/src/types/payload.rs
index 4045cedb4..1d9c6aba5 100644
--- a/actix-web/src/types/payload.rs
+++ b/actix-web/src/types/payload.rs
@@ -16,8 +16,7 @@ use futures_core::{ready, stream::Stream};
use mime::Mime;
use crate::{
- dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage,
- HttpRequest,
+ dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage, HttpRequest,
};
/// Extract a request's raw payload stream.
@@ -377,9 +376,11 @@ mod tests {
use bytes::Bytes;
use super::*;
- use crate::http::{header, StatusCode};
- use crate::test::{call_service, init_service, TestRequest};
- use crate::{web, App, Responder};
+ use crate::{
+ http::{header, StatusCode},
+ test::{call_service, init_service, TestRequest},
+ web, App, Responder,
+ };
#[actix_rt::test]
async fn test_payload_config() {
diff --git a/actix-web/src/web.rs b/actix-web/src/web.rs
index 0533f7f8f..204313752 100644
--- a/actix-web/src/web.rs
+++ b/actix-web/src/web.rs
@@ -21,17 +21,14 @@ use std::{borrow::Cow, future::Future};
use actix_router::IntoPatterns;
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
+pub use crate::{
+ config::ServiceConfig, data::Data, redirect::Redirect, request_data::ReqData, types::*,
+};
use crate::{
error::BlockingError, http::Method, service::WebService, FromRequest, Handler, Resource,
Responder, Route, Scope,
};
-pub use crate::config::ServiceConfig;
-pub use crate::data::Data;
-pub use crate::redirect::Redirect;
-pub use crate::request_data::ReqData;
-pub use crate::types::*;
-
/// Creates a new resource for a specific path.
///
/// Resources may have dynamic path segments. For example, a resource with the path `/a/{name}/c`
@@ -200,10 +197,7 @@ pub fn service(path: T) -> WebService {
/// // the client will resolve this redirect to /api/to-path
/// .service(web::redirect("/api/from-path", "to-path"));
/// ```
-pub fn redirect(
- from: impl Into>,
- to: impl Into>,
-) -> Redirect {
+pub fn redirect(from: impl Into>, to: impl Into>) -> Redirect {
Redirect::new(from, to)
}
diff --git a/actix-web/tests/test_server.rs b/actix-web/tests/test_server.rs
index 270223d69..8ce889396 100644
--- a/actix-web/tests/test_server.rs
+++ b/actix-web/tests/test_server.rs
@@ -19,14 +19,13 @@ use actix_web::{
};
use bytes::Bytes;
use futures_core::ready;
-use rand::{distributions::Alphanumeric, Rng as _};
-
#[cfg(feature = "openssl")]
use openssl::{
pkey::PKey,
ssl::{SslAcceptor, SslMethod},
x509::X509,
};
+use rand::{distributions::Alphanumeric, Rng as _};
mod utils;
@@ -94,9 +93,8 @@ impl futures_core::stream::Stream for TestBody {
#[actix_rt::test]
async fn test_body() {
let srv = actix_test::start(|| {
- App::new().service(
- web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })),
- )
+ App::new()
+ .service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })))
});
let mut res = srv.get("/").send().await.unwrap();
@@ -226,8 +224,7 @@ async fn test_body_chunked_implicit() {
App::new()
.wrap(Compress::default())
.service(web::resource("/").route(web::get().to(|| async {
- HttpResponse::Ok()
- .streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
+ HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
})))
});
@@ -256,8 +253,7 @@ async fn test_body_br_streaming() {
App::new()
.wrap(Compress::default())
.service(web::resource("/").route(web::to(|| async {
- HttpResponse::Ok()
- .streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
+ HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
})))
});
@@ -392,8 +388,7 @@ async fn test_body_zstd_streaming() {
App::new()
.wrap(Compress::default())
.service(web::resource("/").route(web::to(move || async {
- HttpResponse::Ok()
- .streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
+ HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
})))
});
@@ -686,15 +681,14 @@ async fn test_brotli_encoding_large_openssl() {
use actix_web::http::header;
let data = STR.repeat(10);
- let srv =
- actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
- App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
- // echo decompressed request body back in response
- HttpResponse::Ok()
- .insert_header(header::ContentEncoding::Identity)
- .body(bytes)
- })))
- });
+ let srv = actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
+ App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
+ // echo decompressed request body back in response
+ HttpResponse::Ok()
+ .insert_header(header::ContentEncoding::Identity)
+ .body(bytes)
+ })))
+ });
let mut res = srv
.post("/")
diff --git a/actix-web/tests/utils.rs b/actix-web/tests/utils.rs
index 2532640c6..b9c708884 100644
--- a/actix-web/tests/utils.rs
+++ b/actix-web/tests/utils.rs
@@ -4,9 +4,10 @@
use std::io::{Read as _, Write as _};
pub mod gzip {
- use super::*;
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = GzEncoder::new(Vec::new(), Compression::fast());
encoder.write_all(bytes.as_ref()).unwrap();
@@ -22,9 +23,10 @@ pub mod gzip {
}
pub mod deflate {
- use super::*;
use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::fast());
encoder.write_all(bytes.as_ref()).unwrap();
@@ -40,9 +42,10 @@ pub mod deflate {
}
pub mod brotli {
- use super::*;
use ::brotli::{reader::Decompressor as BrotliDecoder, CompressorWriter as BrotliEncoder};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = BrotliEncoder::new(
Vec::new(),
@@ -64,9 +67,10 @@ pub mod brotli {
}
pub mod zstd {
- use super::*;
use ::zstd::stream::{read::Decoder, write::Encoder};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = Encoder::new(Vec::new(), 3).unwrap();
encoder.write_all(bytes.as_ref()).unwrap();
diff --git a/awc/CHANGES.md b/awc/CHANGES.md
index 03cbf61d4..f5bddd04d 100644
--- a/awc/CHANGES.md
+++ b/awc/CHANGES.md
@@ -2,6 +2,8 @@
## Unreleased - 2023-xx-xx
+- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency.
+
## 3.1.1 - 2023-02-26
### Changed
diff --git a/awc/Cargo.toml b/awc/Cargo.toml
index 8edc90fd1..daec84ab9 100644
--- a/awc/Cargo.toml
+++ b/awc/Cargo.toml
@@ -13,7 +13,7 @@ categories = [
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-web.git"
license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
[lib]
name = "awc"
@@ -68,7 +68,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.9"
+h2 = "0.3.17"
http = "0.2.7"
itoa = "1"
log =" 0.4"
@@ -83,8 +83,8 @@ tokio = { version = "1.24.2", features = ["sync"] }
cookie = { version = "0.16", features = ["percent-encode"], optional = true }
-tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
-tls-rustls = { package = "rustls", version = "0.20.0", optional = true, features = ["dangerous_configuration"] }
+tls-openssl = { package = "openssl", version = "0.10.55", optional = true }
+tls-rustls = { package = "rustls", version = "0.20", optional = true, features = ["dangerous_configuration"] }
trust-dns-resolver = { version = "0.22", optional = true }
@@ -98,12 +98,12 @@ actix-utils = "3"
actix-web = { version = "4", features = ["openssl"] }
brotli = "3.3.3"
-const-str = "0.3"
-env_logger = "0.9"
+const-str = "0.5"
+env_logger = "0.10"
flate2 = "1.0.13"
futures-util = { version = "0.3.17", default-features = false }
static_assertions = "1.1"
-rcgen = "0.9"
+rcgen = "0.11"
rustls-pemfile = "1"
tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] }
zstd = "0.12"
diff --git a/awc/README.md b/awc/README.md
index a9d411067..1a480df12 100644
--- a/awc/README.md
+++ b/awc/README.md
@@ -12,7 +12,7 @@
- [API Documentation](https://docs.rs/awc)
- [Example Project](https://github.com/actix/examples/tree/master/https-tls/awc-https)
-- Minimum Supported Rust Version (MSRV): 1.59
+- Minimum Supported Rust Version (MSRV): 1.65
## Example
diff --git a/awc/src/any_body.rs b/awc/src/any_body.rs
index d9c259d8f..08f5cc25e 100644
--- a/awc/src/any_body.rs
+++ b/awc/src/any_body.rs
@@ -4,11 +4,10 @@ use std::{
task::{Context, Poll},
};
+use actix_http::body::{BodySize, BoxBody, MessageBody};
use bytes::Bytes;
use pin_project_lite::pin_project;
-use actix_http::body::{BodySize, BoxBody, MessageBody};
-
pin_project! {
/// Represents various types of HTTP message body.
#[derive(Clone)]
diff --git a/awc/src/builder.rs b/awc/src/builder.rs
index 79838a3f6..a54960382 100644
--- a/awc/src/builder.rs
+++ b/awc/src/builder.rs
@@ -1,6 +1,4 @@
-use std::{convert::TryFrom, fmt, net::IpAddr, rc::Rc, time::Duration};
-
-use base64::prelude::*;
+use std::{fmt, net::IpAddr, rc::Rc, time::Duration};
use actix_http::{
error::HttpError,
@@ -9,6 +7,7 @@ use actix_http::{
};
use actix_rt::net::{ActixStream, TcpStream};
use actix_service::{boxed, Service};
+use base64::prelude::*;
use crate::{
client::{
@@ -72,11 +71,8 @@ where
/// Use custom connector service.
pub fn connector(self, connector: Connector) -> ClientBuilder
where
- S1: Service<
- ConnectInfo,
- Response = TcpConnection,
- Error = TcpConnectError,
- > + Clone
+ S1: Service, Response = TcpConnection, Error = TcpConnectError>
+ + Clone
+ 'static,
Io1: ActixStream + fmt::Debug + 'static,
{
@@ -227,10 +223,7 @@ where
/// Registers middleware, in the form of a middleware component (type), that runs during inbound
/// and/or outbound processing in the request life-cycle (request -> response),
/// modifying request/response as necessary, across all requests managed by the `Client`.
- pub fn wrap(
- self,
- mw: M1,
- ) -> ClientBuilder>
+ pub fn wrap(self, mw: M1) -> ClientBuilder>
where
M: Transform,
M1: Transform,
@@ -253,8 +246,7 @@ where
pub fn finish(self) -> Client
where
M: Transform>, ConnectRequest> + 'static,
- M::Transform:
- Service,
+ M::Transform: Service,
{
let max_redirects = self.max_redirects;
@@ -269,8 +261,7 @@ where
fn _finish(self) -> Client
where
M: Transform>, ConnectRequest> + 'static,
- M::Transform:
- Service,
+ M::Transform: Service,
{
let mut connector = self.connector;
diff --git a/awc/src/client/connection.rs b/awc/src/client/connection.rs
index 9de4ece4f..64075eae8 100644
--- a/awc/src/client/connection.rs
+++ b/awc/src/client/connection.rs
@@ -7,19 +7,15 @@ use std::{
};
use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf};
+use actix_http::{body::MessageBody, h1::ClientCodec, Payload, RequestHeadType, ResponseHead};
use actix_rt::task::JoinHandle;
use bytes::Bytes;
use futures_core::future::LocalBoxFuture;
use h2::client::SendRequest;
-use actix_http::{body::MessageBody, h1::ClientCodec, Payload, RequestHeadType, ResponseHead};
-
+use super::{error::SendRequestError, h1proto, h2proto, pool::Acquired};
use crate::BoxError;
-use super::error::SendRequestError;
-use super::pool::Acquired;
-use super::{h1proto, h2proto};
-
/// Trait alias for types impl [tokio::io::AsyncRead] and [tokio::io::AsyncWrite].
pub trait ConnectionIo: AsyncRead + AsyncWrite + Unpin + 'static {}
@@ -83,10 +79,7 @@ impl AsyncWrite for H1Connection {
self.io_pin_mut().poll_flush(cx)
}
- fn poll_shutdown(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> Poll> {
+ fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> {
self.io_pin_mut().poll_shutdown(cx)
}
diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs
index 51d6e180b..1ecaf9947 100644
--- a/awc/src/client/connector.rs
+++ b/awc/src/client/connector.rs
@@ -133,11 +133,8 @@ impl Connector {
pub fn connector(self, connector: S1) -> Connector
where
Io1: ActixStream + fmt::Debug + 'static,
- S1: Service<
- ConnectInfo,
- Response = TcpConnection,
- Error = TcpConnectError,
- > + Clone,
+ S1: Service, Response = TcpConnection, Error = TcpConnectError>
+ + Clone,
{
Connector {
connector,
@@ -189,10 +186,7 @@ where
#[doc(hidden)]
#[cfg(feature = "openssl")]
#[deprecated(since = "3.0.0", note = "Renamed to `Connector::openssl`.")]
- pub fn ssl(
- mut self,
- connector: actix_tls::connect::openssl::reexports::SslConnector,
- ) -> Self {
+ pub fn ssl(mut self, connector: actix_tls::connect::openssl::reexports::SslConnector) -> Self {
self.tls = OurTlsConnector::Openssl(connector);
self
}
@@ -312,9 +306,7 @@ where
let tls = match self.tls {
#[cfg(feature = "openssl")]
- OurTlsConnector::OpensslBuilder(builder) => {
- OurTlsConnector::Openssl(builder.build())
- }
+ OurTlsConnector::OpensslBuilder(builder) => OurTlsConnector::Openssl(builder.build()),
tls => tls,
};
@@ -467,9 +459,7 @@ pub struct TcpConnectorService {
impl Service for TcpConnectorService
where
- S: Service, Error = ConnectError>
- + Clone
- + 'static,
+ S: Service, Error = ConnectError> + Clone + 'static,
{
type Response = (Io, Protocol);
type Error = ConnectError;
@@ -520,9 +510,8 @@ struct TlsConnectorService {
impl Service for TlsConnectorService
where
- Tcp: Service, Error = ConnectError>
- + Clone
- + 'static,
+ Tcp:
+ Service, Error = ConnectError> + Clone + 'static,
Tls: Service, Error = std::io::Error> + Clone + 'static,
Tls::Response: IntoConnectionIo,
IO: ConnectionIo,
diff --git a/awc/src/client/error.rs b/awc/src/client/error.rs
index 9f290c5c0..d351e1067 100644
--- a/awc/src/client/error.rs
+++ b/awc/src/client/error.rs
@@ -1,11 +1,9 @@
use std::{fmt, io};
-use derive_more::{Display, From};
-
use actix_http::error::{HttpError, ParseError};
-
#[cfg(feature = "openssl")]
use actix_tls::accept::openssl::reexports::Error as OpensslError;
+use derive_more::{Display, From};
use crate::BoxError;
diff --git a/awc/src/client/h1proto.rs b/awc/src/client/h1proto.rs
index 8738c2f7f..c756179a4 100644
--- a/awc/src/client/h1proto.rs
+++ b/awc/src/client/h1proto.rs
@@ -18,12 +18,11 @@ use futures_core::{ready, Stream};
use futures_util::SinkExt as _;
use pin_project_lite::pin_project;
-use crate::BoxError;
-
use super::{
connection::{ConnectionIo, H1Connection},
error::{ConnectError, SendRequestError},
};
+use crate::BoxError;
pub(crate) async fn send_request(
io: H1Connection,
diff --git a/awc/src/client/h2proto.rs b/awc/src/client/h2proto.rs
index 709896ddd..d18db1410 100644
--- a/awc/src/client/h2proto.rs
+++ b/awc/src/client/h2proto.rs
@@ -1,28 +1,29 @@
use std::future::Future;
-use actix_utils::future::poll_fn;
-use bytes::Bytes;
-use h2::{
- client::{Builder, Connection, SendRequest},
- SendStream,
-};
-use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING};
-use http::{request::Request, Method, Version};
-use log::trace;
-
use actix_http::{
body::{BodySize, MessageBody},
header::HeaderMap,
Payload, RequestHeadType, ResponseHead,
};
-
-use crate::BoxError;
+use actix_utils::future::poll_fn;
+use bytes::Bytes;
+use h2::{
+ client::{Builder, Connection, SendRequest},
+ SendStream,
+};
+use http::{
+ header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING},
+ request::Request,
+ Method, Version,
+};
+use log::trace;
use super::{
config::ConnectorConfig,
connection::{ConnectionIo, H2Connection},
error::SendRequestError,
};
+use crate::BoxError;
pub(crate) async fn send_request(
mut io: H2Connection,
diff --git a/awc/src/client/mod.rs b/awc/src/client/mod.rs
index e898d2d04..c9fa37253 100644
--- a/awc/src/client/mod.rs
+++ b/awc/src/client/mod.rs
@@ -1,6 +1,6 @@
//! HTTP client.
-use std::{convert::TryFrom, rc::Rc, time::Duration};
+use std::{rc::Rc, time::Duration};
use actix_http::{error::HttpError, header::HeaderMap, Method, RequestHead, Uri};
use actix_rt::net::TcpStream;
@@ -19,9 +19,11 @@ mod h1proto;
mod h2proto;
mod pool;
-pub use self::connection::{Connection, ConnectionIo};
-pub use self::connector::{Connector, ConnectorService};
-pub use self::error::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError};
+pub use self::{
+ connection::{Connection, ConnectionIo},
+ connector::{Connector, ConnectorService},
+ error::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError},
+};
#[derive(Clone)]
pub struct Connect {
diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs
index 632608c45..2cf1f3ace 100644
--- a/awc/src/client/pool.rs
+++ b/awc/src/client/pool.rs
@@ -23,11 +23,13 @@ use http::uri::Authority;
use pin_project_lite::pin_project;
use tokio::sync::{OwnedSemaphorePermit, Semaphore};
-use super::config::ConnectorConfig;
-use super::connection::{ConnectionInnerType, ConnectionIo, ConnectionType, H2ConnectionInner};
-use super::error::ConnectError;
-use super::h2proto::handshake;
-use super::Connect;
+use super::{
+ config::ConnectorConfig,
+ connection::{ConnectionInnerType, ConnectionIo, ConnectionType, H2ConnectionInner},
+ error::ConnectError,
+ h2proto::handshake,
+ Connect,
+};
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
pub struct Key {
@@ -201,7 +203,9 @@ where
// check if the connection is still usable
if let ConnectionInnerType::H1(ref mut io) = c.conn {
let check = ConnectionCheckFuture { io };
- match check.now_or_never().expect("ConnectionCheckFuture must never yield with Poll::Pending.") {
+ match check.now_or_never().expect(
+ "ConnectionCheckFuture must never yield with Poll::Pending.",
+ ) {
ConnectionState::Tainted => {
inner.close(c.conn);
continue;
diff --git a/awc/src/connect.rs b/awc/src/connect.rs
index be1ea0fee..14ed9e958 100644
--- a/awc/src/connect.rs
+++ b/awc/src/connect.rs
@@ -13,9 +13,7 @@ use futures_core::{future::LocalBoxFuture, ready};
use crate::{
any_body::AnyBody,
- client::{
- Connect as ClientConnect, ConnectError, Connection, ConnectionIo, SendRequestError,
- },
+ client::{Connect as ClientConnect, ConnectError, Connection, ConnectionIo, SendRequestError},
ClientResponse,
};
@@ -62,9 +60,9 @@ impl ConnectResponse {
pub fn into_client_response(self) -> ClientResponse {
match self {
ConnectResponse::Client(res) => res,
- _ => panic!(
- "ClientResponse only reachable with ConnectResponse::ClientResponse variant"
- ),
+ _ => {
+ panic!("ClientResponse only reachable with ConnectResponse::ClientResponse variant")
+ }
}
}
@@ -75,9 +73,9 @@ impl ConnectResponse {
pub fn into_tunnel_response(self) -> (ResponseHead, Framed) {
match self {
ConnectResponse::Tunnel(head, framed) => (head, framed),
- _ => panic!(
- "TunnelResponse only reachable with ConnectResponse::TunnelResponse variant"
- ),
+ _ => {
+ panic!("TunnelResponse only reachable with ConnectResponse::TunnelResponse variant")
+ }
}
}
}
diff --git a/awc/src/error.rs b/awc/src/error.rs
index aa9dc4d99..0104e5fe8 100644
--- a/awc/src/error.rs
+++ b/awc/src/error.rs
@@ -7,7 +7,6 @@ pub use actix_http::{
ws::{HandshakeError as WsHandshakeError, ProtocolError as WsProtocolError},
StatusCode,
};
-
use derive_more::{Display, From};
use serde_json::error::Error as JsonError;
diff --git a/awc/src/frozen.rs b/awc/src/frozen.rs
index 4023bd1c8..8f3244997 100644
--- a/awc/src/frozen.rs
+++ b/awc/src/frozen.rs
@@ -1,15 +1,14 @@
use std::{net, rc::Rc, time::Duration};
-use bytes::Bytes;
-use futures_core::Stream;
-use serde::Serialize;
-
use actix_http::{
body::MessageBody,
error::HttpError,
header::{HeaderMap, TryIntoHeaderPair},
Method, RequestHead, Uri,
};
+use bytes::Bytes;
+use futures_core::Stream;
+use serde::Serialize;
use crate::{
client::ClientConfig,
diff --git a/awc/src/lib.rs b/awc/src/lib.rs
index b06df6b7d..ce2dfb34f 100644
--- a/awc/src/lib.rs
+++ b/awc/src/lib.rs
@@ -113,7 +113,6 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
pub use actix_http::body;
-
#[cfg(feature = "cookies")]
pub use cookie;
@@ -134,18 +133,18 @@ pub mod http {
//! Various HTTP related types.
// TODO: figure out how best to expose http::Error vs actix_http::Error
- pub use actix_http::{
- header, uri, ConnectionType, Error, Method, StatusCode, Uri, Version,
- };
+ pub use actix_http::{header, uri, ConnectionType, Error, Method, StatusCode, Uri, Version};
}
-pub use self::builder::ClientBuilder;
-pub use self::client::{Client, Connect, Connector};
-pub use self::connect::{BoxConnectorService, BoxedSocket, ConnectRequest, ConnectResponse};
-pub use self::frozen::{FrozenClientRequest, FrozenSendBuilder};
-pub use self::request::ClientRequest;
#[allow(deprecated)]
pub use self::responses::{ClientResponse, JsonBody, MessageBody, ResponseBody};
-pub use self::sender::SendClientRequest;
+pub use self::{
+ builder::ClientBuilder,
+ client::{Client, Connect, Connector},
+ connect::{BoxConnectorService, BoxedSocket, ConnectRequest, ConnectResponse},
+ frozen::{FrozenClientRequest, FrozenSendBuilder},
+ request::ClientRequest,
+ sender::SendClientRequest,
+};
pub(crate) type BoxError = Box;
diff --git a/awc/src/middleware/mod.rs b/awc/src/middleware/mod.rs
index 330e3b7fe..8c63e9c75 100644
--- a/awc/src/middleware/mod.rs
+++ b/awc/src/middleware/mod.rs
@@ -1,11 +1,11 @@
mod redirect;
-pub use self::redirect::Redirect;
-
use std::marker::PhantomData;
use actix_service::Service;
+pub use self::redirect::Redirect;
+
/// Trait for transform a type to another one.
/// Both the input and output type should impl [actix_service::Service] trait.
pub trait Transform {
diff --git a/awc/src/middleware/redirect.rs b/awc/src/middleware/redirect.rs
index 67ef5d76f..c38d6ad92 100644
--- a/awc/src/middleware/redirect.rs
+++ b/awc/src/middleware/redirect.rs
@@ -1,5 +1,4 @@
use std::{
- convert::TryFrom,
future::Future,
net::SocketAddr,
pin::Pin,
@@ -450,8 +449,7 @@ mod tests {
}
async fn test(req: HttpRequest, body: Bytes) -> HttpResponse {
- if (req.method() == Method::GET || req.method() == Method::HEAD)
- && body.is_empty()
+ if (req.method() == Method::GET || req.method() == Method::HEAD) && body.is_empty()
{
HttpResponse::Ok().finish()
} else {
@@ -551,10 +549,7 @@ mod tests {
let port = *req.app_data::().unwrap();
if req.headers().get(header::AUTHORIZATION).is_some() {
HttpResponse::Found()
- .append_header((
- "location",
- format!("http://localhost:{}/", port).as_str(),
- ))
+ .append_header(("location", format!("http://localhost:{}/", port).as_str()))
.finish()
} else {
HttpResponse::InternalServerError().finish()
diff --git a/awc/src/request.rs b/awc/src/request.rs
index d3a4eda8c..4e34e5771 100644
--- a/awc/src/request.rs
+++ b/awc/src/request.rs
@@ -1,9 +1,4 @@
-use std::{convert::TryFrom, fmt, net, rc::Rc, time::Duration};
-
-use base64::prelude::*;
-use bytes::Bytes;
-use futures_core::Stream;
-use serde::Serialize;
+use std::{fmt, net, rc::Rc, time::Duration};
use actix_http::{
body::MessageBody,
@@ -11,7 +6,13 @@ use actix_http::{
header::{self, HeaderMap, HeaderValue, TryIntoHeaderPair},
ConnectionType, Method, RequestHead, Uri, Version,
};
+use base64::prelude::*;
+use bytes::Bytes;
+use futures_core::Stream;
+use serde::Serialize;
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
use crate::{
client::ClientConfig,
error::{FreezeRequestError, InvalidUrl},
@@ -20,9 +21,6 @@ use crate::{
BoxError,
};
-#[cfg(feature = "cookies")]
-use crate::cookie::{Cookie, CookieJar};
-
/// An HTTP Client request builder
///
/// This type can be used to construct an instance of `ClientRequest` through a
@@ -291,10 +289,7 @@ impl ClientRequest {
}
/// Sets the query part of the request
- pub fn query(
- mut self,
- query: &T,
- ) -> Result {
+ pub fn query(mut self, query: &T) -> Result {
let mut parts = self.head.uri.clone().into_parts();
if let Some(path_and_query) = parts.path_and_query {
diff --git a/awc/src/responses/mod.rs b/awc/src/responses/mod.rs
index 588ce014c..95a078093 100644
--- a/awc/src/responses/mod.rs
+++ b/awc/src/responses/mod.rs
@@ -8,10 +8,9 @@ mod read_body;
mod response;
mod response_body;
-pub use self::json_body::JsonBody;
-pub use self::response::ClientResponse;
#[allow(deprecated)]
pub use self::response_body::{MessageBody, ResponseBody};
+pub use self::{json_body::JsonBody, response::ClientResponse};
/// Default body size limit: 2 MiB
const DEFAULT_BODY_LIMIT: usize = 2 * 1024 * 1024;
diff --git a/awc/src/responses/response.rs b/awc/src/responses/response.rs
index c7c0a6362..0eafcff0a 100644
--- a/awc/src/responses/response.rs
+++ b/awc/src/responses/response.rs
@@ -7,8 +7,8 @@ use std::{
};
use actix_http::{
- error::PayloadError, header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage,
- Payload, ResponseHead, StatusCode, Version,
+ error::PayloadError, header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Payload,
+ ResponseHead, StatusCode, Version,
};
use actix_rt::time::{sleep, Sleep};
use bytes::Bytes;
@@ -16,11 +16,10 @@ use futures_core::Stream;
use pin_project_lite::pin_project;
use serde::de::DeserializeOwned;
+use super::{JsonBody, ResponseBody, ResponseTimeout};
#[cfg(feature = "cookies")]
use crate::cookie::{Cookie, ParseError as CookieParseError};
-use super::{JsonBody, ResponseBody, ResponseTimeout};
-
pin_project! {
/// Client Response
pub struct ClientResponse {
diff --git a/awc/src/sender.rs b/awc/src/sender.rs
index cd30e571d..c2191d11b 100644
--- a/awc/src/sender.rs
+++ b/awc/src/sender.rs
@@ -13,15 +13,14 @@ use actix_http::{
header::{self, HeaderMap, HeaderName, TryIntoHeaderValue},
RequestHead, RequestHeadType,
};
+#[cfg(feature = "__compress")]
+use actix_http::{encoding::Decoder, header::ContentEncoding, Payload};
use actix_rt::time::{sleep, Sleep};
use bytes::Bytes;
use derive_more::From;
use futures_core::Stream;
use serde::Serialize;
-#[cfg(feature = "__compress")]
-use actix_http::{encoding::Decoder, header::ContentEncoding, Payload};
-
use crate::{
any_body::AnyBody,
client::ClientConfig,
@@ -106,8 +105,9 @@ impl Future for SendClientRequest {
}
let res = futures_core::ready!(send.as_mut().poll(cx)).map(|res| {
- res.into_client_response()._timeout(delay.take()).map_body(
- |head, payload| {
+ res.into_client_response()
+ ._timeout(delay.take())
+ .map_body(|head, payload| {
if *response_decompress {
Payload::Stream {
payload: Decoder::from_headers(payload, &head.headers),
@@ -117,8 +117,7 @@ impl Future for SendClientRequest {
payload: Decoder::new(payload, ContentEncoding::Identity),
}
}
- },
- )
+ })
});
Poll::Ready(res)
diff --git a/awc/src/ws.rs b/awc/src/ws.rs
index 406368e62..836ff2024 100644
--- a/awc/src/ws.rs
+++ b/awc/src/ws.rs
@@ -26,17 +26,17 @@
//! }
//! ```
-use std::{convert::TryFrom, fmt, net::SocketAddr, str};
-
-use base64::prelude::*;
+use std::{fmt, net::SocketAddr, str};
use actix_codec::Framed;
+pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
use actix_http::{ws, Payload, RequestHead};
use actix_rt::time::timeout;
use actix_service::Service as _;
+use base64::prelude::*;
-pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
-
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
use crate::{
client::ClientConfig,
connect::{BoxedSocket, ConnectRequest},
@@ -48,9 +48,6 @@ use crate::{
ClientResponse,
};
-#[cfg(feature = "cookies")]
-use crate::cookie::{Cookie, CookieJar};
-
/// WebSocket connection.
pub struct WebsocketsRequest {
pub(crate) head: RequestHead,
diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs
index 9c3543ff0..6d1459ac0 100644
--- a/awc/tests/test_client.rs
+++ b/awc/tests/test_client.rs
@@ -12,19 +12,18 @@ use std::{
time::Duration,
};
+use actix_http::{HttpService, StatusCode};
+use actix_http_test::test_server;
+use actix_service::{fn_service, map_config, ServiceFactoryExt as _};
use actix_utils::future::ok;
+use actix_web::{dev::AppConfig, http::header, web, App, Error, HttpRequest, HttpResponse};
+use awc::error::{JsonPayloadError, PayloadError, SendRequestError};
use base64::prelude::*;
use bytes::Bytes;
use cookie::Cookie;
use futures_util::stream;
use rand::Rng;
-use actix_http::{HttpService, StatusCode};
-use actix_http_test::test_server;
-use actix_service::{fn_service, map_config, ServiceFactoryExt as _};
-use actix_web::{dev::AppConfig, http::header, web, App, Error, HttpRequest, HttpResponse};
-use awc::error::{JsonPayloadError, PayloadError, SendRequestError};
-
mod utils;
const S: &str = "Hello World ";
@@ -33,9 +32,8 @@ const STR: &str = const_str::repeat!(S, 100);
#[actix_rt::test]
async fn simple() {
let srv = actix_test::start(|| {
- App::new().service(
- web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })),
- )
+ App::new()
+ .service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })))
});
let request = srv.get("/").insert_header(("x-test", "111")).send();
@@ -61,9 +59,8 @@ async fn simple() {
#[actix_rt::test]
async fn json() {
let srv = actix_test::start(|| {
- App::new().service(
- web::resource("/").route(web::to(|_: web::Json| HttpResponse::Ok())),
- )
+ App::new()
+ .service(web::resource("/").route(web::to(|_: web::Json| HttpResponse::Ok())))
});
let request = srv
@@ -340,8 +337,7 @@ async fn connection_wait_queue() {
.and_then(
HttpService::new(map_config(
App::new().service(
- web::resource("/")
- .route(web::to(|| async { HttpResponse::Ok().body(STR) })),
+ web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })),
),
|_| AppConfig::default(),
))
@@ -449,9 +445,7 @@ async fn no_decompress() {
let srv = actix_test::start(|| {
App::new()
.wrap(actix_web::middleware::Compress::default())
- .service(
- web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })),
- )
+ .service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })))
});
let mut res = awc::Client::new()
@@ -833,12 +827,12 @@ async fn local_address() {
let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let srv = actix_test::start(move || {
- App::new().service(web::resource("/").route(web::to(
- move |req: HttpRequest| async move {
+ App::new().service(
+ web::resource("/").route(web::to(move |req: HttpRequest| async move {
assert_eq!(req.peer_addr().unwrap().ip(), ip);
Ok::<_, Error>(HttpResponse::Ok())
- },
- )))
+ })),
+ )
});
let client = awc::Client::builder().local_address(ip).finish();
diff --git a/awc/tests/test_connector.rs b/awc/tests/test_connector.rs
index 0f0b81414..b3eb97367 100644
--- a/awc/tests/test_connector.rs
+++ b/awc/tests/test_connector.rs
@@ -5,8 +5,7 @@ extern crate tls_openssl as openssl;
use actix_http::HttpService;
use actix_http_test::test_server;
use actix_service::{map_config, ServiceFactoryExt};
-use actix_web::http::Version;
-use actix_web::{dev::AppConfig, web, App, HttpResponse};
+use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse};
use openssl::{
pkey::PKey,
ssl::{SslAcceptor, SslConnector, SslMethod, SslVerifyMode},
diff --git a/awc/tests/test_ssl_client.rs b/awc/tests/test_ssl_client.rs
index 40c9ab8f0..5273c3fff 100644
--- a/awc/tests/test_ssl_client.rs
+++ b/awc/tests/test_ssl_client.rs
@@ -2,15 +2,16 @@
extern crate tls_openssl as openssl;
-use std::sync::atomic::{AtomicUsize, Ordering};
-use std::sync::Arc;
+use std::sync::{
+ atomic::{AtomicUsize, Ordering},
+ Arc,
+};
use actix_http::HttpService;
use actix_http_test::test_server;
use actix_service::{fn_service, map_config, ServiceFactoryExt};
use actix_utils::future::ok;
-use actix_web::http::Version;
-use actix_web::{dev::AppConfig, web, App, HttpResponse};
+use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse};
use openssl::{
pkey::PKey,
ssl::{SslAcceptor, SslConnector, SslMethod, SslVerifyMode},
diff --git a/awc/tests/utils.rs b/awc/tests/utils.rs
index 2532640c6..b9c708884 100644
--- a/awc/tests/utils.rs
+++ b/awc/tests/utils.rs
@@ -4,9 +4,10 @@
use std::io::{Read as _, Write as _};
pub mod gzip {
- use super::*;
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = GzEncoder::new(Vec::new(), Compression::fast());
encoder.write_all(bytes.as_ref()).unwrap();
@@ -22,9 +23,10 @@ pub mod gzip {
}
pub mod deflate {
- use super::*;
use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::fast());
encoder.write_all(bytes.as_ref()).unwrap();
@@ -40,9 +42,10 @@ pub mod deflate {
}
pub mod brotli {
- use super::*;
use ::brotli::{reader::Decompressor as BrotliDecoder, CompressorWriter as BrotliEncoder};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = BrotliEncoder::new(
Vec::new(),
@@ -64,9 +67,10 @@ pub mod brotli {
}
pub mod zstd {
- use super::*;
use ::zstd::stream::{read::Decoder, write::Encoder};
+ use super::*;
+
pub fn encode(bytes: impl AsRef<[u8]>) -> Vec {
let mut encoder = Encoder::new(Vec::new(), 3).unwrap();
encoder.write_all(bytes.as_ref()).unwrap();
diff --git a/clippy.toml b/clippy.toml
index abe19b3a0..04371125d 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -1 +1 @@
-msrv = "1.59"
+msrv = "1.65"
diff --git a/rustfmt.toml b/rustfmt.toml
deleted file mode 100644
index 973e002c0..000000000
--- a/rustfmt.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-max_width = 96
-reorder_imports = true
diff --git a/scripts/bump b/scripts/bump
index 40d43d429..b09d9d196 100755
--- a/scripts/bump
+++ b/scripts/bump
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# developed on macOS and probably doesn't work on Linux yet due to minor
# differences in flags on sed
@@ -21,12 +21,9 @@ README_FILE=$DIR/README.md
# determine changelog file name
if [ -f "$DIR/CHANGES.md" ]; then
- CHANGELOG_FILE=$DIR/CHANGES.md
+ CHANGELOG_FILE="$DIR/CHANGES.md"
elif [ -f "$DIR/CHANGELOG.md" ]; then
- CHANGELOG_FILE=$DIR/CHANGELOG.md
-else
- echo "No changelog file found"
- exit 1
+ CHANGELOG_FILE="$DIR/CHANGELOG.md"
fi
# get current version
@@ -37,15 +34,17 @@ CHANGE_CHUNK_FILE="$(mktemp)"
echo saving changelog to $CHANGE_CHUNK_FILE
echo
-# get changelog chunk and save to temp file
-cat "$CHANGELOG_FILE" |
- # skip up to unreleased heading
- sed '1,/Unreleased/ d' |
- # take up to previous version heading
- sed "/$CURRENT_VERSION/ q" |
- # drop last line
- sed '$d' \
- >"$CHANGE_CHUNK_FILE"
+if [ -n "${CHANGELOG_FILE-}" ]; then
+ # get changelog chunk and save to temp file
+ cat "$CHANGELOG_FILE" |
+ # skip up to unreleased heading
+ sed '1,/Unreleased/ d' |
+ # take up to previous version heading
+ sed "/$CURRENT_VERSION/ q" |
+ # drop last line
+ sed '$d' \
+ >"$CHANGE_CHUNK_FILE"
+fi
# if word count of changelog chunk is 0 then insert filler changelog chunk
if [ "$(wc -w "$CHANGE_CHUNK_FILE" | awk '{ print $1 }')" = "0" ]; then
@@ -68,8 +67,7 @@ if [ "${NEW_VERSION:0:1}" = "v" ]; then
NEW_VERSION="${NEW_VERSION:1}"
fi
-DATE="$(date -u +"%Y-%m-%d")"
-echo "updating from $CURRENT_VERSION => $NEW_VERSION ($DATE)"
+echo "updating from $CURRENT_VERSION => $NEW_VERSION"
# update package.version field
sed -i.bak -E "s/^version ?= ?\"[^\"]+\"$/version = \"$NEW_VERSION\"/" "$CARGO_MANIFEST"
@@ -77,19 +75,21 @@ sed -i.bak -E "s/^version ?= ?\"[^\"]+\"$/version = \"$NEW_VERSION\"/" "$CARGO_M
# update readme
[ -f "$README_FILE" ] && sed -i.bak -E "s#$CURRENT_VERSION([/)])#$NEW_VERSION\1#g" "$README_FILE"
-# update changelog file
-(
- sed '/Unreleased/ q' "$CHANGELOG_FILE" # up to unreleased heading
- echo # blank line
- echo "## $NEW_VERSION - $DATE" # new version heading
- cat "$CHANGE_CHUNK_FILE" # previously unreleased changes
- sed "/$CURRENT_VERSION/ q" "$CHANGELOG_FILE" | tail -n 1 # the previous version heading
- sed "1,/$CURRENT_VERSION/ d" "$CHANGELOG_FILE" # everything after previous version heading
-) >"$CHANGELOG_FILE.bak"
-mv "$CHANGELOG_FILE.bak" "$CHANGELOG_FILE"
+if [ -n "${CHANGELOG_FILE-}" ]; then
+ # update changelog file
+ (
+ sed '/Unreleased/ q' "$CHANGELOG_FILE" # up to unreleased heading
+ echo # blank line
+ echo "## $NEW_VERSION" # new version heading
+ cat "$CHANGE_CHUNK_FILE" # previously unreleased changes
+ sed "/$CURRENT_VERSION/ q" "$CHANGELOG_FILE" | tail -n 1 # the previous version heading
+ sed "1,/$CURRENT_VERSION/ d" "$CHANGELOG_FILE" # everything after previous version heading
+ ) >"$CHANGELOG_FILE.bak"
+ mv "$CHANGELOG_FILE.bak" "$CHANGELOG_FILE"
-# format CHANGELOG file according to prettier
-npx -y prettier --write "$CHANGELOG_FILE" || true
+ # format CHANGELOG file according to prettier
+ npx -y prettier --write "$CHANGELOG_FILE" || true
+fi
# done; remove backup files
rm -f $CARGO_MANIFEST.bak