From 351286486c5b88d6fa879ba2d0ccc0335f41dfc1 Mon Sep 17 00:00:00 2001
From: fakeshadow <24548779@qq.com>
Date: Fri, 19 Mar 2021 04:25:35 -0700
Subject: [PATCH 1/4] fix clippy warning on nightly (#2088)
* fix clippy warning on nightly
---
actix-files/src/service.rs | 2 +-
actix-http/src/client/connection.rs | 2 +-
actix-http/src/config.rs | 20 +++++---------------
actix-http/src/header/shared/entity.rs | 5 ++---
actix-http/src/header/shared/extended.rs | 2 +-
src/config.rs | 2 +-
src/lib.rs | 12 ++----------
src/middleware/compress.rs | 17 +++++++++--------
src/resource.rs | 2 +-
src/test.rs | 2 +-
tests/test_httpserver.rs | 16 ++++++----------
11 files changed, 30 insertions(+), 52 deletions(-)
diff --git a/actix-files/src/service.rs b/actix-files/src/service.rs
index 14eea6ebc..3214963ed 100644
--- a/actix-files/src/service.rs
+++ b/actix-files/src/service.rs
@@ -1,4 +1,4 @@
-use std::{fmt, io, path::PathBuf, rc::Rc, task::Poll};
+use std::{fmt, io, path::PathBuf, rc::Rc};
use actix_service::Service;
use actix_web::{
diff --git a/actix-http/src/client/connection.rs b/actix-http/src/client/connection.rs
index 89dfd59de..78101397d 100644
--- a/actix-http/src/client/connection.rs
+++ b/actix-http/src/client/connection.rs
@@ -325,7 +325,7 @@ where
}
}
-const H2_UNREACHABLE_WRITE: &'static str = "H2Connection can not impl AsyncWrite trait";
+const H2_UNREACHABLE_WRITE: &str = "H2Connection can not impl AsyncWrite trait";
impl AsyncWrite for Connection
where
diff --git a/actix-http/src/config.rs b/actix-http/src/config.rs
index 9f84b8694..9a2293e92 100644
--- a/actix-http/src/config.rs
+++ b/actix-http/src/config.rs
@@ -126,9 +126,7 @@ impl ServiceConfig {
pub fn client_timer(&self) -> Option {
let delay_time = self.0.client_timeout;
if delay_time != 0 {
- Some(sleep_until(
- self.0.date_service.now() + Duration::from_millis(delay_time),
- ))
+ Some(sleep_until(self.now() + Duration::from_millis(delay_time)))
} else {
None
}
@@ -138,7 +136,7 @@ impl ServiceConfig {
pub fn client_timer_expire(&self) -> Option {
let delay = self.0.client_timeout;
if delay != 0 {
- Some(self.0.date_service.now() + Duration::from_millis(delay))
+ Some(self.now() + Duration::from_millis(delay))
} else {
None
}
@@ -148,7 +146,7 @@ impl ServiceConfig {
pub fn client_disconnect_timer(&self) -> Option {
let delay = self.0.client_disconnect;
if delay != 0 {
- Some(self.0.date_service.now() + Duration::from_millis(delay))
+ Some(self.now() + Duration::from_millis(delay))
} else {
None
}
@@ -157,20 +155,12 @@ impl ServiceConfig {
#[inline]
/// Return keep-alive timer delay is configured.
pub fn keep_alive_timer(&self) -> Option {
- if let Some(ka) = self.0.keep_alive {
- Some(sleep_until(self.0.date_service.now() + ka))
- } else {
- None
- }
+ self.keep_alive().map(|ka| sleep_until(self.now() + ka))
}
/// Keep-alive expire time
pub fn keep_alive_expire(&self) -> Option {
- if let Some(ka) = self.0.keep_alive {
- Some(self.0.date_service.now() + ka)
- } else {
- None
- }
+ self.keep_alive().map(|ka| self.now() + ka)
}
#[inline]
diff --git a/actix-http/src/header/shared/entity.rs b/actix-http/src/header/shared/entity.rs
index eb383cd6f..2505216f2 100644
--- a/actix-http/src/header/shared/entity.rs
+++ b/actix-http/src/header/shared/entity.rs
@@ -127,9 +127,8 @@ impl Display for EntityTag {
impl FromStr for EntityTag {
type Err = crate::error::ParseError;
- fn from_str(s: &str) -> Result {
- let length: usize = s.len();
- let slice = &s[..];
+ fn from_str(slice: &str) -> Result {
+ let length = slice.len();
// Early exits if it doesn't terminate in a DQUOTE.
if !slice.ends_with('"') || slice.len() < 2 {
return Err(crate::error::ParseError::Header);
diff --git a/actix-http/src/header/shared/extended.rs b/actix-http/src/header/shared/extended.rs
index 6bdcb7922..9fd4cdfb0 100644
--- a/actix-http/src/header/shared/extended.rs
+++ b/actix-http/src/header/shared/extended.rs
@@ -88,9 +88,9 @@ pub fn parse_extended_value(
};
Ok(ExtendedValue {
- value,
charset,
language_tag,
+ value,
})
}
diff --git a/src/config.rs b/src/config.rs
index bd9a25c6f..cd14eb4cc 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -113,7 +113,7 @@ pub struct AppConfig {
impl AppConfig {
pub(crate) fn new(secure: bool, addr: SocketAddr, host: String) -> Self {
- AppConfig { secure, addr, host }
+ AppConfig { secure, host, addr }
}
/// Server host name.
diff --git a/src/lib.rs b/src/lib.rs
index 16b2ab186..136c462b8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -173,11 +173,7 @@ pub mod dev {
impl BodyEncoding for ResponseBuilder {
fn get_encoding(&self) -> Option {
- if let Some(ref enc) = self.extensions().get::() {
- Some(enc.0)
- } else {
- None
- }
+ self.extensions().get::().map(|enc| enc.0)
}
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
@@ -188,11 +184,7 @@ pub mod dev {
impl BodyEncoding for Response {
fn get_encoding(&self) -> Option {
- if let Some(ref enc) = self.extensions().get::() {
- Some(enc.0)
- } else {
- None
- }
+ self.extensions().get::().map(|enc| enc.0)
}
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
diff --git a/src/middleware/compress.rs b/src/middleware/compress.rs
index 698ba768e..fc1a85d30 100644
--- a/src/middleware/compress.rs
+++ b/src/middleware/compress.rs
@@ -197,22 +197,23 @@ impl AcceptEncoding {
/// Parse a raw Accept-Encoding header value into an ordered list.
pub fn parse(raw: &str, encoding: ContentEncoding) -> ContentEncoding {
- let mut encodings: Vec<_> = raw
+ let mut encodings = raw
.replace(' ', "")
.split(',')
.map(|l| AcceptEncoding::new(l))
- .collect();
+ .flatten()
+ .collect::>();
+
encodings.sort();
for enc in encodings {
- if let Some(enc) = enc {
- if encoding == ContentEncoding::Auto {
- return enc.encoding;
- } else if encoding == enc.encoding {
- return encoding;
- }
+ if encoding == ContentEncoding::Auto {
+ return enc.encoding;
+ } else if encoding == enc.encoding {
+ return encoding;
}
}
+
ContentEncoding::Identity
}
}
diff --git a/src/resource.rs b/src/resource.rs
index 1a5619de6..d35131cbb 100644
--- a/src/resource.rs
+++ b/src/resource.rs
@@ -449,9 +449,9 @@ impl ServiceFactory for ResourceFactory {
.collect::, _>>()?;
Ok(ResourceService {
+ routes,
app_data,
default,
- routes,
})
})
}
diff --git a/src/test.rs b/src/test.rs
index dd2426fec..2ebd64558 100644
--- a/src/test.rs
+++ b/src/test.rs
@@ -774,10 +774,10 @@ where
};
TestServer {
- ssl,
addr,
client,
system,
+ ssl,
server,
}
}
diff --git a/tests/test_httpserver.rs b/tests/test_httpserver.rs
index aa2b2ca74..12225b7e5 100644
--- a/tests/test_httpserver.rs
+++ b/tests/test_httpserver.rs
@@ -1,15 +1,11 @@
-use std::sync::mpsc;
-use std::{thread, time::Duration};
-
#[cfg(feature = "openssl")]
extern crate tls_openssl as openssl;
-#[cfg(feature = "rustls")]
-extern crate tls_rustls as rustls;
-#[cfg(feature = "openssl")]
-use openssl::ssl::SslAcceptorBuilder;
-
-use actix_web::{test, web, App, HttpResponse, HttpServer};
+#[cfg(any(unix, feature = "openssl"))]
+use {
+ actix_web::{test, web, App, HttpResponse, HttpServer},
+ std::{sync::mpsc, thread, time::Duration},
+};
#[cfg(unix)]
#[actix_rt::test]
@@ -72,7 +68,7 @@ async fn test_start() {
}
#[cfg(feature = "openssl")]
-fn ssl_acceptor() -> SslAcceptorBuilder {
+fn ssl_acceptor() -> openssl::ssl::SslAcceptorBuilder {
use openssl::{
pkey::PKey,
ssl::{SslAcceptor, SslMethod},
From 9488757c29bf575a113041886050bafad2129a2d Mon Sep 17 00:00:00 2001
From: Thomas de Zeeuw
Date: Fri, 19 Mar 2021 12:17:06 +0000
Subject: [PATCH 2/4] Update to socket2 v0.4 (#2092)
---
Cargo.toml | 2 +-
actix-http-test/Cargo.toml | 2 +-
actix-http-test/src/lib.rs | 4 ++--
src/server.rs | 9 +++------
src/test.rs | 4 ++--
5 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 0877edf9c..f3a6271ee 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -105,7 +105,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_urlencoded = "0.7"
smallvec = "1.6"
-socket2 = "0.3.16"
+socket2 = "0.4.0"
time = { version = "0.2.23", default-features = false, features = ["std"] }
tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
tls-rustls = { package = "rustls", version = "0.19.0", optional = true }
diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml
index c1e61556b..a7efc5310 100644
--- a/actix-http-test/Cargo.toml
+++ b/actix-http-test/Cargo.toml
@@ -42,7 +42,7 @@ bytes = "1"
futures-core = { version = "0.3.7", default-features = false }
http = "0.2.2"
log = "0.4"
-socket2 = "0.3"
+socket2 = "0.4"
serde = "1.0"
serde_json = "1.0"
slab = "0.4"
diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs
index 8de07c8d3..138f14313 100644
--- a/actix-http-test/src/lib.rs
+++ b/actix-http-test/src/lib.rs
@@ -118,10 +118,10 @@ pub async fn test_server_with_addr>(
/// Get first available unused address
pub fn unused_addr() -> net::SocketAddr {
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
- let socket = Socket::new(Domain::ipv4(), Type::stream(), Some(Protocol::tcp())).unwrap();
+ let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).unwrap();
socket.bind(&addr.into()).unwrap();
socket.set_reuse_address(true).unwrap();
- let tcp = socket.into_tcp_listener();
+ let tcp = net::TcpListener::from(socket);
tcp.local_addr().unwrap()
}
diff --git a/src/server.rs b/src/server.rs
index 99355593a..cfd8ae4b4 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -607,17 +607,14 @@ where
fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result {
use socket2::{Domain, Protocol, Socket, Type};
- let domain = match addr {
- net::SocketAddr::V4(_) => Domain::ipv4(),
- net::SocketAddr::V6(_) => Domain::ipv6(),
- };
- let socket = Socket::new(domain, Type::stream(), Some(Protocol::tcp()))?;
+ let domain = Domain::for_address(addr);
+ let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
socket.set_reuse_address(true)?;
socket.bind(&addr.into())?;
// clamp backlog to max u32 that fits in i32 range
let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
socket.listen(backlog)?;
- Ok(socket.into_tcp_listener())
+ Ok(net::TcpListener::from(socket))
}
#[cfg(feature = "openssl")]
diff --git a/src/test.rs b/src/test.rs
index 2ebd64558..bc19296e2 100644
--- a/src/test.rs
+++ b/src/test.rs
@@ -862,10 +862,10 @@ impl TestServerConfig {
/// Get first available unused address
pub fn unused_addr() -> net::SocketAddr {
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
- let socket = Socket::new(Domain::ipv4(), Type::stream(), Some(Protocol::tcp())).unwrap();
+ let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).unwrap();
socket.bind(&addr.into()).unwrap();
socket.set_reuse_address(true).unwrap();
- let tcp = socket.into_tcp_listener();
+ let tcp = net::TcpListener::from(socket);
tcp.local_addr().unwrap()
}
From 8d9de768264e78cf62087be44872c17e24f5428a Mon Sep 17 00:00:00 2001
From: Ibraheem Ahmed
Date: Fri, 19 Mar 2021 12:30:53 -0400
Subject: [PATCH 3/4] Simplify handler factory macro (#2086)
---
src/handler.rs | 50 +++++++++++++++++++-------------------------------
1 file changed, 19 insertions(+), 31 deletions(-)
diff --git a/src/handler.rs b/src/handler.rs
index 0016b741e..7e3c5f47e 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -28,17 +28,6 @@ where
fn call(&self, param: T) -> R;
}
-impl Handler<(), R> for F
-where
- F: Fn() -> R + Clone + 'static,
- R: Future,
- R::Output: Responder,
-{
- fn call(&self, _: ()) -> R {
- (self)()
- }
-}
-
#[doc(hidden)]
/// Extract arguments from request, run factory function and make response.
pub struct HandlerService
@@ -177,30 +166,29 @@ where
}
/// FromRequest trait impl for tuples
-macro_rules! factory_tuple ({ $(($n:tt, $T:ident)),+} => {
- impl Handler<($($T,)+), Res> for Func
- where Func: Fn($($T,)+) -> Res + Clone + 'static,
+macro_rules! factory_tuple ({ $($param:ident)* } => {
+ impl Handler<($($param,)*), Res> for Func
+ where Func: Fn($($param),*) -> Res + Clone + 'static,
Res: Future,
Res::Output: Responder,
{
- fn call(&self, param: ($($T,)+)) -> Res {
- (self)($(param.$n,)+)
+ #[allow(non_snake_case)]
+ fn call(&self, ($($param,)*): ($($param,)*)) -> Res {
+ (self)($($param,)*)
}
}
});
-#[rustfmt::skip]
-mod m {
- use super::*;
-
- factory_tuple!((0, A));
- factory_tuple!((0, A), (1, B));
- factory_tuple!((0, A), (1, B), (2, C));
- factory_tuple!((0, A), (1, B), (2, C), (3, D));
- factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E));
- factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
- factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
- factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
- factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
- factory_tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
-}
+factory_tuple! {}
+factory_tuple! { A }
+factory_tuple! { A B }
+factory_tuple! { A B C }
+factory_tuple! { A B C D }
+factory_tuple! { A B C D E }
+factory_tuple! { A B C D E F }
+factory_tuple! { A B C D E F G }
+factory_tuple! { A B C D E F G H }
+factory_tuple! { A B C D E F G H I }
+factory_tuple! { A B C D E F G H I J }
+factory_tuple! { A B C D E F G H I J K }
+factory_tuple! { A B C D E F G H I J K L }
From 746d983849d7e5bb5ca4ac242276f6e65cca5643 Mon Sep 17 00:00:00 2001
From: fakeshadow <24548779@qq.com>
Date: Fri, 19 Mar 2021 22:18:06 -0700
Subject: [PATCH 4/4] handle header error with CustomResponder (#2093)
---
CHANGES.md | 5 +++++
src/responder.rs | 31 +++++++++++++++----------------
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index ef9ee900a..5df0b6d6d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,11 +4,16 @@
### Fixed
* Double ampersand in Logger format is escaped correctly. [#2067]
+### Changed
+* `CustomResponder` would return error as `HttpResponse` when `CustomResponder::with_header` failed instead of skipping.
+ (Only the first error is kept when multiple error occur) [#2093]
+
### Removed
* The `client` mod was removed. Clients should now use `awc` directly.
[871ca5e4](https://github.com/actix/actix-web/commit/871ca5e4ae2bdc22d1ea02701c2992fa8d04aed7)
[#2067]: https://github.com/actix/actix-web/pull/2067
+[#2093]: https://github.com/actix/actix-web/pull/2093
## 4.0.0-beta.4 - 2021-03-09
diff --git a/src/responder.rs b/src/responder.rs
index 92945cdaa..0b6f47c6b 100644
--- a/src/responder.rs
+++ b/src/responder.rs
@@ -155,8 +155,7 @@ impl Responder for BytesMut {
pub struct CustomResponder {
responder: T,
status: Option,
- headers: Option,
- error: Option,
+ headers: Result,
}
impl CustomResponder {
@@ -164,8 +163,7 @@ impl CustomResponder {
CustomResponder {
responder,
status: None,
- headers: None,
- error: None,
+ headers: Ok(HeaderMap::new()),
}
}
@@ -206,32 +204,33 @@ impl CustomResponder {
where
H: IntoHeaderPair,
{
- if self.headers.is_none() {
- self.headers = Some(HeaderMap::new());
+ if let Ok(ref mut headers) = self.headers {
+ match header.try_into_header_pair() {
+ Ok((key, value)) => headers.append(key, value),
+ Err(e) => self.headers = Err(e.into()),
+ };
}
- match header.try_into_header_pair() {
- Ok((key, value)) => self.headers.as_mut().unwrap().append(key, value),
- Err(e) => self.error = Some(e.into()),
- };
-
self
}
}
impl Responder for CustomResponder {
fn respond_to(self, req: &HttpRequest) -> HttpResponse {
+ let headers = match self.headers {
+ Ok(headers) => headers,
+ Err(err) => return HttpResponse::from_error(Error::from(err)),
+ };
+
let mut res = self.responder.respond_to(req);
if let Some(status) = self.status {
*res.status_mut() = status;
}
- if let Some(ref headers) = self.headers {
- for (k, v) in headers {
- // TODO: before v4, decide if this should be append instead
- res.headers_mut().insert(k.clone(), v.clone());
- }
+ for (k, v) in headers {
+ // TODO: before v4, decide if this should be append instead
+ res.headers_mut().insert(k, v);
}
res