1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

Various refactorings (#2281)

Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
Igor Aleksanov 2021-06-26 18:33:43 +04:00 committed by GitHub
parent 5eba95b731
commit 262c6bc828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 98 additions and 121 deletions

3
.gitignore vendored
View File

@ -16,3 +16,6 @@ guide/build/
# Configuration directory generated by CLion # Configuration directory generated by CLion
.idea .idea
# Configuration directory generated by VSCode
.vscode

View File

@ -12,6 +12,7 @@
* Deprecate `App::data` and `App::data_factory`. [#2271] * Deprecate `App::data` and `App::data_factory`. [#2271]
* Smarter extraction of `ConnectionInfo` parts. [#2282] * Smarter extraction of `ConnectionInfo` parts. [#2282]
### Fixed ### Fixed
* Scope and Resource middleware can access data items set on their own layer. [#2288] * Scope and Resource middleware can access data items set on their own layer. [#2288]

View File

@ -355,8 +355,8 @@ impl NamedFile {
} else if let (Some(ref m), Some(header::IfUnmodifiedSince(ref since))) = } else if let (Some(ref m), Some(header::IfUnmodifiedSince(ref since))) =
(last_modified, req.get_header()) (last_modified, req.get_header())
{ {
let t1: SystemTime = m.clone().into(); let t1: SystemTime = (*m).into();
let t2: SystemTime = since.clone().into(); let t2: SystemTime = (*since).into();
match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) { match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
(Ok(t1), Ok(t2)) => t1.as_secs() > t2.as_secs(), (Ok(t1), Ok(t2)) => t1.as_secs() > t2.as_secs(),
@ -374,8 +374,8 @@ impl NamedFile {
} else if let (Some(ref m), Some(header::IfModifiedSince(ref since))) = } else if let (Some(ref m), Some(header::IfModifiedSince(ref since))) =
(last_modified, req.get_header()) (last_modified, req.get_header())
{ {
let t1: SystemTime = m.clone().into(); let t1: SystemTime = (*m).into();
let t2: SystemTime = since.clone().into(); let t2: SystemTime = (*since).into();
match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) { match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
(Ok(t1), Ok(t2)) => t1.as_secs() <= t2.as_secs(), (Ok(t1), Ok(t2)) => t1.as_secs() <= t2.as_secs(),

View File

@ -78,12 +78,12 @@ impl HeaderIndex {
// test cases taken from: // test cases taken from:
// https://github.com/seanmonstar/httparse/blob/master/benches/parse.rs // https://github.com/seanmonstar/httparse/blob/master/benches/parse.rs
const REQ_SHORT: &'static [u8] = b"\ const REQ_SHORT: &[u8] = b"\
GET / HTTP/1.0\r\n\ GET / HTTP/1.0\r\n\
Host: example.com\r\n\ Host: example.com\r\n\
Cookie: session=60; user_id=1\r\n\r\n"; Cookie: session=60; user_id=1\r\n\r\n";
const REQ: &'static [u8] = b"\ const REQ: &[u8] = b"\
GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\r\n\ GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\r\n\
Host: www.kittyhell.com\r\n\ Host: www.kittyhell.com\r\n\
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\r\n\ User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\r\n\
@ -119,6 +119,8 @@ mod _original {
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
pub fn parse_headers(src: &mut BytesMut) -> usize { pub fn parse_headers(src: &mut BytesMut) -> usize {
#![allow(clippy::uninit_assumed_init)]
let mut headers: [HeaderIndex; MAX_HEADERS] = let mut headers: [HeaderIndex; MAX_HEADERS] =
unsafe { MaybeUninit::uninit().assume_init() }; unsafe { MaybeUninit::uninit().assume_init() };

View File

@ -85,7 +85,7 @@ impl Connector<()> {
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
let mut alpn = BytesMut::with_capacity(20); let mut alpn = BytesMut::with_capacity(20);
for proto in protocols.iter() { for proto in &protocols {
alpn.put_u8(proto.len() as u8); alpn.put_u8(proto.len() as u8);
alpn.put(proto.as_slice()); alpn.put(proto.as_slice());
} }
@ -290,8 +290,7 @@ where
let h2 = sock let h2 = sock
.ssl() .ssl()
.selected_alpn_protocol() .selected_alpn_protocol()
.map(|protos| protos.windows(2).any(|w| w == H2)) .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
.unwrap_or(false);
if h2 { if h2 {
(Box::new(sock), Protocol::Http2) (Box::new(sock), Protocol::Http2)
} else { } else {
@ -325,8 +324,7 @@ where
.get_ref() .get_ref()
.1 .1
.get_alpn_protocol() .get_alpn_protocol()
.map(|protos| protos.windows(2).any(|w| w == H2)) .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
.unwrap_or(false);
if h2 { if h2 {
(Box::new(sock), Protocol::Http2) (Box::new(sock), Protocol::Http2)
} else { } else {

View File

@ -168,7 +168,7 @@ where
if let Err(e) = send.send_data(bytes, false) { if let Err(e) = send.send_data(bytes, false) {
return Err(e.into()); return Err(e.into());
} else { }
if !b.is_empty() { if !b.is_empty() {
send.reserve_capacity(b.len()); send.reserve_capacity(b.len());
} else { } else {
@ -176,7 +176,6 @@ where
} }
continue; continue;
} }
}
Some(Err(e)) => return Err(e.into()), Some(Err(e)) => return Err(e.into()),
} }
} }

View File

@ -152,8 +152,8 @@ impl ServiceConfig {
} }
} }
#[inline]
/// Return keep-alive timer delay is configured. /// Return keep-alive timer delay is configured.
#[inline]
pub fn keep_alive_timer(&self) -> Option<Sleep> { pub fn keep_alive_timer(&self) -> Option<Sleep> {
self.keep_alive().map(|ka| sleep_until(self.now() + ka)) self.keep_alive().map(|ka| sleep_until(self.now() + ka))
} }
@ -365,11 +365,11 @@ mod tests {
let clone3 = service.clone(); let clone3 = service.clone();
drop(clone1); drop(clone1);
assert_eq!(false, notify_on_drop::is_dropped()); assert!(!notify_on_drop::is_dropped());
drop(clone2); drop(clone2);
assert_eq!(false, notify_on_drop::is_dropped()); assert!(!notify_on_drop::is_dropped());
drop(clone3); drop(clone3);
assert_eq!(false, notify_on_drop::is_dropped()); assert!(!notify_on_drop::is_dropped());
drop(service); drop(service);
assert!(notify_on_drop::is_dropped()); assert!(notify_on_drop::is_dropped());

View File

@ -125,7 +125,7 @@ impl fmt::Display for Error {
impl StdError for Error { impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> { fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.inner.cause.as_ref().map(|err| err.as_ref()) self.inner.cause.as_ref().map(Box::as_ref)
} }
} }

View File

@ -102,7 +102,7 @@ pub(crate) trait MessageType: Sized {
} }
// transfer-encoding // transfer-encoding
header::TRANSFER_ENCODING => { header::TRANSFER_ENCODING => {
if let Ok(s) = value.to_str().map(|s| s.trim()) { if let Ok(s) = value.to_str().map(str::trim) {
chunked = s.eq_ignore_ascii_case("chunked"); chunked = s.eq_ignore_ascii_case("chunked");
} else { } else {
return Err(ParseError::Header); return Err(ParseError::Header);
@ -110,7 +110,7 @@ pub(crate) trait MessageType: Sized {
} }
// connection keep-alive state // connection keep-alive state
header::CONNECTION => { header::CONNECTION => {
ka = if let Ok(conn) = value.to_str().map(|conn| conn.trim()) { ka = if let Ok(conn) = value.to_str().map(str::trim) {
if conn.eq_ignore_ascii_case("keep-alive") { if conn.eq_ignore_ascii_case("keep-alive") {
Some(ConnectionType::KeepAlive) Some(ConnectionType::KeepAlive)
} else if conn.eq_ignore_ascii_case("close") { } else if conn.eq_ignore_ascii_case("close") {
@ -125,7 +125,7 @@ pub(crate) trait MessageType: Sized {
}; };
} }
header::UPGRADE => { header::UPGRADE => {
if let Ok(val) = value.to_str().map(|val| val.trim()) { if let Ok(val) = value.to_str().map(str::trim) {
if val.eq_ignore_ascii_case("websocket") { if val.eq_ignore_ascii_case("websocket") {
has_upgrade_websocket = true; has_upgrade_websocket = true;
} }

View File

@ -515,14 +515,13 @@ where
cx: &mut Context<'_>, cx: &mut Context<'_>,
) -> Result<(), DispatchError> { ) -> Result<(), DispatchError> {
// Handle `EXPECT: 100-Continue` header // Handle `EXPECT: 100-Continue` header
let mut this = self.as_mut().project();
if req.head().expect() { if req.head().expect() {
// set dispatcher state so the future is pinned. // set dispatcher state so the future is pinned.
let mut this = self.as_mut().project();
let task = this.flow.expect.call(req); let task = this.flow.expect.call(req);
this.state.set(State::ExpectCall(task)); this.state.set(State::ExpectCall(task));
} else { } else {
// the same as above. // the same as above.
let mut this = self.as_mut().project();
let task = this.flow.service.call(req); let task = this.flow.service.call(req);
this.state.set(State::ServiceCall(task)); this.state.set(State::ServiceCall(task));
}; };

View File

@ -186,8 +186,7 @@ impl Inner {
if self if self
.task .task
.as_ref() .as_ref()
.map(|w| !cx.waker().will_wake(w)) .map_or(true, |w| !cx.waker().will_wake(w))
.unwrap_or(true)
{ {
self.task = Some(cx.waker().clone()); self.task = Some(cx.waker().clone());
} }
@ -199,8 +198,7 @@ impl Inner {
if self if self
.io_task .io_task
.as_ref() .as_ref()
.map(|w| !cx.waker().will_wake(w)) .map_or(true, |w| !cx.waker().will_wake(w))
.unwrap_or(true)
{ {
self.io_task = Some(cx.waker().clone()); self.io_task = Some(cx.waker().clone());
} }

View File

@ -249,7 +249,7 @@ impl HeaderMap {
/// assert!(map.get("INVALID HEADER NAME").is_none()); /// assert!(map.get("INVALID HEADER NAME").is_none());
/// ``` /// ```
pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue> { pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue> {
self.get_value(key).map(|val| val.first()) self.get_value(key).map(Value::first)
} }
/// Returns a mutable reference to the _first_ value associated a header name. /// Returns a mutable reference to the _first_ value associated a header name.
@ -280,8 +280,8 @@ impl HeaderMap {
/// ``` /// ```
pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue> { pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue> {
match key.try_as_name(super::as_name::Seal).ok()? { match key.try_as_name(super::as_name::Seal).ok()? {
Cow::Borrowed(name) => self.inner.get_mut(name).map(|v| v.first_mut()), Cow::Borrowed(name) => self.inner.get_mut(name).map(Value::first_mut),
Cow::Owned(name) => self.inner.get_mut(&name).map(|v| v.first_mut()), Cow::Owned(name) => self.inner.get_mut(&name).map(Value::first_mut),
} }
} }

View File

@ -152,15 +152,16 @@ impl RequestHead {
/// Connection upgrade status /// Connection upgrade status
pub fn upgrade(&self) -> bool { pub fn upgrade(&self) -> bool {
if let Some(hdr) = self.headers().get(header::CONNECTION) { self.headers()
.get(header::CONNECTION)
.map(|hdr| {
if let Ok(s) = hdr.to_str() { if let Ok(s) = hdr.to_str() {
s.to_ascii_lowercase().contains("upgrade") s.to_ascii_lowercase().contains("upgrade")
} else { } else {
false false
} }
} else { })
false .unwrap_or(false)
}
} }
#[inline] #[inline]
@ -308,13 +309,11 @@ impl ResponseHead {
/// Get custom reason for the response /// Get custom reason for the response
#[inline] #[inline]
pub fn reason(&self) -> &str { pub fn reason(&self) -> &str {
if let Some(reason) = self.reason { self.reason.unwrap_or_else(|| {
reason
} else {
self.status self.status
.canonical_reason() .canonical_reason()
.unwrap_or("<unknown status code>") .unwrap_or("<unknown status code>")
} })
} }
#[inline] #[inline]
@ -356,7 +355,7 @@ pub struct Message<T: Head> {
impl<T: Head> Message<T> { impl<T: Head> Message<T> {
/// Get new message from the pool of objects /// Get new message from the pool of objects
pub fn new() -> Self { pub fn new() -> Self {
T::with_pool(|p| p.get_message()) T::with_pool(MessagePool::get_message)
} }
} }

View File

@ -6,7 +6,7 @@ use std::convert::TryFrom;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::{Span, TokenStream as TokenStream2}; use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use quote::{format_ident, quote, ToTokens, TokenStreamExt};
use syn::{parse_macro_input, AttributeArgs, Ident, NestedMeta}; use syn::{parse_macro_input, AttributeArgs, Ident, LitStr, NestedMeta};
enum ResourceType { enum ResourceType {
Async, Async,
@ -227,8 +227,7 @@ impl Route {
format!( format!(
r#"invalid service definition, expected #[{}("<some path>")]"#, r#"invalid service definition, expected #[{}("<some path>")]"#,
method method
.map(|it| it.as_str()) .map_or("route", |it| it.as_str())
.unwrap_or("route")
.to_ascii_lowercase() .to_ascii_lowercase()
), ),
)); ));
@ -298,7 +297,7 @@ impl ToTokens for Route {
} = self; } = self;
let resource_name = resource_name let resource_name = resource_name
.as_ref() .as_ref()
.map_or_else(|| name.to_string(), |n| n.value()); .map_or_else(|| name.to_string(), LitStr::value);
let method_guards = { let method_guards = {
let mut others = methods.iter(); let mut others = methods.iter();
// unwrapping since length is checked to be at least one // unwrapping since length is checked to be at least one

View File

@ -486,7 +486,9 @@ impl ClientRequest {
let mut encoding = vec![]; let mut encoding = vec![];
#[cfg(feature = "compress-brotli")] #[cfg(feature = "compress-brotli")]
{
encoding.push("br"); encoding.push("br");
}
#[cfg(feature = "compress-gzip")] #[cfg(feature = "compress-gzip")]
{ {

View File

@ -517,7 +517,7 @@ mod tests {
"test-origin" "test-origin"
); );
assert_eq!(req.max_size, 100); assert_eq!(req.max_size, 100);
assert_eq!(req.server_mode, true); assert!(req.server_mode);
assert_eq!(req.protocols, Some("v1,v2".to_string())); assert_eq!(req.protocols, Some("v1,v2".to_string()));
assert_eq!( assert_eq!(
req.head.headers.get(header::CONTENT_TYPE).unwrap(), req.head.headers.get(header::CONTENT_TYPE).unwrap(),

View File

@ -1,6 +1,5 @@
use std::{future::Future, time::Instant}; use std::{future::Future, time::Instant};
use actix_http::Response;
use actix_utils::future::{ready, Ready}; use actix_utils::future::{ready, Ready};
use actix_web::http::StatusCode; use actix_web::http::StatusCode;
use actix_web::test::TestRequest; use actix_web::test::TestRequest;
@ -24,11 +23,11 @@ struct StringResponder(String);
impl FutureResponder for StringResponder { impl FutureResponder for StringResponder {
type Error = Error; type Error = Error;
type Future = Ready<Result<Response, Self::Error>>; type Future = Ready<Result<HttpResponse, Self::Error>>;
fn future_respond_to(self, _: &HttpRequest) -> Self::Future { fn future_respond_to(self, _: &HttpRequest) -> Self::Future {
// this is default builder for string response in both new and old responder trait. // this is default builder for string response in both new and old responder trait.
ready(Ok(Response::build(StatusCode::OK) ready(Ok(HttpResponse::build(StatusCode::OK)
.content_type("text/plain; charset=utf-8") .content_type("text/plain; charset=utf-8")
.body(self.0))) .body(self.0)))
} }
@ -37,7 +36,7 @@ impl FutureResponder for StringResponder {
impl<T> FutureResponder for OptionResponder<T> impl<T> FutureResponder for OptionResponder<T>
where where
T: FutureResponder, T: FutureResponder,
T::Future: Future<Output = Result<Response, Error>>, T::Future: Future<Output = Result<HttpResponse, Error>>,
{ {
type Error = Error; type Error = Error;
type Future = Either<T::Future, Ready<Result<HttpResponse, Self::Error>>>; type Future = Either<T::Future, Ready<Result<HttpResponse, Self::Error>>>;
@ -52,7 +51,7 @@ where
impl Responder for StringResponder { impl Responder for StringResponder {
fn respond_to(self, _: &HttpRequest) -> HttpResponse { fn respond_to(self, _: &HttpRequest) -> HttpResponse {
Response::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("text/plain; charset=utf-8") .content_type("text/plain; charset=utf-8")
.body(self.0) .body(self.0)
} }
@ -62,7 +61,7 @@ impl<T: Responder> Responder for OptionResponder<T> {
fn respond_to(self, req: &HttpRequest) -> HttpResponse { fn respond_to(self, req: &HttpRequest) -> HttpResponse {
match self.0 { match self.0 {
Some(t) => t.respond_to(req), Some(t) => t.respond_to(req),
None => Response::from_error(error::ErrorInternalServerError("err")), None => HttpResponse::from_error(error::ErrorInternalServerError("err")),
} }
} }
} }

View File

@ -51,9 +51,8 @@ where
fut.await.unwrap(); fut.await.unwrap();
} }
}); });
let elapsed = start.elapsed();
// check that at least first request succeeded // check that at least first request succeeded
elapsed start.elapsed()
}) })
}); });
} }
@ -93,9 +92,8 @@ fn async_web_service(c: &mut Criterion) {
fut.await.unwrap(); fut.await.unwrap();
} }
}); });
let elapsed = start.elapsed();
// check that at least first request succeeded // check that at least first request succeeded
elapsed start.elapsed()
}) })
}); });
} }

View File

@ -131,9 +131,9 @@ where
let service = endpoint_fut.await?; let service = endpoint_fut.await?;
// populate app data container from (async) data factories. // populate app data container from (async) data factories.
async_data_factories.iter().for_each(|factory| { for factory in &async_data_factories {
factory.create(&mut app_data); factory.create(&mut app_data);
}); }
Ok(AppInitService { Ok(AppInitService {
service, service,

View File

@ -410,41 +410,33 @@ impl ContentDisposition {
/// Return the value of *name* if exists. /// Return the value of *name* if exists.
pub fn get_name(&self) -> Option<&str> { pub fn get_name(&self) -> Option<&str> {
self.parameters.iter().filter_map(|p| p.as_name()).next() self.parameters.iter().find_map(DispositionParam::as_name)
} }
/// Return the value of *filename* if exists. /// Return the value of *filename* if exists.
pub fn get_filename(&self) -> Option<&str> { pub fn get_filename(&self) -> Option<&str> {
self.parameters self.parameters
.iter() .iter()
.filter_map(|p| p.as_filename()) .find_map(DispositionParam::as_filename)
.next()
} }
/// Return the value of *filename\** if exists. /// Return the value of *filename\** if exists.
pub fn get_filename_ext(&self) -> Option<&ExtendedValue> { pub fn get_filename_ext(&self) -> Option<&ExtendedValue> {
self.parameters self.parameters
.iter() .iter()
.filter_map(|p| p.as_filename_ext()) .find_map(DispositionParam::as_filename_ext)
.next()
} }
/// Return the value of the parameter which the `name` matches. /// Return the value of the parameter which the `name` matches.
pub fn get_unknown(&self, name: impl AsRef<str>) -> Option<&str> { pub fn get_unknown(&self, name: impl AsRef<str>) -> Option<&str> {
let name = name.as_ref(); let name = name.as_ref();
self.parameters self.parameters.iter().find_map(|p| p.as_unknown(name))
.iter()
.filter_map(|p| p.as_unknown(name))
.next()
} }
/// Return the value of the extended parameter which the `name` matches. /// Return the value of the extended parameter which the `name` matches.
pub fn get_unknown_ext(&self, name: impl AsRef<str>) -> Option<&ExtendedValue> { pub fn get_unknown_ext(&self, name: impl AsRef<str>) -> Option<&ExtendedValue> {
let name = name.as_ref(); let name = name.as_ref();
self.parameters self.parameters.iter().find_map(|p| p.as_unknown_ext(name))
.iter()
.filter_map(|p| p.as_unknown_ext(name))
.next()
} }
} }

View File

@ -200,8 +200,7 @@ impl AcceptEncoding {
let mut encodings = raw let mut encodings = raw
.replace(' ', "") .replace(' ', "")
.split(',') .split(',')
.map(|l| AcceptEncoding::new(l)) .filter_map(|l| AcceptEncoding::new(l))
.flatten()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
encodings.sort(); encodings.sort();

View File

@ -111,11 +111,7 @@ impl HttpRequest {
/// E.g., id=10 /// E.g., id=10
#[inline] #[inline]
pub fn query_string(&self) -> &str { pub fn query_string(&self) -> &str {
if let Some(query) = self.uri().query().as_ref() { self.uri().query().unwrap_or_default()
query
} else {
""
}
} }
/// Get a reference to the Path parameters. /// Get a reference to the Path parameters.

View File

@ -465,7 +465,7 @@ impl Service<ServiceRequest> for ResourceService {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&self, mut req: ServiceRequest) -> Self::Future { fn call(&self, mut req: ServiceRequest) -> Self::Future {
for route in self.routes.iter() { for route in &self.routes {
if route.check(&mut req) { if route.check(&mut req) {
return route.call(req); return route.call(req);
} }

View File

@ -406,7 +406,7 @@ impl HttpResponseBuilder {
return None; return None;
} }
self.res.as_mut().map(|res| res.head_mut()) self.res.as_mut().map(Response::head_mut)
} }
} }

View File

@ -292,15 +292,15 @@ where
let c = cfg.lock().unwrap(); let c = cfg.lock().unwrap();
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr)); let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
let svc = HttpService::build() let mut svc = HttpService::build()
.keep_alive(c.keep_alive) .keep_alive(c.keep_alive)
.client_timeout(c.client_timeout) .client_timeout(c.client_timeout)
.local_addr(addr); .local_addr(addr);
let svc = if let Some(handler) = on_connect_fn.clone() { if let Some(handler) = on_connect_fn.clone() {
svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext)) svc = svc.on_connect_ext(move |io: &_, ext: _| {
} else { (handler)(io as &dyn Any, ext)
svc })
}; };
let fac = factory() let fac = factory()
@ -461,8 +461,9 @@ where
} }
} }
if !success { if success {
if let Some(e) = err.take() { Ok(sockets)
} else if let Some(e) = err.take() {
Err(e) Err(e)
} else { } else {
Err(io::Error::new( Err(io::Error::new(
@ -470,9 +471,6 @@ where
"Can not bind to address.", "Can not bind to address.",
)) ))
} }
} else {
Ok(sockets)
}
} }
#[cfg(feature = "openssl")] #[cfg(feature = "openssl")]
@ -537,15 +535,14 @@ where
); );
fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({ fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
let svc = HttpService::build() let mut svc = HttpService::build()
.keep_alive(c.keep_alive) .keep_alive(c.keep_alive)
.client_timeout(c.client_timeout); .client_timeout(c.client_timeout);
let svc = if let Some(handler) = on_connect_fn.clone() { if let Some(handler) = on_connect_fn.clone() {
svc.on_connect_ext(move |io: &_, ext: _| (&*handler)(io as &dyn Any, ext)) svc = svc
} else { .on_connect_ext(move |io: &_, ext: _| (&*handler)(io as &dyn Any, ext));
svc }
};
let fac = factory() let fac = factory()
.into_factory() .into_factory()

View File

@ -167,11 +167,7 @@ impl ServiceRequest {
/// E.g., id=10 /// E.g., id=10
#[inline] #[inline]
pub fn query_string(&self) -> &str { pub fn query_string(&self) -> &str {
if let Some(query) = self.uri().query().as_ref() { self.uri().query().unwrap_or_default()
query
} else {
""
}
} }
/// Peer socket address. /// Peer socket address.

View File

@ -1,6 +1,7 @@
//! For URL encoded form helper documentation, see [`Form`]. //! For URL encoded form helper documentation, see [`Form`].
use std::{ use std::{
borrow::Cow,
fmt, fmt,
future::Future, future::Future,
ops, ops,
@ -384,7 +385,7 @@ where
} else { } else {
let body = encoding let body = encoding
.decode_without_bom_handling_and_without_replacement(&body) .decode_without_bom_handling_and_without_replacement(&body)
.map(|s| s.into_owned()) .map(Cow::into_owned)
.ok_or(UrlencodedError::Encoding)?; .ok_or(UrlencodedError::Encoding)?;
serde_urlencoded::from_str::<T>(&body).map_err(UrlencodedError::Parse) serde_urlencoded::from_str::<T>(&body).map_err(UrlencodedError::Parse)

View File

@ -103,8 +103,7 @@ where
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let error_handler = req let error_handler = req
.app_data::<Self::Config>() .app_data::<Self::Config>()
.map(|c| c.ehandler.clone()) .and_then(|c| c.ehandler.clone());
.unwrap_or(None);
ready( ready(
de::Deserialize::deserialize(PathDeserializer::new(req.match_info())) de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))

View File

@ -1,6 +1,7 @@
//! Basic binary and string payload extractors. //! Basic binary and string payload extractors.
use std::{ use std::{
borrow::Cow,
future::Future, future::Future,
pin::Pin, pin::Pin,
str, str,
@ -190,7 +191,7 @@ fn bytes_to_string(body: Bytes, encoding: &'static Encoding) -> Result<String, E
} else { } else {
Ok(encoding Ok(encoding
.decode_without_bom_handling_and_without_replacement(&body) .decode_without_bom_handling_and_without_replacement(&body)
.map(|s| s.into_owned()) .map(Cow::into_owned)
.ok_or_else(|| ErrorBadRequest("Can not decode body"))?) .ok_or_else(|| ErrorBadRequest("Can not decode body"))?)
} }
} }

View File

@ -119,8 +119,7 @@ where
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let error_handler = req let error_handler = req
.app_data::<Self::Config>() .app_data::<Self::Config>()
.map(|c| c.err_handler.clone()) .and_then(|c| c.err_handler.clone());
.unwrap_or(None);
serde_urlencoded::from_str::<T>(req.query_string()) serde_urlencoded::from_str::<T>(req.query_string())
.map(|val| ok(Query(val))) .map(|val| ok(Query(val)))