Merge branch 'master' into feature/const_codec

This commit is contained in:
fakeshadow 2021-03-04 10:47:22 -08:00 committed by GitHub
commit 1d39ab0c78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 34 deletions

View File

@ -61,7 +61,7 @@ derive_more = "0.99.5"
encoding_rs = "0.8" encoding_rs = "0.8"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
futures-util = { version = "0.3.7", default-features = false, features = ["alloc", "sink"] } futures-util = { version = "0.3.7", default-features = false, features = ["alloc", "sink"] }
h2 = "=0.3.0" h2 = "0.3.1"
http = "0.2.2" http = "0.2.2"
httparse = "1.3" httparse = "1.3"
itoa = "0.4" itoa = "0.4"

View File

@ -123,16 +123,14 @@ async fn test_h2_content_length() {
let srv = test_server(move || { let srv = test_server(move || {
HttpService::build() HttpService::build()
.h2(|req: Request| { .h2(|req: Request| {
let indx: usize = req.uri().path()[1..].parse().unwrap(); let idx: usize = req.uri().path()[1..].parse().unwrap();
let statuses = [ let statuses = [
StatusCode::NO_CONTENT,
StatusCode::CONTINUE, StatusCode::CONTINUE,
StatusCode::SWITCHING_PROTOCOLS, StatusCode::NO_CONTENT,
StatusCode::PROCESSING,
StatusCode::OK, StatusCode::OK,
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
]; ];
ok::<_, ()>(Response::new(statuses[indx])) ok::<_, ()>(Response::new(statuses[idx]))
}) })
.openssl(tls_config()) .openssl(tls_config())
.map_err(|_| ()) .map_err(|_| ())
@ -143,21 +141,29 @@ async fn test_h2_content_length() {
let value = HeaderValue::from_static("0"); let value = HeaderValue::from_static("0");
{ {
for i in 0..4 { for &i in &[0] {
let req = srv
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
.send();
let _response = req.await.expect_err("should timeout on recv 1xx frame");
// assert_eq!(response.headers().get(&header), None);
let req = srv
.request(Method::GET, srv.surl(&format!("/{}", i)))
.send();
let _response = req.await.expect_err("should timeout on recv 1xx frame");
// assert_eq!(response.headers().get(&header), None);
}
for &i in &[1] {
let req = srv let req = srv
.request(Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = req.await.unwrap(); let response = req.await.unwrap();
assert_eq!(response.headers().get(&header), None); assert_eq!(response.headers().get(&header), None);
let req = srv
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
.send();
let response = req.await.unwrap();
assert_eq!(response.headers().get(&header), None);
} }
for i in 4..6 { for &i in &[2, 3] {
let req = srv let req = srv
.request(Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();

View File

@ -17,7 +17,6 @@ use rustls::{
NoClientAuth, ServerConfig as RustlsServerConfig, NoClientAuth, ServerConfig as RustlsServerConfig,
}; };
use std::fs::File;
use std::io::{self, BufReader}; use std::io::{self, BufReader};
async fn load_body<S>(mut stream: S) -> Result<BytesMut, PayloadError> async fn load_body<S>(mut stream: S) -> Result<BytesMut, PayloadError>
@ -139,10 +138,8 @@ async fn test_h2_content_length() {
.h2(|req: Request| { .h2(|req: Request| {
let indx: usize = req.uri().path()[1..].parse().unwrap(); let indx: usize = req.uri().path()[1..].parse().unwrap();
let statuses = [ let statuses = [
StatusCode::NO_CONTENT,
StatusCode::CONTINUE, StatusCode::CONTINUE,
StatusCode::SWITCHING_PROTOCOLS, StatusCode::NO_CONTENT,
StatusCode::PROCESSING,
StatusCode::OK, StatusCode::OK,
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
]; ];
@ -154,22 +151,31 @@ async fn test_h2_content_length() {
let header = HeaderName::from_static("content-length"); let header = HeaderName::from_static("content-length");
let value = HeaderValue::from_static("0"); let value = HeaderValue::from_static("0");
{ {
for i in 0..4 { for &i in &[0] {
let req = srv
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
.send();
let _response = req.await.expect_err("should timeout on recv 1xx frame");
// assert_eq!(response.headers().get(&header), None);
let req = srv
.request(Method::GET, srv.surl(&format!("/{}", i)))
.send();
let _response = req.await.expect_err("should timeout on recv 1xx frame");
// assert_eq!(response.headers().get(&header), None);
}
for &i in &[1] {
let req = srv let req = srv
.request(Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = req.await.unwrap(); let response = req.await.unwrap();
assert_eq!(response.headers().get(&header), None); assert_eq!(response.headers().get(&header), None);
let req = srv
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
.send();
let response = req.await.unwrap();
assert_eq!(response.headers().get(&header), None);
} }
for i in 4..6 { for &i in &[2, 3] {
let req = srv let req = srv
.request(Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();

View File

@ -16,7 +16,7 @@ name = "actix_web_actors"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
actix = { version = "0.11.0-beta.2", default-features = false } actix = { version = "0.11.0-beta.3", default-features = false }
actix-codec = "0.4.0-beta.1" actix-codec = "0.4.0-beta.1"
actix-http = "3.0.0-beta.3" actix-http = "3.0.0-beta.3"
actix-web = { version = "4.0.0-beta.3", default-features = false } actix-web = { version = "4.0.0-beta.3", default-features = false }

View File

@ -44,7 +44,7 @@ where
#[inline] #[inline]
fn spawn<F>(&mut self, fut: F) -> SpawnHandle fn spawn<F>(&mut self, fut: F) -> SpawnHandle
where where
F: ActorFuture<Output = (), Actor = A> + 'static, F: ActorFuture<A, Output = ()> + 'static,
{ {
self.inner.spawn(fut) self.inner.spawn(fut)
} }
@ -52,7 +52,7 @@ where
#[inline] #[inline]
fn wait<F>(&mut self, fut: F) fn wait<F>(&mut self, fut: F)
where where
F: ActorFuture<Output = (), Actor = A> + 'static, F: ActorFuture<A, Output = ()> + 'static,
{ {
self.inner.wait(fut) self.inner.wait(fut)
} }

View File

@ -211,14 +211,14 @@ where
{ {
fn spawn<F>(&mut self, fut: F) -> SpawnHandle fn spawn<F>(&mut self, fut: F) -> SpawnHandle
where where
F: ActorFuture<Output = (), Actor = A> + 'static, F: ActorFuture<A, Output = ()> + 'static,
{ {
self.inner.spawn(fut) self.inner.spawn(fut)
} }
fn wait<F>(&mut self, fut: F) fn wait<F>(&mut self, fut: F)
where where
F: ActorFuture<Output = (), Actor = A> + 'static, F: ActorFuture<A, Output = ()> + 'static,
{ {
self.inner.wait(fut) self.inner.wait(fut)
} }
@ -495,7 +495,6 @@ where
if !*this.closed { if !*this.closed {
loop { loop {
this = self.as_mut().project();
match Pin::new(&mut this.stream).poll_next(cx) { match Pin::new(&mut this.stream).poll_next(cx) {
Poll::Ready(Some(Ok(chunk))) => { Poll::Ready(Some(Ok(chunk))) => {
this.buf.extend_from_slice(&chunk[..]); this.buf.extend_from_slice(&chunk[..]);

View File

@ -2,8 +2,10 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
* Preserve doc comments when using route macros. [#2022] * Preserve doc comments when using route macros. [#2022]
* Add `name` attribute to `route` macro. [#1934]
[#2022]: https://github.com/actix/actix-web/pull/2022 [#2022]: https://github.com/actix/actix-web/pull/2022
[#1934]: https://github.com/actix/actix-web/pull/1934
## 0.5.0-beta.1 - 2021-02-10 ## 0.5.0-beta.1 - 2021-02-10

View File

@ -71,6 +71,7 @@ mod route;
/// ///
/// # Attributes /// # Attributes
/// - `"path"` - Raw literal string with path for which to register handler. /// - `"path"` - Raw literal string with path for which to register handler.
/// - `name="resource_name"` - Specifies resource name for the handler. If not set, the function name of handler is used.
/// - `method="HTTP_METHOD"` - Registers HTTP method to provide guard for. Upper-case string, "GET", "POST" for example. /// - `method="HTTP_METHOD"` - Registers HTTP method to provide guard for. Upper-case string, "GET", "POST" for example.
/// - `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard` /// - `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard`
/// - `wrap="Middleware"` - Registers a resource middleware. /// - `wrap="Middleware"` - Registers a resource middleware.
@ -116,6 +117,7 @@ Creates route handler with `actix_web::guard::", stringify!($variant), "`.
# Attributes # Attributes
- `"path"` - Raw literal string with path for which to register handler. - `"path"` - Raw literal string with path for which to register handler.
- `name="resource_name"` - Specifies resource name for the handler. If not set, the function name of handler is used.
- `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard`. - `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard`.
- `wrap="Middleware"` - Registers a resource middleware. - `wrap="Middleware"` - Registers a resource middleware.

View File

@ -78,6 +78,7 @@ impl TryFrom<&syn::LitStr> for MethodType {
struct Args { struct Args {
path: syn::LitStr, path: syn::LitStr,
resource_name: Option<syn::LitStr>,
guards: Vec<Ident>, guards: Vec<Ident>,
wrappers: Vec<syn::Type>, wrappers: Vec<syn::Type>,
methods: HashSet<MethodType>, methods: HashSet<MethodType>,
@ -86,6 +87,7 @@ struct Args {
impl Args { impl Args {
fn new(args: AttributeArgs, method: Option<MethodType>) -> syn::Result<Self> { fn new(args: AttributeArgs, method: Option<MethodType>) -> syn::Result<Self> {
let mut path = None; let mut path = None;
let mut resource_name = None;
let mut guards = Vec::new(); let mut guards = Vec::new();
let mut wrappers = Vec::new(); let mut wrappers = Vec::new();
let mut methods = HashSet::new(); let mut methods = HashSet::new();
@ -109,7 +111,16 @@ impl Args {
} }
}, },
NestedMeta::Meta(syn::Meta::NameValue(nv)) => { NestedMeta::Meta(syn::Meta::NameValue(nv)) => {
if nv.path.is_ident("guard") { if nv.path.is_ident("name") {
if let syn::Lit::Str(lit) = nv.lit {
resource_name = Some(lit);
} else {
return Err(syn::Error::new_spanned(
nv.lit,
"Attribute name expects literal string!",
));
}
} else if nv.path.is_ident("guard") {
if let syn::Lit::Str(lit) = nv.lit { if let syn::Lit::Str(lit) = nv.lit {
guards.push(Ident::new(&lit.value(), Span::call_site())); guards.push(Ident::new(&lit.value(), Span::call_site()));
} else { } else {
@ -164,6 +175,7 @@ impl Args {
} }
Ok(Args { Ok(Args {
path: path.unwrap(), path: path.unwrap(),
resource_name,
guards, guards,
wrappers, wrappers,
methods, methods,
@ -276,6 +288,7 @@ impl ToTokens for Route {
args: args:
Args { Args {
path, path,
resource_name,
guards, guards,
wrappers, wrappers,
methods, methods,
@ -283,7 +296,9 @@ impl ToTokens for Route {
resource_type, resource_type,
doc_attributes, doc_attributes,
} = self; } = self;
let resource_name = name.to_string(); let resource_name = resource_name
.as_ref()
.map_or_else(|| name.to_string(), |n| n.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

@ -83,6 +83,13 @@ async fn route_test() -> impl Responder {
HttpResponse::Ok() HttpResponse::Ok()
} }
#[get("/custom_resource_name", name = "custom")]
async fn custom_resource_name_test<'a>(req: actix_web::HttpRequest) -> impl Responder {
assert!(req.url_for_static("custom").is_ok());
assert!(req.url_for_static("custom_resource_name_test").is_err());
HttpResponse::Ok()
}
pub struct ChangeStatusCode; pub struct ChangeStatusCode;
impl<S, B> Transform<S, ServiceRequest> for ChangeStatusCode impl<S, B> Transform<S, ServiceRequest> for ChangeStatusCode
@ -174,6 +181,7 @@ async fn test_body() {
.service(patch_test) .service(patch_test)
.service(test_handler) .service(test_handler)
.service(route_test) .service(route_test)
.service(custom_resource_name_test)
}); });
let request = srv.request(http::Method::GET, srv.url("/test")); let request = srv.request(http::Method::GET, srv.url("/test"));
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();
@ -228,6 +236,10 @@ async fn test_body() {
let request = srv.request(http::Method::PATCH, srv.url("/multi")); let request = srv.request(http::Method::PATCH, srv.url("/multi"));
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();
assert!(!response.status().is_success()); assert!(!response.status().is_success());
let request = srv.request(http::Method::GET, srv.url("/custom_resource_name"));
let response = request.send().await.unwrap();
assert!(response.status().is_success());
} }
#[actix_rt::test] #[actix_rt::test]