mirror of https://github.com/fafhrd91/actix-web
Merge branch 'master' into feature/const_codec
This commit is contained in:
commit
1d39ab0c78
|
@ -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"
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[..]);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Reference in New Issue