Merge branch 'master' into feature/client_middleware

This commit is contained in:
fakeshadow 2021-02-27 02:51:48 -08:00 committed by GitHub
commit e620f8d83a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 25 deletions

View File

@ -168,7 +168,7 @@
## 3.0.0-beta.4 - 2020-09-09
### Added
* `middleware::NormalizePath` now has configurable behaviour for either always having a trailing
* `middleware::NormalizePath` now has configurable behavior for either always having a trailing
slash, or as the new addition, always trimming trailing slashes. [#1639]
### Changed
@ -496,7 +496,7 @@
## [1.0.0-rc] - 2019-05-18
### Add
### Added
* Add `Query<T>::from_query()` to extract parameters from a query string. #846
* `QueryConfig`, similar to `JsonConfig` for customizing error handling of query extractors.
@ -512,7 +512,7 @@
## [1.0.0-beta.4] - 2019-05-12
### Add
### Added
* Allow to set/override app data on scope level
@ -538,7 +538,7 @@
* CORS handling without headers #702
* Allow to construct `Data` instances to avoid double `Arc` for `Send + Sync` types.
* Allow constructing `Data` instances to avoid double `Arc` for `Send + Sync` types.
### Fixed
@ -602,7 +602,7 @@
### Changed
* Allow to use any service as default service.
* Allow using any service as default service.
* Remove generic type for request payload, always use default.
@ -665,13 +665,13 @@
### Added
* rustls support
* Rustls support
### Changed
* use forked cookie
* Use forked cookie
* multipart::Field renamed to MultipartField
* Multipart::Field renamed to MultipartField
## [1.0.0-alpha.1] - 2019-03-28

View File

@ -71,18 +71,18 @@ async fn main() -> std::io::Result<()> {
### More examples
* [Basic Setup](https://github.com/actix/examples/tree/master/basics/)
* [Application State](https://github.com/actix/examples/tree/master/state/)
* [JSON Handling](https://github.com/actix/examples/tree/master/json/)
* [Multipart Streams](https://github.com/actix/examples/tree/master/multipart/)
* [Diesel Integration](https://github.com/actix/examples/tree/master/diesel/)
* [r2d2 Integration](https://github.com/actix/examples/tree/master/r2d2/)
* [Simple WebSocket](https://github.com/actix/examples/tree/master/websocket/)
* [Tera Templates](https://github.com/actix/examples/tree/master/template_tera/)
* [Askama Templates](https://github.com/actix/examples/tree/master/template_askama/)
* [HTTPS using Rustls](https://github.com/actix/examples/tree/master/rustls/)
* [HTTPS using OpenSSL](https://github.com/actix/examples/tree/master/openssl/)
* [WebSocket Chat](https://github.com/actix/examples/tree/master/websocket-chat/)
* [Basic Setup](https://github.com/actix/examples/tree/master/basics/basics/)
* [Application State](https://github.com/actix/examples/tree/master/basics/state/)
* [JSON Handling](https://github.com/actix/examples/tree/master/json/json/)
* [Multipart Streams](https://github.com/actix/examples/tree/master/forms/multipart/)
* [Diesel Integration](https://github.com/actix/examples/tree/master/database_interactions/diesel/)
* [r2d2 Integration](https://github.com/actix/examples/tree/master/database_interactions/r2d2/)
* [Simple WebSocket](https://github.com/actix/examples/tree/master/websockets/websocket/)
* [Tera Templates](https://github.com/actix/examples/tree/master/template_engines/tera/)
* [Askama Templates](https://github.com/actix/examples/tree/master/template_engines/askama/)
* [HTTPS using Rustls](https://github.com/actix/examples/tree/master/security/rustls/)
* [HTTPS using OpenSSL](https://github.com/actix/examples/tree/master/security/openssl/)
* [WebSocket Chat](https://github.com/actix/examples/tree/master/websockets/chat/)
You may consider checking out
[this directory](https://github.com/actix/examples/tree/master/) for more examples.

View File

@ -22,7 +22,7 @@ actix-utils = "3.0.0-beta.2"
bytes = "1"
derive_more = "0.99.5"
httparse = "1.3"
futures-util = { version = "0.3.7", default-features = false }
futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] }
log = "0.4"
mime = "0.3"
twoway = "0.2"
@ -30,3 +30,5 @@ twoway = "0.2"
[dev-dependencies]
actix-rt = "2"
actix-http = "3.0.0-beta.3"
tokio = { version = "1", features = ["sync"] }
tokio-stream = "0.1"

View File

@ -804,12 +804,13 @@ mod tests {
use super::*;
use actix_http::h1::Payload;
use actix_utils::mpsc;
use actix_web::http::header::{DispositionParam, DispositionType};
use actix_web::test::TestRequest;
use actix_web::FromRequest;
use bytes::Bytes;
use futures_util::future::lazy;
use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream;
#[actix_rt::test]
async fn test_boundary() {
@ -855,13 +856,17 @@ mod tests {
}
fn create_stream() -> (
mpsc::Sender<Result<Bytes, PayloadError>>,
mpsc::UnboundedSender<Result<Bytes, PayloadError>>,
impl Stream<Item = Result<Bytes, PayloadError>>,
) {
let (tx, rx) = mpsc::channel();
let (tx, rx) = mpsc::unbounded_channel();
(tx, rx.map(|res| res.map_err(|_| panic!())))
(
tx,
UnboundedReceiverStream::new(rx).map(|res| res.map_err(|_| panic!())),
)
}
// Stream that returns from a Bytes, one char at a time and Pending every other poll()
struct SlowStream {
bytes: Bytes,
@ -889,9 +894,11 @@ mod tests {
cx.waker().wake_by_ref();
return Poll::Pending;
}
if this.pos == this.bytes.len() {
return Poll::Ready(None);
}
let res = Poll::Ready(Some(Ok(this.bytes.slice(this.pos..(this.pos + 1)))));
this.pos += 1;
this.ready = false;

View File

@ -1,6 +1,9 @@
# Changes
## Unreleased - 2021-xx-xx
* Preserve doc comments when using route macros. [#2022]
[#2022]: https://github.com/actix/actix-web/pull/2022
## 0.5.0-beta.1 - 2021-02-10

View File

@ -176,6 +176,9 @@ pub struct Route {
args: Args,
ast: syn::ItemFn,
resource_type: ResourceType,
/// The doc comment attributes to copy to generated struct, if any.
doc_attributes: Vec<syn::Attribute>,
}
fn guess_resource_type(typ: &syn::Type) -> ResourceType {
@ -221,6 +224,18 @@ impl Route {
let ast: syn::ItemFn = syn::parse(input)?;
let name = ast.sig.ident.clone();
// Try and pull out the doc comments so that we can reapply them to the
// generated struct.
//
// Note that multi line doc comments are converted to multiple doc
// attributes.
let doc_attributes = ast
.attrs
.iter()
.filter(|attr| attr.path.is_ident("doc"))
.cloned()
.collect();
let args = Args::new(args, method)?;
if args.methods.is_empty() {
return Err(syn::Error::new(
@ -248,6 +263,7 @@ impl Route {
args,
ast,
resource_type,
doc_attributes,
})
}
}
@ -265,6 +281,7 @@ impl ToTokens for Route {
methods,
},
resource_type,
doc_attributes,
} = self;
let resource_name = name.to_string();
let method_guards = {
@ -287,6 +304,7 @@ impl ToTokens for Route {
};
let stream = quote! {
#(#doc_attributes)*
#[allow(non_camel_case_types, missing_docs)]
pub struct #name;

View File

@ -9,6 +9,8 @@ fn compile_macros() {
t.compile_fail("tests/trybuild/route-missing-method-fail.rs");
t.compile_fail("tests/trybuild/route-duplicate-method-fail.rs");
t.compile_fail("tests/trybuild/route-unexpected-method-fail.rs");
t.pass("tests/trybuild/docstring-ok.rs");
}
// #[rustversion::not(nightly)]

View File

@ -0,0 +1,17 @@
use actix_web::{Responder, HttpResponse, App, test};
use actix_web_codegen::*;
/// Docstrings shouldn't break anything.
#[get("/")]
async fn index() -> impl Responder {
HttpResponse::Ok()
}
#[actix_web::main]
async fn main() {
let srv = test::start(|| App::new().service(index));
let request = srv.get("/");
let response = request.send().await.unwrap();
assert!(response.status().is_success());
}