Various fixes in actix-web crate

This commit is contained in:
Igor Aleksanov 2021-06-22 19:11:26 +03:00
parent 225cacb599
commit ee2fb80deb
30 changed files with 199 additions and 75 deletions

View File

@ -42,6 +42,7 @@ pub struct App<T, B> {
impl App<AppEntry, Body> { impl App<AppEntry, Body> {
/// Create application builder. Application can be configured with a builder-like pattern. /// Create application builder. Application can be configured with a builder-like pattern.
#[allow(clippy::new_without_default)] #[allow(clippy::new_without_default)]
#[must_use]
pub fn new() -> Self { pub fn new() -> Self {
let fref = Rc::new(RefCell::new(None)); let fref = Rc::new(RefCell::new(None));
App { App {

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

@ -44,6 +44,7 @@ impl AppService {
} }
/// Check if root is being configured /// Check if root is being configured
#[must_use]
pub fn is_root(&self) -> bool { pub fn is_root(&self) -> bool {
self.root self.root
} }
@ -72,11 +73,13 @@ impl AppService {
} }
/// Service configuration /// Service configuration
#[must_use]
pub fn config(&self) -> &AppConfig { pub fn config(&self) -> &AppConfig {
&self.config &self.config
} }
/// Default resource /// Default resource
#[must_use]
pub fn default_service(&self) -> Rc<HttpNewService> { pub fn default_service(&self) -> Rc<HttpNewService> {
self.default.clone() self.default.clone()
} }
@ -129,16 +132,19 @@ impl AppConfig {
/// documentation for more information. /// documentation for more information.
/// ///
/// By default host name is set to a "localhost" value. /// By default host name is set to a "localhost" value.
#[must_use]
pub fn host(&self) -> &str { pub fn host(&self) -> &str {
&self.host &self.host
} }
/// Returns true if connection is secure(https) /// Returns true if connection is secure(https)
#[must_use]
pub fn secure(&self) -> bool { pub fn secure(&self) -> bool {
self.secure self.secure
} }
/// Returns the socket address of the local half of this TCP connection /// Returns the socket address of the local half of this TCP connection
#[must_use]
pub fn local_addr(&self) -> SocketAddr { pub fn local_addr(&self) -> SocketAddr {
self.addr self.addr
} }

View File

@ -72,11 +72,13 @@ impl<T> Data<T> {
} }
/// Get reference to inner app data. /// Get reference to inner app data.
#[must_use]
pub fn get_ref(&self) -> &T { pub fn get_ref(&self) -> &T {
self.0.as_ref() self.0.as_ref()
} }
/// Convert to the internal Arc<T> /// Convert to the internal Arc<T>
#[must_use]
pub fn into_inner(self) -> Arc<T> { pub fn into_inner(self) -> Arc<T> {
self.0 self.0
} }

View File

@ -20,16 +20,19 @@ pub struct Error {
impl Error { impl Error {
/// Returns the reference to the underlying `ResponseError`. /// Returns the reference to the underlying `ResponseError`.
#[must_use]
pub fn as_response_error(&self) -> &dyn ResponseError { pub fn as_response_error(&self) -> &dyn ResponseError {
self.cause.as_ref() self.cause.as_ref()
} }
/// Similar to `as_response_error` but downcasts. /// Similar to `as_response_error` but downcasts.
#[must_use]
pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T> { pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T> {
<dyn ResponseError>::downcast_ref(self.cause.as_ref()) <dyn ResponseError>::downcast_ref(self.cause.as_ref())
} }
/// Shortcut for creating an `HttpResponse`. /// Shortcut for creating an `HttpResponse`.
#[must_use]
pub fn error_response(&self) -> HttpResponse { pub fn error_response(&self) -> HttpResponse {
self.cause.error_response() self.cause.error_response()
} }

View File

@ -195,57 +195,68 @@ impl Guard for MethodGuard {
} }
/// Guard to match *GET* HTTP method. /// Guard to match *GET* HTTP method.
#[must_use]
pub fn Get() -> MethodGuard { pub fn Get() -> MethodGuard {
MethodGuard(http::Method::GET) MethodGuard(http::Method::GET)
} }
/// Predicate to match *POST* HTTP method. /// Predicate to match *POST* HTTP method.
#[must_use]
pub fn Post() -> MethodGuard { pub fn Post() -> MethodGuard {
MethodGuard(http::Method::POST) MethodGuard(http::Method::POST)
} }
/// Predicate to match *PUT* HTTP method. /// Predicate to match *PUT* HTTP method.
#[must_use]
pub fn Put() -> MethodGuard { pub fn Put() -> MethodGuard {
MethodGuard(http::Method::PUT) MethodGuard(http::Method::PUT)
} }
/// Predicate to match *DELETE* HTTP method. /// Predicate to match *DELETE* HTTP method.
#[must_use]
pub fn Delete() -> MethodGuard { pub fn Delete() -> MethodGuard {
MethodGuard(http::Method::DELETE) MethodGuard(http::Method::DELETE)
} }
/// Predicate to match *HEAD* HTTP method. /// Predicate to match *HEAD* HTTP method.
#[must_use]
pub fn Head() -> MethodGuard { pub fn Head() -> MethodGuard {
MethodGuard(http::Method::HEAD) MethodGuard(http::Method::HEAD)
} }
/// Predicate to match *OPTIONS* HTTP method. /// Predicate to match *OPTIONS* HTTP method.
#[must_use]
pub fn Options() -> MethodGuard { pub fn Options() -> MethodGuard {
MethodGuard(http::Method::OPTIONS) MethodGuard(http::Method::OPTIONS)
} }
/// Predicate to match *CONNECT* HTTP method. /// Predicate to match *CONNECT* HTTP method.
#[must_use]
pub fn Connect() -> MethodGuard { pub fn Connect() -> MethodGuard {
MethodGuard(http::Method::CONNECT) MethodGuard(http::Method::CONNECT)
} }
/// Predicate to match *PATCH* HTTP method. /// Predicate to match *PATCH* HTTP method.
#[must_use]
pub fn Patch() -> MethodGuard { pub fn Patch() -> MethodGuard {
MethodGuard(http::Method::PATCH) MethodGuard(http::Method::PATCH)
} }
/// Predicate to match *TRACE* HTTP method. /// Predicate to match *TRACE* HTTP method.
#[must_use]
pub fn Trace() -> MethodGuard { pub fn Trace() -> MethodGuard {
MethodGuard(http::Method::TRACE) MethodGuard(http::Method::TRACE)
} }
/// Predicate to match specified HTTP method. /// Predicate to match specified HTTP method.
#[must_use]
pub fn Method(method: http::Method) -> MethodGuard { pub fn Method(method: http::Method) -> MethodGuard {
MethodGuard(method) MethodGuard(method)
} }
/// Return predicate that matches if request contains specified header and /// Return predicate that matches if request contains specified header and
/// value. /// value.
#[must_use]
pub fn Header(name: &'static str, value: &'static str) -> HeaderGuard { pub fn Header(name: &'static str, value: &'static str) -> HeaderGuard {
HeaderGuard( HeaderGuard(
header::HeaderName::try_from(name).unwrap(), header::HeaderName::try_from(name).unwrap(),

View File

@ -126,26 +126,31 @@ crate::__define_common_header! {
impl Accept { impl Accept {
/// Construct `Accept: */*`. /// Construct `Accept: */*`.
#[must_use]
pub fn star() -> Accept { pub fn star() -> Accept {
Accept(vec![qitem(mime::STAR_STAR)]) Accept(vec![qitem(mime::STAR_STAR)])
} }
/// Construct `Accept: application/json`. /// Construct `Accept: application/json`.
#[must_use]
pub fn json() -> Accept { pub fn json() -> Accept {
Accept(vec![qitem(mime::APPLICATION_JSON)]) Accept(vec![qitem(mime::APPLICATION_JSON)])
} }
/// Construct `Accept: text/*`. /// Construct `Accept: text/*`.
#[must_use]
pub fn text() -> Accept { pub fn text() -> Accept {
Accept(vec![qitem(mime::TEXT_STAR)]) Accept(vec![qitem(mime::TEXT_STAR)])
} }
/// Construct `Accept: image/*`. /// Construct `Accept: image/*`.
#[must_use]
pub fn image() -> Accept { pub fn image() -> Accept {
Accept(vec![qitem(mime::IMAGE_STAR)]) Accept(vec![qitem(mime::IMAGE_STAR)])
} }
/// Construct `Accept: text/html`. /// Construct `Accept: text/html`.
#[must_use]
pub fn html() -> Accept { pub fn html() -> Accept {
Accept(vec![qitem(mime::TEXT_HTML)]) Accept(vec![qitem(mime::TEXT_HTML)])
} }
@ -154,6 +159,7 @@ impl Accept {
/// [q-factor weighting] and specificity. /// [q-factor weighting] and specificity.
/// ///
/// [q-factor weighting]: https://tools.ietf.org/html/rfc7231#section-5.3.2 /// [q-factor weighting]: https://tools.ietf.org/html/rfc7231#section-5.3.2
#[must_use]
pub fn mime_precedence(&self) -> Vec<Mime> { pub fn mime_precedence(&self) -> Vec<Mime> {
let mut types = self.0.clone(); let mut types = self.0.clone();
@ -204,6 +210,7 @@ impl Accept {
/// Returns `None` if contained list is empty. /// Returns `None` if contained list is empty.
/// ///
/// [q-factor weighting]: https://tools.ietf.org/html/rfc7231#section-5.3.2 /// [q-factor weighting]: https://tools.ietf.org/html/rfc7231#section-5.3.2
#[must_use]
pub fn mime_preference(&self) -> Option<Mime> { pub fn mime_preference(&self) -> Option<Mime> {
let types = self.mime_precedence(); let types = self.mime_precedence();
types.first().cloned() types.first().cloned()

View File

@ -101,24 +101,28 @@ pub enum DispositionParam {
impl DispositionParam { impl DispositionParam {
/// Returns `true` if the parameter is [`Name`](DispositionParam::Name). /// Returns `true` if the parameter is [`Name`](DispositionParam::Name).
#[inline] #[inline]
#[must_use]
pub fn is_name(&self) -> bool { pub fn is_name(&self) -> bool {
self.as_name().is_some() self.as_name().is_some()
} }
/// Returns `true` if the parameter is [`Filename`](DispositionParam::Filename). /// Returns `true` if the parameter is [`Filename`](DispositionParam::Filename).
#[inline] #[inline]
#[must_use]
pub fn is_filename(&self) -> bool { pub fn is_filename(&self) -> bool {
self.as_filename().is_some() self.as_filename().is_some()
} }
/// Returns `true` if the parameter is [`FilenameExt`](DispositionParam::FilenameExt). /// Returns `true` if the parameter is [`FilenameExt`](DispositionParam::FilenameExt).
#[inline] #[inline]
#[must_use]
pub fn is_filename_ext(&self) -> bool { pub fn is_filename_ext(&self) -> bool {
self.as_filename_ext().is_some() self.as_filename_ext().is_some()
} }
/// Returns `true` if the parameter is [`Unknown`](DispositionParam::Unknown) and the `name` /// Returns `true` if the parameter is [`Unknown`](DispositionParam::Unknown) and the `name`
#[inline] #[inline]
#[must_use]
/// matches. /// matches.
pub fn is_unknown<T: AsRef<str>>(&self, name: T) -> bool { pub fn is_unknown<T: AsRef<str>>(&self, name: T) -> bool {
self.as_unknown(name).is_some() self.as_unknown(name).is_some()
@ -127,12 +131,14 @@ impl DispositionParam {
/// Returns `true` if the parameter is [`UnknownExt`](DispositionParam::UnknownExt) and the /// Returns `true` if the parameter is [`UnknownExt`](DispositionParam::UnknownExt) and the
/// `name` matches. /// `name` matches.
#[inline] #[inline]
#[must_use]
pub fn is_unknown_ext<T: AsRef<str>>(&self, name: T) -> bool { pub fn is_unknown_ext<T: AsRef<str>>(&self, name: T) -> bool {
self.as_unknown_ext(name).is_some() self.as_unknown_ext(name).is_some()
} }
/// Returns the name if applicable. /// Returns the name if applicable.
#[inline] #[inline]
#[must_use]
pub fn as_name(&self) -> Option<&str> { pub fn as_name(&self) -> Option<&str> {
match self { match self {
DispositionParam::Name(ref name) => Some(name.as_str()), DispositionParam::Name(ref name) => Some(name.as_str()),
@ -142,6 +148,7 @@ impl DispositionParam {
/// Returns the filename if applicable. /// Returns the filename if applicable.
#[inline] #[inline]
#[must_use]
pub fn as_filename(&self) -> Option<&str> { pub fn as_filename(&self) -> Option<&str> {
match self { match self {
DispositionParam::Filename(ref filename) => Some(filename.as_str()), DispositionParam::Filename(ref filename) => Some(filename.as_str()),
@ -151,6 +158,7 @@ impl DispositionParam {
/// Returns the filename* if applicable. /// Returns the filename* if applicable.
#[inline] #[inline]
#[must_use]
pub fn as_filename_ext(&self) -> Option<&ExtendedValue> { pub fn as_filename_ext(&self) -> Option<&ExtendedValue> {
match self { match self {
DispositionParam::FilenameExt(ref value) => Some(value), DispositionParam::FilenameExt(ref value) => Some(value),
@ -161,6 +169,7 @@ impl DispositionParam {
/// Returns the value of the unrecognized regular parameter if it is /// Returns the value of the unrecognized regular parameter if it is
/// [`Unknown`](DispositionParam::Unknown) and the `name` matches. /// [`Unknown`](DispositionParam::Unknown) and the `name` matches.
#[inline] #[inline]
#[must_use]
pub fn as_unknown<T: AsRef<str>>(&self, name: T) -> Option<&str> { pub fn as_unknown<T: AsRef<str>>(&self, name: T) -> Option<&str> {
match self { match self {
DispositionParam::Unknown(ref ext_name, ref value) DispositionParam::Unknown(ref ext_name, ref value)
@ -175,6 +184,7 @@ impl DispositionParam {
/// Returns the value of the unrecognized extended parameter if it is /// Returns the value of the unrecognized extended parameter if it is
/// [`Unknown`](DispositionParam::Unknown) and the `name` matches. /// [`Unknown`](DispositionParam::Unknown) and the `name` matches.
#[inline] #[inline]
#[must_use]
pub fn as_unknown_ext<T: AsRef<str>>(&self, name: T) -> Option<&ExtendedValue> { pub fn as_unknown_ext<T: AsRef<str>>(&self, name: T) -> Option<&ExtendedValue> {
match self { match self {
DispositionParam::UnknownExt(ref ext_name, ref value) DispositionParam::UnknownExt(ref ext_name, ref value)
@ -386,21 +396,25 @@ impl ContentDisposition {
} }
/// Returns `true` if it is [`Inline`](DispositionType::Inline). /// Returns `true` if it is [`Inline`](DispositionType::Inline).
#[must_use]
pub fn is_inline(&self) -> bool { pub fn is_inline(&self) -> bool {
matches!(self.disposition, DispositionType::Inline) matches!(self.disposition, DispositionType::Inline)
} }
/// Returns `true` if it is [`Attachment`](DispositionType::Attachment). /// Returns `true` if it is [`Attachment`](DispositionType::Attachment).
#[must_use]
pub fn is_attachment(&self) -> bool { pub fn is_attachment(&self) -> bool {
matches!(self.disposition, DispositionType::Attachment) matches!(self.disposition, DispositionType::Attachment)
} }
/// Returns `true` if it is [`FormData`](DispositionType::FormData). /// Returns `true` if it is [`FormData`](DispositionType::FormData).
#[must_use]
pub fn is_form_data(&self) -> bool { pub fn is_form_data(&self) -> bool {
matches!(self.disposition, DispositionType::FormData) matches!(self.disposition, DispositionType::FormData)
} }
/// Returns `true` if it is [`Ext`](DispositionType::Ext) and the `disp_type` matches. /// Returns `true` if it is [`Ext`](DispositionType::Ext) and the `disp_type` matches.
#[must_use]
pub fn is_ext(&self, disp_type: impl AsRef<str>) -> bool { pub fn is_ext(&self, disp_type: impl AsRef<str>) -> bool {
matches!( matches!(
self.disposition, self.disposition,
@ -409,42 +423,39 @@ impl ContentDisposition {
} }
/// Return the value of *name* if exists. /// Return the value of *name* if exists.
#[must_use]
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.
#[must_use]
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.
#[must_use]
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.
#[must_use]
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.
#[must_use]
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

@ -63,6 +63,7 @@ impl ContentType {
/// A constructor to easily create a `Content-Type: application/json` /// A constructor to easily create a `Content-Type: application/json`
/// header. /// header.
#[inline] #[inline]
#[must_use]
pub fn json() -> ContentType { pub fn json() -> ContentType {
ContentType(mime::APPLICATION_JSON) ContentType(mime::APPLICATION_JSON)
} }
@ -70,18 +71,21 @@ impl ContentType {
/// A constructor to easily create a `Content-Type: text/plain; /// A constructor to easily create a `Content-Type: text/plain;
/// charset=utf-8` header. /// charset=utf-8` header.
#[inline] #[inline]
#[must_use]
pub fn plaintext() -> ContentType { pub fn plaintext() -> ContentType {
ContentType(mime::TEXT_PLAIN_UTF_8) ContentType(mime::TEXT_PLAIN_UTF_8)
} }
/// A constructor to easily create a `Content-Type: text/html` header. /// A constructor to easily create a `Content-Type: text/html` header.
#[inline] #[inline]
#[must_use]
pub fn html() -> ContentType { pub fn html() -> ContentType {
ContentType(mime::TEXT_HTML) ContentType(mime::TEXT_HTML)
} }
/// A constructor to easily create a `Content-Type: text/xml` header. /// A constructor to easily create a `Content-Type: text/xml` header.
#[inline] #[inline]
#[must_use]
pub fn xml() -> ContentType { pub fn xml() -> ContentType {
ContentType(mime::TEXT_XML) ContentType(mime::TEXT_XML)
} }
@ -89,18 +93,21 @@ impl ContentType {
/// A constructor to easily create a `Content-Type: /// A constructor to easily create a `Content-Type:
/// application/www-form-url-encoded` header. /// application/www-form-url-encoded` header.
#[inline] #[inline]
#[must_use]
pub fn form_url_encoded() -> ContentType { pub fn form_url_encoded() -> ContentType {
ContentType(mime::APPLICATION_WWW_FORM_URLENCODED) ContentType(mime::APPLICATION_WWW_FORM_URLENCODED)
} }
/// A constructor to easily create a `Content-Type: image/jpeg` header. /// A constructor to easily create a `Content-Type: image/jpeg` header.
#[inline] #[inline]
#[must_use]
pub fn jpeg() -> ContentType { pub fn jpeg() -> ContentType {
ContentType(mime::IMAGE_JPEG) ContentType(mime::IMAGE_JPEG)
} }
/// A constructor to easily create a `Content-Type: image/png` header. /// A constructor to easily create a `Content-Type: image/png` header.
#[inline] #[inline]
#[must_use]
pub fn png() -> ContentType { pub fn png() -> ContentType {
ContentType(mime::IMAGE_PNG) ContentType(mime::IMAGE_PNG)
} }
@ -108,6 +115,7 @@ impl ContentType {
/// A constructor to easily create a `Content-Type: /// A constructor to easily create a `Content-Type:
/// application/octet-stream` header. /// application/octet-stream` header.
#[inline] #[inline]
#[must_use]
pub fn octet_stream() -> ContentType { pub fn octet_stream() -> ContentType {
ContentType(mime::APPLICATION_OCTET_STREAM) ContentType(mime::APPLICATION_OCTET_STREAM)
} }

View File

@ -38,6 +38,7 @@ crate::__define_common_header! {
impl Date { impl Date {
/// Create a date instance set to the current system time /// Create a date instance set to the current system time
#[must_use]
pub fn now() -> Date { pub fn now() -> Date {
Date(SystemTime::now().into()) Date(SystemTime::now().into())
} }

View File

@ -58,6 +58,7 @@ impl EntityTag {
/// Constructs a new EntityTag. /// Constructs a new EntityTag.
/// # Panics /// # Panics
/// If the tag contains invalid characters. /// If the tag contains invalid characters.
#[must_use]
pub fn new(weak: bool, tag: String) -> EntityTag { pub fn new(weak: bool, tag: String) -> EntityTag {
assert!(check_slice_validity(&tag), "Invalid tag: {:?}", tag); assert!(check_slice_validity(&tag), "Invalid tag: {:?}", tag);
EntityTag { weak, tag } EntityTag { weak, tag }
@ -66,6 +67,7 @@ impl EntityTag {
/// Constructs a new weak EntityTag. /// Constructs a new weak EntityTag.
/// # Panics /// # Panics
/// If the tag contains invalid characters. /// If the tag contains invalid characters.
#[must_use]
pub fn weak(tag: String) -> EntityTag { pub fn weak(tag: String) -> EntityTag {
EntityTag::new(true, tag) EntityTag::new(true, tag)
} }
@ -73,11 +75,13 @@ impl EntityTag {
/// Constructs a new strong EntityTag. /// Constructs a new strong EntityTag.
/// # Panics /// # Panics
/// If the tag contains invalid characters. /// If the tag contains invalid characters.
#[must_use]
pub fn strong(tag: String) -> EntityTag { pub fn strong(tag: String) -> EntityTag {
EntityTag::new(false, tag) EntityTag::new(false, tag)
} }
/// Get the tag. /// Get the tag.
#[must_use]
pub fn tag(&self) -> &str { pub fn tag(&self) -> &str {
self.tag.as_ref() self.tag.as_ref()
} }
@ -92,6 +96,7 @@ impl EntityTag {
/// For strong comparison two entity-tags are equivalent if both are not /// For strong comparison two entity-tags are equivalent if both are not
/// weak and their opaque-tags match character-by-character. /// weak and their opaque-tags match character-by-character.
#[must_use]
pub fn strong_eq(&self, other: &EntityTag) -> bool { pub fn strong_eq(&self, other: &EntityTag) -> bool {
!self.weak && !other.weak && self.tag == other.tag !self.weak && !other.weak && self.tag == other.tag
} }
@ -99,16 +104,19 @@ impl EntityTag {
/// For weak comparison two entity-tags are equivalent if their /// For weak comparison two entity-tags are equivalent if their
/// opaque-tags match character-by-character, regardless of either or /// opaque-tags match character-by-character, regardless of either or
/// both being tagged as "weak". /// both being tagged as "weak".
#[must_use]
pub fn weak_eq(&self, other: &EntityTag) -> bool { pub fn weak_eq(&self, other: &EntityTag) -> bool {
self.tag == other.tag self.tag == other.tag
} }
/// The inverse of `EntityTag.strong_eq()`. /// The inverse of `EntityTag.strong_eq()`.
#[must_use]
pub fn strong_ne(&self, other: &EntityTag) -> bool { pub fn strong_ne(&self, other: &EntityTag) -> bool {
!self.strong_eq(other) !self.strong_eq(other)
} }
/// The inverse of `EntityTag.weak_eq()`. /// The inverse of `EntityTag.weak_eq()`.
#[must_use]
pub fn weak_ne(&self, other: &EntityTag) -> bool { pub fn weak_ne(&self, other: &EntityTag) -> bool {
!self.weak_eq(other) !self.weak_eq(other)
} }

View File

@ -2,6 +2,7 @@ use std::cell::Ref;
use crate::dev::{AppConfig, RequestHead}; use crate::dev::{AppConfig, RequestHead};
use crate::http::header::{self, HeaderName}; use crate::http::header::{self, HeaderName};
use crate::http::uri::{Authority, Scheme};
const X_FORWARDED_FOR: &[u8] = b"x-forwarded-for"; const X_FORWARDED_FOR: &[u8] = b"x-forwarded-for";
const X_FORWARDED_HOST: &[u8] = b"x-forwarded-host"; const X_FORWARDED_HOST: &[u8] = b"x-forwarded-host";
@ -71,11 +72,11 @@ impl ConnectionInfo {
.get(&HeaderName::from_lowercase(X_FORWARDED_PROTO).unwrap()) .get(&HeaderName::from_lowercase(X_FORWARDED_PROTO).unwrap())
{ {
if let Ok(h) = h.to_str() { if let Ok(h) = h.to_str() {
scheme = h.split(',').next().map(|v| v.trim()); scheme = h.split(',').next().map(str::trim);
} }
} }
if scheme.is_none() { if scheme.is_none() {
scheme = req.uri.scheme().map(|a| a.as_str()); scheme = req.uri.scheme().map(Scheme::as_str);
if scheme.is_none() && cfg.secure() { if scheme.is_none() && cfg.secure() {
scheme = Some("https") scheme = Some("https")
} }
@ -89,7 +90,7 @@ impl ConnectionInfo {
.get(&HeaderName::from_lowercase(X_FORWARDED_HOST).unwrap()) .get(&HeaderName::from_lowercase(X_FORWARDED_HOST).unwrap())
{ {
if let Ok(h) = h.to_str() { if let Ok(h) = h.to_str() {
host = h.split(',').next().map(|v| v.trim()); host = h.split(',').next().map(str::trim);
} }
} }
if host.is_none() { if host.is_none() {
@ -97,7 +98,7 @@ impl ConnectionInfo {
host = h.to_str().ok(); host = h.to_str().ok();
} }
if host.is_none() { if host.is_none() {
host = req.uri.authority().map(|a| a.as_str()); host = req.uri.authority().map(Authority::as_str);
if host.is_none() { if host.is_none() {
host = Some(cfg.host()); host = Some(cfg.host());
} }
@ -114,7 +115,7 @@ impl ConnectionInfo {
.get(&HeaderName::from_lowercase(X_FORWARDED_FOR).unwrap()) .get(&HeaderName::from_lowercase(X_FORWARDED_FOR).unwrap())
{ {
if let Ok(h) = h.to_str() { if let Ok(h) = h.to_str() {
realip_remote_addr = h.split(',').next().map(|v| v.trim()); realip_remote_addr = h.split(',').next().map(str::trim);
} }
} }
} }
@ -123,7 +124,7 @@ impl ConnectionInfo {
remote_addr, remote_addr,
scheme: scheme.unwrap_or("http").to_owned(), scheme: scheme.unwrap_or("http").to_owned(),
host: host.unwrap_or("localhost").to_owned(), host: host.unwrap_or("localhost").to_owned(),
realip_remote_addr: realip_remote_addr.map(|s| s.to_owned()), realip_remote_addr: realip_remote_addr.map(str::to_owned),
} }
} }
@ -135,6 +136,7 @@ impl ConnectionInfo {
/// - X-Forwarded-Proto /// - X-Forwarded-Proto
/// - Uri /// - Uri
#[inline] #[inline]
#[must_use]
pub fn scheme(&self) -> &str { pub fn scheme(&self) -> &str {
&self.scheme &self.scheme
} }
@ -148,6 +150,7 @@ impl ConnectionInfo {
/// - Host /// - Host
/// - Uri /// - Uri
/// - Server hostname /// - Server hostname
#[must_use]
pub fn host(&self) -> &str { pub fn host(&self) -> &str {
&self.host &self.host
} }
@ -155,12 +158,9 @@ impl ConnectionInfo {
/// remote_addr address of the request. /// remote_addr address of the request.
/// ///
/// Get remote_addr address from socket address /// Get remote_addr address from socket address
#[must_use]
pub fn remote_addr(&self) -> Option<&str> { pub fn remote_addr(&self) -> Option<&str> {
if let Some(ref remote_addr) = self.remote_addr { self.remote_addr.as_ref().map(String::as_ref)
Some(remote_addr)
} else {
None
}
} }
/// Real ip remote addr of client initiated HTTP request. /// Real ip remote addr of client initiated HTTP request.
/// ///
@ -176,13 +176,12 @@ impl ConnectionInfo {
/// address explicitly, use /// address explicitly, use
/// [`HttpRequest::peer_addr()`](super::web::HttpRequest::peer_addr()) instead. /// [`HttpRequest::peer_addr()`](super::web::HttpRequest::peer_addr()) instead.
#[inline] #[inline]
#[must_use]
pub fn realip_remote_addr(&self) -> Option<&str> { pub fn realip_remote_addr(&self) -> Option<&str> {
if let Some(ref r) = self.realip_remote_addr { if let Some(ref r) = self.realip_remote_addr {
Some(r) Some(r)
} else if let Some(ref remote_addr) = self.remote_addr {
Some(remote_addr)
} else { } else {
None self.remote_addr.as_ref().map(String::as_ref)
} }
} }
} }

View File

@ -43,6 +43,7 @@ pub struct Compress(ContentEncoding);
impl Compress { impl Compress {
/// Create new `Compress` middleware with the specified encoding. /// Create new `Compress` middleware with the specified encoding.
#[must_use]
pub fn new(encoding: ContentEncoding) -> Self { pub fn new(encoding: ContentEncoding) -> Self {
Compress(encoding) Compress(encoding)
} }
@ -200,8 +201,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

@ -65,6 +65,7 @@ impl HttpRequest {
impl HttpRequest { impl HttpRequest {
/// This method returns reference to the request head /// This method returns reference to the request head
#[inline] #[inline]
#[must_use]
pub fn head(&self) -> &RequestHead { pub fn head(&self) -> &RequestHead {
&self.inner.head &self.inner.head
} }
@ -78,23 +79,27 @@ impl HttpRequest {
/// Request's uri. /// Request's uri.
#[inline] #[inline]
#[must_use]
pub fn uri(&self) -> &Uri { pub fn uri(&self) -> &Uri {
&self.head().uri &self.head().uri
} }
/// Read the Request method. /// Read the Request method.
#[inline] #[inline]
#[must_use]
pub fn method(&self) -> &Method { pub fn method(&self) -> &Method {
&self.head().method &self.head().method
} }
/// Read the Request Version. /// Read the Request Version.
#[inline] #[inline]
#[must_use]
pub fn version(&self) -> Version { pub fn version(&self) -> Version {
self.head().version self.head().version
} }
#[inline] #[inline]
#[must_use]
/// Returns request's headers. /// Returns request's headers.
pub fn headers(&self) -> &HeaderMap { pub fn headers(&self) -> &HeaderMap {
&self.head().headers &self.head().headers
@ -102,6 +107,7 @@ impl HttpRequest {
/// The target path of this Request. /// The target path of this Request.
#[inline] #[inline]
#[must_use]
pub fn path(&self) -> &str { pub fn path(&self) -> &str {
self.head().uri.path() self.head().uri.path()
} }
@ -110,12 +116,9 @@ impl HttpRequest {
/// ///
/// E.g., id=10 /// E.g., id=10
#[inline] #[inline]
#[must_use]
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.
@ -125,6 +128,7 @@ impl HttpRequest {
/// where the identifier can be used later in a request handler to /// where the identifier can be used later in a request handler to
/// access the matched value for that segment. /// access the matched value for that segment.
#[inline] #[inline]
#[must_use]
pub fn match_info(&self) -> &Path<Url> { pub fn match_info(&self) -> &Path<Url> {
&self.inner.path &self.inner.path
} }
@ -141,6 +145,7 @@ impl HttpRequest {
/// ///
/// Returns a None when no resource is fully matched, including default services. /// Returns a None when no resource is fully matched, including default services.
#[inline] #[inline]
#[must_use]
pub fn match_pattern(&self) -> Option<String> { pub fn match_pattern(&self) -> Option<String> {
self.resource_map().match_pattern(self.path()) self.resource_map().match_pattern(self.path())
} }
@ -149,18 +154,21 @@ impl HttpRequest {
/// ///
/// Returns a None when no resource is fully matched, including default services. /// Returns a None when no resource is fully matched, including default services.
#[inline] #[inline]
#[must_use]
pub fn match_name(&self) -> Option<&str> { pub fn match_name(&self) -> Option<&str> {
self.resource_map().match_name(self.path()) self.resource_map().match_name(self.path())
} }
/// Request extensions /// Request extensions
#[inline] #[inline]
#[must_use]
pub fn extensions(&self) -> Ref<'_, Extensions> { pub fn extensions(&self) -> Ref<'_, Extensions> {
self.head().extensions() self.head().extensions()
} }
/// Mutable reference to a the request's extensions /// Mutable reference to a the request's extensions
#[inline] #[inline]
#[must_use]
pub fn extensions_mut(&self) -> RefMut<'_, Extensions> { pub fn extensions_mut(&self) -> RefMut<'_, Extensions> {
self.head().extensions_mut() self.head().extensions_mut()
} }
@ -201,6 +209,7 @@ impl HttpRequest {
} }
#[inline] #[inline]
#[must_use]
/// Get a reference to a `ResourceMap` of current application. /// Get a reference to a `ResourceMap` of current application.
pub fn resource_map(&self) -> &ResourceMap { pub fn resource_map(&self) -> &ResourceMap {
&self.app_state().rmap() &self.app_state().rmap()
@ -215,6 +224,7 @@ impl HttpRequest {
/// ///
/// Will only return None when called in unit tests. /// Will only return None when called in unit tests.
#[inline] #[inline]
#[must_use]
pub fn peer_addr(&self) -> Option<net::SocketAddr> { pub fn peer_addr(&self) -> Option<net::SocketAddr> {
self.head().peer_addr self.head().peer_addr
} }
@ -224,12 +234,14 @@ impl HttpRequest {
/// This method panics if request's extensions container is already /// This method panics if request's extensions container is already
/// borrowed. /// borrowed.
#[inline] #[inline]
#[must_use]
pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> { pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> {
ConnectionInfo::get(self.head(), self.app_config()) ConnectionInfo::get(self.head(), self.app_config())
} }
/// App config /// App config
#[inline] #[inline]
#[must_use]
pub fn app_config(&self) -> &AppConfig { pub fn app_config(&self) -> &AppConfig {
self.app_state().config() self.app_state().config()
} }
@ -242,6 +254,7 @@ impl HttpRequest {
/// ```ignore /// ```ignore
/// let opt_t = req.app_data::<Data<T>>(); /// let opt_t = req.app_data::<Data<T>>();
/// ``` /// ```
#[must_use]
pub fn app_data<T: 'static>(&self) -> Option<&T> { pub fn app_data<T: 'static>(&self) -> Option<&T> {
for container in self.inner.app_data.iter().rev() { for container in self.inner.app_data.iter().rev() {
if let Some(data) = container.get::<T>() { if let Some(data) = container.get::<T>() {
@ -282,11 +295,12 @@ impl HttpRequest {
/// Return request cookie. /// Return request cookie.
#[cfg(feature = "cookies")] #[cfg(feature = "cookies")]
#[must_use]
pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> { pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> {
if let Ok(cookies) = self.cookies() { if let Ok(cookies) = self.cookies() {
for cookie in cookies.iter() { for cookie in cookies.iter() {
if cookie.name() == name { if cookie.name() == name {
return Some(cookie.to_owned()); return Some(cookie.clone());
} }
} }
} }

View File

@ -474,7 +474,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) {
if let Some(ref app_data) = self.app_data { if let Some(ref app_data) = self.app_data {
req.add_data_container(app_data.clone()); req.add_data_container(app_data.clone());

View File

@ -42,6 +42,7 @@ pub struct HttpResponseBuilder {
impl HttpResponseBuilder { impl HttpResponseBuilder {
#[inline] #[inline]
/// Create response builder /// Create response builder
#[must_use]
pub fn new(status: StatusCode) -> Self { pub fn new(status: StatusCode) -> Self {
Self { Self {
res: Some(Response::new(status)), res: Some(Response::new(status)),
@ -406,7 +407,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

@ -7,6 +7,7 @@ use crate::{HttpResponse, HttpResponseBuilder};
macro_rules! static_resp { macro_rules! static_resp {
($name:ident, $status:expr) => { ($name:ident, $status:expr) => {
#[allow(non_snake_case, missing_docs)] #[allow(non_snake_case, missing_docs)]
#[must_use]
pub fn $name() -> HttpResponseBuilder { pub fn $name() -> HttpResponseBuilder {
HttpResponseBuilder::new($status) HttpResponseBuilder::new($status)
} }

View File

@ -33,11 +33,13 @@ pub struct HttpResponse<B = AnyBody> {
impl HttpResponse<AnyBody> { impl HttpResponse<AnyBody> {
/// Create HTTP response builder with specific status. /// Create HTTP response builder with specific status.
#[inline] #[inline]
#[must_use]
pub fn build(status: StatusCode) -> HttpResponseBuilder { pub fn build(status: StatusCode) -> HttpResponseBuilder {
HttpResponseBuilder::new(status) HttpResponseBuilder::new(status)
} }
/// Create a response. /// Create a response.
#[must_use]
#[inline] #[inline]
pub fn new(status: StatusCode) -> Self { pub fn new(status: StatusCode) -> Self {
Self { Self {
@ -48,6 +50,7 @@ impl HttpResponse<AnyBody> {
/// Create an error response. /// Create an error response.
#[inline] #[inline]
#[must_use]
pub fn from_error(error: impl Into<Error>) -> Self { pub fn from_error(error: impl Into<Error>) -> Self {
error.into().as_response_error().error_response() error.into().as_response_error().error_response()
} }
@ -129,10 +132,7 @@ impl<B> HttpResponse<B> {
pub fn del_cookie(&mut self, name: &str) -> usize { pub fn del_cookie(&mut self, name: &str) -> usize {
let headers = self.headers_mut(); let headers = self.headers_mut();
let vals: Vec<HeaderValue> = headers let vals: Vec<HeaderValue> = headers.get_all(header::SET_COOKIE).cloned().collect();
.get_all(header::SET_COOKIE)
.map(|v| v.to_owned())
.collect();
headers.remove(header::SET_COOKIE); headers.remove(header::SET_COOKIE);

View File

@ -17,6 +17,7 @@ pub struct ResourceMap {
} }
impl ResourceMap { impl ResourceMap {
#[must_use]
pub fn new(root: ResourceDef) -> Self { pub fn new(root: ResourceDef) -> Self {
ResourceMap { ResourceMap {
root, root,

View File

@ -28,6 +28,7 @@ pub struct Route {
impl Route { impl Route {
/// Create new route which matches any request. /// Create new route which matches any request.
#[allow(clippy::new_without_default)] #[allow(clippy::new_without_default)]
#[must_use]
pub fn new() -> Route { pub fn new() -> Route {
Route { Route {
service: boxed::factory(HandlerService::new(HttpResponse::NotFound)), service: boxed::factory(HandlerService::new(HttpResponse::NotFound)),
@ -101,6 +102,7 @@ impl Route {
/// ); /// );
/// # } /// # }
/// ``` /// ```
#[must_use]
pub fn method(mut self, method: Method) -> Self { pub fn method(mut self, method: Method) -> Self {
Rc::get_mut(&mut self.guards) Rc::get_mut(&mut self.guards)
.unwrap() .unwrap()

View File

@ -70,6 +70,7 @@ pub struct Scope<T = ScopeEndpoint> {
impl Scope { impl Scope {
/// Create a new scope /// Create a new scope
#[must_use]
pub fn new(path: &str) -> Scope { pub fn new(path: &str) -> Scope {
let fref = Rc::new(RefCell::new(None)); let fref = Rc::new(RefCell::new(None));
Scope { Scope {

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

@ -76,11 +76,13 @@ impl ServiceRequest {
/// Deconstruct request into parts /// Deconstruct request into parts
#[inline] #[inline]
#[must_use]
pub fn into_parts(self) -> (HttpRequest, Payload) { pub fn into_parts(self) -> (HttpRequest, Payload) {
(self.req, self.payload) (self.req, self.payload)
} }
/// Construct request from parts. /// Construct request from parts.
#[must_use]
pub fn from_parts(req: HttpRequest, payload: Payload) -> Self { pub fn from_parts(req: HttpRequest, payload: Payload) -> Self {
Self { req, payload } Self { req, payload }
} }
@ -88,6 +90,7 @@ impl ServiceRequest {
/// Construct request from request. /// Construct request from request.
/// ///
/// The returned `ServiceRequest` would have no payload. /// The returned `ServiceRequest` would have no payload.
#[must_use]
pub fn from_request(req: HttpRequest) -> Self { pub fn from_request(req: HttpRequest) -> Self {
ServiceRequest { ServiceRequest {
req, req,
@ -111,6 +114,7 @@ impl ServiceRequest {
/// This method returns reference to the request head /// This method returns reference to the request head
#[inline] #[inline]
#[must_use]
pub fn head(&self) -> &RequestHead { pub fn head(&self) -> &RequestHead {
&self.req.head() &self.req.head()
} }
@ -123,29 +127,34 @@ impl ServiceRequest {
/// Request's uri. /// Request's uri.
#[inline] #[inline]
#[must_use]
pub fn uri(&self) -> &Uri { pub fn uri(&self) -> &Uri {
&self.head().uri &self.head().uri
} }
/// Read the Request method. /// Read the Request method.
#[inline] #[inline]
#[must_use]
pub fn method(&self) -> &Method { pub fn method(&self) -> &Method {
&self.head().method &self.head().method
} }
/// Read the Request Version. /// Read the Request Version.
#[inline] #[inline]
#[must_use]
pub fn version(&self) -> Version { pub fn version(&self) -> Version {
self.head().version self.head().version
} }
#[inline] #[inline]
#[must_use]
/// Returns request's headers. /// Returns request's headers.
pub fn headers(&self) -> &HeaderMap { pub fn headers(&self) -> &HeaderMap {
&self.head().headers &self.head().headers
} }
#[inline] #[inline]
#[must_use]
/// Returns mutable request's headers. /// Returns mutable request's headers.
pub fn headers_mut(&mut self) -> &mut HeaderMap { pub fn headers_mut(&mut self) -> &mut HeaderMap {
&mut self.head_mut().headers &mut self.head_mut().headers
@ -153,6 +162,7 @@ impl ServiceRequest {
/// The target path of this Request. /// The target path of this Request.
#[inline] #[inline]
#[must_use]
pub fn path(&self) -> &str { pub fn path(&self) -> &str {
self.head().uri.path() self.head().uri.path()
} }
@ -161,12 +171,9 @@ impl ServiceRequest {
/// ///
/// E.g., id=10 /// E.g., id=10
#[inline] #[inline]
#[must_use]
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.
@ -178,12 +185,14 @@ impl ServiceRequest {
/// ///
/// Will only return None when called in unit tests. /// Will only return None when called in unit tests.
#[inline] #[inline]
#[must_use]
pub fn peer_addr(&self) -> Option<net::SocketAddr> { pub fn peer_addr(&self) -> Option<net::SocketAddr> {
self.head().peer_addr self.head().peer_addr
} }
/// Get *ConnectionInfo* for the current request. /// Get *ConnectionInfo* for the current request.
#[inline] #[inline]
#[must_use]
pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> { pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> {
ConnectionInfo::get(self.head(), &*self.app_config()) ConnectionInfo::get(self.head(), &*self.app_config())
} }
@ -195,29 +204,34 @@ impl ServiceRequest {
/// where the identifier can be used later in a request handler to /// where the identifier can be used later in a request handler to
/// access the matched value for that segment. /// access the matched value for that segment.
#[inline] #[inline]
#[must_use]
pub fn match_info(&self) -> &Path<Url> { pub fn match_info(&self) -> &Path<Url> {
self.req.match_info() self.req.match_info()
} }
/// Counterpart to [`HttpRequest::match_name`](super::HttpRequest::match_name()). /// Counterpart to [`HttpRequest::match_name`](super::HttpRequest::match_name()).
#[inline] #[inline]
#[must_use]
pub fn match_name(&self) -> Option<&str> { pub fn match_name(&self) -> Option<&str> {
self.req.match_name() self.req.match_name()
} }
/// Counterpart to [`HttpRequest::match_pattern`](super::HttpRequest::match_pattern()). /// Counterpart to [`HttpRequest::match_pattern`](super::HttpRequest::match_pattern()).
#[inline] #[inline]
#[must_use]
pub fn match_pattern(&self) -> Option<String> { pub fn match_pattern(&self) -> Option<String> {
self.req.match_pattern() self.req.match_pattern()
} }
#[inline] #[inline]
#[must_use]
/// Get a mutable reference to the Path parameters. /// Get a mutable reference to the Path parameters.
pub fn match_info_mut(&mut self) -> &mut Path<Url> { pub fn match_info_mut(&mut self) -> &mut Path<Url> {
self.req.match_info_mut() self.req.match_info_mut()
} }
#[inline] #[inline]
#[must_use]
/// Get a reference to a `ResourceMap` of current application. /// Get a reference to a `ResourceMap` of current application.
pub fn resource_map(&self) -> &ResourceMap { pub fn resource_map(&self) -> &ResourceMap {
self.req.resource_map() self.req.resource_map()
@ -225,11 +239,13 @@ impl ServiceRequest {
/// Service configuration /// Service configuration
#[inline] #[inline]
#[must_use]
pub fn app_config(&self) -> &AppConfig { pub fn app_config(&self) -> &AppConfig {
self.req.app_config() self.req.app_config()
} }
/// Counterpart to [`HttpRequest::app_data`](super::HttpRequest::app_data()). /// Counterpart to [`HttpRequest::app_data`](super::HttpRequest::app_data()).
#[must_use]
pub fn app_data<T: 'static>(&self) -> Option<&T> { pub fn app_data<T: 'static>(&self) -> Option<&T> {
for container in self.req.inner.app_data.iter().rev() { for container in self.req.inner.app_data.iter().rev() {
if let Some(data) = container.get::<T>() { if let Some(data) = container.get::<T>() {
@ -247,6 +263,7 @@ impl ServiceRequest {
/// Return request cookie. /// Return request cookie.
#[cfg(feature = "cookies")] #[cfg(feature = "cookies")]
#[must_use]
pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> { pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> {
self.req.cookie(name) self.req.cookie(name)
} }
@ -475,6 +492,7 @@ impl WebService {
/// Set service name. /// Set service name.
/// ///
/// Name is used for url generation. /// Name is used for url generation.
#[must_use]
pub fn name(mut self, name: &str) -> Self { pub fn name(mut self, name: &str) -> Self {
self.name = Some(name.to_string()); self.name = Some(name.to_string());
self self

View File

@ -31,12 +31,14 @@ use crate::{
}; };
/// Create service that always responds with `HttpResponse::Ok()` and no body. /// Create service that always responds with `HttpResponse::Ok()` and no body.
#[must_use]
pub fn ok_service( pub fn ok_service(
) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> { ) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> {
default_service(StatusCode::OK) default_service(StatusCode::OK)
} }
/// Create service that always responds with given status code and no body. /// Create service that always responds with given status code and no body.
#[must_use]
pub fn default_service( pub fn default_service(
status_code: StatusCode, status_code: StatusCode,
) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> { ) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> {
@ -398,31 +400,37 @@ impl Default for TestRequest {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
impl TestRequest { impl TestRequest {
/// Create TestRequest and set request uri /// Create TestRequest and set request uri
#[must_use]
pub fn with_uri(path: &str) -> TestRequest { pub fn with_uri(path: &str) -> TestRequest {
TestRequest::default().uri(path) TestRequest::default().uri(path)
} }
/// Create TestRequest and set method to `Method::GET` /// Create TestRequest and set method to `Method::GET`
#[must_use]
pub fn get() -> TestRequest { pub fn get() -> TestRequest {
TestRequest::default().method(Method::GET) TestRequest::default().method(Method::GET)
} }
/// Create TestRequest and set method to `Method::POST` /// Create TestRequest and set method to `Method::POST`
#[must_use]
pub fn post() -> TestRequest { pub fn post() -> TestRequest {
TestRequest::default().method(Method::POST) TestRequest::default().method(Method::POST)
} }
/// Create TestRequest and set method to `Method::PUT` /// Create TestRequest and set method to `Method::PUT`
#[must_use]
pub fn put() -> TestRequest { pub fn put() -> TestRequest {
TestRequest::default().method(Method::PUT) TestRequest::default().method(Method::PUT)
} }
/// Create TestRequest and set method to `Method::PATCH` /// Create TestRequest and set method to `Method::PATCH`
#[must_use]
pub fn patch() -> TestRequest { pub fn patch() -> TestRequest {
TestRequest::default().method(Method::PATCH) TestRequest::default().method(Method::PATCH)
} }
/// Create TestRequest and set method to `Method::DELETE` /// Create TestRequest and set method to `Method::DELETE`
#[must_use]
pub fn delete() -> TestRequest { pub fn delete() -> TestRequest {
TestRequest::default().method(Method::DELETE) TestRequest::default().method(Method::DELETE)
} }

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,
@ -223,12 +224,14 @@ pub struct FormConfig {
impl FormConfig { impl FormConfig {
/// Set maximum accepted payload size. By default this limit is 16kB. /// Set maximum accepted payload size. By default this limit is 16kB.
#[must_use]
pub fn limit(mut self, limit: usize) -> Self { pub fn limit(mut self, limit: usize) -> Self {
self.limit = limit; self.limit = limit;
self self
} }
/// Set custom error handler /// Set custom error handler
#[must_use]
pub fn error_handler<F>(mut self, f: F) -> Self pub fn error_handler<F>(mut self, f: F) -> Self
where where
F: Fn(UrlencodedError, &HttpRequest) -> Error + 'static, F: Fn(UrlencodedError, &HttpRequest) -> Error + 'static,
@ -325,6 +328,7 @@ impl<T> UrlEncoded<T> {
} }
/// Set maximum accepted payload size. The default limit is 256kB. /// Set maximum accepted payload size. The default limit is 256kB.
#[must_use]
pub fn limit(mut self, limit: usize) -> Self { pub fn limit(mut self, limit: usize) -> Self {
self.limit = limit; self.limit = limit;
self self
@ -380,7 +384,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

@ -241,12 +241,14 @@ pub struct JsonConfig {
impl JsonConfig { impl JsonConfig {
/// Set maximum accepted payload size. By default this limit is 2MB. /// Set maximum accepted payload size. By default this limit is 2MB.
#[must_use]
pub fn limit(mut self, limit: usize) -> Self { pub fn limit(mut self, limit: usize) -> Self {
self.limit = limit; self.limit = limit;
self self
} }
/// Set custom error handler. /// Set custom error handler.
#[must_use]
pub fn error_handler<F>(mut self, f: F) -> Self pub fn error_handler<F>(mut self, f: F) -> Self
where where
F: Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync + 'static, F: Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,
@ -256,6 +258,7 @@ impl JsonConfig {
} }
/// Set predicate for allowed content types. /// Set predicate for allowed content types.
#[must_use]
pub fn content_type<F>(mut self, predicate: F) -> Self pub fn content_type<F>(mut self, predicate: F) -> Self
where where
F: Fn(mime::Mime) -> bool + Send + Sync + 'static, F: Fn(mime::Mime) -> bool + Send + Sync + 'static,
@ -365,6 +368,7 @@ where
} }
/// Set maximum accepted payload size. The default limit is 2MB. /// Set maximum accepted payload size. The default limit is 2MB.
#[must_use]
pub fn limit(self, limit: usize) -> Self { pub fn limit(self, limit: usize) -> Self {
match self { match self {
JsonBody::Body { JsonBody::Body {

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,
@ -46,6 +47,7 @@ pub struct Payload(pub crate::dev::Payload);
impl Payload { impl Payload {
/// Unwrap to inner Payload type. /// Unwrap to inner Payload type.
#[must_use]
pub fn into_inner(self) -> crate::dev::Payload { pub fn into_inner(self) -> crate::dev::Payload {
self.0 self.0
} }
@ -190,7 +192,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"))?)
} }
} }
@ -213,6 +215,7 @@ pub struct PayloadConfig {
impl PayloadConfig { impl PayloadConfig {
/// Create new instance with a size limit (in bytes) and no mime type condition. /// Create new instance with a size limit (in bytes) and no mime type condition.
#[must_use]
pub fn new(limit: usize) -> Self { pub fn new(limit: usize) -> Self {
Self { Self {
limit, limit,
@ -221,12 +224,14 @@ impl PayloadConfig {
} }
/// Set maximum accepted payload size in bytes. The default limit is 256kB. /// Set maximum accepted payload size in bytes. The default limit is 256kB.
#[must_use]
pub fn limit(mut self, limit: usize) -> Self { pub fn limit(mut self, limit: usize) -> Self {
self.limit = limit; self.limit = limit;
self self
} }
/// Set required mime type of the request. By default mime type is not enforced. /// Set required mime type of the request. By default mime type is not enforced.
#[must_use]
pub fn mimetype(mut self, mt: Mime) -> Self { pub fn mimetype(mut self, mt: Mime) -> Self {
self.mimetype = Some(mt); self.mimetype = Some(mt);
self self

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)))

View File

@ -52,6 +52,7 @@ pub use crate::types::*;
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed())) /// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// ); /// );
/// ``` /// ```
#[must_use]
pub fn resource<T: IntoPattern>(path: T) -> Resource { pub fn resource<T: IntoPattern>(path: T) -> Resource {
Resource::new(path) Resource::new(path)
} }
@ -77,11 +78,13 @@ pub fn resource<T: IntoPattern>(path: T) -> Resource {
/// * /{project_id}/path2 /// * /{project_id}/path2
/// * /{project_id}/path3 /// * /{project_id}/path3
/// ///
#[must_use]
pub fn scope(path: &str) -> Scope { pub fn scope(path: &str) -> Scope {
Scope::new(path) Scope::new(path)
} }
/// Create *route* without configuration. /// Create *route* without configuration.
#[must_use]
pub fn route() -> Route { pub fn route() -> Route {
Route::new() Route::new()
} }
@ -100,6 +103,7 @@ pub fn route() -> Route {
/// In the above example, one `GET` route gets added: /// In the above example, one `GET` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn get() -> Route { pub fn get() -> Route {
method(Method::GET) method(Method::GET)
} }
@ -118,6 +122,7 @@ pub fn get() -> Route {
/// In the above example, one `POST` route gets added: /// In the above example, one `POST` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn post() -> Route { pub fn post() -> Route {
method(Method::POST) method(Method::POST)
} }
@ -136,6 +141,7 @@ pub fn post() -> Route {
/// In the above example, one `PUT` route gets added: /// In the above example, one `PUT` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn put() -> Route { pub fn put() -> Route {
method(Method::PUT) method(Method::PUT)
} }
@ -154,6 +160,7 @@ pub fn put() -> Route {
/// In the above example, one `PATCH` route gets added: /// In the above example, one `PATCH` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn patch() -> Route { pub fn patch() -> Route {
method(Method::PATCH) method(Method::PATCH)
} }
@ -172,6 +179,7 @@ pub fn patch() -> Route {
/// In the above example, one `DELETE` route gets added: /// In the above example, one `DELETE` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn delete() -> Route { pub fn delete() -> Route {
method(Method::DELETE) method(Method::DELETE)
} }
@ -190,6 +198,7 @@ pub fn delete() -> Route {
/// In the above example, one `HEAD` route gets added: /// In the above example, one `HEAD` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn head() -> Route { pub fn head() -> Route {
method(Method::HEAD) method(Method::HEAD)
} }
@ -208,6 +217,7 @@ pub fn head() -> Route {
/// In the above example, one `HEAD` route gets added: /// In the above example, one `HEAD` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn trace() -> Route { pub fn trace() -> Route {
method(Method::TRACE) method(Method::TRACE)
} }
@ -226,6 +236,7 @@ pub fn trace() -> Route {
/// In the above example, one `GET` route gets added: /// In the above example, one `GET` route gets added:
/// * /{project_id} /// * /{project_id}
/// ///
#[must_use]
pub fn method(method: Method) -> Route { pub fn method(method: Method) -> Route {
Route::new().method(method) Route::new().method(method)
} }
@ -244,6 +255,7 @@ pub fn method(method: Method) -> Route {
/// web::to(index)) /// web::to(index))
/// ); /// );
/// ``` /// ```
#[must_use]
pub fn to<F, I, R>(handler: F) -> Route pub fn to<F, I, R>(handler: F) -> Route
where where
F: Handler<I, R>, F: Handler<I, R>,
@ -269,6 +281,7 @@ where
/// .finish(my_service) /// .finish(my_service)
/// ); /// );
/// ``` /// ```
#[must_use]
pub fn service<T: IntoPattern>(path: T) -> WebService { pub fn service<T: IntoPattern>(path: T) -> WebService {
WebService::new(path) WebService::new(path)
} }