,
+
flags: Flags,
}
diff --git a/actix-http/src/requests/request.rs b/actix-http/src/requests/request.rs
index 1750fb2f7..6a267a7a6 100644
--- a/actix-http/src/requests/request.rs
+++ b/actix-http/src/requests/request.rs
@@ -173,7 +173,7 @@ impl Request
{
/// Peer address is the directly connected peer's socket address. If a proxy is used in front of
/// the Actix Web server, then it would be address of this proxy.
///
- /// Will only return None when called in unit tests.
+ /// Will only return None when called in unit tests unless set manually.
#[inline]
pub fn peer_addr(&self) -> Option {
self.head().peer_addr
diff --git a/actix-http/src/responses/builder.rs b/actix-http/src/responses/builder.rs
index 063af92da..bb7d0f712 100644
--- a/actix-http/src/responses/builder.rs
+++ b/actix-http/src/responses/builder.rs
@@ -93,7 +93,7 @@ impl ResponseBuilder {
Ok((key, value)) => {
parts.headers.insert(key, value);
}
- Err(e) => self.err = Some(e.into()),
+ Err(err) => self.err = Some(err.into()),
};
}
@@ -119,7 +119,7 @@ impl ResponseBuilder {
if let Some(parts) = self.inner() {
match header.try_into_pair() {
Ok((key, value)) => parts.headers.append(key, value),
- Err(e) => self.err = Some(e.into()),
+ Err(err) => self.err = Some(err.into()),
};
}
@@ -193,7 +193,7 @@ impl ResponseBuilder {
Ok(value) => {
parts.headers.insert(header::CONTENT_TYPE, value);
}
- Err(e) => self.err = Some(e.into()),
+ Err(err) => self.err = Some(err.into()),
};
}
self
@@ -351,12 +351,9 @@ mod tests {
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/plain");
let resp = Response::build(StatusCode::OK)
- .content_type(mime::APPLICATION_JAVASCRIPT_UTF_8)
+ .content_type(mime::TEXT_JAVASCRIPT)
.body(Bytes::new());
- assert_eq!(
- resp.headers().get(CONTENT_TYPE).unwrap(),
- "application/javascript; charset=utf-8"
- );
+ assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/javascript");
}
#[test]
diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs
index e118d8361..3be099d9f 100644
--- a/actix-http/src/service.rs
+++ b/actix-http/src/service.rs
@@ -241,13 +241,13 @@ where
}
/// Configuration options used when accepting TLS connection.
-#[cfg(any(feature = "openssl", feature = "rustls"))]
+#[cfg(feature = "__tls")]
#[derive(Debug, Default)]
pub struct TlsAcceptorConfig {
pub(crate) handshake_timeout: Option,
}
-#[cfg(any(feature = "openssl", feature = "rustls"))]
+#[cfg(feature = "__tls")]
impl TlsAcceptorConfig {
/// Set TLS handshake timeout duration.
pub fn handshake_timeout(self, dur: std::time::Duration) -> Self {
@@ -352,13 +352,13 @@ mod openssl {
}
}
-#[cfg(feature = "rustls")]
-mod rustls {
+#[cfg(feature = "rustls-0_20")]
+mod rustls_0_20 {
use std::io;
use actix_service::ServiceFactoryExt as _;
use actix_tls::accept::{
- rustls::{reexports::ServerConfig, Acceptor, TlsStream},
+ rustls_0_20::{reexports::ServerConfig, Acceptor, TlsStream},
TlsError,
};
@@ -389,7 +389,7 @@ mod rustls {
U::Error: fmt::Display + Into>,
U::InitError: fmt::Debug,
{
- /// Create Rustls based service.
+ /// Create Rustls v0.20 based service.
pub fn rustls(
self,
config: ServerConfig,
@@ -403,7 +403,7 @@ mod rustls {
self.rustls_with_config(config, TlsAcceptorConfig::default())
}
- /// Create Rustls based service with custom TLS acceptor configuration.
+ /// Create Rustls v0.20 based service with custom TLS acceptor configuration.
pub fn rustls_with_config(
self,
mut config: ServerConfig,
@@ -448,6 +448,294 @@ mod rustls {
}
}
+#[cfg(feature = "rustls-0_21")]
+mod rustls_0_21 {
+ use std::io;
+
+ use actix_service::ServiceFactoryExt as _;
+ use actix_tls::accept::{
+ rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream},
+ TlsError,
+ };
+
+ use super::*;
+
+ impl HttpService, S, B, X, U>
+ where
+ S: ServiceFactory,
+ S::Future: 'static,
+ S::Error: Into> + 'static,
+ S::InitError: fmt::Debug,
+ S::Response: Into> + 'static,
+ >::Future: 'static,
+
+ B: MessageBody + 'static,
+
+ X: ServiceFactory,
+ X::Future: 'static,
+ X::Error: Into>,
+ X::InitError: fmt::Debug,
+
+ U: ServiceFactory<
+ (Request, Framed, h1::Codec>),
+ Config = (),
+ Response = (),
+ >,
+ U::Future: 'static,
+ U::Error: fmt::Display + Into>,
+ U::InitError: fmt::Debug,
+ {
+ /// Create Rustls v0.21 based service.
+ pub fn rustls_021(
+ self,
+ config: ServerConfig,
+ ) -> impl ServiceFactory<
+ TcpStream,
+ Config = (),
+ Response = (),
+ Error = TlsError,
+ InitError = (),
+ > {
+ self.rustls_021_with_config(config, TlsAcceptorConfig::default())
+ }
+
+ /// Create Rustls v0.21 based service with custom TLS acceptor configuration.
+ pub fn rustls_021_with_config(
+ self,
+ mut config: ServerConfig,
+ tls_acceptor_config: TlsAcceptorConfig,
+ ) -> impl ServiceFactory<
+ TcpStream,
+ Config = (),
+ Response = (),
+ Error = TlsError,
+ InitError = (),
+ > {
+ let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+ protos.extend_from_slice(&config.alpn_protocols);
+ config.alpn_protocols = protos;
+
+ let mut acceptor = Acceptor::new(config);
+
+ if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+ acceptor.set_handshake_timeout(handshake_timeout);
+ }
+
+ acceptor
+ .map_init_err(|_| {
+ unreachable!("TLS acceptor service factory does not error on init")
+ })
+ .map_err(TlsError::into_service_error)
+ .and_then(|io: TlsStream| async {
+ let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+ if protos.windows(2).any(|window| window == b"h2") {
+ Protocol::Http2
+ } else {
+ Protocol::Http1
+ }
+ } else {
+ Protocol::Http1
+ };
+ let peer_addr = io.get_ref().0.peer_addr().ok();
+ Ok((io, proto, peer_addr))
+ })
+ .and_then(self.map_err(TlsError::Service))
+ }
+ }
+}
+
+#[cfg(feature = "rustls-0_22")]
+mod rustls_0_22 {
+ use std::io;
+
+ use actix_service::ServiceFactoryExt as _;
+ use actix_tls::accept::{
+ rustls_0_22::{reexports::ServerConfig, Acceptor, TlsStream},
+ TlsError,
+ };
+
+ use super::*;
+
+ impl HttpService, S, B, X, U>
+ where
+ S: ServiceFactory,
+ S::Future: 'static,
+ S::Error: Into> + 'static,
+ S::InitError: fmt::Debug,
+ S::Response: Into> + 'static,
+ >::Future: 'static,
+
+ B: MessageBody + 'static,
+
+ X: ServiceFactory,
+ X::Future: 'static,
+ X::Error: Into>,
+ X::InitError: fmt::Debug,
+
+ U: ServiceFactory<
+ (Request, Framed, h1::Codec>),
+ Config = (),
+ Response = (),
+ >,
+ U::Future: 'static,
+ U::Error: fmt::Display + Into>,
+ U::InitError: fmt::Debug,
+ {
+ /// Create Rustls v0.22 based service.
+ pub fn rustls_0_22(
+ self,
+ config: ServerConfig,
+ ) -> impl ServiceFactory<
+ TcpStream,
+ Config = (),
+ Response = (),
+ Error = TlsError,
+ InitError = (),
+ > {
+ self.rustls_0_22_with_config(config, TlsAcceptorConfig::default())
+ }
+
+ /// Create Rustls v0.22 based service with custom TLS acceptor configuration.
+ pub fn rustls_0_22_with_config(
+ self,
+ mut config: ServerConfig,
+ tls_acceptor_config: TlsAcceptorConfig,
+ ) -> impl ServiceFactory<
+ TcpStream,
+ Config = (),
+ Response = (),
+ Error = TlsError,
+ InitError = (),
+ > {
+ let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+ protos.extend_from_slice(&config.alpn_protocols);
+ config.alpn_protocols = protos;
+
+ let mut acceptor = Acceptor::new(config);
+
+ if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+ acceptor.set_handshake_timeout(handshake_timeout);
+ }
+
+ acceptor
+ .map_init_err(|_| {
+ unreachable!("TLS acceptor service factory does not error on init")
+ })
+ .map_err(TlsError::into_service_error)
+ .and_then(|io: TlsStream| async {
+ let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+ if protos.windows(2).any(|window| window == b"h2") {
+ Protocol::Http2
+ } else {
+ Protocol::Http1
+ }
+ } else {
+ Protocol::Http1
+ };
+ let peer_addr = io.get_ref().0.peer_addr().ok();
+ Ok((io, proto, peer_addr))
+ })
+ .and_then(self.map_err(TlsError::Service))
+ }
+ }
+}
+
+#[cfg(feature = "rustls-0_23")]
+mod rustls_0_23 {
+ use std::io;
+
+ use actix_service::ServiceFactoryExt as _;
+ use actix_tls::accept::{
+ rustls_0_23::{reexports::ServerConfig, Acceptor, TlsStream},
+ TlsError,
+ };
+
+ use super::*;
+
+ impl HttpService, S, B, X, U>
+ where
+ S: ServiceFactory,
+ S::Future: 'static,
+ S::Error: Into> + 'static,
+ S::InitError: fmt::Debug,
+ S::Response: Into> + 'static,
+ >::Future: 'static,
+
+ B: MessageBody + 'static,
+
+ X: ServiceFactory,
+ X::Future: 'static,
+ X::Error: Into>,
+ X::InitError: fmt::Debug,
+
+ U: ServiceFactory<
+ (Request, Framed, h1::Codec>),
+ Config = (),
+ Response = (),
+ >,
+ U::Future: 'static,
+ U::Error: fmt::Display + Into>,
+ U::InitError: fmt::Debug,
+ {
+ /// Create Rustls v0.23 based service.
+ pub fn rustls_0_23(
+ self,
+ config: ServerConfig,
+ ) -> impl ServiceFactory<
+ TcpStream,
+ Config = (),
+ Response = (),
+ Error = TlsError,
+ InitError = (),
+ > {
+ self.rustls_0_23_with_config(config, TlsAcceptorConfig::default())
+ }
+
+ /// Create Rustls v0.23 based service with custom TLS acceptor configuration.
+ pub fn rustls_0_23_with_config(
+ self,
+ mut config: ServerConfig,
+ tls_acceptor_config: TlsAcceptorConfig,
+ ) -> impl ServiceFactory<
+ TcpStream,
+ Config = (),
+ Response = (),
+ Error = TlsError,
+ InitError = (),
+ > {
+ let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+ protos.extend_from_slice(&config.alpn_protocols);
+ config.alpn_protocols = protos;
+
+ let mut acceptor = Acceptor::new(config);
+
+ if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+ acceptor.set_handshake_timeout(handshake_timeout);
+ }
+
+ acceptor
+ .map_init_err(|_| {
+ unreachable!("TLS acceptor service factory does not error on init")
+ })
+ .map_err(TlsError::into_service_error)
+ .and_then(|io: TlsStream| async {
+ let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+ if protos.windows(2).any(|window| window == b"h2") {
+ Protocol::Http2
+ } else {
+ Protocol::Http1
+ }
+ } else {
+ Protocol::Http1
+ };
+ let peer_addr = io.get_ref().0.peer_addr().ok();
+ Ok((io, proto, peer_addr))
+ })
+ .and_then(self.map_err(TlsError::Service))
+ }
+ }
+}
+
impl ServiceFactory<(T, Protocol, Option)>
for HttpService
where
@@ -487,23 +775,23 @@ where
let cfg = self.cfg.clone();
Box::pin(async move {
- let expect = expect
- .await
- .map_err(|e| error!("Init http expect service error: {:?}", e))?;
+ let expect = expect.await.map_err(|err| {
+ tracing::error!("Initialization of HTTP expect service error: {err:?}");
+ })?;
let upgrade = match upgrade {
Some(upgrade) => {
- let upgrade = upgrade
- .await
- .map_err(|e| error!("Init http upgrade service error: {:?}", e))?;
+ let upgrade = upgrade.await.map_err(|err| {
+ tracing::error!("Initialization of HTTP upgrade service error: {err:?}");
+ })?;
Some(upgrade)
}
None => None,
};
- let service = service
- .await
- .map_err(|e| error!("Init http service error: {:?}", e))?;
+ let service = service.await.map_err(|err| {
+ tracing::error!("Initialization of HTTP service error: {err:?}");
+ })?;
Ok(HttpServiceHandler::new(
cfg,
@@ -622,7 +910,7 @@ where
handshake: Some((
crate::h2::handshake_with_timeout(io, &self.cfg),
self.cfg.clone(),
- self.flow.clone(),
+ Rc::clone(&self.flow),
conn_data,
peer_addr,
)),
@@ -638,7 +926,7 @@ where
state: State::H1 {
dispatcher: h1::Dispatcher::new(
io,
- self.flow.clone(),
+ Rc::clone(&self.flow),
self.cfg.clone(),
peer_addr,
conn_data,
diff --git a/actix-http/src/test.rs b/actix-http/src/test.rs
index 3815e64c6..926efe2f5 100644
--- a/actix-http/src/test.rs
+++ b/actix-http/src/test.rs
@@ -11,7 +11,7 @@ use std::{
use actix_codec::{AsyncRead, AsyncWrite, ReadBuf};
use bytes::{Bytes, BytesMut};
-use http::{Method, Uri, Version};
+use http::{header, Method, Uri, Version};
use crate::{
header::{HeaderMap, TryIntoHeaderPair},
@@ -98,9 +98,13 @@ impl TestRequest {
}
/// Set request payload.
+ ///
+ /// This sets the `Content-Length` header with the size of `data`.
pub fn set_payload(&mut self, data: impl Into) -> &mut Self {
let mut payload = crate::h1::Payload::empty();
- payload.unread_data(data.into());
+ let bytes = data.into();
+ self.insert_header((header::CONTENT_LENGTH, bytes.len()));
+ payload.unread_data(bytes);
parts(&mut self.0).payload = Some(payload.into());
self
}
@@ -159,8 +163,8 @@ impl TestBuffer {
#[allow(dead_code)]
pub(crate) fn clone(&self) -> Self {
Self {
- read_buf: self.read_buf.clone(),
- write_buf: self.write_buf.clone(),
+ read_buf: Rc::clone(&self.read_buf),
+ write_buf: Rc::clone(&self.write_buf),
err: self.err.clone(),
}
}
@@ -271,6 +275,7 @@ impl TestSeqBuffer {
{
Self(Rc::new(RefCell::new(TestSeqInner {
read_buf: data.into(),
+ read_closed: false,
write_buf: BytesMut::new(),
err: None,
})))
@@ -289,36 +294,59 @@ impl TestSeqBuffer {
Ref::map(self.0.borrow(), |inner| &inner.write_buf)
}
+ pub fn take_write_buf(&self) -> Bytes {
+ self.0.borrow_mut().write_buf.split().freeze()
+ }
+
pub fn err(&self) -> Ref<'_, Option> {
Ref::map(self.0.borrow(), |inner| &inner.err)
}
/// Add data to read buffer.
+ ///
+ /// # Panics
+ ///
+ /// Panics if called after [`TestSeqBuffer::close_read`] has been called
pub fn extend_read_buf>(&mut self, data: T) {
- self.0
- .borrow_mut()
- .read_buf
- .extend_from_slice(data.as_ref())
+ let mut inner = self.0.borrow_mut();
+ if inner.read_closed {
+ panic!("Tried to extend the read buffer after calling close_read");
+ }
+
+ inner.read_buf.extend_from_slice(data.as_ref())
+ }
+
+ /// Closes the [`AsyncRead`]/[`Read`] part of this test buffer.
+ ///
+ /// The current data in the buffer will still be returned by a call to read/poll_read, however,
+ /// after the buffer is empty, it will return `Ok(0)` to signify the EOF condition
+ pub fn close_read(&self) {
+ self.0.borrow_mut().read_closed = true;
}
}
pub struct TestSeqInner {
read_buf: BytesMut,
+ read_closed: bool,
write_buf: BytesMut,
err: Option,
}
impl io::Read for TestSeqBuffer {
fn read(&mut self, dst: &mut [u8]) -> Result {
- if self.0.borrow().read_buf.is_empty() {
- if self.0.borrow().err.is_some() {
- Err(self.0.borrow_mut().err.take().unwrap())
+ let mut inner = self.0.borrow_mut();
+
+ if inner.read_buf.is_empty() {
+ if let Some(err) = inner.err.take() {
+ Err(err)
+ } else if inner.read_closed {
+ Ok(0)
} else {
Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
}
} else {
- let size = std::cmp::min(self.0.borrow().read_buf.len(), dst.len());
- let b = self.0.borrow_mut().read_buf.split_to(size);
+ let size = std::cmp::min(inner.read_buf.len(), dst.len());
+ let b = inner.read_buf.split_to(size);
dst[..size].copy_from_slice(&b);
Ok(size)
}
diff --git a/actix-http/src/ws/codec.rs b/actix-http/src/ws/codec.rs
index 681649a7e..ad487e400 100644
--- a/actix-http/src/ws/codec.rs
+++ b/actix-http/src/ws/codec.rs
@@ -296,7 +296,7 @@ impl Decoder for Codec {
}
}
Ok(None) => Ok(None),
- Err(e) => Err(e),
+ Err(err) => Err(err),
}
}
}
diff --git a/actix-http/src/ws/dispatcher.rs b/actix-http/src/ws/dispatcher.rs
index 1354d5ae1..7d0a300b7 100644
--- a/actix-http/src/ws/dispatcher.rs
+++ b/actix-http/src/ws/dispatcher.rs
@@ -114,14 +114,14 @@ mod inner {
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- DispatcherError::Service(ref e) => {
- write!(fmt, "DispatcherError::Service({:?})", e)
+ DispatcherError::Service(ref err) => {
+ write!(fmt, "DispatcherError::Service({err:?})")
}
- DispatcherError::Encoder(ref e) => {
- write!(fmt, "DispatcherError::Encoder({:?})", e)
+ DispatcherError::Encoder(ref err) => {
+ write!(fmt, "DispatcherError::Encoder({err:?})")
}
- DispatcherError::Decoder(ref e) => {
- write!(fmt, "DispatcherError::Decoder({:?})", e)
+ DispatcherError::Decoder(ref err) => {
+ write!(fmt, "DispatcherError::Decoder({err:?})")
}
}
}
@@ -136,9 +136,9 @@ mod inner {
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- DispatcherError::Service(ref e) => write!(fmt, "{}", e),
- DispatcherError::Encoder(ref e) => write!(fmt, "{:?}", e),
- DispatcherError::Decoder(ref e) => write!(fmt, "{:?}", e),
+ DispatcherError::Service(ref err) => write!(fmt, "{err}"),
+ DispatcherError::Encoder(ref err) => write!(fmt, "{err:?}"),
+ DispatcherError::Decoder(ref err) => write!(fmt, "{err:?}"),
}
}
}
diff --git a/actix-http/src/ws/frame.rs b/actix-http/src/ws/frame.rs
index c9fb0cde9..7147cc92a 100644
--- a/actix-http/src/ws/frame.rs
+++ b/actix-http/src/ws/frame.rs
@@ -94,11 +94,21 @@ impl Parser {
Some(res) => res,
};
+ let frame_len = match idx.checked_add(length) {
+ Some(len) => len,
+ None => return Err(ProtocolError::Overflow),
+ };
+
// not enough data
- if src.len() < idx + length {
+ if src.len() < frame_len {
let min_length = min(length, max_size);
- if src.capacity() < idx + min_length {
- src.reserve(idx + min_length - src.capacity());
+ let required_cap = match idx.checked_add(min_length) {
+ Some(cap) => cap,
+ None => return Err(ProtocolError::Overflow),
+ };
+
+ if src.capacity() < required_cap {
+ src.reserve(required_cap - src.capacity());
}
return Ok(None);
}
@@ -178,14 +188,14 @@ impl Parser {
};
if payload_len < 126 {
- dst.reserve(p_len + 2 + if mask { 4 } else { 0 });
+ dst.reserve(p_len + 2);
dst.put_slice(&[one, two | payload_len as u8]);
} else if payload_len <= 65_535 {
- dst.reserve(p_len + 4 + if mask { 4 } else { 0 });
+ dst.reserve(p_len + 4);
dst.put_slice(&[one, two | 126]);
dst.put_u16(payload_len as u16);
} else {
- dst.reserve(p_len + 10 + if mask { 4 } else { 0 });
+ dst.reserve(p_len + 10);
dst.put_slice(&[one, two | 127]);
dst.put_u64(payload_len as u64);
};
@@ -402,4 +412,14 @@ mod tests {
Parser::write_close(&mut buf, None, false);
assert_eq!(&buf[..], &vec![0x88, 0x00][..]);
}
+
+ #[test]
+ fn test_parse_length_overflow() {
+ let buf: [u8; 14] = [
+ 0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0x0e, 0x8f,
+ ];
+ let mut buf = BytesMut::from(&buf[..]);
+ let result = Parser::parse(&mut buf, true, 65536);
+ assert!(matches!(result, Err(ProtocolError::Overflow)));
+ }
}
diff --git a/actix-http/src/ws/mod.rs b/actix-http/src/ws/mod.rs
index 87f9b38f3..c2ae010c2 100644
--- a/actix-http/src/ws/mod.rs
+++ b/actix-http/src/ws/mod.rs
@@ -27,43 +27,43 @@ pub use self::{
#[derive(Debug, Display, Error, From)]
pub enum ProtocolError {
/// Received an unmasked frame from client.
- #[display(fmt = "received an unmasked frame from client")]
+ #[display("received an unmasked frame from client")]
UnmaskedFrame,
/// Received a masked frame from server.
- #[display(fmt = "received a masked frame from server")]
+ #[display("received a masked frame from server")]
MaskedFrame,
/// Encountered invalid opcode.
- #[display(fmt = "invalid opcode ({})", _0)]
+ #[display("invalid opcode ({})", _0)]
InvalidOpcode(#[error(not(source))] u8),
/// Invalid control frame length
- #[display(fmt = "invalid control frame length ({})", _0)]
+ #[display("invalid control frame length ({})", _0)]
InvalidLength(#[error(not(source))] usize),
/// Bad opcode.
- #[display(fmt = "bad opcode")]
+ #[display("bad opcode")]
BadOpCode,
/// A payload reached size limit.
- #[display(fmt = "payload reached size limit")]
+ #[display("payload reached size limit")]
Overflow,
/// Continuation has not started.
- #[display(fmt = "continuation has not started")]
+ #[display("continuation has not started")]
ContinuationNotStarted,
/// Received new continuation but it is already started.
- #[display(fmt = "received new continuation but it has already started")]
+ #[display("received new continuation but it has already started")]
ContinuationStarted,
/// Unknown continuation fragment.
- #[display(fmt = "unknown continuation fragment: {}", _0)]
+ #[display("unknown continuation fragment: {}", _0)]
ContinuationFragment(#[error(not(source))] OpCode),
/// I/O error.
- #[display(fmt = "I/O error: {}", _0)]
+ #[display("I/O error: {}", _0)]
Io(io::Error),
}
@@ -71,27 +71,27 @@ pub enum ProtocolError {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)]
pub enum HandshakeError {
/// Only get method is allowed.
- #[display(fmt = "method not allowed")]
+ #[display("method not allowed")]
GetMethodRequired,
/// Upgrade header if not set to WebSocket.
- #[display(fmt = "WebSocket upgrade is expected")]
+ #[display("WebSocket upgrade is expected")]
NoWebsocketUpgrade,
/// Connection header is not set to upgrade.
- #[display(fmt = "connection upgrade is expected")]
+ #[display("connection upgrade is expected")]
NoConnectionUpgrade,
/// WebSocket version header is not set.
- #[display(fmt = "WebSocket version header is required")]
+ #[display("WebSocket version header is required")]
NoVersionHeader,
/// Unsupported WebSocket version.
- #[display(fmt = "unsupported WebSocket version")]
+ #[display("unsupported WebSocket version")]
UnsupportedVersion,
/// WebSocket key is not set or wrong.
- #[display(fmt = "unknown WebSocket key")]
+ #[display("unknown WebSocket key")]
BadWebsocketKey,
}
@@ -221,7 +221,7 @@ pub fn handshake_response(req: &RequestHead) -> ResponseBuilder {
#[cfg(test)]
mod tests {
use super::*;
- use crate::{header, test::TestRequest, Method};
+ use crate::{header, test::TestRequest};
#[test]
fn test_handshake() {
diff --git a/actix-http/src/ws/proto.rs b/actix-http/src/ws/proto.rs
index 0653c00b0..27815eaf2 100644
--- a/actix-http/src/ws/proto.rs
+++ b/actix-http/src/ws/proto.rs
@@ -1,7 +1,4 @@
-use std::{
- convert::{From, Into},
- fmt,
-};
+use std::fmt;
use base64::prelude::*;
use tracing::error;
diff --git a/actix-http/tests/test_client.rs b/actix-http/tests/test_client.rs
index 5888527f1..2d940984d 100644
--- a/actix-http/tests/test_client.rs
+++ b/actix-http/tests/test_client.rs
@@ -94,7 +94,7 @@ async fn with_query_parameter() {
}
#[derive(Debug, Display, Error)]
-#[display(fmt = "expect failed")]
+#[display("expect failed")]
struct ExpectFailed;
impl From for Response