Merge branch 'master' into fix-directory-attack-bug

This commit is contained in:
Thomas Harmon 2021-03-09 12:11:31 -05:00 committed by GitHub
commit 4a60fcf355
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 69 additions and 98 deletions

View File

@ -87,8 +87,8 @@ actix-utils = "3.0.0-beta.2"
actix-tls = { version = "3.0.0-beta.4", default-features = false, optional = true }
actix-web-codegen = "0.5.0-beta.1"
actix-http = "3.0.0-beta.3"
awc = { version = "3.0.0-beta.2", default-features = false }
actix-http = "3.0.0-beta.4"
awc = { version = "3.0.0-beta.3", default-features = false }
ahash = "0.7"
bytes = "1"

View File

@ -35,7 +35,7 @@ actix-tls = "3.0.0-beta.4"
actix-utils = "3.0.0-beta.2"
actix-rt = "2.1"
actix-server = "2.0.0-beta.3"
awc = { version = "3.0.0-beta.2", default-features = false }
awc = { version = "3.0.0-beta.3", default-features = false }
base64 = "0.13"
bytes = "1"
@ -58,4 +58,4 @@ optional = true
[dev-dependencies]
actix-web = { version = "4.0.0-beta.3", default-features = false, features = ["cookies"] }
actix-http = "3.0.0-beta.3"
actix-http = "3.0.0-beta.4"

View File

@ -1,13 +1,16 @@
# Changes
## Unreleased - 2021-xx-xx
## 3.0.0-beta.4 - 2021-03-08
### Changed
* Feature `cookies` is now optional and disabled by default. [#1981]
* `ws::hash_key` now returns array. [#2035]
* `ResponseBuilder::json` now takes `impl Serialize`. [#2052]
### Removed
* re-export of `futures_channel::oneshot::Canceled` is removed from `error` mod. [#1994]
* Re-export of `futures_channel::oneshot::Canceled` is removed from `error` mod. [#1994]
* `ResponseError` impl for `futures_channel::oneshot::Canceled` is removed. [#1994]
[#1981]: https://github.com/actix/actix-web/pull/1981

View File

@ -1,6 +1,6 @@
[package]
name = "actix-http"
version = "3.0.0-beta.3"
version = "3.0.0-beta.4"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "HTTP primitives for the Actix ecosystem"
readme = "README.md"

View File

@ -3,11 +3,11 @@
> HTTP primitives for the Actix ecosystem.
[![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http)
[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.0.0-beta.3)](https://docs.rs/actix-http/3.0.0-beta.3)
[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.0.0-beta.4)](https://docs.rs/actix-http/3.0.0-beta.4)
[![Version](https://img.shields.io/badge/rustc-1.46+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.46.html)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-http/3.0.0-beta.3/status.svg)](https://deps.rs/crate/actix-http/3.0.0-beta.3)
[![dependency status](https://deps.rs/crate/actix-http/3.0.0-beta.4/status.svg)](https://deps.rs/crate/actix-http/3.0.0-beta.4)
[![Download](https://img.shields.io/crates/d/actix-http.svg)](https://crates.io/crates/actix-http)
[![Join the chat at https://gitter.im/actix/actix](https://badges.gitter.im/actix/actix.svg)](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

View File

@ -2,7 +2,6 @@ use std::task::{Context, Poll};
use std::{cmp, future::Future, marker::PhantomData, net, pin::Pin, rc::Rc};
use actix_codec::{AsyncRead, AsyncWrite};
use actix_rt::time::{Instant, Sleep};
use actix_service::Service;
use bytes::{Bytes, BytesMut};
use futures_core::ready;
@ -36,8 +35,6 @@ where
on_connect_data: OnConnectData,
config: ServiceConfig,
peer_addr: Option<net::SocketAddr>,
ka_expire: Instant,
ka_timer: Option<Sleep>,
_phantom: PhantomData<B>,
}
@ -54,33 +51,14 @@ where
connection: Connection<T, Bytes>,
on_connect_data: OnConnectData,
config: ServiceConfig,
timeout: Option<Sleep>,
peer_addr: Option<net::SocketAddr>,
) -> Self {
// let keepalive = config.keep_alive_enabled();
// let flags = if keepalive {
// Flags::KEEPALIVE | Flags::KEEPALIVE_ENABLED
// } else {
// Flags::empty()
// };
// keep-alive timer
let (ka_expire, ka_timer) = if let Some(delay) = timeout {
(delay.deadline(), Some(delay))
} else if let Some(delay) = config.keep_alive_timer() {
(delay.deadline(), Some(delay))
} else {
(config.now(), None)
};
Dispatcher {
flow,
config,
peer_addr,
connection,
on_connect_data,
ka_expire,
ka_timer,
_phantom: PhantomData,
}
}
@ -108,13 +86,6 @@ where
Some(Err(err)) => return Poll::Ready(Err(err.into())),
Some(Ok((req, res))) => {
// update keep-alive expire
if this.ka_timer.is_some() {
if let Some(expire) = this.config.keep_alive_expire() {
this.ka_expire = expire;
}
}
let (parts, body) = req.into_parts();
let pl = crate::h2::Payload::new(body);
let pl = Payload::<crate::payload::PayloadStream>::H2(pl);
@ -130,7 +101,7 @@ where
// merge on_connect_ext data into request extensions
this.on_connect_data.merge_into(&mut req);
let svc = ServiceResponse::<S::Future, S::Response, S::Error, B> {
let svc = ServiceResponse {
state: ServiceResponseState::ServiceCall(
this.flow.service.call(req),
Some(res),
@ -312,57 +283,50 @@ where
ServiceResponseStateProj::SendPayload(ref mut stream, ref mut body) => {
loop {
loop {
match this.buffer {
Some(ref mut buffer) => {
match ready!(stream.poll_capacity(cx)) {
None => return Poll::Ready(()),
match this.buffer {
Some(ref mut buffer) => match ready!(stream.poll_capacity(cx)) {
None => return Poll::Ready(()),
Some(Ok(cap)) => {
let len = buffer.len();
let bytes = buffer.split_to(cmp::min(cap, len));
Some(Ok(cap)) => {
let len = buffer.len();
let bytes = buffer.split_to(cmp::min(cap, len));
if let Err(e) = stream.send_data(bytes, false) {
warn!("{:?}", e);
return Poll::Ready(());
} else if !buffer.is_empty() {
let cap = cmp::min(buffer.len(), CHUNK_SIZE);
stream.reserve_capacity(cap);
} else {
this.buffer.take();
}
}
Some(Err(e)) => {
warn!("{:?}", e);
return Poll::Ready(());
}
if let Err(e) = stream.send_data(bytes, false) {
warn!("{:?}", e);
return Poll::Ready(());
} else if !buffer.is_empty() {
let cap = cmp::min(buffer.len(), CHUNK_SIZE);
stream.reserve_capacity(cap);
} else {
this.buffer.take();
}
}
None => match ready!(body.as_mut().poll_next(cx)) {
None => {
if let Err(e) = stream.send_data(Bytes::new(), true)
{
warn!("{:?}", e);
}
return Poll::Ready(());
}
Some(Err(e)) => {
warn!("{:?}", e);
return Poll::Ready(());
}
},
Some(Ok(chunk)) => {
stream.reserve_capacity(cmp::min(
chunk.len(),
CHUNK_SIZE,
));
*this.buffer = Some(chunk);
None => match ready!(body.as_mut().poll_next(cx)) {
None => {
if let Err(e) = stream.send_data(Bytes::new(), true) {
warn!("{:?}", e);
}
return Poll::Ready(());
}
Some(Err(e)) => {
error!("Response payload stream error: {:?}", e);
return Poll::Ready(());
}
},
}
Some(Ok(chunk)) => {
stream
.reserve_capacity(cmp::min(chunk.len(), CHUNK_SIZE));
*this.buffer = Some(chunk);
}
Some(Err(e)) => {
error!("Response payload stream error: {:?}", e);
return Poll::Ready(());
}
},
}
}
}

View File

@ -368,7 +368,6 @@ where
conn,
on_connect_data,
config.take().unwrap(),
None,
*peer_addr,
));
self.poll(cx)

View File

@ -658,7 +658,6 @@ where
conn,
on_connect_data,
cfg,
None,
peer_addr,
)));
self.poll(cx)

View File

@ -126,7 +126,7 @@ async fn test_chunked_payload() {
.take_payload()
.map(|res| match res {
Ok(pl) => pl,
Err(e) => panic!(format!("Error reading payload: {}", e)),
Err(e) => panic!("Error reading payload: {}", e),
})
.fold(0usize, |acc, chunk| ready(acc + chunk.len()))
.map(|req_size| {
@ -162,7 +162,7 @@ async fn test_chunked_payload() {
let re = Regex::new(r"size=(\d+)").unwrap();
let size: usize = match re.captures(&data) {
Some(caps) => caps.get(1).unwrap().as_str().parse().unwrap(),
None => panic!(format!("Failed to find size in HTTP Response: {}", data)),
None => panic!("Failed to find size in HTTP Response: {}", data),
};
size
};

View File

@ -29,6 +29,6 @@ twoway = "0.2"
[dev-dependencies]
actix-rt = "2.1"
actix-http = "3.0.0-beta.3"
actix-http = "3.0.0-beta.4"
tokio = { version = "1", features = ["sync"] }
tokio-stream = "0.1"

View File

@ -18,7 +18,7 @@ path = "src/lib.rs"
[dependencies]
actix = { version = "0.11.0-beta.3", default-features = false }
actix-codec = "0.4.0-beta.1"
actix-http = "3.0.0-beta.3"
actix-http = "3.0.0-beta.4"
actix-web = { version = "4.0.0-beta.3", default-features = false }
bytes = "1"

View File

@ -1,6 +1,9 @@
# Changes
## Unreleased - 2021-xx-xx
## 3.0.0-beta.3 - 2021-03-08
### Added
* `ClientResponse::timeout` for set the timeout of collecting response body. [#1931]
* `ClientBuilder::local_address` for bind to a local ip address for this client. [#2024]

View File

@ -1,6 +1,6 @@
[package]
name = "awc"
version = "3.0.0-beta.2"
version = "3.0.0-beta.3"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Async HTTP and WebSocket client library built on the Actix ecosystem"
readme = "README.md"
@ -46,7 +46,7 @@ trust-dns = ["actix-http/trust-dns"]
[dependencies]
actix-codec = "0.4.0-beta.1"
actix-service = "2.0.0-beta.4"
actix-http = "3.0.0-beta.3"
actix-http = "3.0.0-beta.4"
actix-rt = { version = "2.1", default-features = false }
base64 = "0.13"
@ -74,7 +74,7 @@ optional = true
[dev-dependencies]
actix-web = { version = "4.0.0-beta.3", features = ["openssl"] }
actix-http = { version = "3.0.0-beta.3", features = ["openssl"] }
actix-http = { version = "3.0.0-beta.4", features = ["openssl"] }
actix-http-test = { version = "3.0.0-beta.2", features = ["openssl"] }
actix-utils = "3.0.0-beta.1"
actix-server = "2.0.0-beta.3"

View File

@ -3,9 +3,9 @@
> Async HTTP and WebSocket client library.
[![crates.io](https://img.shields.io/crates/v/awc?label=latest)](https://crates.io/crates/awc)
[![Documentation](https://docs.rs/awc/badge.svg?version=3.0.0-beta.2)](https://docs.rs/awc/3.0.0-beta.2)
[![Documentation](https://docs.rs/awc/badge.svg?version=3.0.0-beta.3)](https://docs.rs/awc/3.0.0-beta.3)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc)
[![Dependency Status](https://deps.rs/crate/awc/3.0.0-beta.2/status.svg)](https://deps.rs/crate/awc/3.0.0-beta.2)
[![Dependency Status](https://deps.rs/crate/awc/3.0.0-beta.3/status.svg)](https://deps.rs/crate/awc/3.0.0-beta.3)
[![Join the chat at https://gitter.im/actix/actix-web](https://badges.gitter.im/actix/actix-web.svg)](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Documentation & Resources

View File

@ -382,7 +382,7 @@ impl WebsocketsRequest {
if let Some(hdr_key) = head.headers.get(&header::SEC_WEBSOCKET_ACCEPT) {
let encoded = ws::hash_key(key.as_ref());
if hdr_key.as_bytes() != &encoded {
if hdr_key.as_bytes() != encoded {
log::trace!(
"Invalid challenge response: expected: {:?} received: {:?}",
&encoded,

View File

@ -30,7 +30,7 @@ async fn main() -> std::io::Result<()> {
.service(
web::resource("/resource2/index.html")
.wrap(middleware::DefaultHeaders::new().header("X-Version-R2", "0.3"))
.default_service(web::route().to(|| HttpResponse::MethodNotAllowed()))
.default_service(web::route().to(HttpResponse::MethodNotAllowed))
.route(web::get().to(index_async)),
)
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))

View File

@ -34,7 +34,7 @@ async fn main() -> std::io::Result<()> {
.service(
web::resource("/resource2/index.html")
.wrap(middleware::DefaultHeaders::new().header("X-Version-R2", "0.3"))
.default_service(web::route().to(|| HttpResponse::MethodNotAllowed()))
.default_service(web::route().to(HttpResponse::MethodNotAllowed))
.route(web::get().to(index_async)),
)
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))

View File

@ -106,6 +106,7 @@ mod tests {
HttpResponse,
};
#[allow(clippy::unnecessary_wraps)]
fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
res.response_mut()
.headers_mut()

View File

@ -182,6 +182,7 @@ mod tests {
use crate::test::{self, TestRequest};
use crate::HttpResponse;
#[allow(clippy::unnecessary_wraps)]
fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
res.response_mut()
.headers_mut()
@ -205,6 +206,7 @@ mod tests {
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
}
#[allow(clippy::unnecessary_wraps)]
fn render_500_async<B: 'static>(
mut res: ServiceResponse<B>,
) -> Result<ErrorHandlerResponse<B>> {

View File

@ -72,7 +72,7 @@ async fn test_start() {
}
#[cfg(feature = "openssl")]
fn ssl_acceptor() -> std::io::Result<SslAcceptorBuilder> {
fn ssl_acceptor() -> SslAcceptorBuilder {
use openssl::{
pkey::PKey,
ssl::{SslAcceptor, SslMethod},
@ -89,7 +89,7 @@ fn ssl_acceptor() -> std::io::Result<SslAcceptorBuilder> {
builder.set_certificate(&cert).unwrap();
builder.set_private_key(&key).unwrap();
Ok(builder)
builder
}
#[actix_rt::test]
@ -102,7 +102,7 @@ async fn test_start_ssl() {
thread::spawn(move || {
let sys = actix_rt::System::new();
let builder = ssl_acceptor().unwrap();
let builder = ssl_acceptor();
let srv = HttpServer::new(|| {
App::new().service(web::resource("/").route(web::to(|req: HttpRequest| {