From 809930d36e3d414662205ad02eb514083843463b Mon Sep 17 00:00:00 2001 From: Elliot Jackson Date: Wed, 19 Feb 2020 21:13:10 +0100 Subject: [PATCH 01/12] Add dependencies to docs example (#1343) * Add dependencies to docs example * Change codeblock type to toml * Clarify the need for actix-rt Co-authored-by: Yuki Okushi --- src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index d51005cfe..a898bd704 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,12 @@ //! Actix web is a small, pragmatic, and extremely fast web framework //! for Rust. //! +//! ## Example +//! +//! The `#[actix_rt::main]` macro in the example below is provided by the Actix runtime +//! crate, [`actix-rt`](https://crates.io/crates/actix-rt). You will need to include +//! `actix-rt` in your dependencies for it to run. +//! //! ```rust,no_run //! use actix_web::{web, App, Responder, HttpServer}; //! From e6811e8818b015c31f88d22bd037d3377deac1c3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 21:03:53 -0500 Subject: [PATCH 02/12] Use #[pin_project] with `ConnectorPoolSupport` This removes a use of `Pin::get_unchecked_mut` --- actix-http/src/client/pool.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actix-http/src/client/pool.rs b/actix-http/src/client/pool.rs index 8c94423ac..139cf9f66 100644 --- a/actix-http/src/client/pool.rs +++ b/actix-http/src/client/pool.rs @@ -17,6 +17,7 @@ use h2::client::{handshake, Connection, SendRequest}; use http::uri::Authority; use indexmap::IndexSet; use slab::Slab; +use pin_project::pin_project; use super::connection::{ConnectionType, IoConnection}; use super::error::ConnectError; @@ -422,6 +423,7 @@ where } } +#[pin_project] struct ConnectorPoolSupport where Io: AsyncRead + AsyncWrite + Unpin + 'static, @@ -439,7 +441,7 @@ where type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = unsafe { self.get_unchecked_mut() }; + let this = self.project(); let mut inner = this.inner.as_ref().borrow_mut(); inner.waker.register(cx.waker()); From 245f96868aaf6b86bbefc36e79ef39fd70878730 Mon Sep 17 00:00:00 2001 From: Daniel YU Date: Fri, 21 Feb 2020 12:31:51 +0800 Subject: [PATCH 03/12] impl downcast_ref for MessageBody (#1287) Co-authored-by: Yuki Okushi --- actix-http/src/body.rs | 23 +++++++++- actix-http/src/error.rs | 44 +------------------ actix-http/src/lib.rs | 3 ++ actix-http/src/macros.rs | 95 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 actix-http/src/macros.rs diff --git a/actix-http/src/body.rs b/actix-http/src/body.rs index e2bcce359..1a2428e14 100644 --- a/actix-http/src/body.rs +++ b/actix-http/src/body.rs @@ -37,8 +37,12 @@ pub trait MessageBody { fn size(&self) -> BodySize; fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll>>; + + downcast_get_type_id!(); } +downcast!(MessageBody); + impl MessageBody for () { fn size(&self) -> BodySize { BodySize::Empty @@ -416,7 +420,10 @@ where S: Stream>, { pub fn new(size: u64, stream: S) -> Self { - SizedStream { size, stream: Box::pin(stream) } + SizedStream { + size, + stream: Box::pin(stream), + } } } @@ -643,4 +650,18 @@ mod tests { ); } } + + #[actix_rt::test] + async fn test_body_casting() { + let mut body = String::from("hello cast"); + let resp_body: &mut dyn MessageBody = &mut body; + let body = resp_body.downcast_ref::().unwrap(); + assert_eq!(body, "hello cast"); + let body = &mut resp_body.downcast_mut::().unwrap(); + body.push_str("!"); + let body = resp_body.downcast_ref::().unwrap(); + assert_eq!(body, "hello cast!"); + let not_body = resp_body.downcast_ref::<()>(); + assert!(not_body.is_none()); + } } diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index b6637075c..c19aef2aa 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -1,5 +1,4 @@ //! Error and Result module -use std::any::TypeId; use std::cell::RefCell; use std::io::Write; use std::str::Utf8Error; @@ -60,12 +59,6 @@ impl Error { } } -/// A struct with a private constructor, for use with -/// `__private_get_type_id__`. Its single field is private, -/// ensuring that it can only be constructed from this module -#[doc(hidden)] -pub struct PrivateHelper(()); - /// Error that can be converted to `Response` pub trait ResponseError: fmt::Debug + fmt::Display { /// Response's status code @@ -89,43 +82,10 @@ pub trait ResponseError: fmt::Debug + fmt::Display { resp.set_body(Body::from(buf)) } - /// A helper method to get the type ID of the type - /// this trait is implemented on. - /// This method is unsafe to *implement*, since `downcast_ref` relies - /// on the returned `TypeId` to perform a cast. - /// - /// Unfortunately, Rust has no notion of a trait method that is - /// unsafe to implement (marking it as `unsafe` makes it unsafe - /// to *call*). As a workaround, we require this method - /// to return a private type along with the `TypeId`. This - /// private type (`PrivateHelper`) has a private constructor, - /// making it impossible for safe code to construct outside of - /// this module. This ensures that safe code cannot violate - /// type-safety by implementing this method. - #[doc(hidden)] - fn __private_get_type_id__(&self) -> (TypeId, PrivateHelper) - where - Self: 'static, - { - (TypeId::of::(), PrivateHelper(())) - } + downcast_get_type_id!(); } -impl dyn ResponseError + 'static { - /// Downcasts a response error to a specific type. - pub fn downcast_ref(&self) -> Option<&T> { - if self.__private_get_type_id__().0 == TypeId::of::() { - // Safety: external crates cannot override the default - // implementation of `__private_get_type_id__`, since - // it requires returning a private type. We can therefore - // rely on the returned `TypeId`, which ensures that this - // case is correct. - unsafe { Some(&*(self as *const dyn ResponseError as *const T)) } - } else { - None - } - } -} +downcast!(ResponseError); impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index a5ae4b447..1cda9437f 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -10,6 +10,9 @@ #[macro_use] extern crate log; +#[macro_use] +mod macros; + pub mod body; mod builder; pub mod client; diff --git a/actix-http/src/macros.rs b/actix-http/src/macros.rs new file mode 100644 index 000000000..0aaf1abec --- /dev/null +++ b/actix-http/src/macros.rs @@ -0,0 +1,95 @@ +#[macro_export] +macro_rules! downcast_get_type_id { + () => { + /// A helper method to get the type ID of the type + /// this trait is implemented on. + /// This method is unsafe to *implement*, since `downcast_ref` relies + /// on the returned `TypeId` to perform a cast. + /// + /// Unfortunately, Rust has no notion of a trait method that is + /// unsafe to implement (marking it as `unsafe` makes it unsafe + /// to *call*). As a workaround, we require this method + /// to return a private type along with the `TypeId`. This + /// private type (`PrivateHelper`) has a private constructor, + /// making it impossible for safe code to construct outside of + /// this module. This ensures that safe code cannot violate + /// type-safety by implementing this method. + #[doc(hidden)] + fn __private_get_type_id__(&self) -> (std::any::TypeId, PrivateHelper) + where + Self: 'static, + { + (std::any::TypeId::of::(), PrivateHelper(())) + } + } +} + +//Generate implementation for dyn $name +#[macro_export] +macro_rules! downcast { + ($name:ident) => { + /// A struct with a private constructor, for use with + /// `__private_get_type_id__`. Its single field is private, + /// ensuring that it can only be constructed from this module + #[doc(hidden)] + pub struct PrivateHelper(()); + + impl dyn $name + 'static { + /// Downcasts generic body to a specific type. + pub fn downcast_ref(&self) -> Option<&T> { + if self.__private_get_type_id__().0 == std::any::TypeId::of::() { + // Safety: external crates cannot override the default + // implementation of `__private_get_type_id__`, since + // it requires returning a private type. We can therefore + // rely on the returned `TypeId`, which ensures that this + // case is correct. + unsafe { Some(&*(self as *const dyn $name as *const T)) } + } else { + None + } + } + /// Downcasts a generic body to a mutable specific type. + pub fn downcast_mut(&mut self) -> Option<&mut T> { + if self.__private_get_type_id__().0 == std::any::TypeId::of::() { + // Safety: external crates cannot override the default + // implementation of `__private_get_type_id__`, since + // it requires returning a private type. We can therefore + // rely on the returned `TypeId`, which ensures that this + // case is correct. + unsafe { + Some(&mut *(self as *const dyn $name as *const T as *mut T)) + } + } else { + None + } + } + } + }; +} + +#[cfg(test)] +mod tests { + + trait MB { + downcast_get_type_id!(); + } + + downcast!(MB); + + impl MB for String {} + impl MB for () {} + + #[actix_rt::test] + async fn test_any_casting() { + let mut body = String::from("hello cast"); + let resp_body: &mut dyn MB = &mut body; + let body = resp_body.downcast_ref::().unwrap(); + assert_eq!(body, "hello cast"); + let body = &mut resp_body.downcast_mut::().unwrap(); + body.push_str("!"); + let body = resp_body.downcast_ref::().unwrap(); + assert_eq!(body, "hello cast!"); + let not_body = resp_body.downcast_ref::<()>(); + assert!(not_body.is_none()); + } +} From 060c392c676c55accfc569ea8c05e570efe6df8e Mon Sep 17 00:00:00 2001 From: Matt Gathu Date: Sat, 22 Feb 2020 10:32:12 +0100 Subject: [PATCH 04/12] Add missing_docs attribute to generated structs --- actix-web-codegen/src/route.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index d48198484..60b829595 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -191,7 +191,7 @@ impl Route { let extra_guards = &self.args.guards; let resource_type = &self.resource_type; let stream = quote! { - #[allow(non_camel_case_types)] + #[allow(non_camel_case_types, missing_docs)] pub struct #name; impl actix_web::dev::HttpServiceFactory for #name { From 036ffd43f964b24c1aa975efb9de48073f5b80f5 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 23 Feb 2020 06:40:02 +0900 Subject: [PATCH 05/12] Prepare for new release --- actix-web-codegen/CHANGES.md | 8 ++++++-- actix-web-codegen/Cargo.toml | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 95696abd3..13ed5d43d 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -1,8 +1,12 @@ # Changes -## [0.2.NEXT] - 2020-xx-xx +## [0.2.1] - 2020-02-23 -* Allow the handler function to be named as `config` #1290 +* Add `#[allow(missing_docs)]` attribute to generated structs [#1368] +* Allow the handler function to be named as `config` [#1290] + +[#1368]: https://github.com/actix/actix-web/issues/1368 +[#1290]: https://github.com/actix/actix-web/issues/1290 ## [0.2.0] - 2019-12-13 diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 3fe561deb..0b926b807 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-codegen" -version = "0.2.0" +version = "0.2.1" description = "Actix web proc macros" readme = "README.md" authors = ["Nikolay Kim "] @@ -17,6 +17,6 @@ syn = { version = "^1", features = ["full", "parsing"] } proc-macro2 = "^1" [dev-dependencies] -actix-rt = { version = "1.0.0" } -actix-web = { version = "2.0.0-rc" } -futures = { version = "0.3.1" } +actix-rt = "1.0.0" +actix-web = "2.0.0" +futures = "0.3.1" From 1b77963aacb38df135cef31b2b41838d71c3b188 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 23 Feb 2020 07:08:22 +0900 Subject: [PATCH 06/12] actix-web: update `time` to 0.2.7 --- CHANGES.md | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b42635b86..5da4e19ec 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,7 +9,7 @@ * Skip empty chunks when returning response from a `Stream` #1308 -* Update the `time` dependency to 0.2.5 +* Update the `time` dependency to 0.2.7 ## [2.0.0] - 2019-12-25 diff --git a/Cargo.toml b/Cargo.toml index a6783a6db..d06e47ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,7 +87,7 @@ regex = "1.3" serde = { version = "1.0", features=["derive"] } serde_json = "1.0" serde_urlencoded = "0.6.1" -time = { version = "0.2.5", default-features = false, features = ["std"] } +time = { version = "0.2.7", default-features = false, features = ["std"] } url = "2.1" open-ssl = { version="0.10", package = "openssl", optional = true } rust-tls = { version = "0.16.0", package = "rustls", optional = true } From f9f9fb4c840c9c6c31837d18e4984a87d662c81c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 23 Feb 2020 07:08:50 +0900 Subject: [PATCH 07/12] actix-http-test: update `time` to 0.2.7 --- test-server/CHANGES.md | 2 +- test-server/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-server/CHANGES.md b/test-server/CHANGES.md index 617b8092f..f8b29f39d 100644 --- a/test-server/CHANGES.md +++ b/test-server/CHANGES.md @@ -2,7 +2,7 @@ ## [Unreleased] - 2020-xx-xx -* Update the `time` dependency to 0.2.5 +* Update the `time` dependency to 0.2.7 ## [1.0.0] - 2019-12-13 diff --git a/test-server/Cargo.toml b/test-server/Cargo.toml index b22414e29..774c8f0b2 100644 --- a/test-server/Cargo.toml +++ b/test-server/Cargo.toml @@ -51,7 +51,7 @@ serde_json = "1.0" sha1 = "0.6" slab = "0.4" serde_urlencoded = "0.6.1" -time = { version = "0.2.5", default-features = false, features = ["std"] } +time = { version = "0.2.7", default-features = false, features = ["std"] } open-ssl = { version="0.10", package="openssl", optional = true } [dev-dependencies] From c8ccc69b93e016e42c47978fb8cf64b87119db3e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 23 Feb 2020 07:09:00 +0900 Subject: [PATCH 08/12] actix-http: update `time` to 0.2.7 --- actix-http/CHANGES.md | 2 +- actix-http/Cargo.toml | 2 +- actix-http/src/cookie/mod.rs | 4 ++-- actix-http/src/cookie/parse.rs | 10 +++++----- actix-http/src/header/shared/httpdate.rs | 8 ++++---- actix-http/src/time_parser.rs | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 511ef4f1c..4e8d7fd42 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -4,7 +4,7 @@ ### Changed -* Update the `time` dependency to 0.2.5 +* Update the `time` dependency to 0.2.7 ### Fixed diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index cd813e49f..10aa79d18 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -76,7 +76,7 @@ serde_json = "1.0" sha-1 = "0.8" slab = "0.4" serde_urlencoded = "0.6.1" -time = { version = "0.2.5", default-features = false, features = ["std"] } +time = { version = "0.2.7", default-features = false, features = ["std"] } # for secure cookie ring = { version = "0.16.9", optional = true } diff --git a/actix-http/src/cookie/mod.rs b/actix-http/src/cookie/mod.rs index 09120e19f..8dccd0b6d 100644 --- a/actix-http/src/cookie/mod.rs +++ b/actix-http/src/cookie/mod.rs @@ -990,7 +990,7 @@ impl<'a, 'b> PartialEq> for Cookie<'a> { #[cfg(test)] mod tests { use super::{Cookie, SameSite}; - use time::{offset, PrimitiveDateTime}; + use time::PrimitiveDateTime; #[test] fn format() { @@ -1015,7 +1015,7 @@ mod tests { assert_eq!(&cookie.to_string(), "foo=bar; Domain=www.rust-lang.org"); let time_str = "Wed, 21 Oct 2015 07:28:00 GMT"; - let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S").unwrap().using_offset(offset!(UTC)); + let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S").unwrap().assume_utc(); let cookie = Cookie::build("foo", "bar").expires(expires).finish(); assert_eq!( &cookie.to_string(), diff --git a/actix-http/src/cookie/parse.rs b/actix-http/src/cookie/parse.rs index 28eb4f8b6..537069de3 100644 --- a/actix-http/src/cookie/parse.rs +++ b/actix-http/src/cookie/parse.rs @@ -6,7 +6,7 @@ use std::fmt; use std::str::Utf8Error; use percent_encoding::percent_decode; -use time::{Duration, offset}; +use time::Duration; use super::{Cookie, CookieStr, SameSite}; @@ -188,7 +188,7 @@ fn parse_inner<'c>(s: &str, decode: bool) -> Result, ParseError> { .or_else(|| time::parse(v, "%a, %d-%b-%Y %H:%M:%S").ok()); if let Some(time) = tm { - cookie.expires = Some(time.using_offset(offset!(UTC))) + cookie.expires = Some(time.assume_utc()) } } _ => { @@ -216,7 +216,7 @@ where #[cfg(test)] mod tests { use super::{Cookie, SameSite}; - use time::{offset, Duration, PrimitiveDateTime}; + use time::{Duration, PrimitiveDateTime}; macro_rules! assert_eq_parse { ($string:expr, $expected:expr) => { @@ -376,7 +376,7 @@ mod tests { ); let time_str = "Wed, 21 Oct 2015 07:28:00 GMT"; - let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S").unwrap().using_offset(offset!(UTC)); + let expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%M:%S").unwrap().assume_utc(); expected.set_expires(expires); assert_eq_parse!( " foo=bar ;HttpOnly; Secure; Max-Age=4; Path=/foo; \ @@ -385,7 +385,7 @@ mod tests { ); unexpected.set_domain("foo.com"); - let bad_expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%S:%M").unwrap().using_offset(offset!(UTC)); + let bad_expires = PrimitiveDateTime::parse(time_str, "%a, %d %b %Y %H:%S:%M").unwrap().assume_utc(); expected.set_expires(bad_expires); assert_ne_parse!( " foo=bar ;HttpOnly; Secure; Max-Age=4; Path=/foo; \ diff --git a/actix-http/src/header/shared/httpdate.rs b/actix-http/src/header/shared/httpdate.rs index 1b52f0de4..5227118fa 100644 --- a/actix-http/src/header/shared/httpdate.rs +++ b/actix-http/src/header/shared/httpdate.rs @@ -20,7 +20,7 @@ impl FromStr for HttpDate { fn from_str(s: &str) -> Result { match time_parser::parse_http_date(s) { - Some(t) => Ok(HttpDate(t.using_offset(offset!(UTC)))), + Some(t) => Ok(HttpDate(t.assume_utc())), None => Err(ParseError::Header) } } @@ -40,7 +40,7 @@ impl From for HttpDate { impl From for HttpDate { fn from(sys: SystemTime) -> HttpDate { - HttpDate(PrimitiveDateTime::from(sys).using_offset(offset!(UTC))) + HttpDate(PrimitiveDateTime::from(sys).assume_utc()) } } @@ -66,14 +66,14 @@ impl From for SystemTime { #[cfg(test)] mod tests { use super::HttpDate; - use time::{PrimitiveDateTime, date, time, offset}; + use time::{PrimitiveDateTime, date, time}; #[test] fn test_date() { let nov_07 = HttpDate(PrimitiveDateTime::new( date!(1994-11-07), time!(8:48:37) - ).using_offset(offset!(UTC))); + ).assume_utc()); assert_eq!( "Sun, 07 Nov 1994 08:48:37 GMT".parse::().unwrap(), diff --git a/actix-http/src/time_parser.rs b/actix-http/src/time_parser.rs index f6623d24e..34fac139e 100644 --- a/actix-http/src/time_parser.rs +++ b/actix-http/src/time_parser.rs @@ -1,4 +1,4 @@ -use time::{PrimitiveDateTime, Date}; +use time::{OffsetDateTime, PrimitiveDateTime, Date}; /// Attempt to parse a `time` string as one of either RFC 1123, RFC 850, or asctime. pub fn parse_http_date(time: &str) -> Option { @@ -19,7 +19,7 @@ fn try_parse_rfc_850(time: &str) -> Option { // If the `time` string contains a two-digit year, then as per RFC 2616 ยง 19.3, // we consider the year as part of this century if it's within the next 50 years, // otherwise we consider as part of the previous century. - let now = PrimitiveDateTime::now(); + let now = OffsetDateTime::now(); let century_start_year = (now.year() / 100) * 100; let mut expanded_year = century_start_year + dt.year(); From 8ec8ccf4fb38e5ceb0c6853f8ad1a0b7110b0fa5 Mon Sep 17 00:00:00 2001 From: Matt Gathu Date: Sat, 22 Feb 2020 16:19:29 +0100 Subject: [PATCH 09/12] Create helper function for HTTP Trace Method Create *route* with `TRACE` method guard. --- src/web.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/web.rs b/src/web.rs index 962c1157b..f47cf865e 100644 --- a/src/web.rs +++ b/src/web.rs @@ -193,6 +193,24 @@ pub fn head() -> Route { method(Method::HEAD) } +/// Create *route* with `TRACE` method guard. +/// +/// ```rust +/// use actix_web::{web, App, HttpResponse}; +/// +/// let app = App::new().service( +/// web::resource("/{project_id}") +/// .route(web::trace().to(|| HttpResponse::Ok())) +/// ); +/// ``` +/// +/// In the above example, one `HEAD` route gets added: +/// * /{project_id} +/// +pub fn trace() -> Route { + method(Method::TRACE) +} + /// Create *route* and add method guard. /// /// ```rust From d143c44130213e43fecc82068c28f33303d9ed98 Mon Sep 17 00:00:00 2001 From: Matt Gathu Date: Sun, 23 Feb 2020 09:33:28 +0100 Subject: [PATCH 10/12] Update the ChangeLog --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index b42635b86..f9cfdf5fa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,10 @@ ## [2.0.NEXT] - 2020-01-xx +### Added + +* Add helper function for creating routes with `TRACE` method guard `web::trace()` + ### Changed * Use `sha-1` crate instead of unmaintained `sha1` crate From 845ce3cf343487ea5fc48a0d8484d75f0e8d148f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 25 Feb 2020 07:46:03 +0900 Subject: [PATCH 11/12] Fix doc comment --- actix-http/src/header/common/accept_charset.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-http/src/header/common/accept_charset.rs b/actix-http/src/header/common/accept_charset.rs index 117e2015d..291ca53b6 100644 --- a/actix-http/src/header/common/accept_charset.rs +++ b/actix-http/src/header/common/accept_charset.rs @@ -63,7 +63,7 @@ header! { (AcceptCharset, ACCEPT_CHARSET) => (QualityItem)+ test_accept_charset { - /// Test case from RFC + // Test case from RFC test_header!(test1, vec![b"iso-8859-5, unicode-1-1;q=0.8"]); } } From a4f87a53da7813e03fa5872e4ed702b21b9afd7e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 25 Feb 2020 08:42:39 +0900 Subject: [PATCH 12/12] Update CHANGES.md --- actix-web-codegen/CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 13ed5d43d..941cd36de 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -1,6 +1,6 @@ # Changes -## [0.2.1] - 2020-02-23 +## [0.2.1] - 2020-02-25 * Add `#[allow(missing_docs)]` attribute to generated structs [#1368] * Allow the handler function to be named as `config` [#1290]