Merge branch 'master' into remove-indirect

This commit is contained in:
Rob Ede 2020-12-09 11:23:06 +00:00 committed by GitHub
commit c355fca21e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 78 additions and 53 deletions

View File

@ -2,11 +2,25 @@
## Unreleased - 2020-xx-xx ## Unreleased - 2020-xx-xx
### Fixed ### Fixed
* Ensure `actix-http` dependency uses same `serde_urlencoded`. * added the actual parsing error to `test::read_body_json` [#1812]
* Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`.
* Fix match_pattern() returning None for scope with resource of empty path. [#1798]
[#1812]: https://github.com/actix/actix-web/pull/1812
## 3.3.2 - 2020-12-01
### Fixed
* Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`. [#1762]
* Fix `match_pattern()` returning `None` for scope with empty path resource. [#1798]
* Increase minimum `socket2` version. [#1803]
[#1762]: https://github.com/actix/actix-web/pull/1762
[#1798]: https://github.com/actix/actix-web/pull/1798 [#1798]: https://github.com/actix/actix-web/pull/1798
[#1803]: https://github.com/actix/actix-web/pull/1803
## 3.3.1 - 2020-11-29
* Ensure `actix-http` dependency uses same `serde_urlencoded`.
## 3.3.0 - 2020-11-25 ## 3.3.0 - 2020-11-25

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-web" name = "actix-web"
version = "3.3.1" version = "3.3.2"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust"
readme = "README.md" readme = "README.md"
@ -34,7 +34,7 @@ members = [
"actix-multipart", "actix-multipart",
"actix-web-actors", "actix-web-actors",
"actix-web-codegen", "actix-web-codegen",
"test-server", "actix-http-test",
] ]
[features] [features]
@ -127,10 +127,10 @@ codegen-units = 1
[patch.crates-io] [patch.crates-io]
actix-web = { path = "." } actix-web = { path = "." }
actix-http = { path = "actix-http" } actix-http = { path = "actix-http" }
actix-http-test = { path = "test-server" } actix-http-test = { path = "actix-http-test" }
actix-web-codegen = { path = "actix-web-codegen" } actix-web-codegen = { path = "actix-web-codegen" }
actix-files = { path = "actix-files" }
actix-multipart = { path = "actix-multipart" } actix-multipart = { path = "actix-multipart" }
actix-files = { path = "actix-files" }
awc = { path = "awc" } awc = { path = "awc" }
[[bench]] [[bench]]

View File

@ -6,10 +6,10 @@
<p> <p>
[![crates.io](https://img.shields.io/crates/v/actix-web?label=latest)](https://crates.io/crates/actix-web) [![crates.io](https://img.shields.io/crates/v/actix-web?label=latest)](https://crates.io/crates/actix-web)
[![Documentation](https://docs.rs/actix-web/badge.svg?version=3.3.1)](https://docs.rs/actix-web/3.3.1) [![Documentation](https://docs.rs/actix-web/badge.svg?version=3.3.2)](https://docs.rs/actix-web/3.3.2)
[![Version](https://img.shields.io/badge/rustc-1.42+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html) [![Version](https://img.shields.io/badge/rustc-1.42+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html)
![License](https://img.shields.io/crates/l/actix-web.svg) ![License](https://img.shields.io/crates/l/actix-web.svg)
[![Dependency Status](https://deps.rs/crate/actix-web/3.3.1/status.svg)](https://deps.rs/crate/actix-web/3.3.1) [![Dependency Status](https://deps.rs/crate/actix-web/3.3.2/status.svg)](https://deps.rs/crate/actix-web/3.3.2)
<br /> <br />
[![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) [![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web)
[![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web)

View File

@ -550,8 +550,7 @@ impl fmt::Display for ContentDisposition {
write!(f, "{}", self.disposition)?; write!(f, "{}", self.disposition)?;
self.parameters self.parameters
.iter() .iter()
.map(|param| write!(f, "; {}", param)) .try_for_each(|param| write!(f, "; {}", param))
.collect()
} }
} }

View File

@ -7,10 +7,12 @@ use crate::header::{HeaderValue, IntoHeaderValue, InvalidHeaderValue, Writer};
/// 1. `%x21`, or /// 1. `%x21`, or
/// 2. in the range `%x23` to `%x7E`, or /// 2. in the range `%x23` to `%x7E`, or
/// 3. above `%x80` /// 3. above `%x80`
fn entity_validate_char(c: u8) -> bool {
c == 0x21 || (0x23..=0x7e).contains(&c) || (c >= 0x80)
}
fn check_slice_validity(slice: &str) -> bool { fn check_slice_validity(slice: &str) -> bool {
slice slice.bytes().all(entity_validate_char)
.bytes()
.all(|c| c == b'\x21' || (c >= b'\x23' && c <= b'\x7e') | (c >= b'\x80'))
} }
/// An entity tag, defined in [RFC7232](https://tools.ietf.org/html/rfc7232#section-2.3) /// An entity tag, defined in [RFC7232](https://tools.ietf.org/html/rfc7232#section-2.3)

View File

@ -1,6 +1,9 @@
# Changes # Changes
## Unreleased - 2020-xx-xx ## Unreleased - 2020-xx-xx
## 2.0.3 - 2020-11-29
### Fixed ### Fixed
* Ensure `actix-http` dependency uses same `serde_urlencoded`. * Ensure `actix-http` dependency uses same `serde_urlencoded`.

View File

@ -70,9 +70,14 @@ impl WebsocketsRequest {
<Uri as TryFrom<U>>::Error: Into<HttpError>, <Uri as TryFrom<U>>::Error: Into<HttpError>,
{ {
let mut err = None; let mut err = None;
let mut head = RequestHead::default();
head.method = Method::GET; #[allow(clippy::field_reassign_with_default)]
head.version = Version::HTTP_11; let mut head = {
let mut head = RequestHead::default();
head.method = Method::GET;
head.version = Version::HTTP_11;
head
};
match Uri::try_from(uri) { match Uri::try_from(uri) {
Ok(uri) => head.uri = uri, Ok(uri) => head.uri = uri,

View File

@ -1,4 +1,13 @@
ignore: # ignore codecoverage on following paths coverage:
status:
project:
default:
threshold: 10% # make CI green
patch:
default:
threshold: 10% # make CI green
ignore: # ignore code coverage on following paths
- "**/tests" - "**/tests"
- "test-server" - "test-server"
- "**/benches" - "**/benches"

View File

@ -192,10 +192,7 @@ impl AcceptEncoding {
}; };
let quality = match parts.len() { let quality = match parts.len() {
1 => encoding.quality(), 1 => encoding.quality(),
_ => match f64::from_str(parts[1]) { _ => f64::from_str(parts[1]).unwrap_or(0.0),
Ok(q) => q,
Err(_) => 0.0,
},
}; };
Some(AcceptEncoding { encoding, quality }) Some(AcceptEncoding { encoding, quality })
} }

View File

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

View File

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

View File

@ -16,24 +16,24 @@ use crate::responder::Responder;
use crate::service::{ServiceRequest, ServiceResponse}; use crate::service::{ServiceRequest, ServiceResponse};
use crate::HttpResponse; use crate::HttpResponse;
type BoxedRouteService<Req, Res> = Box< type BoxedRouteService = Box<
dyn Service< dyn Service<
Request = Req, Request = ServiceRequest,
Response = Res, Response = ServiceResponse,
Error = Error, Error = Error,
Future = LocalBoxFuture<'static, Result<Res, Error>>, Future = LocalBoxFuture<'static, Result<ServiceResponse, Error>>,
>, >,
>; >;
type BoxedRouteNewService<Req, Res> = Box< type BoxedRouteNewService = Box<
dyn ServiceFactory< dyn ServiceFactory<
Config = (), Config = (),
Request = Req, Request = ServiceRequest,
Response = Res, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
Service = BoxedRouteService<Req, Res>, Service = BoxedRouteService,
Future = LocalBoxFuture<'static, Result<BoxedRouteService<Req, Res>, ()>>, Future = LocalBoxFuture<'static, Result<BoxedRouteService, ()>>,
>, >,
>; >;
@ -42,7 +42,7 @@ type BoxedRouteNewService<Req, Res> = Box<
/// Route uses builder-like pattern for configuration. /// Route uses builder-like pattern for configuration.
/// If handler is not explicitly set, default *404 Not Found* handler is used. /// If handler is not explicitly set, default *404 Not Found* handler is used.
pub struct Route { pub struct Route {
service: BoxedRouteNewService<ServiceRequest, ServiceResponse>, service: BoxedRouteNewService,
guards: Rc<Vec<Box<dyn Guard>>>, guards: Rc<Vec<Box<dyn Guard>>>,
} }
@ -80,15 +80,8 @@ impl ServiceFactory for Route {
} }
} }
type RouteFuture = LocalBoxFuture<
'static,
Result<BoxedRouteService<ServiceRequest, ServiceResponse>, ()>,
>;
#[pin_project::pin_project]
pub struct CreateRouteService { pub struct CreateRouteService {
#[pin] fut: LocalBoxFuture<'static, Result<BoxedRouteService, ()>>,
fut: RouteFuture,
guards: Rc<Vec<Box<dyn Guard>>>, guards: Rc<Vec<Box<dyn Guard>>>,
} }
@ -96,9 +89,9 @@ impl Future for CreateRouteService {
type Output = Result<RouteService, ()>; type Output = Result<RouteService, ()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.get_mut();
match this.fut.poll(cx)? { match this.fut.as_mut().poll(cx)? {
Poll::Ready(service) => Poll::Ready(Ok(RouteService { Poll::Ready(service) => Poll::Ready(Ok(RouteService {
service, service,
guards: this.guards.clone(), guards: this.guards.clone(),
@ -109,7 +102,7 @@ impl Future for CreateRouteService {
} }
pub struct RouteService { pub struct RouteService {
service: BoxedRouteService<ServiceRequest, ServiceResponse>, service: BoxedRouteService,
guards: Rc<Vec<Box<dyn Guard>>>, guards: Rc<Vec<Box<dyn Guard>>>,
} }
@ -135,7 +128,7 @@ impl Service for RouteService {
} }
fn call(&mut self, req: ServiceRequest) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
self.service.call(req).boxed_local() self.service.call(req)
} }
} }
@ -275,12 +268,12 @@ where
T::Service: 'static, T::Service: 'static,
<T::Service as Service>::Future: 'static, <T::Service as Service>::Future: 'static,
{ {
type Config = ();
type Request = ServiceRequest; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Config = ();
type Service = BoxedRouteService;
type InitError = (); type InitError = ();
type Service = BoxedRouteService<ServiceRequest, Self::Response>;
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>; type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
fn new_service(&self, _: ()) -> Self::Future { fn new_service(&self, _: ()) -> Self::Future {
@ -288,8 +281,7 @@ where
.new_service(()) .new_service(())
.map(|result| match result { .map(|result| match result {
Ok(service) => { Ok(service) => {
let service: BoxedRouteService<_, _> = let service = Box::new(RouteServiceWrapper { service }) as _;
Box::new(RouteServiceWrapper { service });
Ok(service) Ok(service)
} }
Err(_) => Err(()), Err(_) => Err(()),

View File

@ -269,8 +269,9 @@ where
{ {
let body = read_body(res).await; let body = read_body(res).await;
serde_json::from_slice(&body) serde_json::from_slice(&body).unwrap_or_else(|e| {
.unwrap_or_else(|_| panic!("read_response_json failed during deserialization")) panic!("read_response_json failed during deserialization: {}", e)
})
} }
pub async fn load_stream<S>(mut stream: S) -> Result<Bytes, Error> pub async fn load_stream<S>(mut stream: S) -> Result<Bytes, Error>

View File

@ -241,9 +241,10 @@ pub struct PayloadConfig {
impl PayloadConfig { impl PayloadConfig {
/// Create `PayloadConfig` instance and set max size of payload. /// Create `PayloadConfig` instance and set max size of payload.
pub fn new(limit: usize) -> Self { pub fn new(limit: usize) -> Self {
let mut cfg = Self::default(); Self {
cfg.limit = limit; limit,
cfg ..Default::default()
}
} }
/// Change max size of payload. By default max size is 256Kb /// Change max size of payload. By default max size is 256Kb