1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-24 00:21:08 +01:00

Merge remote-tracking branch 'origin/master' into remove-extensions-from-head

This commit is contained in:
Rob Ede 2021-12-08 07:30:14 +00:00
commit fb5b4734a4
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
62 changed files with 252 additions and 392 deletions

View File

@ -262,9 +262,9 @@ impl Files {
self
}
/// See [`Files::method_guard`].
#[doc(hidden)]
#[deprecated(since = "0.6.0", note = "Renamed to `method_guard`.")]
/// See [`Files::method_guard`].
pub fn use_guards<G: Guard + 'static>(self, guard: G) -> Self {
self.method_guard(guard)
}

View File

@ -11,8 +11,8 @@
//! .service(Files::new("/static", ".").prefer_utf8(true));
//! ```
#![deny(rust_2018_idioms)]
#![warn(missing_docs, missing_debug_implementations)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible, missing_docs, missing_debug_implementations)]
use actix_service::boxed::{BoxService, BoxServiceFactory};
use actix_web::{

View File

@ -1,6 +1,7 @@
//! Various helpers for Actix applications to use during testing.
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

View File

@ -189,11 +189,7 @@ mod _original {
n /= 100;
curr -= 2;
unsafe {
ptr::copy_nonoverlapping(
lut_ptr.offset(d1 as isize),
buf_ptr.offset(curr),
2,
);
ptr::copy_nonoverlapping(lut_ptr.offset(d1 as isize), buf_ptr.offset(curr), 2);
}
// decode last 1 or 2 chars
@ -206,11 +202,7 @@ mod _original {
let d1 = n << 1;
curr -= 2;
unsafe {
ptr::copy_nonoverlapping(
lut_ptr.offset(d1 as isize),
buf_ptr.offset(curr),
2,
);
ptr::copy_nonoverlapping(lut_ptr.offset(d1 as isize), buf_ptr.offset(curr), 2);
}
}

View File

@ -54,15 +54,10 @@ const EMPTY_HEADER_INDEX: HeaderIndex = HeaderIndex {
value: (0, 0),
};
const EMPTY_HEADER_INDEX_ARRAY: [HeaderIndex; MAX_HEADERS] =
[EMPTY_HEADER_INDEX; MAX_HEADERS];
const EMPTY_HEADER_INDEX_ARRAY: [HeaderIndex; MAX_HEADERS] = [EMPTY_HEADER_INDEX; MAX_HEADERS];
impl HeaderIndex {
fn record(
bytes: &[u8],
headers: &[httparse::Header<'_>],
indices: &mut [HeaderIndex],
) {
fn record(bytes: &[u8], headers: &[httparse::Header<'_>], indices: &mut [HeaderIndex]) {
let bytes_ptr = bytes.as_ptr() as usize;
for (header, indices) in headers.iter().zip(indices.iter_mut()) {
let name_start = header.name.as_ptr() as usize - bytes_ptr;

View File

@ -25,10 +25,7 @@ async fn main() -> io::Result<()> {
Ok::<_, Error>(
Response::build(StatusCode::OK)
.insert_header((
"x-head",
HeaderValue::from_static("dummy value!"),
))
.insert_header(("x-head", HeaderValue::from_static("dummy value!")))
.body(body),
)
})

View File

@ -1,8 +1,7 @@
use std::io;
use actix_http::{
body::MessageBody, header::HeaderValue, Error, HttpService, Request, Response,
StatusCode,
body::MessageBody, header::HeaderValue, Error, HttpService, Request, Response, StatusCode,
};
use actix_server::Server;
use bytes::BytesMut;

View File

@ -21,10 +21,7 @@ async fn main() -> io::Result<()> {
log::info!("{:?}", req);
let mut res = Response::build(StatusCode::OK);
res.insert_header((
"x-head",
HeaderValue::from_static("dummy value!"),
));
res.insert_header(("x-head", HeaderValue::from_static("dummy value!")));
let forty_two = req.extensions().get::<u32>().unwrap().to_string();
res.insert_header((

View File

@ -60,10 +60,7 @@ impl Heartbeat {
impl Stream for Heartbeat {
type Item = Result<Bytes, Error>;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
log::trace!("poll");
ready!(self.as_mut().interval.poll_tick(cx));

View File

@ -1,5 +0,0 @@
max_width = 89
reorder_imports = true
#wrap_comments = true
#fn_args_density = "Compressed"
#use_small_heuristics = false

View File

@ -165,8 +165,7 @@ mod tests {
#[actix_rt::test]
async fn stream_delayed_error() {
let body =
BodyStream::new(stream::iter(vec![Ok(Bytes::from("1")), Err(StreamErr)]));
let body = BodyStream::new(stream::iter(vec![Ok(Bytes::from("1")), Err(StreamErr)]));
assert!(matches!(to_bytes(body).await, Err(StreamErr)));
pin_project! {

View File

@ -24,9 +24,7 @@ impl BoxBody {
}
/// Returns a mutable pinned reference to the inner message body type.
pub fn as_pin_mut(
&mut self,
) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
self.0.as_mut()
}
}

View File

@ -68,9 +68,8 @@ mod test {
let bytes = to_bytes(body).await.unwrap();
assert_eq!(bytes, b"123"[..]);
let stream =
stream::iter(vec![Bytes::from_static(b"123"), Bytes::from_static(b"abc")])
.map(Ok::<_, Error>);
let stream = stream::iter(vec![Bytes::from_static(b"123"), Bytes::from_static(b"abc")])
.map(Ok::<_, Error>);
let body = BodyStream::new(stream);
let bytes = to_bytes(body).await.unwrap();
assert_eq!(bytes, b"123abc"[..]);

View File

@ -214,8 +214,7 @@ where
self.local_addr,
);
H2Service::with_config(cfg, service.into_factory())
.on_connect_ext(self.on_connect_ext)
H2Service::with_config(cfg, service.into_factory()).on_connect_ext(self.on_connect_ext)
}
/// Finish service configuration and create `HttpService` instance.

View File

@ -44,17 +44,17 @@ where
pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
let decoder = match encoding {
#[cfg(feature = "compress-brotli")]
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(
BrotliDecoder::new(Writer::new()),
))),
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(BrotliDecoder::new(
Writer::new(),
)))),
#[cfg(feature = "compress-gzip")]
ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(
ZlibDecoder::new(Writer::new()),
))),
#[cfg(feature = "compress-gzip")]
ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(
GzDecoder::new(Writer::new()),
))),
ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(GzDecoder::new(
Writer::new(),
)))),
#[cfg(feature = "compress-zstd")]
ContentEncoding::Zstd => Some(ContentDecoder::Zstd(Box::new(
ZstdDecoder::new(Writer::new()).expect(
@ -93,10 +93,7 @@ where
{
type Item = Result<Bytes, PayloadError>;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
loop {
if let Some(ref mut fut) = self.fut {
let (chunk, decoder) =

View File

@ -53,11 +53,7 @@ impl<B: MessageBody> Encoder<B> {
}
}
pub fn response(
encoding: ContentEncoding,
head: &mut ResponseHead,
body: B,
) -> Self {
pub fn response(encoding: ContentEncoding, head: &mut ResponseHead, body: B) -> Self {
let can_encode = !(head.headers().contains_key(&CONTENT_ENCODING)
|| head.status == StatusCode::SWITCHING_PROTOCOLS
|| head.status == StatusCode::NO_CONTENT

View File

@ -457,8 +457,7 @@ mod tests {
#[test]
fn test_payload_error() {
let err: PayloadError =
io::Error::new(io::ErrorKind::Other, "ParseError").into();
let err: PayloadError = io::Error::new(io::ErrorKind::Other, "ParseError").into();
assert!(err.to_string().contains("ParseError"));
let err = PayloadError::Incomplete(None);

View File

@ -50,10 +50,7 @@ impl ChunkedState {
}
}
fn read_size(
rdr: &mut BytesMut,
size: &mut u64,
) -> Poll<Result<ChunkedState, io::Error>> {
fn read_size(rdr: &mut BytesMut, size: &mut u64) -> Poll<Result<ChunkedState, io::Error>> {
let radix = 16;
let rem = match byte!(rdr) {
@ -111,10 +108,7 @@ impl ChunkedState {
_ => Poll::Ready(Ok(ChunkedState::Extension)), // no supported extensions
}
}
fn read_size_lf(
rdr: &mut BytesMut,
size: u64,
) -> Poll<Result<ChunkedState, io::Error>> {
fn read_size_lf(rdr: &mut BytesMut, size: u64) -> Poll<Result<ChunkedState, io::Error>> {
match byte!(rdr) {
b'\n' if size > 0 => Poll::Ready(Ok(ChunkedState::Body)),
b'\n' if size == 0 => Poll::Ready(Ok(ChunkedState::EndCr)),

View File

@ -74,8 +74,7 @@ pub(crate) trait MessageType: Sized {
let headers = self.headers_mut();
for idx in raw_headers.iter() {
let name =
HeaderName::from_bytes(&slice[idx.name.0..idx.name.1]).unwrap();
let name = HeaderName::from_bytes(&slice[idx.name.0..idx.name.1]).unwrap();
// SAFETY: httparse already checks header value is only visible ASCII bytes
// from_maybe_shared_unchecked contains debug assertions so they are omitted here
@ -605,8 +604,7 @@ mod tests {
#[test]
fn test_parse_body() {
let mut buf =
BytesMut::from("GET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
let mut buf = BytesMut::from("GET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
let mut reader = MessageDecoder::<Request>::default();
let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
@ -622,8 +620,7 @@ mod tests {
#[test]
fn test_parse_body_crlf() {
let mut buf =
BytesMut::from("\r\nGET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
let mut buf = BytesMut::from("\r\nGET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
let mut reader = MessageDecoder::<Request>::default();
let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();

View File

@ -27,6 +27,7 @@ use crate::{
use super::{
codec::Codec,
decoder::MAX_BUFFER_SIZE,
payload::{Payload, PayloadSender, PayloadStatus},
Message, MessageType,
};
@ -259,10 +260,7 @@ where
}
}
fn poll_flush(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), io::Error>> {
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
let InnerDispatcherProj { io, write_buf, .. } = self.project();
let mut io = Pin::new(io.as_mut().unwrap());
@ -272,10 +270,7 @@ where
while written < len {
match io.as_mut().poll_write(cx, &write_buf[written..])? {
Poll::Ready(0) => {
return Poll::Ready(Err(io::Error::new(
io::ErrorKind::WriteZero,
"",
)))
return Poll::Ready(Err(io::Error::new(io::ErrorKind::WriteZero, "")))
}
Poll::Ready(n) => written += n,
Poll::Pending => {
@ -418,15 +413,12 @@ where
while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
match stream.as_mut().poll_next(cx) {
Poll::Ready(Some(Ok(item))) => {
this.codec.encode(
Message::Chunk(Some(item)),
this.write_buf,
)?;
this.codec
.encode(Message::Chunk(Some(item)), this.write_buf)?;
}
Poll::Ready(None) => {
this.codec
.encode(Message::Chunk(None), this.write_buf)?;
this.codec.encode(Message::Chunk(None), this.write_buf)?;
// payload stream finished.
// set state to None and handle next message
this.state.set(State::None);
@ -453,15 +445,12 @@ where
while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
match stream.as_mut().poll_next(cx) {
Poll::Ready(Some(Ok(item))) => {
this.codec.encode(
Message::Chunk(Some(item)),
this.write_buf,
)?;
this.codec
.encode(Message::Chunk(Some(item)), this.write_buf)?;
}
Poll::Ready(None) => {
this.codec
.encode(Message::Chunk(None), this.write_buf)?;
this.codec.encode(Message::Chunk(None), this.write_buf)?;
// payload stream finished.
// set state to None and handle next message
this.state.set(State::None);
@ -567,9 +556,11 @@ where
}
};
}
_ => unreachable!(
"State must be set to ServiceCall or ExceptCall in handle_request"
),
_ => {
unreachable!(
"State must be set to ServiceCall or ExceptCall in handle_request"
)
}
}
}
}
@ -603,8 +594,7 @@ where
// everything remain in read buffer would be handed to
// upgraded Request.
MessageType::Stream if this.flow.upgrade.is_some() => {
this.messages
.push_back(DispatcherMessage::Upgrade(req));
this.messages.push_back(DispatcherMessage::Upgrade(req));
break;
}
@ -619,8 +609,7 @@ where
where the state can be collected and consumed.
*/
let (ps, pl) = Payload::create(false);
let (req1, _) =
req.replace_payload(crate::Payload::H1(pl));
let (req1, _) = req.replace_payload(crate::Payload::H1(pl));
req = req1;
*this.payload = Some(ps);
}
@ -641,9 +630,7 @@ where
if let Some(ref mut payload) = this.payload {
payload.feed_data(chunk);
} else {
error!(
"Internal server error: unexpected payload chunk"
);
error!("Internal server error: unexpected payload chunk");
this.flags.insert(Flags::READ_DISCONNECT);
this.messages.push_back(DispatcherMessage::Error(
Response::internal_server_error().drop_body(),
@ -681,12 +668,11 @@ where
payload.set_error(PayloadError::Overflow);
}
// Requests overflow buffer size should be responded with 431
this.messages.push_back(DispatcherMessage::Error(
Response::with_body(
this.messages
.push_back(DispatcherMessage::Error(Response::with_body(
StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE,
(),
),
));
)));
this.flags.insert(Flags::READ_DISCONNECT);
*this.error = Some(ParseError::TooLarge.into());
break;
@ -728,8 +714,7 @@ where
None => {
// conditionally go into shutdown timeout
if this.flags.contains(Flags::SHUTDOWN) {
if let Some(deadline) = this.codec.config().client_disconnect_timer()
{
if let Some(deadline) = this.codec.config().client_disconnect_timer() {
// write client disconnect time out and poll again to
// go into Some<Pin<&mut Sleep>> branch
this.ka_timer.set(Some(sleep_until(deadline)));
@ -772,9 +757,7 @@ where
this.flags.insert(Flags::STARTED | Flags::SHUTDOWN);
}
// still have unfinished task. try to reset and register keep-alive.
} else if let Some(deadline) =
this.codec.config().keep_alive_expire()
{
} else if let Some(deadline) = this.codec.config().keep_alive_expire() {
timer.as_mut().reset(deadline);
let _ = timer.poll(cx);
}
@ -793,7 +776,6 @@ where
/// Returns true when io stream can be disconnected after write to it.
///
/// It covers these conditions:
///
/// - `std::io::ErrorKind::ConnectionReset` after partial read.
/// - all data read done.
#[inline(always)]
@ -813,46 +795,39 @@ where
loop {
// Return early when read buf exceed decoder's max buffer size.
if this.read_buf.len() >= super::decoder::MAX_BUFFER_SIZE {
/*
At this point it's not known IO stream is still scheduled
to be waked up. so force wake up dispatcher just in case.
if this.read_buf.len() >= MAX_BUFFER_SIZE {
// At this point it's not known IO stream is still scheduled to be waked up so
// force wake up dispatcher just in case.
//
// Reason:
// AsyncRead mostly would only have guarantee wake up when the poll_read
// return Poll::Pending.
//
// Case:
// When read_buf is beyond max buffer size the early return could be successfully
// be parsed as a new Request. This case would not generate ParseError::TooLarge and
// at this point IO stream is not fully read to Pending and would result in
// dispatcher stuck until timeout (KA)
//
// Note:
// This is a perf choice to reduce branch on <Request as MessageType>::decode.
//
// A Request head too large to parse is only checked on
// `httparse::Status::Partial` condition.
Reason:
AsyncRead mostly would only have guarantee wake up
when the poll_read return Poll::Pending.
Case:
When read_buf is beyond max buffer size the early return
could be successfully be parsed as a new Request.
This case would not generate ParseError::TooLarge
and at this point IO stream is not fully read to Pending
and would result in dispatcher stuck until timeout (KA)
Note:
This is a perf choice to reduce branch on
<Request as MessageType>::decode.
A Request head too large to parse is only checked on
httparse::Status::Partial condition.
*/
if this.payload.is_none() {
/*
When dispatcher has a payload the responsibility of
wake up it would be shift to h1::payload::Payload.
Reason:
Self wake up when there is payload would waste poll
and/or result in over read.
Case:
When payload is (partial) dropped by user there is
no need to do read anymore.
At this case read_buf could always remain beyond
MAX_BUFFER_SIZE and self wake up would be busy poll
dispatcher and waste resource.
*/
// When dispatcher has a payload the responsibility of wake up it would be shift
// to h1::payload::Payload.
//
// Reason:
// Self wake up when there is payload would waste poll and/or result in
// over read.
//
// Case:
// When payload is (partial) dropped by user there is no need to do
// read anymore. At this case read_buf could always remain beyond
// MAX_BUFFER_SIZE and self wake up would be busy poll dispatcher and
// waste resources.
cx.waker().wake_by_ref();
}
@ -1060,14 +1035,12 @@ mod tests {
}
fn ok_service(
) -> impl Service<Request, Response = Response<impl MessageBody>, Error = Error>
{
) -> impl Service<Request, Response = Response<impl MessageBody>, Error = Error> {
fn_service(|_req: Request| ready(Ok::<_, Error>(Response::ok())))
}
fn echo_path_service(
) -> impl Service<Request, Response = Response<impl MessageBody>, Error = Error>
{
) -> impl Service<Request, Response = Response<impl MessageBody>, Error = Error> {
fn_service(|req: Request| {
let path = req.path().as_bytes();
ready(Ok::<_, Error>(
@ -1076,8 +1049,8 @@ mod tests {
})
}
fn echo_payload_service(
) -> impl Service<Request, Response = Response<Bytes>, Error = Error> {
fn echo_payload_service() -> impl Service<Request, Response = Response<Bytes>, Error = Error>
{
fn_service(|mut req: Request| {
Box::pin(async move {
use futures_util::stream::StreamExt as _;

View File

@ -103,9 +103,7 @@ pub(crate) trait MessageType: Sized {
dst.put_slice(b"\r\n");
}
}
BodySize::Sized(0) if camel_case => {
dst.put_slice(b"\r\nContent-Length: 0\r\n")
}
BodySize::Sized(0) if camel_case => dst.put_slice(b"\r\nContent-Length: 0\r\n"),
BodySize::Sized(0) => dst.put_slice(b"\r\ncontent-length: 0\r\n"),
BodySize::Sized(len) => helpers::write_content_length(len, dst),
BodySize::None => dst.put_slice(b"\r\n"),
@ -307,11 +305,7 @@ impl MessageType for RequestHeadType {
Version::HTTP_11 => "HTTP/1.1",
Version::HTTP_2 => "HTTP/2.0",
Version::HTTP_3 => "HTTP/3.0",
_ =>
return Err(io::Error::new(
io::ErrorKind::Other,
"unsupported version"
)),
_ => return Err(io::Error::new(io::ErrorKind::Other, "unsupported version")),
}
)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
@ -568,8 +562,7 @@ mod tests {
ConnectionType::Close,
&ServiceConfig::default(),
);
let data =
String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
assert!(data.contains("Content-Length: 0\r\n"));
assert!(data.contains("Connection: close\r\n"));
@ -583,8 +576,7 @@ mod tests {
ConnectionType::KeepAlive,
&ServiceConfig::default(),
);
let data =
String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
assert!(data.contains("Transfer-Encoding: chunked\r\n"));
assert!(data.contains("Content-Type: plain/text\r\n"));
assert!(data.contains("Date: date\r\n"));
@ -605,8 +597,7 @@ mod tests {
ConnectionType::KeepAlive,
&ServiceConfig::default(),
);
let data =
String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
assert!(data.contains("transfer-encoding: chunked\r\n"));
assert!(data.contains("content-type: xml\r\n"));
assert!(data.contains("content-type: plain/text\r\n"));
@ -639,8 +630,7 @@ mod tests {
ConnectionType::Close,
&ServiceConfig::default(),
);
let data =
String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
assert!(data.contains("content-length: 0\r\n"));
assert!(data.contains("connection: close\r\n"));
assert!(data.contains("authorization: another authorization\r\n"));
@ -663,8 +653,7 @@ mod tests {
ConnectionType::Upgrade,
&ServiceConfig::default(),
);
let data =
String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
assert!(!data.contains("content-length: 0\r\n"));
assert!(!data.contains("transfer-encoding: chunked\r\n"));
}

View File

@ -227,10 +227,7 @@ impl Inner {
self.len
}
fn readany(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, PayloadError>>> {
fn readany(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, PayloadError>>> {
if let Some(data) = self.items.pop_front() {
self.len -= data.len();
self.need_read = self.len < MAX_BUFFER_SIZE;

View File

@ -266,8 +266,7 @@ where
}
}
impl<T, S, B, X, U> ServiceFactory<(T, Option<net::SocketAddr>)>
for H1Service<T, S, B, X, U>
impl<T, S, B, X, U> ServiceFactory<(T, Option<net::SocketAddr>)> for H1Service<T, S, B, X, U>
where
T: AsyncRead + AsyncWrite + Unpin + 'static,
@ -310,9 +309,9 @@ where
let upgrade = match upgrade {
Some(upgrade) => {
let upgrade = upgrade.await.map_err(|e| {
log::error!("Init http upgrade service error: {:?}", e)
})?;
let upgrade = upgrade
.await
.map_err(|e| log::error!("Init http upgrade service error: {:?}", e))?;
Some(upgrade)
}
None => None,
@ -336,8 +335,7 @@ where
/// `Service` implementation for HTTP/1 transport
pub type H1ServiceHandler<T, S, B, X, U> = HttpServiceHandler<T, S, B, X, U>;
impl<T, S, B, X, U> Service<(T, Option<net::SocketAddr>)>
for HttpServiceHandler<T, S, B, X, U>
impl<T, S, B, X, U> Service<(T, Option<net::SocketAddr>)> for HttpServiceHandler<T, S, B, X, U>
where
T: AsyncRead + AsyncWrite + Unpin,

View File

@ -70,15 +70,12 @@ where
.unwrap()
.is_write_buf_full()
{
let next =
match this.body.as_mut().as_pin_mut().unwrap().poll_next(cx) {
Poll::Ready(Some(Ok(item))) => Poll::Ready(Some(item)),
Poll::Ready(Some(Err(err))) => {
return Poll::Ready(Err(err.into()))
}
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending,
};
let next = match this.body.as_mut().as_pin_mut().unwrap().poll_next(cx) {
Poll::Ready(Some(Ok(item))) => Poll::Ready(Some(item)),
Poll::Ready(Some(Err(err))) => return Poll::Ready(Err(err.into())),
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending,
};
match next {
Poll::Ready(item) => {
@ -88,9 +85,9 @@ where
let _ = this.body.take();
}
let framed = this.framed.as_mut().as_pin_mut().unwrap();
framed.write(Message::Chunk(item)).map_err(|err| {
Error::new_send_response().with_cause(err)
})?;
framed
.write(Message::Chunk(item))
.map_err(|err| Error::new_send_response().with_cause(err))?;
}
Poll::Pending => body_ready = false,
}

View File

@ -109,7 +109,7 @@ where
Poll::Ready(Some((req, tx))) => {
let (parts, body) = req.into_parts();
let pl = crate::h2::Payload::new(body);
let pl = Payload::<crate::payload::PayloadStream>::H2(pl);
let pl = Payload::H2(pl);
let mut req = Request::with_payload(pl);
let head = req.head_mut();
@ -160,16 +160,11 @@ where
Poll::Ready(_) => {
ping_pong.on_flight = false;
let dead_line =
this.config.keep_alive_expire().unwrap();
let dead_line = this.config.keep_alive_expire().unwrap();
ping_pong.timer.as_mut().reset(dead_line);
}
Poll::Pending => {
return ping_pong
.timer
.as_mut()
.poll(cx)
.map(|_| Ok(()))
return ping_pong.timer.as_mut().poll(cx).map(|_| Ok(()))
}
}
} else {

View File

@ -40,10 +40,7 @@ impl Payload {
impl Stream for Payload {
type Item = Result<Bytes, PayloadError>;
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let this = self.get_mut();
match ready!(Pin::new(&mut this.stream).poll_data(cx)) {

View File

@ -10,8 +10,7 @@ use std::{
use actix_codec::{AsyncRead, AsyncWrite};
use actix_rt::net::TcpStream;
use actix_service::{
fn_factory, fn_service, IntoServiceFactory, Service, ServiceFactory,
ServiceFactoryExt as _,
fn_factory, fn_service, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
};
use actix_utils::future::ready;
use futures_core::{future::LocalBoxFuture, ready};
@ -279,8 +278,7 @@ where
}
fn call(&self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
let on_connect_data =
OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
let on_connect_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
H2ServiceHandlerResponse {
state: State::Handshake(

View File

@ -6,7 +6,7 @@ use http::header::{HeaderName, InvalidHeaderName};
/// Sealed trait implemented for types that can be effectively borrowed as a [`HeaderValue`].
///
/// [`HeaderValue`]: crate::http::HeaderValue
/// [`HeaderValue`]: super::HeaderValue
pub trait AsHeaderName: Sealed {}
pub struct Seal;

View File

@ -12,7 +12,7 @@ use super::{Header, IntoHeaderValue};
/// An interface for types that can be converted into a [`HeaderName`]/[`HeaderValue`] pair for
/// insertion into a [`HeaderMap`].
///
/// [`HeaderMap`]: crate::http::HeaderMap
/// [`HeaderMap`]: super::HeaderMap
pub trait IntoHeaderPair: Sized {
type Error: Into<HttpError>;

View File

@ -123,12 +123,11 @@ impl HeaderMap {
let mut map = HeaderMap::with_capacity(capacity);
map.append(first_name.clone(), first_value);
let (map, _) =
drain.fold((map, first_name), |(mut map, prev_name), (name, value)| {
let name = name.unwrap_or(prev_name);
map.append(name.clone(), value);
(map, name)
});
let (map, _) = drain.fold((map, first_name), |(mut map, prev_name), (name, value)| {
let name = name.unwrap_or(prev_name);
map.append(name.clone(), value);
(map, name)
});
map
}

View File

@ -11,22 +11,20 @@ pub use http::header::{
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,
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,
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 crate::{error::ParseError, HttpMessage};
@ -43,8 +41,8 @@ pub use self::into_pair::IntoHeaderPair;
pub use self::into_value::IntoHeaderValue;
pub use self::map::HeaderMap;
pub use self::shared::{
parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate,
LanguageTag, Quality, QualityItem,
parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate, LanguageTag,
Quality, QualityItem,
};
pub use self::utils::{
fmt_comma_delimited, from_comma_delimited, from_one_raw_str, http_percent_encode,

View File

@ -63,9 +63,7 @@ pub struct ExtendedValue {
/// [RFC 2231 §7]: https://datatracker.ietf.org/doc/html/rfc2231#section-7
/// [RFC 2978 §2.3]: https://datatracker.ietf.org/doc/html/rfc2978#section-2.3
/// [RFC 3986 §2.1]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
pub fn parse_extended_value(
val: &str,
) -> Result<ExtendedValue, crate::error::ParseError> {
pub fn parse_extended_value(val: &str) -> Result<ExtendedValue, crate::error::ParseError> {
// Break into three pieces separated by the single-quote character
let mut parts = val.splitn(3, '\'');
@ -100,8 +98,7 @@ pub fn parse_extended_value(
impl fmt::Display for ExtendedValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let encoded_value =
percent_encoding::percent_encode(&self.value[..], HTTP_VALUE);
let encoded_value = percent_encoding::percent_encode(&self.value[..], HTTP_VALUE);
if let Some(ref lang) = self.language_tag {
write!(f, "{}'{}'{}", self.charset, lang, encoded_value)
} else {
@ -143,8 +140,8 @@ mod tests {
assert!(extended_value.language_tag.is_none());
assert_eq!(
vec![
194, 163, b' ', b'a', b'n', b'd', b' ', 226, 130, 172, b' ', b'r', b'a',
b't', b'e', b's',
194, 163, b' ', b'a', b'n', b'd', b' ', 226, 130, 172, b' ', b'r', b'a', b't',
b'e', b's',
],
extended_value.value
);
@ -185,8 +182,8 @@ mod tests {
charset: Charset::Ext("UTF-8".to_string()),
language_tag: None,
value: vec![
194, 163, b' ', b'a', b'n', b'd', b' ', 226, 130, 172, b' ', b'r', b'a',
b't', b'e', b's',
194, 163, b' ', b'a', b'n', b'd', b' ', 226, 130, 172, b' ', b'r', b'a', b't',
b'e', b's',
],
};
assert_eq!(

View File

@ -4,8 +4,7 @@ use bytes::BytesMut;
use http::header::{HeaderValue, InvalidHeaderValue};
use crate::{
config::DATE_VALUE_LENGTH, error::ParseError, header::IntoHeaderValue,
helpers::MutWriter,
config::DATE_VALUE_LENGTH, error::ParseError, header::IntoHeaderValue, helpers::MutWriter,
};
/// A timestamp with HTTP-style formatting and parsing.

View File

@ -120,8 +120,7 @@ impl<T: str::FromStr> str::FromStr for QualityItem<T> {
}
let q_value = q_val.parse::<f32>().map_err(|_| ParseError::Header)?;
let q_value =
Quality::try_from(q_value).map_err(|_| ParseError::Header)?;
let q_value = Quality::try_from(q_value).map_err(|_| ParseError::Header)?;
quality = q_value;
raw_item = val;

View File

@ -14,7 +14,8 @@
//! [rustls]: https://crates.io/crates/rustls
//! [trust-dns]: https://crates.io/crates/trust-dns
#![deny(rust_2018_idioms, nonstandard_style, clippy::uninit_assumed_init)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![allow(
clippy::type_complexity,
clippy::too_many_arguments,
@ -87,10 +88,7 @@ pub(crate) struct OnConnectData(Option<Extensions>);
impl OnConnectData {
/// Construct by calling the on-connect callback with the underlying transport I/O.
pub(crate) fn from_io<T>(
io: &T,
on_connect_ext: Option<&ConnectCallback<T>>,
) -> Self {
pub(crate) fn from_io<T>(io: &T, on_connect_ext: Option<&ConnectCallback<T>>) -> Self {
let ext = on_connect_ext.map(|handler| {
let mut extensions = Extensions::default();
handler(io, &mut extensions);

View File

@ -56,10 +56,7 @@ where
type Item = Result<Bytes, PayloadError>;
#[inline]
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match self.get_mut() {
Payload::None => Poll::Ready(None),
Payload::H1(ref mut pl) => pl.readany(cx),

View File

@ -231,9 +231,7 @@ impl<B: Default> Default for Response<B> {
}
}
impl<I: Into<Response<BoxBody>>, E: Into<Error>> From<Result<I, E>>
for Response<BoxBody>
{
impl<I: Into<Response<BoxBody>>, E: Into<Error>> From<Result<I, E>> for Response<BoxBody> {
fn from(res: Result<I, E>) -> Self {
match res {
Ok(val) => val.into(),

View File

@ -47,7 +47,8 @@ impl ResponseBuilder {
/// Create response builder
///
/// # Examples
// /// use actix_http::{Response, ResponseBuilder, StatusCode};, / ``
/// ```
/// use actix_http::{Response, ResponseBuilder, StatusCode};
/// let res: Response<_> = ResponseBuilder::default().finish();
/// assert_eq!(res.status(), StatusCode::OK);
/// ```
@ -62,7 +63,8 @@ impl ResponseBuilder {
/// Set HTTP status code of this response.
///
/// # Examples
// /// use actix_http::{ResponseBuilder, StatusCode};, / ``
/// ```
/// use actix_http::{ResponseBuilder, StatusCode};
/// let res = ResponseBuilder::default().status(StatusCode::NOT_FOUND).finish();
/// assert_eq!(res.status(), StatusCode::NOT_FOUND);
/// ```

View File

@ -161,11 +161,7 @@ where
X::Error: Into<Response<BoxBody>>,
X::InitError: fmt::Debug,
U: ServiceFactory<
(Request, Framed<TcpStream, h1::Codec>),
Config = (),
Response = (),
>,
U: ServiceFactory<(Request, Framed<TcpStream, h1::Codec>), Config = (), Response = ()>,
U::Future: 'static,
U::Error: fmt::Display + Into<Response<BoxBody>>,
U::InitError: fmt::Debug,
@ -381,9 +377,9 @@ where
let upgrade = match upgrade {
Some(upgrade) => {
let upgrade = upgrade.await.map_err(|e| {
log::error!("Init http upgrade service error: {:?}", e)
})?;
let upgrade = upgrade
.await
.map_err(|e| log::error!("Init http upgrade service error: {:?}", e))?;
Some(upgrade)
}
None => None,
@ -626,8 +622,7 @@ where
StateProj::H2Handshake { handshake: data } => {
match ready!(Pin::new(&mut data.as_mut().unwrap().0).poll(cx)) {
Ok((conn, timer)) => {
let (_, config, flow, conn_data, peer_addr) =
data.take().unwrap();
let (_, config, flow, conn_data, peer_addr) = data.take().unwrap();
self.as_mut().project().state.set(State::H2 {
dispatcher: h2::Dispatcher::new(

View File

@ -224,9 +224,7 @@ impl Decoder for Codec {
OpCode::Continue => {
if self.flags.contains(Flags::CONTINUATION) {
Ok(Some(Frame::Continuation(Item::Continue(
payload
.map(|pl| pl.freeze())
.unwrap_or_else(Bytes::new),
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
))))
} else {
Err(ProtocolError::ContinuationNotStarted)
@ -236,9 +234,7 @@ impl Decoder for Codec {
if !self.flags.contains(Flags::CONTINUATION) {
self.flags.insert(Flags::CONTINUATION);
Ok(Some(Frame::Continuation(Item::FirstBinary(
payload
.map(|pl| pl.freeze())
.unwrap_or_else(Bytes::new),
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
))))
} else {
Err(ProtocolError::ContinuationStarted)
@ -248,9 +244,7 @@ impl Decoder for Codec {
if !self.flags.contains(Flags::CONTINUATION) {
self.flags.insert(Flags::CONTINUATION);
Ok(Some(Frame::Continuation(Item::FirstText(
payload
.map(|pl| pl.freeze())
.unwrap_or_else(Bytes::new),
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
))))
} else {
Err(ProtocolError::ContinuationStarted)

View File

@ -304,8 +304,7 @@ mod inner {
let item = match this.framed.next_item(cx) {
Poll::Ready(Some(Ok(el))) => el,
Poll::Ready(Some(Err(err))) => {
*this.state =
State::FramedError(DispatcherError::Decoder(err));
*this.state = State::FramedError(DispatcherError::Decoder(err));
return true;
}
Poll::Pending => return false,
@ -348,8 +347,7 @@ mod inner {
match Pin::new(&mut this.rx).poll_next(cx) {
Poll::Ready(Some(Ok(Message::Item(msg)))) => {
if let Err(err) = this.framed.as_mut().write(msg) {
*this.state =
State::FramedError(DispatcherError::Encoder(err));
*this.state = State::FramedError(DispatcherError::Encoder(err));
return true;
}
}
@ -371,8 +369,7 @@ mod inner {
Poll::Ready(Ok(_)) => {}
Poll::Ready(Err(err)) => {
debug!("Error sending data: {:?}", err);
*this.state =
State::FramedError(DispatcherError::Encoder(err));
*this.state = State::FramedError(DispatcherError::Encoder(err));
return true;
}
}
@ -432,9 +429,7 @@ mod inner {
Poll::Ready(Ok(()))
}
}
State::FramedError(_) => {
Poll::Ready(Err(this.state.take_framed_error()))
}
State::FramedError(_) => Poll::Ready(Err(this.state.take_framed_error())),
State::Stopping => Poll::Ready(Ok(())),
};
}

View File

@ -16,8 +16,7 @@ impl Parser {
src: &[u8],
server: bool,
max_size: usize,
) -> Result<Option<(usize, bool, OpCode, usize, Option<[u8; 4]>)>, ProtocolError>
{
) -> Result<Option<(usize, bool, OpCode, usize, Option<[u8; 4]>)>, ProtocolError> {
let chunk_len = src.len();
let mut idx = 2;
@ -228,15 +227,11 @@ mod tests {
payload: Bytes,
}
fn is_none(
frm: &Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>,
) -> bool {
fn is_none(frm: &Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>) -> bool {
matches!(*frm, Ok(None))
}
fn extract(
frm: Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>,
) -> F {
fn extract(frm: Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>) -> F {
match frm {
Ok(Some((finished, opcode, payload))) => F {
finished,

View File

@ -54,8 +54,8 @@ mod tests {
let mask = [0x6d, 0xb6, 0xb2, 0x80];
let unmasked = vec![
0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17,
0x74, 0xf9, 0x12, 0x03,
0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17, 0x74, 0xf9,
0x12, 0x03,
];
// Check masking with proper alignment.
@ -85,8 +85,8 @@ mod tests {
fn test_apply_mask() {
let mask = [0x6d, 0xb6, 0xb2, 0x80];
let unmasked = vec![
0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17,
0x74, 0xf9, 0x12, 0x03,
0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17, 0x74, 0xf9,
0x12, 0x03,
];
for data_len in 0..=unmasked.len() {

View File

@ -9,9 +9,7 @@ use derive_more::{Display, Error, From};
use http::{header, Method, StatusCode};
use crate::body::BoxBody;
use crate::{
header::HeaderValue, message::RequestHead, response::Response, ResponseBuilder,
};
use crate::{header::HeaderValue, message::RequestHead, response::Response, ResponseBuilder};
mod codec;
mod dispatcher;

View File

@ -1,8 +1,6 @@
use std::convert::Infallible;
use actix_http::{
body::BoxBody, HttpMessage, HttpService, Request, Response, StatusCode,
};
use actix_http::{body::BoxBody, HttpMessage, HttpService, Request, Response, StatusCode};
use actix_http_test::test_server;
use actix_service::ServiceFactoryExt;
use actix_utils::future;

View File

@ -170,10 +170,11 @@ async fn test_h2_headers() {
let mut srv = test_server(move || {
let data = data.clone();
HttpService::build().h2(move |_| {
let mut builder = Response::build(StatusCode::OK);
for idx in 0..90 {
builder.insert_header(
HttpService::build()
.h2(move |_| {
let mut builder = Response::build(StatusCode::OK);
for idx in 0..90 {
builder.insert_header(
(format!("X-TEST-{}", idx).as_str(),
"TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
@ -189,12 +190,13 @@ async fn test_h2_headers() {
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ",
));
}
ok::<_, Infallible>(builder.body(data.clone()))
})
}
ok::<_, Infallible>(builder.body(data.clone()))
})
.openssl(tls_config())
.map_err(|_| ())
}).await;
.map_err(|_| ())
})
.await;
let response = srv.sget("/").send().await.unwrap();
assert!(response.status().is_success());
@ -315,9 +317,8 @@ async fn test_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)),

View File

@ -238,10 +238,11 @@ async fn test_h2_headers() {
let mut srv = test_server(move || {
let data = data.clone();
HttpService::build().h2(move |_| {
let mut config = Response::build(StatusCode::OK);
for idx in 0..90 {
config.insert_header((
HttpService::build()
.h2(move |_| {
let mut config = Response::build(StatusCode::OK);
for idx in 0..90 {
config.insert_header((
format!("X-TEST-{}", idx).as_str(),
"TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
@ -257,11 +258,12 @@ async fn test_h2_headers() {
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ",
));
}
ok::<_, Infallible>(config.body(data.clone()))
})
}
ok::<_, Infallible>(config.body(data.clone()))
})
.rustls(tls_config())
}).await;
})
.await;
let response = srv.sget("/").send().await.unwrap();
assert!(response.status().is_success());

View File

@ -154,9 +154,7 @@ async fn test_chunked_payload() {
})
.fold(0usize, |acc, chunk| ready(acc + chunk.len()))
.map(|req_size| {
Ok::<_, Error>(
Response::ok().set_body(format!("size={}", req_size)),
)
Ok::<_, Error>(Response::ok().set_body(format!("size={}", req_size)))
})
}))
.tcp()
@ -165,8 +163,7 @@ async fn test_chunked_payload() {
let returned_size = {
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
let _ = stream
.write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n");
let _ = stream.write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n");
for chunk_size in chunk_sizes.iter() {
let mut bytes = Vec::new();
@ -293,8 +290,7 @@ async fn test_http1_keepalive_close() {
.await;
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
let _ =
stream.write_all(b"GET /test/tests/test HTTP/1.1\r\nconnection: close\r\n\r\n");
let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\nconnection: close\r\n\r\n");
let mut data = vec![0; 1024];
let _ = stream.read(&mut data);
assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n");
@ -338,8 +334,8 @@ async fn test_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");
@ -436,10 +432,11 @@ async fn test_h1_headers() {
let mut srv = test_server(move || {
let data = data.clone();
HttpService::build().h1(move |_| {
let mut builder = Response::build(StatusCode::OK);
for idx in 0..90 {
builder.insert_header((
HttpService::build()
.h1(move |_| {
let mut builder = Response::build(StatusCode::OK);
for idx in 0..90 {
builder.insert_header((
format!("X-TEST-{}", idx).as_str(),
"TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
@ -455,10 +452,12 @@ async fn test_h1_headers() {
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ",
));
}
ok::<_, Infallible>(builder.body(data.clone()))
}).tcp()
}).await;
}
ok::<_, Infallible>(builder.body(data.clone()))
})
.tcp()
})
.await;
let response = srv.get("/").send().await.unwrap();
assert!(response.status().is_success());
@ -655,9 +654,7 @@ async fn test_h1_body_chunked_implicit() {
HttpService::build()
.h1(|_| {
let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref())));
ok::<_, Infallible>(
Response::build(StatusCode::OK).body(BodyStream::new(body)),
)
ok::<_, Infallible>(Response::build(StatusCode::OK).body(BodyStream::new(body)))
})
.tcp()
})
@ -776,10 +773,8 @@ async fn test_not_modified_spec_h1() {
.h1(|req: Request| {
let res: Response<BoxBody> = match req.path() {
// with no content-length
"/none" => {
Response::with_body(StatusCode::NOT_MODIFIED, body::None::new())
.map_into_boxed_body()
}
"/none" => Response::with_body(StatusCode::NOT_MODIFIED, body::None::new())
.map_into_boxed_body(),
// with no content-length
"/body" => Response::with_body(StatusCode::NOT_MODIFIED, "1234")
@ -787,10 +782,8 @@ async fn test_not_modified_spec_h1() {
// with manual content-length header and specific None body
"/cl-none" => {
let mut res = Response::with_body(
StatusCode::NOT_MODIFIED,
body::None::new(),
);
let mut res =
Response::with_body(StatusCode::NOT_MODIFIED, body::None::new());
res.headers_mut()
.insert(CL.clone(), header::HeaderValue::from_static("24"));
res.map_into_boxed_body()
@ -798,8 +791,7 @@ async fn test_not_modified_spec_h1() {
// with manual content-length header and ignore-able body
"/cl-body" => {
let mut res =
Response::with_body(StatusCode::NOT_MODIFIED, "1234");
let mut res = Response::with_body(StatusCode::NOT_MODIFIED, "1234");
res.headers_mut()
.insert(CL.clone(), header::HeaderValue::from_static("4"));
res.map_into_boxed_body()

View File

@ -56,8 +56,9 @@ impl From<WsServiceError> for Response<BoxBody> {
WsServiceError::Http(err) => err.into(),
WsServiceError::Ws(err) => err.into(),
WsServiceError::Io(_err) => unreachable!(),
WsServiceError::Dispatcher => Response::internal_server_error()
.set_body(BoxBody::new(format!("{}", err))),
WsServiceError::Dispatcher => {
Response::internal_server_error().set_body(BoxBody::new(format!("{}", err)))
}
}
}
}
@ -97,9 +98,7 @@ where
async fn service(msg: Frame) -> Result<Message, Error> {
let msg = match msg {
Frame::Ping(msg) => Message::Pong(msg),
Frame::Text(text) => {
Message::Text(String::from_utf8_lossy(&text).into_owned().into())
}
Frame::Text(text) => Message::Text(String::from_utf8_lossy(&text).into_owned().into()),
Frame::Binary(bin) => Message::Binary(bin),
Frame::Continuation(item) => Message::Continuation(item),
Frame::Close(reason) => Message::Close(reason),

View File

@ -1,6 +1,7 @@
//! Multipart form support for Actix Web.
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![allow(clippy::borrow_interior_mutable_const)]
mod error;

View File

@ -1,6 +1,7 @@
//! Resource path matching and router.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

View File

@ -168,7 +168,7 @@ const REGEX_FLAGS: &str = "(?s-m)";
/// extracted in the same way as non-tail dynamic segments.
///
/// ## Examples
/// ```rust
/// ```
/// # use actix_router::{Path, ResourceDef};
/// let resource = ResourceDef::new("/blob/{tail}*");
/// assert!(resource.is_match("/blob/HEAD/Cargo.toml"));
@ -191,7 +191,7 @@ const REGEX_FLAGS: &str = "(?s-m)";
/// expectations in the router using these definitions and cause runtime panics.
///
/// ## Examples
/// ```rust
/// ```
/// # use actix_router::ResourceDef;
/// let resource = ResourceDef::new(["/home", "/index"]);
/// assert!(resource.is_match("/home"));
@ -206,7 +206,7 @@ const REGEX_FLAGS: &str = "(?s-m)";
/// resource-path pairs that would not be compatible.
///
/// ## Examples
/// ```rust
/// ```
/// # use actix_router::ResourceDef;
/// assert!(!ResourceDef::new("/root").is_match("/root/"));
/// assert!(!ResourceDef::new("/root/").is_match("/root"));

View File

@ -26,6 +26,9 @@
//! }
//! ```
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#[cfg(feature = "openssl")]
extern crate tls_openssl as openssl;
#[cfg(feature = "rustls")]

View File

@ -1,7 +1,7 @@
//! Actix actors support for Actix Web.
#![deny(rust_2018_idioms)]
#![allow(clippy::borrow_interior_mutable_const)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
mod context;
pub mod ws;

View File

@ -57,6 +57,8 @@
//! [DELETE]: macro@delete
#![recursion_limit = "512"]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
use proc_macro::TokenStream;
use quote::quote;

View File

@ -1,7 +1,4 @@
extern crate proc_macro;
use std::collections::HashSet;
use std::convert::TryFrom;
use std::{collections::HashSet, convert::TryFrom};
use actix_router::ResourceDef;
use proc_macro::TokenStream;

View File

@ -95,7 +95,8 @@
//! # }
//! ```
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![allow(
clippy::type_complexity,
clippy::borrow_interior_mutable_const,

View File

@ -128,7 +128,7 @@ macro_rules! error_helper {
InternalError::new(err, StatusCode::$status).into()
}
}
}
};
}
error_helper!(ErrorBadRequest, BAD_REQUEST);

View File

@ -1,8 +1,9 @@
//! Error and Result module
/// This is meant to be a glob import of the whole error module, but rustdoc can't handle
/// shadowing `Error` type, so it is expanded manually.
/// See https://github.com/rust-lang/rust/issues/83375
// This is meant to be a glob import of the whole error module except for `Error`. Rustdoc can't yet
// correctly resolve the conflicting `Error` type defined in this module, so these re-exports are
// expanded manually.
//
// See <https://github.com/rust-lang/rust/issues/83375>
pub use actix_http::error::{
BlockingError, ContentTypeError, DispatchError, HttpError, ParseError, PayloadError,
};

View File

@ -65,6 +65,7 @@
//! * `secure-cookies` - secure cookies support
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![allow(clippy::needless_doctest_main, clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

View File

@ -173,7 +173,7 @@ impl HttpRequest {
/// let opt_t = req.conn_data::<PeerCertificate>();
/// ```
///
/// [on-connect]: crate::HttpServiceBuilder::on_connect_ext
/// [on-connect]: crate::HttpServer::on_connect
pub fn conn_data<T: 'static>(&self) -> Option<&T> {
self.inner
.conn_data

View File

@ -109,6 +109,7 @@ impl HttpResponseBuilder {
}
/// Replaced with [`Self::insert_header()`].
#[doc(hidden)]
#[deprecated(
since = "4.0.0",
note = "Replaced with `insert_header((key, value))`. Will be removed in v5."
@ -133,6 +134,7 @@ impl HttpResponseBuilder {
}
/// Replaced with [`Self::append_header()`].
#[doc(hidden)]
#[deprecated(
since = "4.0.0",
note = "Replaced with `append_header((key, value))`. Will be removed in v5."