mirror of
https://github.com/ntex-rs/ntex.git
synced 2025-04-03 21:07:39 +03:00
update tests
This commit is contained in:
parent
341e5c38bf
commit
88cd070ced
77 changed files with 2062 additions and 972 deletions
|
@ -1,4 +1,5 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"ntex",
|
||||
"ntex-web-macros",
|
||||
]
|
||||
|
|
101
README.md
101
README.md
|
@ -1,106 +1,9 @@
|
|||
<div align="center">
|
||||
<p><h1>Actix web</h1> </p>
|
||||
<p><strong>Actix web is a small, pragmatic, and extremely fast rust web framework</strong> </p>
|
||||
<p><h1>ntex</h1> </p>
|
||||
<p><strong>This is personal project, please, do not use it</strong> </p>
|
||||
<p>
|
||||
|
||||
[](https://travis-ci.org/actix/actix-web)
|
||||
[](https://codecov.io/gh/actix/actix-web)
|
||||
[](https://crates.io/crates/actix-web)
|
||||
[](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://docs.rs/actix-web)
|
||||
[](https://crates.io/crates/actix-web)
|
||||
[](https://blog.rust-lang.org/2019/11/07/Rust-1.39.0.html)
|
||||

|
||||
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a href="https://actix.rs">Website</a>
|
||||
<span> | </span>
|
||||
<a href="https://gitter.im/actix/actix">Chat</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/actix/examples">Examples</a>
|
||||
</h3>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
Actix web is a simple, pragmatic and extremely fast web framework for Rust.
|
||||
|
||||
* Supported *HTTP/1.x* and *HTTP/2.0* protocols
|
||||
* Streaming and pipelining
|
||||
* Keep-alive and slow requests handling
|
||||
* Client/server [WebSockets](https://actix.rs/docs/websockets/) support
|
||||
* Transparent content compression/decompression (br, gzip, deflate)
|
||||
* Configurable [request routing](https://actix.rs/docs/url-dispatch/)
|
||||
* Multipart streams
|
||||
* Static assets
|
||||
* SSL support with OpenSSL or Rustls
|
||||
* Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
|
||||
* Includes an asynchronous [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html)
|
||||
* Supports [Actix actor framework](https://github.com/actix/actix)
|
||||
|
||||
## Example
|
||||
|
||||
Dependencies:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
actix-web = "2"
|
||||
actix-rt = "1"
|
||||
```
|
||||
|
||||
Code:
|
||||
|
||||
```rust
|
||||
use actix_web::{get, web, App, HttpServer, Responder};
|
||||
|
||||
#[get("/{id}/{name}/index.html")]
|
||||
async fn index(info: web::Path<(u32, String)>) -> impl Responder {
|
||||
format!("Hello {}! id:{}", info.1, info.0)
|
||||
}
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
HttpServer::new(|| App::new().service(index))
|
||||
.bind("127.0.0.1:8080")?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
```
|
||||
|
||||
### More examples
|
||||
|
||||
* [Basics](https://github.com/actix/examples/tree/master/basics/)
|
||||
* [Stateful](https://github.com/actix/examples/tree/master/state/)
|
||||
* [Multipart streams](https://github.com/actix/examples/tree/master/multipart/)
|
||||
* [Simple websocket](https://github.com/actix/examples/tree/master/websocket/)
|
||||
* [Tera](https://github.com/actix/examples/tree/master/template_tera/) /
|
||||
* [Askama](https://github.com/actix/examples/tree/master/template_askama/) templates
|
||||
* [Diesel integration](https://github.com/actix/examples/tree/master/diesel/)
|
||||
* [r2d2](https://github.com/actix/examples/tree/master/r2d2/)
|
||||
* [OpenSSL](https://github.com/actix/examples/tree/master/openssl/)
|
||||
* [Rustls](https://github.com/actix/examples/tree/master/rustls/)
|
||||
* [Tcp/Websocket chat](https://github.com/actix/examples/tree/master/websocket-chat/)
|
||||
* [Json](https://github.com/actix/examples/tree/master/json/)
|
||||
|
||||
You may consider checking out
|
||||
[this directory](https://github.com/actix/examples/tree/master/) for more examples.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
* [TechEmpower Framework Benchmark](https://www.techempower.com/benchmarks/#section=data-r18)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
|
||||
|
||||
at your option.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Contribution to the actix-web crate is organized under the terms of the
|
||||
Contributor Covenant, the maintainer of actix-web, @fafhrd91, promises to
|
||||
intervene to uphold that code of conduct.
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
use std::{env, io};
|
||||
|
||||
use actix_http::{Error, HttpService, Request, Response};
|
||||
use actix_server::Server;
|
||||
use bytes::BytesMut;
|
||||
use futures::StreamExt;
|
||||
use http::header::HeaderValue;
|
||||
use log::info;
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
env::set_var("RUST_LOG", "echo=info");
|
||||
env_logger::init();
|
||||
|
||||
Server::build()
|
||||
.bind("echo", "127.0.0.1:8080", || {
|
||||
HttpService::build()
|
||||
.client_timeout(1000)
|
||||
.client_disconnect(1000)
|
||||
.finish(|mut req: Request| {
|
||||
async move {
|
||||
let mut body = BytesMut::new();
|
||||
while let Some(item) = req.payload().next().await {
|
||||
body.extend_from_slice(&item?);
|
||||
}
|
||||
|
||||
info!("request body: {:?}", body);
|
||||
Ok::<_, Error>(
|
||||
Response::Ok()
|
||||
.header(
|
||||
"x-head",
|
||||
HeaderValue::from_static("dummy value!"),
|
||||
)
|
||||
.body(body),
|
||||
)
|
||||
}
|
||||
})
|
||||
.tcp()
|
||||
})?
|
||||
.run()
|
||||
.await
|
||||
}
|
5
ntex-web-macros/CHANGES.md
Normal file
5
ntex-web-macros/CHANGES.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Changes
|
||||
|
||||
## [0.1.0] - 2020-xx-xx
|
||||
|
||||
* Fork
|
21
ntex-web-macros/Cargo.toml
Normal file
21
ntex-web-macros/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[package]
|
||||
name = "ntex-web-macros"
|
||||
version = "0.1.0"
|
||||
description = "ntex web proc macros"
|
||||
readme = "README.md"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "^1"
|
||||
syn = { version = "^1", features = ["full", "parsing"] }
|
||||
proc-macro2 = "^1"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "1.0.0"
|
||||
ntex = { path = "../ntex/" }
|
||||
futures = { version = "0.3.1" }
|
1
ntex-web-macros/README.md
Normal file
1
ntex-web-macros/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Macros for ntex::web framework [](https://travis-ci.org/fafhrd91/ntex)
|
185
ntex-web-macros/src/lib.rs
Normal file
185
ntex-web-macros/src/lib.rs
Normal file
|
@ -0,0 +1,185 @@
|
|||
#![recursion_limit = "512"]
|
||||
//! web macros module
|
||||
//!
|
||||
//! Generators for routes and scopes
|
||||
//!
|
||||
//! ## Route
|
||||
//!
|
||||
//! Macros:
|
||||
//!
|
||||
//! - [get](attr.get.html)
|
||||
//! - [post](attr.post.html)
|
||||
//! - [put](attr.put.html)
|
||||
//! - [delete](attr.delete.html)
|
||||
//! - [head](attr.head.html)
|
||||
//! - [connect](attr.connect.html)
|
||||
//! - [options](attr.options.html)
|
||||
//! - [trace](attr.trace.html)
|
||||
//! - [patch](attr.patch.html)
|
||||
//!
|
||||
//! ### Attributes:
|
||||
//!
|
||||
//! - `"path"` - Raw literal string with path for which to register handle. Mandatory.
|
||||
//! - `guard="function_name"` - Registers function as guard using `ntex::web::guard::fn_guard`
|
||||
//!
|
||||
//! ## Notes
|
||||
//!
|
||||
//! Function name can be specified as any expression that is going to be accessible to the generate
|
||||
//! code (e.g `my_guard` or `my_module::my_guard`)
|
||||
//!
|
||||
//! ## Example:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use ntex::web::{get, HttpResponse};
|
||||
//! use futures::{future, Future};
|
||||
//!
|
||||
//! #[get("/test")]
|
||||
//! async fn async_test() -> Result<HttpResponse, ntex::http::Error> {
|
||||
//! Ok(HttpResponse::Ok().finish())
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
mod route;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
/// Creates route handler with `GET` method guard.
|
||||
///
|
||||
/// Syntax: `#[get("path"[, attributes])]`
|
||||
///
|
||||
/// ## Attributes:
|
||||
///
|
||||
/// - `"path"` - Raw literal string with path for which to register handler. Mandatory.
|
||||
/// - `guard="function_name"` - Registers function as guard using `ntex::web::guard::fn_guard`
|
||||
#[proc_macro_attribute]
|
||||
pub fn get(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Get) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `POST` method guard.
|
||||
///
|
||||
/// Syntax: `#[post("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [get](attr.get.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn post(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Post) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `PUT` method guard.
|
||||
///
|
||||
/// Syntax: `#[put("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [get](attr.get.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn put(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Put) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `DELETE` method guard.
|
||||
///
|
||||
/// Syntax: `#[delete("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [get](attr.get.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Delete) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `HEAD` method guard.
|
||||
///
|
||||
/// Syntax: `#[head("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [head](attr.head.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn head(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Head) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `CONNECT` method guard.
|
||||
///
|
||||
/// Syntax: `#[connect("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [connect](attr.connect.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Connect) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `OPTIONS` method guard.
|
||||
///
|
||||
/// Syntax: `#[options("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [options](attr.options.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn options(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Options) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `TRACE` method guard.
|
||||
///
|
||||
/// Syntax: `#[trace("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [trace](attr.trace.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Trace) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
||||
|
||||
/// Creates route handler with `PATCH` method guard.
|
||||
///
|
||||
/// Syntax: `#[patch("path"[, attributes])]`
|
||||
///
|
||||
/// Attributes are the same as in [patch](attr.patch.html)
|
||||
#[proc_macro_attribute]
|
||||
pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
let gen = match route::Route::new(args, input, route::GuardType::Patch) {
|
||||
Ok(gen) => gen,
|
||||
Err(err) => return err.to_compile_error().into(),
|
||||
};
|
||||
gen.generate()
|
||||
}
|
212
ntex-web-macros/src/route.rs
Normal file
212
ntex-web-macros/src/route.rs
Normal file
|
@ -0,0 +1,212 @@
|
|||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||
use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use syn::{AttributeArgs, Ident, NestedMeta};
|
||||
|
||||
enum ResourceType {
|
||||
Async,
|
||||
Sync,
|
||||
}
|
||||
|
||||
impl ToTokens for ResourceType {
|
||||
fn to_tokens(&self, stream: &mut TokenStream2) {
|
||||
let ident = match self {
|
||||
ResourceType::Async => "to",
|
||||
ResourceType::Sync => "to",
|
||||
};
|
||||
let ident = Ident::new(ident, Span::call_site());
|
||||
stream.append(ident);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum GuardType {
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Head,
|
||||
Connect,
|
||||
Options,
|
||||
Trace,
|
||||
Patch,
|
||||
}
|
||||
|
||||
impl GuardType {
|
||||
fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
GuardType::Get => "Get",
|
||||
GuardType::Post => "Post",
|
||||
GuardType::Put => "Put",
|
||||
GuardType::Delete => "Delete",
|
||||
GuardType::Head => "Head",
|
||||
GuardType::Connect => "Connect",
|
||||
GuardType::Options => "Options",
|
||||
GuardType::Trace => "Trace",
|
||||
GuardType::Patch => "Patch",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for GuardType {
|
||||
fn to_tokens(&self, stream: &mut TokenStream2) {
|
||||
let ident = self.as_str();
|
||||
let ident = Ident::new(ident, Span::call_site());
|
||||
stream.append(ident);
|
||||
}
|
||||
}
|
||||
|
||||
struct Args {
|
||||
path: syn::LitStr,
|
||||
guards: Vec<Ident>,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
fn new(args: AttributeArgs) -> syn::Result<Self> {
|
||||
let mut path = None;
|
||||
let mut guards = Vec::new();
|
||||
for arg in args {
|
||||
match arg {
|
||||
NestedMeta::Lit(syn::Lit::Str(lit)) => match path {
|
||||
None => {
|
||||
path = Some(lit);
|
||||
}
|
||||
_ => {
|
||||
return Err(syn::Error::new_spanned(
|
||||
lit,
|
||||
"Multiple paths specified! Should be only one!",
|
||||
));
|
||||
}
|
||||
},
|
||||
NestedMeta::Meta(syn::Meta::NameValue(nv)) => {
|
||||
if nv.path.is_ident("guard") {
|
||||
if let syn::Lit::Str(lit) = nv.lit {
|
||||
guards.push(Ident::new(&lit.value(), Span::call_site()));
|
||||
} else {
|
||||
return Err(syn::Error::new_spanned(
|
||||
nv.lit,
|
||||
"Attribute guard expects literal string!",
|
||||
));
|
||||
}
|
||||
} else {
|
||||
return Err(syn::Error::new_spanned(
|
||||
nv.path,
|
||||
"Unknown attribute key is specified. Allowed: guard",
|
||||
));
|
||||
}
|
||||
}
|
||||
arg => {
|
||||
return Err(syn::Error::new_spanned(arg, "Unknown attribute"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Args {
|
||||
path: path.unwrap(),
|
||||
guards,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Route {
|
||||
name: syn::Ident,
|
||||
args: Args,
|
||||
ast: syn::ItemFn,
|
||||
resource_type: ResourceType,
|
||||
guard: GuardType,
|
||||
}
|
||||
|
||||
fn guess_resource_type(typ: &syn::Type) -> ResourceType {
|
||||
let mut guess = ResourceType::Sync;
|
||||
|
||||
if let syn::Type::ImplTrait(typ) = typ {
|
||||
for bound in typ.bounds.iter() {
|
||||
if let syn::TypeParamBound::Trait(bound) = bound {
|
||||
for bound in bound.path.segments.iter() {
|
||||
if bound.ident == "Future" {
|
||||
guess = ResourceType::Async;
|
||||
break;
|
||||
} else if bound.ident == "Responder" {
|
||||
guess = ResourceType::Sync;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guess
|
||||
}
|
||||
|
||||
impl Route {
|
||||
pub fn new(
|
||||
args: AttributeArgs,
|
||||
input: TokenStream,
|
||||
guard: GuardType,
|
||||
) -> syn::Result<Self> {
|
||||
if args.is_empty() {
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
format!(
|
||||
r#"invalid server definition, expected #[{}("<some path>")]"#,
|
||||
guard.as_str().to_ascii_lowercase()
|
||||
),
|
||||
));
|
||||
}
|
||||
let ast: syn::ItemFn = syn::parse(input)?;
|
||||
let name = ast.sig.ident.clone();
|
||||
|
||||
let args = Args::new(args)?;
|
||||
|
||||
let resource_type = if ast.sig.asyncness.is_some() {
|
||||
ResourceType::Async
|
||||
} else {
|
||||
match ast.sig.output {
|
||||
syn::ReturnType::Default => {
|
||||
return Err(syn::Error::new_spanned(
|
||||
ast,
|
||||
"Function has no return type. Cannot be used as handler",
|
||||
));
|
||||
}
|
||||
syn::ReturnType::Type(_, ref typ) => guess_resource_type(typ.as_ref()),
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name,
|
||||
args,
|
||||
ast,
|
||||
resource_type,
|
||||
guard,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate(&self) -> TokenStream {
|
||||
let name = &self.name;
|
||||
let resource_name = name.to_string();
|
||||
let guard = &self.guard;
|
||||
let ast = &self.ast;
|
||||
let path = &self.args.path;
|
||||
let extra_guards = &self.args.guards;
|
||||
let resource_type = &self.resource_type;
|
||||
let stream = quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct #name;
|
||||
|
||||
impl ntex::web::dev::HttpServiceFactory for #name {
|
||||
fn register(self, __config: &mut ntex::web::dev::AppService) {
|
||||
#ast
|
||||
let __resource = ntex::web::Resource::new(#path)
|
||||
.name(#resource_name)
|
||||
.guard(ntex::web::guard::#guard())
|
||||
#(.guard(ntex::web::guard::fn_guard(#extra_guards)))*
|
||||
.#resource_type(#name);
|
||||
|
||||
ntex::web::dev::HttpServiceFactory::register(__resource, __config)
|
||||
}
|
||||
}
|
||||
};
|
||||
stream.into()
|
||||
}
|
||||
}
|
158
ntex-web-macros/tests/test_macro.rs
Normal file
158
ntex-web-macros/tests/test_macro.rs
Normal file
|
@ -0,0 +1,158 @@
|
|||
use ntex::http::{Error, StatusCode, Method};
|
||||
use ntex::web::{test, types::Path, App, HttpResponse, Responder};
|
||||
use ntex_web_macros::{connect, delete, get, head, options, patch, post, put, trace};
|
||||
use futures::{future, Future};
|
||||
|
||||
// Make sure that we can name function as 'config'
|
||||
#[get("/config")]
|
||||
async fn config() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[get("/test")]
|
||||
async fn test_handler() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[put("/test")]
|
||||
async fn put_test() -> impl Responder {
|
||||
HttpResponse::Created()
|
||||
}
|
||||
|
||||
#[patch("/test")]
|
||||
async fn patch_test() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[post("/test")]
|
||||
async fn post_test() -> impl Responder {
|
||||
HttpResponse::NoContent()
|
||||
}
|
||||
|
||||
#[head("/test")]
|
||||
async fn head_test() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[connect("/test")]
|
||||
async fn connect_test() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[options("/test")]
|
||||
async fn options_test() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[trace("/test")]
|
||||
async fn trace_test() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[get("/test")]
|
||||
fn auto_async() -> impl Future<Output = Result<HttpResponse, Error>> {
|
||||
future::ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
|
||||
#[get("/test")]
|
||||
fn auto_sync() -> impl Future<Output = Result<HttpResponse, Error>> {
|
||||
future::ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
|
||||
#[put("/test/{param}")]
|
||||
async fn put_param_test(_: Path<String>) -> impl Responder {
|
||||
HttpResponse::Created()
|
||||
}
|
||||
|
||||
#[delete("/test/{param}")]
|
||||
async fn delete_param_test(_: Path<String>) -> impl Responder {
|
||||
HttpResponse::NoContent()
|
||||
}
|
||||
|
||||
#[get("/test/{param}")]
|
||||
async fn get_param_test(_: Path<String>) -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
#[ntex::test]
|
||||
async fn test_params() {
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
.service(get_param_test)
|
||||
.service(put_param_test)
|
||||
.service(delete_param_test)
|
||||
});
|
||||
|
||||
let request = srv.request(Method::GET, srv.url("/test/it"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
|
||||
let request = srv.request(Method::PUT, srv.url("/test/it"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::CREATED);
|
||||
|
||||
let request = srv.request(Method::DELETE, srv.url("/test/it"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::NO_CONTENT);
|
||||
}
|
||||
|
||||
#[ntex::test]
|
||||
async fn test_body() {
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
.service(post_test)
|
||||
.service(put_test)
|
||||
.service(head_test)
|
||||
.service(connect_test)
|
||||
.service(options_test)
|
||||
.service(trace_test)
|
||||
.service(patch_test)
|
||||
.service(test_handler)
|
||||
});
|
||||
let request = srv.request(Method::GET, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let request = srv.request(Method::HEAD, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let request = srv.request(Method::CONNECT, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let request = srv.request(Method::OPTIONS, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let request = srv.request(Method::TRACE, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let request = srv.request(Method::PATCH, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let request = srv.request(Method::PUT, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
assert_eq!(response.status(), StatusCode::CREATED);
|
||||
|
||||
let request = srv.request(Method::POST, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
assert_eq!(response.status(), StatusCode::NO_CONTENT);
|
||||
|
||||
let request = srv.request(Method::GET, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[ntex::test]
|
||||
async fn test_auto_async() {
|
||||
let srv = test::start(|| App::new().service(auto_async));
|
||||
|
||||
let request = srv.request(Method::GET, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
[package]
|
||||
name = "ntex"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = ""
|
||||
description = "Framework for composable network services"
|
||||
readme = "README.md"
|
||||
keywords = ["ntex", "networking", "framework", "async", "futures"]
|
||||
repository = "https://github.com/fafhrd91/ntex.git"
|
||||
|
@ -24,10 +24,10 @@ path = "src/lib.rs"
|
|||
default = []
|
||||
|
||||
# openssl
|
||||
openssl = ["actix-tls/openssl", "actix-connect/openssl"]
|
||||
openssl = ["actix-tls/openssl", "actix-connect/openssl", "open-ssl"]
|
||||
|
||||
# rustls support
|
||||
rustls = ["actix-tls/rustls", "actix-connect/rustls"]
|
||||
rustls = ["actix-tls/rustls", "actix-connect/rustls", "rust-tls"]
|
||||
|
||||
# enable compressison support
|
||||
compress = ["flate2", "brotli2"]
|
||||
|
@ -36,6 +36,8 @@ compress = ["flate2", "brotli2"]
|
|||
cookie = ["coo-kie", "coo-kie/percent-encode"]
|
||||
|
||||
[dependencies]
|
||||
ntex-web-macros = { path = "../ntex-web-macros" }
|
||||
|
||||
actix-service = "1.0.1"
|
||||
actix-codec = "0.2.0"
|
||||
actix-connect = "1.0.1"
|
||||
|
@ -75,6 +77,8 @@ serde_urlencoded = "0.6.1"
|
|||
url = "2.1"
|
||||
time = { version = "0.2.5", default-features = false, features = ["std"] }
|
||||
coo-kie = { version = "0.13.3", package = "cookie", optional = true }
|
||||
open-ssl = { version="0.10", package = "openssl", optional = true }
|
||||
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
||||
|
||||
# compression
|
||||
brotli2 = { version="0.3.2", optional = true }
|
||||
|
@ -90,4 +94,5 @@ futures = "0.3.1"
|
|||
env_logger = "0.7"
|
||||
serde_derive = "1.0"
|
||||
open-ssl = { version="0.10", package = "openssl" }
|
||||
rust-tls = { version="0.16", package = "rustls" }
|
||||
rust-tls = { version = "0.16.0", package="rustls", features = ["dangerous_configuration"] }
|
||||
webpki = "0.21"
|
||||
|
|
|
@ -1,46 +1,7 @@
|
|||
# Actix http [](https://travis-ci.org/actix/actix-web) [](https://codecov.io/gh/actix/actix-web) [](https://crates.io/crates/actix-http) [](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Actix http
|
||||
|
||||
## Documentation & community resources
|
||||
|
||||
* [User Guide](https://actix.rs/docs/)
|
||||
* [API Documentation](https://docs.rs/actix-http/)
|
||||
* [Chat on gitter](https://gitter.im/actix/actix)
|
||||
* Cargo package: [actix-http](https://crates.io/crates/actix-http)
|
||||
* Minimum supported Rust version: 1.31 or later
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
// see examples/framed_hello.rs for complete list of used crates.
|
||||
extern crate actix_http;
|
||||
use actix_http::{h1, Response, ServiceConfig};
|
||||
|
||||
fn main() {
|
||||
Server::new().bind("framed_hello", "127.0.0.1:8080", || {
|
||||
IntoFramed::new(|| h1::Codec::new(ServiceConfig::default())) // <- create h1 codec
|
||||
.and_then(TakeItem::new().map_err(|_| ())) // <- read one request
|
||||
.and_then(|(_req, _framed): (_, Framed<_, _>)| { // <- send response and close conn
|
||||
SendResponse::send(_framed, Response::Ok().body("Hello world!"))
|
||||
.map_err(|_| ())
|
||||
.map(|_| ())
|
||||
})
|
||||
}).unwrap().run();
|
||||
}
|
||||
```
|
||||
# ntex
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
|
||||
|
||||
at your option.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Contribution to the actix-http crate is organized under the terms of the
|
||||
Contributor Covenant, the maintainer of actix-http, @fafhrd91, promises to
|
||||
intervene to uphold that code of conduct.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use actix_web::{get, middleware, web, App, HttpRequest, HttpResponse, HttpServer};
|
||||
use ntex::web::{self, get, middleware, App, HttpRequest, HttpResponse, HttpServer};
|
||||
|
||||
#[get("/resource1/{name}/index.html")]
|
||||
async fn index(req: HttpRequest, name: web::Path<String>) -> String {
|
||||
async fn index(req: HttpRequest, name: web::types::Path<String>) -> String {
|
||||
println!("REQ: {:?}", req);
|
||||
format!("Hello: {}!\r\n", name)
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
use actix_http::Error;
|
||||
use ntex::http::client::Client;
|
||||
use ntex::http::Error;
|
||||
|
||||
#[actix_rt::main]
|
||||
#[ntex::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
std::env::set_var("RUST_LOG", "actix_http=trace");
|
||||
env_logger::init();
|
||||
|
||||
let client = awc::Client::new();
|
||||
let client = Client::new();
|
||||
|
||||
// Create request builder, configure request and send
|
||||
let mut response = client
|
37
ntex/examples/echo.rs
Normal file
37
ntex/examples/echo.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use std::{env, io};
|
||||
|
||||
use bytes::BytesMut;
|
||||
use futures::StreamExt;
|
||||
use log::info;
|
||||
use ntex::http::header::HeaderValue;
|
||||
use ntex::http::{Error, HttpService, Request, Response};
|
||||
use ntex::server::Server;
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
env::set_var("RUST_LOG", "echo=info");
|
||||
env_logger::init();
|
||||
|
||||
Server::build()
|
||||
.bind("echo", "127.0.0.1:8080", || {
|
||||
HttpService::build()
|
||||
.client_timeout(1000)
|
||||
.client_disconnect(1000)
|
||||
.finish(|mut req: Request| async move {
|
||||
let mut body = BytesMut::new();
|
||||
while let Some(item) = req.payload().next().await {
|
||||
body.extend_from_slice(&item?);
|
||||
}
|
||||
|
||||
info!("request body: {:?}", body);
|
||||
Ok::<_, Error>(
|
||||
Response::Ok()
|
||||
.header("x-head", HeaderValue::from_static("dummy value!"))
|
||||
.body(body),
|
||||
)
|
||||
})
|
||||
.tcp()
|
||||
})?
|
||||
.run()
|
||||
.await
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use std::{env, io};
|
||||
|
||||
use actix_http::http::HeaderValue;
|
||||
use actix_http::{Error, HttpService, Request, Response};
|
||||
use actix_server::Server;
|
||||
use bytes::BytesMut;
|
||||
use futures::StreamExt;
|
||||
use log::info;
|
||||
use ntex::http::header::HeaderValue;
|
||||
use ntex::http::{Error, HttpService, Request, Response};
|
||||
use ntex::server::Server;
|
||||
|
||||
async fn handle_request(mut req: Request) -> Result<Response, Error> {
|
||||
let mut body = BytesMut::new();
|
|
@ -1,10 +1,10 @@
|
|||
use std::{env, io};
|
||||
|
||||
use actix_http::{HttpService, Response};
|
||||
use actix_server::Server;
|
||||
use futures::future;
|
||||
use http::header::HeaderValue;
|
||||
use log::info;
|
||||
use ntex::http::header::HeaderValue;
|
||||
use ntex::http::{HttpService, Response};
|
||||
use ntex::server::Server;
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> io::Result<()> {
|
|
@ -1,9 +1,8 @@
|
|||
use actix_web::{
|
||||
get, middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer,
|
||||
};
|
||||
use ntex::http::Error;
|
||||
use ntex::web::{self, get, middleware, App, HttpRequest, HttpResponse, HttpServer};
|
||||
|
||||
#[get("/resource1/{name}/index.html")]
|
||||
async fn index(req: HttpRequest, name: web::Path<String>) -> String {
|
||||
async fn index(req: HttpRequest, name: web::types::Path<String>) -> String {
|
||||
println!("REQ: {:?}", req);
|
||||
format!("Hello: {}!\r\n", name)
|
||||
}
|
|
@ -80,6 +80,28 @@ impl ResponseBody<Body> {
|
|||
ResponseBody::Other(b) => ResponseBody::Other(b),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn bin_ref(&self) -> &[u8] {
|
||||
match self {
|
||||
ResponseBody::Body(ref b) => match b {
|
||||
Body::Bytes(ref bin) => &bin,
|
||||
_ => panic!(),
|
||||
},
|
||||
ResponseBody::Other(ref b) => match b {
|
||||
Body::Bytes(ref bin) => &bin,
|
||||
_ => panic!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn body(&self) -> &Body {
|
||||
match self {
|
||||
ResponseBody::Body(ref b) => b,
|
||||
ResponseBody::Other(ref b) => b,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> ResponseBody<B> {
|
||||
|
|
|
@ -40,9 +40,9 @@ type SslConnector = ();
|
|||
/// The `Connector` type uses a builder-like combinator pattern for service
|
||||
/// construction that finishes by calling the `.finish()` method.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// ```rust,no_run
|
||||
/// use std::time::Duration;
|
||||
/// use actix_http::client::Connector;
|
||||
/// use ntex::http::client::Connector;
|
||||
///
|
||||
/// let connector = Connector::new()
|
||||
/// .timeout(Duration::from_secs(5))
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
//!
|
||||
//! ```rust
|
||||
//! use futures::future::{lazy, Future};
|
||||
//! use actix_rt::System;
|
||||
//! use awc::Client;
|
||||
//! use ntex::http::client::Client;
|
||||
//!
|
||||
//! #[actix_rt::main]
|
||||
//! #[ntex::main]
|
||||
//! async fn main() {
|
||||
//! let mut client = Client::default();
|
||||
//!
|
||||
|
@ -62,9 +61,9 @@ pub struct Connect {
|
|||
/// An HTTP Client
|
||||
///
|
||||
/// ```rust
|
||||
/// use awc::Client;
|
||||
/// use ntex::http::client::Client;
|
||||
///
|
||||
/// #[actix_rt::main]
|
||||
/// #[ntex::main]
|
||||
/// async fn main() {
|
||||
/// let mut client = Client::default();
|
||||
///
|
||||
|
|
|
@ -31,11 +31,11 @@ const HTTPS_ENCODING: &str = "br";
|
|||
/// builder-like pattern.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_rt::System;
|
||||
/// use ntex::http::client::Client;
|
||||
///
|
||||
/// #[actix_rt::main]
|
||||
/// #[ntex::main]
|
||||
/// async fn main() {
|
||||
/// let response = awc::Client::new()
|
||||
/// let response = Client::new()
|
||||
/// .get("http://www.rust-lang.org") // <- Create request builder
|
||||
/// .header("User-Agent", "Actix-web")
|
||||
/// .send() // <- Send http request
|
||||
|
@ -157,16 +157,15 @@ impl ClientRequest {
|
|||
/// To override header use `set_header()` method.
|
||||
///
|
||||
/// ```rust
|
||||
/// use awc::{http, Client};
|
||||
/// use ntex::http;
|
||||
/// use ntex::http::client::Client;
|
||||
///
|
||||
/// fn main() {
|
||||
/// # actix_rt::System::new("test").block_on(async {
|
||||
/// #[ntex::main]
|
||||
/// async fn main() {
|
||||
/// let req = Client::new()
|
||||
/// .get("http://www.rust-lang.org")
|
||||
/// .header("X-TEST", "value")
|
||||
/// .header(http::header::CONTENT_TYPE, "application/json");
|
||||
/// # Ok::<_, ()>(())
|
||||
/// # });
|
||||
/// }
|
||||
/// ```
|
||||
pub fn header<K, V>(mut self, key: K, value: V) -> Self
|
||||
|
@ -285,11 +284,14 @@ impl ClientRequest {
|
|||
/// Set a cookie
|
||||
///
|
||||
/// ```rust
|
||||
/// #[actix_rt::main]
|
||||
/// use coo_kie as cookie;
|
||||
/// use ntex::http::client::Client;
|
||||
///
|
||||
/// #[ntex::main]
|
||||
/// async fn main() {
|
||||
/// let resp = awc::Client::new().get("https://www.rust-lang.org")
|
||||
/// let resp = Client::new().get("https://www.rust-lang.org")
|
||||
/// .cookie(
|
||||
/// awc::http::Cookie::build("name", "value")
|
||||
/// cookie::Cookie::build("name", "value")
|
||||
/// .domain("www.rust-lang.org")
|
||||
/// .path("/")
|
||||
/// .secure(true)
|
||||
|
@ -571,10 +573,8 @@ impl fmt::Debug for ClientRequest {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::time::SystemTime;
|
||||
|
||||
use super::*;
|
||||
use crate::Client;
|
||||
use crate::http::client::Client;
|
||||
|
||||
#[test]
|
||||
fn test_debug() {
|
||||
|
@ -589,7 +589,7 @@ mod tests {
|
|||
let mut req = Client::new()
|
||||
.put("/")
|
||||
.version(Version::HTTP_2)
|
||||
.set(header::Date(SystemTime::now().into()))
|
||||
.header(header::DATE, "data")
|
||||
.content_type("plain/text")
|
||||
.if_true(true, |req| req.header(header::SERVER, "awc"))
|
||||
.if_true(false, |req| req.header(header::EXPECT, "awc"))
|
||||
|
|
|
@ -367,7 +367,8 @@ mod tests {
|
|||
use super::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{http::header, test::TestResponse};
|
||||
use crate::http::client::test::TestResponse;
|
||||
use crate::http::header;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_body() {
|
||||
|
|
|
@ -90,7 +90,7 @@ impl Future for SendClientRequest {
|
|||
}
|
||||
}
|
||||
|
||||
let res = futures_core::ready!(Pin::new(send).poll(cx)).map(|res| {
|
||||
let res = futures::ready!(Pin::new(send).poll(cx)).map(|res| {
|
||||
res.map_body(|head, payload| {
|
||||
if *response_decompress {
|
||||
Payload::Stream(Decoder::from_headers(
|
||||
|
|
|
@ -117,18 +117,29 @@ impl TestResponse {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::time::SystemTime;
|
||||
|
||||
use super::*;
|
||||
use crate::{cookie, http::header};
|
||||
use crate::http::header;
|
||||
|
||||
#[test]
|
||||
fn test_basics() {
|
||||
let res = TestResponse::default()
|
||||
.version(Version::HTTP_2)
|
||||
.set(header::Date(SystemTime::now().into()))
|
||||
.cookie(cookie::Cookie::build("name", "value").finish())
|
||||
.finish();
|
||||
let res = {
|
||||
#[cfg(feature = "cookie")]
|
||||
{
|
||||
TestResponse::default()
|
||||
.version(Version::HTTP_2)
|
||||
.header(header::DATE, "data")
|
||||
.cookie(coo_kie::Cookie::build("name", "value").finish())
|
||||
.finish()
|
||||
}
|
||||
#[cfg(not(feature = "cookie"))]
|
||||
{
|
||||
TestResponse::default()
|
||||
.version(Version::HTTP_2)
|
||||
.header(header::DATE, "data")
|
||||
.finish()
|
||||
}
|
||||
};
|
||||
#[cfg(feature = "cookie")]
|
||||
assert!(res.headers().contains_key(header::SET_COOKIE));
|
||||
assert!(res.headers().contains_key(header::DATE));
|
||||
assert_eq!(res.version(), Version::HTTP_2);
|
||||
|
|
|
@ -409,7 +409,7 @@ impl fmt::Debug for WebsocketsRequest {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::Client;
|
||||
use crate::http::client::Client;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_debug() {
|
||||
|
|
|
@ -94,7 +94,10 @@ impl<B: MessageBody> MessageBody for Encoder<B> {
|
|||
}
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next_chunk(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
loop {
|
||||
if self.eof {
|
||||
return Poll::Ready(None);
|
||||
|
@ -121,8 +124,8 @@ impl<B: MessageBody> MessageBody for Encoder<B> {
|
|||
Poll::Ready(Some(Ok(std::mem::replace(b, Bytes::new()))))
|
||||
}
|
||||
}
|
||||
EncoderBody::Stream(ref mut b) => b.poll_next(cx),
|
||||
EncoderBody::BoxedStream(ref mut b) => b.poll_next(cx),
|
||||
EncoderBody::Stream(ref mut b) => b.poll_next_chunk(cx),
|
||||
EncoderBody::BoxedStream(ref mut b) => b.poll_next_chunk(cx),
|
||||
};
|
||||
match result {
|
||||
Poll::Ready(Some(Ok(chunk))) => {
|
||||
|
|
|
@ -477,11 +477,10 @@ where
|
|||
/// default.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::io;
|
||||
/// # use actix_http::*;
|
||||
/// use ntex::http::{error, Request};
|
||||
///
|
||||
/// fn index(req: Request) -> Result<&'static str> {
|
||||
/// Err(error::ErrorBadRequest(io::Error::new(io::ErrorKind::Other, "error")))
|
||||
/// fn index(req: Request) -> Result<&'static str, error::Error> {
|
||||
/// Err(error::ErrorBadRequest(std::io::Error::new(std::io::ErrorKind::Other, "error")))
|
||||
/// }
|
||||
/// ```
|
||||
pub struct InternalError<T> {
|
||||
|
|
|
@ -197,10 +197,9 @@ impl Encoder for Codec {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bytes::BytesMut;
|
||||
use http::Method;
|
||||
|
||||
use super::*;
|
||||
use crate::httpmessage::HttpMessage;
|
||||
use crate::http::{HttpMessage, Method};
|
||||
|
||||
#[test]
|
||||
fn test_http_request_chunked_payload_and_next_message() {
|
||||
|
|
|
@ -640,12 +640,11 @@ impl ChunkedState {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use http::{Method, Version};
|
||||
|
||||
use super::*;
|
||||
use crate::error::ParseError;
|
||||
use crate::http::error::ParseError;
|
||||
use crate::http::header::{HeaderName, SET_COOKIE};
|
||||
use crate::httpmessage::HttpMessage;
|
||||
use crate::http::{HttpMessage, Method, Version};
|
||||
|
||||
impl PayloadType {
|
||||
fn unwrap(self) -> PayloadDecoder {
|
||||
|
|
|
@ -893,9 +893,9 @@ mod tests {
|
|||
use futures::future::{lazy, ok};
|
||||
|
||||
use super::*;
|
||||
use crate::error::Error;
|
||||
use crate::h1::{ExpectHandler, UpgradeHandler};
|
||||
use crate::test::TestBuffer;
|
||||
use crate::http::error::Error;
|
||||
use crate::http::h1::{ExpectHandler, UpgradeHandler};
|
||||
use crate::http::test::TestBuffer;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_req_parse_err() {
|
||||
|
|
|
@ -524,11 +524,10 @@ mod tests {
|
|||
use std::rc::Rc;
|
||||
|
||||
use bytes::Bytes;
|
||||
use http::header::AUTHORIZATION;
|
||||
|
||||
use super::*;
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
||||
use crate::RequestHead;
|
||||
use crate::http::header::{HeaderValue, AUTHORIZATION, CONTENT_TYPE};
|
||||
use crate::http::RequestHead;
|
||||
|
||||
#[test]
|
||||
fn test_chunked_te() {
|
||||
|
|
|
@ -57,7 +57,7 @@ pub(crate) fn reserve_readbuf(src: &mut BytesMut) {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::request::Request;
|
||||
use crate::http::request::Request;
|
||||
|
||||
impl Message<Request> {
|
||||
pub fn message(self) -> Request {
|
||||
|
|
|
@ -74,9 +74,9 @@ impl Response {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::body::Body;
|
||||
use crate::response::Response;
|
||||
use http::StatusCode;
|
||||
use crate::http::body::Body;
|
||||
use crate::http::response::Response;
|
||||
use crate::http::StatusCode;
|
||||
|
||||
#[test]
|
||||
fn test_build() {
|
||||
|
|
|
@ -162,7 +162,7 @@ mod tests {
|
|||
use mime;
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::http::test::TestRequest;
|
||||
|
||||
#[test]
|
||||
fn test_content_type() {
|
||||
|
|
|
@ -354,12 +354,12 @@ impl ResponseBuilder {
|
|||
/// Append a header to existing headers.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_http::{http, Request, Response};
|
||||
/// use ntex::http::{header, Request, Response};
|
||||
///
|
||||
/// fn index(req: Request) -> Response {
|
||||
/// Response::Ok()
|
||||
/// .header("X-TEST", "value")
|
||||
/// .header(http::header::CONTENT_TYPE, "application/json")
|
||||
/// .header(header::CONTENT_TYPE, "application/json")
|
||||
/// .finish()
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -386,12 +386,12 @@ impl ResponseBuilder {
|
|||
/// Set a header.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_http::{http, Request, Response};
|
||||
/// use ntex::http::{header, Request, Response};
|
||||
///
|
||||
/// fn index(req: Request) -> Response {
|
||||
/// Response::Ok()
|
||||
/// .set_header("X-TEST", "value")
|
||||
/// .set_header(http::header::CONTENT_TYPE, "application/json")
|
||||
/// .set_header(header::CONTENT_TYPE, "application/json")
|
||||
/// .finish()
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -491,12 +491,13 @@ impl ResponseBuilder {
|
|||
/// Set a cookie
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_http::{http, Request, Response};
|
||||
/// use coo_kie as cookie;
|
||||
/// use ntex::http::{Request, Response};
|
||||
///
|
||||
/// fn index(req: Request) -> Response {
|
||||
/// Response::Ok()
|
||||
/// .cookie(
|
||||
/// http::Cookie::build("name", "value")
|
||||
/// cookie::Cookie::build("name", "value")
|
||||
/// .domain("www.rust-lang.org")
|
||||
/// .path("/")
|
||||
/// .secure(true)
|
||||
|
@ -521,7 +522,7 @@ impl ResponseBuilder {
|
|||
/// Remove cookie
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_http::{http, Request, Response, HttpMessage};
|
||||
/// use ntex::http::{Request, Response, HttpMessage};
|
||||
///
|
||||
/// fn index(req: Request) -> Response {
|
||||
/// let mut builder = Response::Ok();
|
||||
|
@ -863,8 +864,8 @@ impl From<BytesMut> for Response {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::body::Body;
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE, COOKIE, SET_COOKIE};
|
||||
use crate::http::body::Body;
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE, COOKIE};
|
||||
|
||||
#[test]
|
||||
fn test_debug() {
|
||||
|
@ -876,11 +877,13 @@ mod tests {
|
|||
assert!(dbg.contains("Response"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "cookie")]
|
||||
#[test]
|
||||
fn test_response_cookies() {
|
||||
use crate::httpmessage::HttpMessage;
|
||||
use crate::http::header::{COOKIE, SET_COOKIE};
|
||||
use crate::http::httpmessage::HttpMessage;
|
||||
|
||||
let req = crate::test::TestRequest::default()
|
||||
let req = crate::http::test::TestRequest::default()
|
||||
.header(COOKIE, "cookie1=value1")
|
||||
.header(COOKIE, "cookie2=value2")
|
||||
.finish();
|
||||
|
@ -888,11 +891,11 @@ mod tests {
|
|||
|
||||
let resp = Response::Ok()
|
||||
.cookie(
|
||||
crate::http::Cookie::build("name", "value")
|
||||
coo_kie::Cookie::build("name", "value")
|
||||
.domain("www.rust-lang.org")
|
||||
.path("/test")
|
||||
.http_only(true)
|
||||
.max_age_time(time::Duration::days(1))
|
||||
.max_age(time::Duration::days(1))
|
||||
.finish(),
|
||||
)
|
||||
.del_cookie(&cookies[1])
|
||||
|
@ -911,17 +914,18 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "cookie")]
|
||||
#[test]
|
||||
fn test_update_response_cookies() {
|
||||
let mut r = Response::Ok()
|
||||
.cookie(crate::http::Cookie::new("original", "val100"))
|
||||
.cookie(coo_kie::Cookie::new("original", "val100"))
|
||||
.finish();
|
||||
|
||||
r.add_cookie(&crate::http::Cookie::new("cookie2", "val200"))
|
||||
r.add_cookie(&coo_kie::Cookie::new("cookie2", "val200"))
|
||||
.unwrap();
|
||||
r.add_cookie(&crate::http::Cookie::new("cookie2", "val250"))
|
||||
r.add_cookie(&coo_kie::Cookie::new("cookie2", "val250"))
|
||||
.unwrap();
|
||||
r.add_cookie(&crate::http::Cookie::new("cookie3", "val300"))
|
||||
r.add_cookie(&coo_kie::Cookie::new("cookie3", "val300"))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(r.cookies().count(), 4);
|
||||
|
@ -1082,17 +1086,22 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_into_builder() {
|
||||
#[allow(unused_mut)]
|
||||
let mut resp: Response = "test".into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
resp.add_cookie(&crate::http::Cookie::new("cookie1", "val100"))
|
||||
#[cfg(feature = "cookie")]
|
||||
resp.add_cookie(&coo_kie::Cookie::new("cookie1", "val100"))
|
||||
.unwrap();
|
||||
|
||||
let mut builder: ResponseBuilder = resp.into();
|
||||
let resp = builder.status(StatusCode::BAD_REQUEST).finish();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
|
||||
let cookie = resp.cookies().next().unwrap();
|
||||
assert_eq!((cookie.name(), cookie.value()), ("cookie1", "val100"));
|
||||
#[cfg(feature = "cookie")]
|
||||
{
|
||||
let cookie = resp.cookies().next().unwrap();
|
||||
assert_eq!((cookie.name(), cookie.value()), ("cookie1", "val100"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,28 +3,34 @@ use std::convert::TryFrom;
|
|||
use std::io::{self, Read, Write};
|
||||
use std::pin::Pin;
|
||||
use std::str::FromStr;
|
||||
use std::sync::mpsc;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{net, thread, time};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_rt::{net::TcpStream, System};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use http::header::HeaderName;
|
||||
use http::{Error as HttpError, Method, Uri, Version};
|
||||
use futures::Stream;
|
||||
|
||||
#[cfg(feature = "cookie")]
|
||||
use coo_kie::{Cookie, CookieJar};
|
||||
|
||||
use super::header::{HeaderMap, IntoHeaderValue};
|
||||
use crate::server::{Server, ServiceFactory};
|
||||
|
||||
use super::client::error::WsClientError;
|
||||
use super::client::{Client, ClientRequest, ClientResponse, Connector};
|
||||
use super::error::{HttpError, PayloadError};
|
||||
use super::header::{HeaderMap, HeaderName, IntoHeaderValue};
|
||||
use super::payload::Payload;
|
||||
use super::Request;
|
||||
use super::{Method, Request, Uri, Version};
|
||||
|
||||
/// Test `Request` builder
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// # use http::{header, StatusCode};
|
||||
/// # use actix_web::*;
|
||||
/// use actix_web::test::TestRequest;
|
||||
/// ```rust,no_run
|
||||
/// use ntex::http::test::TestRequest;
|
||||
/// use ntex::http::{header, Request, Response, StatusCode, HttpMessage};
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> Response {
|
||||
/// fn index(req: Request) -> Response {
|
||||
/// if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
|
||||
/// Response::Ok().into()
|
||||
/// } else {
|
||||
|
@ -32,12 +38,12 @@ use super::Request;
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let resp = TestRequest::with_header("content-type", "text/plain")
|
||||
/// .run(&index)
|
||||
/// .unwrap();
|
||||
/// let resp = index(
|
||||
/// TestRequest::with_header("content-type", "text/plain").finish());
|
||||
/// assert_eq!(resp.status(), StatusCode::OK);
|
||||
///
|
||||
/// let resp = TestRequest::default().run(&index).unwrap();
|
||||
/// let resp = index(
|
||||
/// TestRequest::default().finish());
|
||||
/// assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
/// ```
|
||||
pub struct TestRequest(Option<Inner>);
|
||||
|
@ -266,3 +272,237 @@ impl AsyncWrite for TestBuffer {
|
|||
Poll::Ready(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Start test server
|
||||
///
|
||||
/// `TestServer` is very simple test server that simplify process of writing
|
||||
/// integration tests cases for actix web applications.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// async fn my_handler() -> Result<HttpResponse, http::Error> {
|
||||
/// Ok(HttpResponse::Ok().into())
|
||||
/// }
|
||||
///
|
||||
/// #[ntex::test]
|
||||
/// async fn test_example() {
|
||||
/// let mut srv = http::test::server(
|
||||
/// || http::HttpService::new(
|
||||
/// App::new().service(
|
||||
/// web::resource("/").to(my_handler))
|
||||
/// )
|
||||
/// );
|
||||
///
|
||||
/// let req = srv.get("/");
|
||||
/// let response = req.send().await.unwrap();
|
||||
/// assert!(response.status().is_success());
|
||||
/// }
|
||||
/// ```
|
||||
pub fn server<F: ServiceFactory<TcpStream>>(factory: F) -> TestServer {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
// run server in separate thread
|
||||
thread::spawn(move || {
|
||||
let sys = System::new("actix-test-server");
|
||||
let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let local_addr = tcp.local_addr().unwrap();
|
||||
|
||||
Server::build()
|
||||
.listen("test", tcp, factory)?
|
||||
.workers(1)
|
||||
.disable_signals()
|
||||
.start();
|
||||
|
||||
tx.send((System::current(), local_addr)).unwrap();
|
||||
sys.run()
|
||||
});
|
||||
|
||||
let (system, addr) = rx.recv().unwrap();
|
||||
|
||||
let client = {
|
||||
let connector = {
|
||||
#[cfg(feature = "openssl")]
|
||||
{
|
||||
use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||
|
||||
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||
builder.set_verify(SslVerifyMode::NONE);
|
||||
let _ = builder
|
||||
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
||||
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
||||
Connector::new()
|
||||
.conn_lifetime(time::Duration::from_secs(0))
|
||||
.timeout(time::Duration::from_millis(30000))
|
||||
.ssl(builder.build())
|
||||
.finish()
|
||||
}
|
||||
#[cfg(not(feature = "openssl"))]
|
||||
{
|
||||
Connector::new()
|
||||
.conn_lifetime(time::Duration::from_secs(0))
|
||||
.timeout(time::Duration::from_millis(30000))
|
||||
.finish()
|
||||
}
|
||||
};
|
||||
|
||||
Client::build().connector(connector).finish()
|
||||
};
|
||||
actix_connect::start_default_resolver();
|
||||
|
||||
TestServer {
|
||||
addr,
|
||||
client,
|
||||
system,
|
||||
}
|
||||
}
|
||||
|
||||
/// Test server controller
|
||||
pub struct TestServer {
|
||||
addr: net::SocketAddr,
|
||||
client: Client,
|
||||
system: System,
|
||||
}
|
||||
|
||||
impl TestServer {
|
||||
/// Construct test server url
|
||||
pub fn addr(&self) -> net::SocketAddr {
|
||||
self.addr
|
||||
}
|
||||
|
||||
/// Construct test server url
|
||||
pub fn url(&self, uri: &str) -> String {
|
||||
if uri.starts_with('/') {
|
||||
format!("http://localhost:{}{}", self.addr.port(), uri)
|
||||
} else {
|
||||
format!("http://localhost:{}/{}", self.addr.port(), uri)
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct test https server url
|
||||
pub fn surl(&self, uri: &str) -> String {
|
||||
if uri.starts_with('/') {
|
||||
format!("https://localhost:{}{}", self.addr.port(), uri)
|
||||
} else {
|
||||
format!("https://localhost:{}/{}", self.addr.port(), uri)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create `GET` request
|
||||
pub fn get<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.get(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `GET` request
|
||||
pub fn sget<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.get(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create `POST` request
|
||||
pub fn post<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.post(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `POST` request
|
||||
pub fn spost<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.post(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create `HEAD` request
|
||||
pub fn head<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.head(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `HEAD` request
|
||||
pub fn shead<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.head(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create `PUT` request
|
||||
pub fn put<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.put(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `PUT` request
|
||||
pub fn sput<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.put(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create `PATCH` request
|
||||
pub fn patch<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.patch(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `PATCH` request
|
||||
pub fn spatch<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.patch(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create `DELETE` request
|
||||
pub fn delete<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.delete(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `DELETE` request
|
||||
pub fn sdelete<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.delete(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create `OPTIONS` request
|
||||
pub fn options<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.options(self.url(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Create https `OPTIONS` request
|
||||
pub fn soptions<S: AsRef<str>>(&self, path: S) -> ClientRequest {
|
||||
self.client.options(self.surl(path.as_ref()).as_str())
|
||||
}
|
||||
|
||||
/// Connect to test http server
|
||||
pub fn request<S: AsRef<str>>(&self, method: Method, path: S) -> ClientRequest {
|
||||
self.client.request(method, path.as_ref())
|
||||
}
|
||||
|
||||
pub async fn load_body<S>(
|
||||
&mut self,
|
||||
mut response: ClientResponse<S>,
|
||||
) -> Result<Bytes, PayloadError>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, PayloadError>> + Unpin + 'static,
|
||||
{
|
||||
response.body().limit(10_485_760).await
|
||||
}
|
||||
|
||||
/// Connect to websocket server at a given path
|
||||
pub async fn ws_at(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<Framed<impl AsyncRead + AsyncWrite, crate::ws::Codec>, WsClientError>
|
||||
{
|
||||
let url = self.url(path);
|
||||
let connect = self.client.ws(url).connect();
|
||||
connect.await.map(|(_, framed)| framed)
|
||||
}
|
||||
|
||||
/// Connect to a websocket server
|
||||
pub async fn ws(
|
||||
&mut self,
|
||||
) -> Result<Framed<impl AsyncRead + AsyncWrite, crate::ws::Codec>, WsClientError>
|
||||
{
|
||||
self.ws_at("/").await
|
||||
}
|
||||
|
||||
/// Stop http server
|
||||
fn stop(&mut self) {
|
||||
self.system.stop();
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestServer {
|
||||
fn drop(&mut self) {
|
||||
self.stop()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,8 +135,8 @@ pub fn handshake_response(req: &RequestHead) -> ResponseBuilder {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use http::{header, Method};
|
||||
use crate::http::test::TestRequest;
|
||||
use crate::http::{header, Method};
|
||||
|
||||
#[test]
|
||||
fn test_handshake() {
|
||||
|
|
|
@ -16,5 +16,10 @@ extern crate log;
|
|||
pub use actix_macros::{main, test};
|
||||
|
||||
pub mod http;
|
||||
pub mod server;
|
||||
pub mod web;
|
||||
pub mod ws;
|
||||
|
||||
pub mod service {
|
||||
pub use actix_service::*;
|
||||
}
|
||||
|
|
6
ntex/src/server/mod.rs
Normal file
6
ntex/src/server/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
//! General purpose tcp server
|
||||
|
||||
mod test;
|
||||
|
||||
pub use self::test::{test_server, TestServer};
|
||||
pub use actix_server::*;
|
174
ntex/src/server/test.rs
Normal file
174
ntex/src/server/test.rs
Normal file
|
@ -0,0 +1,174 @@
|
|||
//! Test server
|
||||
use std::sync::mpsc;
|
||||
use std::{net, thread, time};
|
||||
|
||||
use actix_rt::{net::TcpStream, System};
|
||||
use net2::TcpBuilder;
|
||||
|
||||
use super::{Server, ServiceFactory};
|
||||
use crate::http::client::{Client, Connector};
|
||||
|
||||
/// Start test server
|
||||
///
|
||||
/// `TestServer` is very simple test server that simplify process of writing
|
||||
/// integration tests cases for actix web applications.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use ntex::http;
|
||||
/// use ntex::server;
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// async fn my_handler() -> Result<HttpResponse, http::Error> {
|
||||
/// Ok(HttpResponse::Ok().into())
|
||||
/// }
|
||||
///
|
||||
/// #[ntex::test]
|
||||
/// async fn test_example() {
|
||||
/// let mut srv = server::test_server(
|
||||
/// || http::HttpService::new(
|
||||
/// App::new().service(
|
||||
/// web::resource("/").to(my_handler))
|
||||
/// )
|
||||
/// );
|
||||
///
|
||||
/// let req = srv.get("/");
|
||||
/// let response = req.send().await.unwrap();
|
||||
/// assert!(response.status().is_success());
|
||||
/// }
|
||||
/// ```
|
||||
pub fn test_server<F: ServiceFactory<TcpStream>>(factory: F) -> TestServer {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
// run server in separate thread
|
||||
thread::spawn(move || {
|
||||
let sys = System::new("ntex-test-server");
|
||||
let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let local_addr = tcp.local_addr().unwrap();
|
||||
|
||||
Server::build()
|
||||
.listen("test", tcp, factory)?
|
||||
.workers(1)
|
||||
.disable_signals()
|
||||
.start();
|
||||
|
||||
tx.send((System::current(), local_addr)).unwrap();
|
||||
sys.run()
|
||||
});
|
||||
|
||||
let (system, addr) = rx.recv().unwrap();
|
||||
|
||||
let client = {
|
||||
let connector = {
|
||||
#[cfg(feature = "openssl")]
|
||||
{
|
||||
use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||
|
||||
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||
builder.set_verify(SslVerifyMode::NONE);
|
||||
let _ = builder
|
||||
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
||||
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
||||
Connector::new()
|
||||
.conn_lifetime(time::Duration::from_secs(0))
|
||||
.timeout(time::Duration::from_millis(30000))
|
||||
.ssl(builder.build())
|
||||
.finish()
|
||||
}
|
||||
#[cfg(not(feature = "openssl"))]
|
||||
{
|
||||
Connector::new()
|
||||
.conn_lifetime(time::Duration::from_secs(0))
|
||||
.timeout(time::Duration::from_millis(30000))
|
||||
.finish()
|
||||
}
|
||||
};
|
||||
|
||||
Client::build().connector(connector).finish()
|
||||
};
|
||||
actix_connect::start_default_resolver();
|
||||
|
||||
TestServer {
|
||||
addr,
|
||||
client,
|
||||
system,
|
||||
host: "127.0.0.1".to_string(),
|
||||
port: addr.port(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Test server controller
|
||||
pub struct TestServer {
|
||||
addr: net::SocketAddr,
|
||||
host: String,
|
||||
port: u16,
|
||||
client: Client,
|
||||
system: System,
|
||||
}
|
||||
|
||||
impl TestServer {
|
||||
/// Test server host
|
||||
pub fn host(&self) -> &str {
|
||||
&self.host
|
||||
}
|
||||
|
||||
/// Test server port
|
||||
pub fn port(&self) -> u16 {
|
||||
self.port
|
||||
}
|
||||
|
||||
/// Test server socket addr
|
||||
pub fn addr(&self) -> net::SocketAddr {
|
||||
self.addr
|
||||
}
|
||||
|
||||
/// Construct test server url
|
||||
pub fn url(&self, uri: &str) -> String {
|
||||
if uri.starts_with('/') {
|
||||
format!("http://localhost:{}{}", self.addr.port(), uri)
|
||||
} else {
|
||||
format!("http://localhost:{}/{}", self.addr.port(), uri)
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct test https server url
|
||||
pub fn surl(&self, uri: &str) -> String {
|
||||
if uri.starts_with('/') {
|
||||
format!("https://localhost:{}{}", self.addr.port(), uri)
|
||||
} else {
|
||||
format!("https://localhost:{}/{}", self.addr.port(), uri)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns http client reference
|
||||
pub fn client(&self) -> &Client {
|
||||
&self.client
|
||||
}
|
||||
|
||||
/// Connect to server, return TcpStream
|
||||
pub fn connect(&self) -> std::io::Result<TcpStream> {
|
||||
TcpStream::from_std(net::TcpStream::connect(self.addr)?)
|
||||
}
|
||||
|
||||
/// Stop http server
|
||||
fn stop(&mut self) {
|
||||
self.system.stop();
|
||||
}
|
||||
|
||||
/// Get first available unused address
|
||||
pub fn unused_addr() -> net::SocketAddr {
|
||||
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||
let socket = TcpBuilder::new_v4().unwrap();
|
||||
socket.bind(&addr).unwrap();
|
||||
socket.reuse_address(true).unwrap();
|
||||
let tcp = socket.to_tcp_listener().unwrap();
|
||||
tcp.local_addr().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestServer {
|
||||
fn drop(&mut self) {
|
||||
self.stop()
|
||||
}
|
||||
}
|
|
@ -84,7 +84,7 @@ where
|
|||
///
|
||||
/// ```rust
|
||||
/// use std::cell::Cell;
|
||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
||||
/// use ntex::web::{self, App, HttpResponse, Responder};
|
||||
///
|
||||
/// struct MyData {
|
||||
/// counter: Cell<usize>,
|
||||
|
@ -98,8 +98,8 @@ where
|
|||
/// let app = App::new()
|
||||
/// .data(MyData{ counter: Cell::new(0) })
|
||||
/// .service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::get().to(index)));
|
||||
/// web::resource("/index.html").route(web::get().to(index))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn data<U: 'static>(mut self, data: U) -> Self {
|
||||
self.data.push(Box::new(Data::new(data)));
|
||||
|
@ -157,8 +157,7 @@ where
|
|||
/// some of the resource's configuration could be moved to different module.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// use actix_web::{web, middleware, App, HttpResponse};
|
||||
/// use ntex::web::{self, middleware, App, HttpResponse};
|
||||
///
|
||||
/// // this function could be located in different module
|
||||
/// fn config(cfg: &mut web::ServiceConfig) {
|
||||
|
@ -194,9 +193,9 @@ where
|
|||
/// multiple resources with one route would be registered for same resource path.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::types::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -237,7 +236,7 @@ where
|
|||
/// It is possible to use services like `Resource`, `Route`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
|
@ -255,7 +254,7 @@ where
|
|||
/// It is also possible to use static files as default service.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
|
@ -292,9 +291,10 @@ where
|
|||
/// `HttpRequest::url_for()` will work as expected.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpRequest, HttpResponse, Result};
|
||||
/// use ntex::http::Error;
|
||||
/// use ntex::web::{self, App, HttpRequest, HttpResponse};
|
||||
///
|
||||
/// async fn index(req: HttpRequest) -> Result<HttpResponse> {
|
||||
/// async fn index(req: HttpRequest) -> Result<HttpResponse, Error> {
|
||||
/// let url = req.url_for("youtube", &["asdlkjqme"])?;
|
||||
/// assert_eq!(url.as_str(), "https://youtube.com/watch/asdlkjqme");
|
||||
/// Ok(HttpResponse::Ok().into())
|
||||
|
@ -334,9 +334,8 @@ where
|
|||
/// in the builder chain is the *last* to execute during request processing.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// use actix_web::{middleware, web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
/// use ntex::http::header::{CONTENT_TYPE, HeaderValue};
|
||||
/// use ntex::web::{self, middleware, App};
|
||||
///
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
|
@ -392,16 +391,16 @@ where
|
|||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
/// use ntex::service::Service;
|
||||
/// use ntex::web;
|
||||
/// use ntex::http::header::{CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// let app = web::App::new()
|
||||
/// .wrap_fn(|req, srv| {
|
||||
/// let fut = srv.call(req);
|
||||
/// async {
|
||||
|
@ -479,11 +478,12 @@ mod tests {
|
|||
use futures::future::ok;
|
||||
|
||||
use super::*;
|
||||
use crate::http::{header, HeaderValue, Method, StatusCode};
|
||||
use crate::middleware::DefaultHeaders;
|
||||
use crate::service::ServiceRequest;
|
||||
use crate::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::{web, HttpRequest, HttpResponse};
|
||||
use crate::http::header::{self, HeaderValue};
|
||||
use crate::http::{Method, StatusCode};
|
||||
use crate::web::middleware::DefaultHeaders;
|
||||
use crate::web::service::ServiceRequest;
|
||||
use crate::web::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::web::{self, HttpRequest, HttpResponse};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_default_resource() {
|
||||
|
|
|
@ -445,9 +445,9 @@ mod tests {
|
|||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::test::{init_service, TestRequest};
|
||||
use crate::{web, App, HttpResponse};
|
||||
use actix_service::Service;
|
||||
use crate::service::Service;
|
||||
use crate::web::test::{init_service, TestRequest};
|
||||
use crate::web::{self, App, HttpResponse};
|
||||
|
||||
struct DropData(Arc<AtomicBool>);
|
||||
|
||||
|
|
|
@ -246,8 +246,8 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::http::{Method, StatusCode};
|
||||
use crate::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::{web, App, HttpRequest, HttpResponse};
|
||||
use crate::web::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::web::{self, App, HttpRequest, HttpResponse};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_data() {
|
||||
|
|
|
@ -38,7 +38,7 @@ pub(crate) trait DataFactory {
|
|||
///
|
||||
/// ```rust
|
||||
/// use std::sync::Mutex;
|
||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
||||
/// use ntex::web::{self, App, HttpResponse, Responder};
|
||||
///
|
||||
/// struct MyData {
|
||||
/// counter: usize,
|
||||
|
@ -140,8 +140,8 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::http::StatusCode;
|
||||
use crate::test::{self, init_service, TestRequest};
|
||||
use crate::{web, App, HttpResponse};
|
||||
use crate::web::test::{self, init_service, TestRequest};
|
||||
use crate::web::{self, App, HttpResponse};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_data_extractor() {
|
||||
|
|
|
@ -47,8 +47,8 @@ pub trait FromRequest: Sized {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, dev, App, Error, HttpRequest, FromRequest};
|
||||
/// use actix_web::error::ErrorBadRequest;
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, dev, App, HttpRequest, FromRequest};
|
||||
/// use futures::future::{ok, err, Ready};
|
||||
/// use serde_derive::Deserialize;
|
||||
/// use rand;
|
||||
|
@ -59,15 +59,15 @@ pub trait FromRequest: Sized {
|
|||
/// }
|
||||
///
|
||||
/// impl FromRequest for Thing {
|
||||
/// type Error = Error;
|
||||
/// type Error = http::Error;
|
||||
/// type Future = Ready<Result<Self, Self::Error>>;
|
||||
/// type Config = ();
|
||||
///
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut http::Payload) -> Self::Future {
|
||||
/// if rand::random() {
|
||||
/// ok(Thing { name: "thingy".into() })
|
||||
/// } else {
|
||||
/// err(ErrorBadRequest("no luck"))
|
||||
/// err(http::error::ErrorBadRequest("no luck"))
|
||||
/// }
|
||||
///
|
||||
/// }
|
||||
|
@ -119,8 +119,8 @@ where
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, dev, App, Result, Error, HttpRequest, FromRequest};
|
||||
/// use actix_web::error::ErrorBadRequest;
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, App, HttpRequest, FromRequest};
|
||||
/// use futures::future::{ok, err, Ready};
|
||||
/// use serde_derive::Deserialize;
|
||||
/// use rand;
|
||||
|
@ -131,21 +131,21 @@ where
|
|||
/// }
|
||||
///
|
||||
/// impl FromRequest for Thing {
|
||||
/// type Error = Error;
|
||||
/// type Future = Ready<Result<Thing, Error>>;
|
||||
/// type Error = http::Error;
|
||||
/// type Future = Ready<Result<Thing, http::Error>>;
|
||||
/// type Config = ();
|
||||
///
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut http::Payload) -> Self::Future {
|
||||
/// if rand::random() {
|
||||
/// ok(Thing { name: "thingy".into() })
|
||||
/// } else {
|
||||
/// err(ErrorBadRequest("no luck"))
|
||||
/// err(http::error::ErrorBadRequest("no luck"))
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// /// extract `Thing` from request
|
||||
/// async fn index(supplied_thing: Result<Thing>) -> String {
|
||||
/// async fn index(supplied_thing: Result<Thing, http::Error>) -> String {
|
||||
/// match supplied_thing {
|
||||
/// Ok(thing) => format!("Got thing: {:?}", thing),
|
||||
/// Err(e) => format!("Error extracting thing: {}", e)
|
||||
|
@ -265,13 +265,13 @@ tuple_from_req!(TupleFromRequest10, (0, A), (1, B), (2, C), (3, D), (4, E), (5,
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_http::http::header;
|
||||
use bytes::Bytes;
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::types::{Form, FormConfig};
|
||||
use crate::http::header;
|
||||
use crate::web::test::TestRequest;
|
||||
use crate::web::types::{Form, FormConfig};
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
struct Info {
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
//! Extensions containers are available via the `RequestHead::extensions()` method.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use actix_web::{web, http, dev, guard, App, HttpResponse};
|
||||
//! use ntex::http::Method;
|
||||
//! use ntex::web::{self, guard, App, HttpResponse};
|
||||
//!
|
||||
//! fn main() {
|
||||
//! App::new().service(web::resource("/index.html").route(
|
||||
//! web::route()
|
||||
//! .guard(guard::Post())
|
||||
//! .guard(guard::fn_guard(|head| head.method == http::Method::GET))
|
||||
//! .guard(guard::fn_guard(|head| head.method == Method::GET))
|
||||
//! .to(|| HttpResponse::MethodNotAllowed()))
|
||||
//! );
|
||||
//! }
|
||||
|
@ -42,7 +43,7 @@ pub trait Guard {
|
|||
/// Create guard object for supplied function.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{guard, web, App, HttpResponse};
|
||||
/// use ntex::web::{self, guard, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// App::new().service(web::resource("/index.html").route(
|
||||
|
@ -85,7 +86,7 @@ where
|
|||
/// Return guard that matches if any of supplied guards.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard, App, HttpResponse};
|
||||
/// use ntex::web::{self, guard, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// App::new().service(web::resource("/index.html").route(
|
||||
|
@ -124,7 +125,7 @@ impl Guard for AnyGuard {
|
|||
/// Return guard that matches if all of the supplied guards.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{guard, web, App, HttpResponse};
|
||||
/// use ntex::web::{self, guard, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// App::new().service(web::resource("/index.html").route(
|
||||
|
@ -259,7 +260,7 @@ impl Guard for HeaderGuard {
|
|||
/// Return predicate that matches if request contains specified Host name.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard::Host, App, HttpResponse};
|
||||
/// use ntex::web::{self, guard::Host, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// App::new().service(
|
||||
|
@ -322,10 +323,9 @@ impl Guard for HostGuard {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_http::http::{header, Method};
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::http::{header, Method};
|
||||
use crate::web::test::TestRequest;
|
||||
|
||||
#[test]
|
||||
fn test_header() {
|
||||
|
|
|
@ -184,7 +184,7 @@ impl ConnectionInfo {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::web::test::TestRequest;
|
||||
|
||||
#[test]
|
||||
fn test_forwarded() {
|
||||
|
|
|
@ -6,16 +6,17 @@ use std::pin::Pin;
|
|||
use std::str::FromStr;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_http::body::MessageBody;
|
||||
use actix_http::encoding::Encoder;
|
||||
use actix_http::http::header::{ContentEncoding, ACCEPT_ENCODING};
|
||||
use actix_http::Error;
|
||||
use actix_service::{Service, Transform};
|
||||
use futures::future::{ok, Ready};
|
||||
use pin_project::pin_project;
|
||||
|
||||
use crate::dev::BodyEncoding;
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
use crate::http::body::MessageBody;
|
||||
use crate::http::encoding::Encoder;
|
||||
use crate::http::header::{ContentEncoding, ACCEPT_ENCODING};
|
||||
use crate::http::Error;
|
||||
use crate::service::{Service, Transform};
|
||||
|
||||
use crate::web::dev::BodyEncoding;
|
||||
use crate::web::service::{ServiceRequest, ServiceResponse};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// `Middleware` for compressing response body.
|
||||
|
@ -24,7 +25,7 @@ use crate::service::{ServiceRequest, ServiceResponse};
|
|||
/// To disable compression set encoding to `ContentEncoding::Identity` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, middleware, App, HttpResponse};
|
||||
/// use ntex::web::{self, middleware, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
|
|
211
ntex/src/web/middleware/defaultheaders.rs
Normal file
211
ntex/src/web/middleware/defaultheaders.rs
Normal file
|
@ -0,0 +1,211 @@
|
|||
//! Middleware for setting default response headers
|
||||
use std::convert::TryFrom;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use futures::future::{ok, FutureExt, LocalBoxFuture, Ready};
|
||||
|
||||
use crate::http::error::{Error, HttpError};
|
||||
use crate::http::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use crate::service::{Service, Transform};
|
||||
use crate::web::service::{ServiceRequest, ServiceResponse};
|
||||
|
||||
/// `Middleware` for setting default response headers.
|
||||
///
|
||||
/// This middleware does not set header if response headers already contains it.
|
||||
///
|
||||
/// ```rust
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, middleware, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
|
||||
/// .service(
|
||||
/// web::resource("/test")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::method(http::Method::HEAD).to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
pub struct DefaultHeaders {
|
||||
inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
ct: bool,
|
||||
headers: HeaderMap,
|
||||
}
|
||||
|
||||
impl Default for DefaultHeaders {
|
||||
fn default() -> Self {
|
||||
DefaultHeaders {
|
||||
inner: Rc::new(Inner {
|
||||
ct: false,
|
||||
headers: HeaderMap::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultHeaders {
|
||||
/// Construct `DefaultHeaders` middleware.
|
||||
pub fn new() -> DefaultHeaders {
|
||||
DefaultHeaders::default()
|
||||
}
|
||||
|
||||
/// Set a header.
|
||||
#[inline]
|
||||
pub fn header<K, V>(mut self, key: K, value: V) -> Self
|
||||
where
|
||||
HeaderName: TryFrom<K>,
|
||||
<HeaderName as TryFrom<K>>::Error: Into<HttpError>,
|
||||
HeaderValue: TryFrom<V>,
|
||||
<HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
|
||||
{
|
||||
#[allow(clippy::match_wild_err_arm)]
|
||||
match HeaderName::try_from(key) {
|
||||
Ok(key) => match HeaderValue::try_from(value) {
|
||||
Ok(value) => {
|
||||
Rc::get_mut(&mut self.inner)
|
||||
.expect("Multiple copies exist")
|
||||
.headers
|
||||
.append(key, value);
|
||||
}
|
||||
Err(_) => panic!("Can not create header value"),
|
||||
},
|
||||
Err(_) => panic!("Can not create header name"),
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set *CONTENT-TYPE* header if response does not contain this header.
|
||||
pub fn content_type(mut self) -> Self {
|
||||
Rc::get_mut(&mut self.inner)
|
||||
.expect("Multiple copies exist")
|
||||
.ct = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, B> Transform<S> for DefaultHeaders
|
||||
where
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = DefaultHeadersMiddleware<S>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(DefaultHeadersMiddleware {
|
||||
service,
|
||||
inner: self.inner.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultHeadersMiddleware<S> {
|
||||
service: S,
|
||||
inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
impl<S, B> Service for DefaultHeadersMiddleware<S>
|
||||
where
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.service.poll_ready(cx)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
let inner = self.inner.clone();
|
||||
let fut = self.service.call(req);
|
||||
|
||||
async move {
|
||||
let mut res = fut.await?;
|
||||
|
||||
// set response headers
|
||||
for (key, value) in inner.headers.iter() {
|
||||
if !res.headers().contains_key(key) {
|
||||
res.headers_mut().insert(key.clone(), value.clone());
|
||||
}
|
||||
}
|
||||
// default content-type
|
||||
if inner.ct && !res.headers().contains_key(&CONTENT_TYPE) {
|
||||
res.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_static("application/octet-stream"),
|
||||
);
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use futures::future::ok;
|
||||
|
||||
use super::*;
|
||||
use crate::http::header::CONTENT_TYPE;
|
||||
use crate::service::IntoService;
|
||||
use crate::web::service::ServiceRequest;
|
||||
use crate::web::test::{ok_service, TestRequest};
|
||||
use crate::web::HttpResponse;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_default_headers() {
|
||||
let mut mw = DefaultHeaders::new()
|
||||
.header(CONTENT_TYPE, "0001")
|
||||
.new_transform(ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let req = TestRequest::default().to_srv_request();
|
||||
let resp = mw.call(req).await.unwrap();
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
|
||||
let req = TestRequest::default().to_srv_request();
|
||||
let srv = |req: ServiceRequest| {
|
||||
ok(req
|
||||
.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish()))
|
||||
};
|
||||
let mut mw = DefaultHeaders::new()
|
||||
.header(CONTENT_TYPE, "0001")
|
||||
.new_transform(srv.into_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let resp = mw.call(req).await.unwrap();
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_content_type() {
|
||||
let srv =
|
||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish()));
|
||||
let mut mw = DefaultHeaders::new()
|
||||
.content_type()
|
||||
.new_transform(srv.into_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let req = TestRequest::default().to_srv_request();
|
||||
let resp = mw.call(req).await.unwrap();
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
"application/octet-stream"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,18 +9,19 @@ use std::pin::Pin;
|
|||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_service::{Service, Transform};
|
||||
use bytes::Bytes;
|
||||
use futures::future::{ok, Ready};
|
||||
use log::debug;
|
||||
use regex::Regex;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::dev::{BodySize, MessageBody, ResponseBody};
|
||||
use crate::error::{Error, Result};
|
||||
use crate::http::{HeaderName, StatusCode};
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
use crate::HttpResponse;
|
||||
use crate::http::body::{BodySize, MessageBody, ResponseBody};
|
||||
use crate::http::error::Error;
|
||||
use crate::http::header::HeaderName;
|
||||
use crate::http::StatusCode;
|
||||
use crate::service::{Service, Transform};
|
||||
use crate::web::service::{ServiceRequest, ServiceResponse};
|
||||
use crate::web::HttpResponse;
|
||||
|
||||
/// `Middleware` for logging request and response info to the terminal.
|
||||
///
|
||||
|
@ -38,8 +39,8 @@ use crate::HttpResponse;
|
|||
/// %a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// use actix_web::middleware::Logger;
|
||||
/// use actix_web::App;
|
||||
/// use ntex::web::App;
|
||||
/// use ntex::web::middleware::Logger;
|
||||
///
|
||||
/// fn main() {
|
||||
/// std::env::set_var("RUST_LOG", "actix_web=info");
|
||||
|
@ -264,8 +265,11 @@ impl<B: MessageBody> MessageBody for StreamLog<B> {
|
|||
self.body.size()
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
match self.body.poll_next(cx) {
|
||||
fn poll_next_chunk(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
match self.body.poll_next_chunk(cx) {
|
||||
Poll::Ready(Some(Ok(chunk))) => {
|
||||
self.size += chunk.len();
|
||||
Poll::Ready(Some(Ok(chunk)))
|
||||
|
@ -475,12 +479,12 @@ impl<'a> fmt::Display for FormatDisplay<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_service::{IntoService, Service, Transform};
|
||||
use futures::future::ok;
|
||||
|
||||
use super::*;
|
||||
use crate::http::{header, StatusCode};
|
||||
use crate::test::TestRequest;
|
||||
use crate::service::{IntoService, Service, Transform};
|
||||
use crate::web::test::TestRequest;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_logger() {
|
||||
|
|
|
@ -7,3 +7,6 @@ pub use self::compress::Compress;
|
|||
|
||||
mod logger;
|
||||
pub use self::logger::Logger;
|
||||
|
||||
mod defaultheaders;
|
||||
pub use self::defaultheaders::DefaultHeaders;
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
//! Actix web is a small, pragmatic, and extremely fast web framework
|
||||
//! for Rust.
|
||||
//! Web framework for Rust.
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use actix_web::{web, App, Responder, HttpServer};
|
||||
//! use ntex::web;
|
||||
//!
|
||||
//! async fn index(info: web::Path<(String, u32)>) -> impl Responder {
|
||||
//! async fn index(info: web::types::Path<(String, u32)>) -> impl web::Responder {
|
||||
//! format!("Hello {}! id:{}", info.0, info.1)
|
||||
//! }
|
||||
//!
|
||||
//! #[actix_rt::main]
|
||||
//! #[ntex::main]
|
||||
//! async fn main() -> std::io::Result<()> {
|
||||
//! HttpServer::new(|| App::new().service(
|
||||
//! web::server(|| web::App::new().service(
|
||||
//! web::resource("/{name}/{id}/index.html").to(index))
|
||||
//! )
|
||||
//! .bind("127.0.0.1:8080")?
|
||||
|
@ -24,10 +23,9 @@
|
|||
//! Besides the API documentation (which you are currently looking
|
||||
//! at!), several other resources are available:
|
||||
//!
|
||||
//! * [User Guide](https://actix.rs/docs/)
|
||||
//! * [Chat on gitter](https://gitter.im/actix/actix)
|
||||
//! * [GitHub repository](https://github.com/actix/actix-web)
|
||||
//! * [Cargo package](https://crates.io/crates/actix-web)
|
||||
//! * [User Guide](https://docs.rs/ntex/)
|
||||
//! * [GitHub repository](https://github.com/fafhrd91/ntex)
|
||||
//! * [Cargo package](https://crates.io/crates/ntex)
|
||||
//!
|
||||
//! To get started navigating the API documentation you may want to
|
||||
//! consider looking at the following pages:
|
||||
|
@ -40,9 +38,6 @@
|
|||
//! represents an HTTP server instance and is used to instantiate and
|
||||
//! configure servers.
|
||||
//!
|
||||
//! * [web](web/index.html): This module
|
||||
//! provides essential helper functions and types for application registration.
|
||||
//!
|
||||
//! * [HttpRequest](struct.HttpRequest.html) and
|
||||
//! [HttpResponse](struct.HttpResponse.html): These structs
|
||||
//! represent HTTP requests and responses and expose various methods
|
||||
|
@ -53,23 +48,20 @@
|
|||
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
|
||||
//! * Streaming and pipelining
|
||||
//! * Keep-alive and slow requests handling
|
||||
//! * `WebSockets` server/client
|
||||
//! * *WebSockets* server/client
|
||||
//! * Transparent content compression/decompression (br, gzip, deflate)
|
||||
//! * Configurable request routing
|
||||
//! * Multipart streams
|
||||
//! * SSL support with OpenSSL or `native-tls`
|
||||
//! * Middlewares (`Logger`, `Session`, `CORS`, `DefaultHeaders`)
|
||||
//! * Supports [Actix actor framework](https://github.com/actix/actix)
|
||||
//! * SSL support with OpenSSL or `rustls`
|
||||
//! * Middlewares
|
||||
//! * Supported Rust version: 1.39 or later
|
||||
//!
|
||||
//! ## Package feature
|
||||
//!
|
||||
//! * `client` - enables http client (default enabled)
|
||||
//! * `compress` - enables content encoding compression support (default enabled)
|
||||
//! * `cookie` - enables http cookie support
|
||||
//! * `compress` - enables content encoding compression support
|
||||
//! * `openssl` - enables ssl support via `openssl` crate, supports `http/2`
|
||||
//! * `rustls` - enables ssl support via `rustls` crate, supports `http/2`
|
||||
//! * `secure-cookies` - enables secure cookies support, includes `ring` crate as
|
||||
//! dependency
|
||||
#![allow(clippy::type_complexity, clippy::new_without_default)]
|
||||
|
||||
mod app;
|
||||
|
@ -81,7 +73,7 @@ mod extract;
|
|||
pub mod guard;
|
||||
mod handler;
|
||||
mod info;
|
||||
// pub mod middleware;
|
||||
pub mod middleware;
|
||||
mod request;
|
||||
mod resource;
|
||||
mod responder;
|
||||
|
@ -92,14 +84,14 @@ mod server;
|
|||
mod service;
|
||||
pub mod test;
|
||||
pub mod types;
|
||||
mod web;
|
||||
mod util;
|
||||
|
||||
// #[doc(hidden)]
|
||||
// pub use actix_web_codegen::*;
|
||||
pub use ntex_web_macros::*;
|
||||
|
||||
pub use crate::http::Response as HttpResponse;
|
||||
|
||||
pub use self::app::App;
|
||||
pub use self::config::ServiceConfig;
|
||||
pub use self::data::Data;
|
||||
pub use self::extract::FromRequest;
|
||||
pub use self::request::HttpRequest;
|
||||
|
@ -109,20 +101,15 @@ pub use self::route::Route;
|
|||
pub use self::scope::Scope;
|
||||
pub use self::server::HttpServer;
|
||||
pub use self::service::WebService;
|
||||
pub use self::web::*;
|
||||
pub use self::util::*;
|
||||
|
||||
pub mod dev {
|
||||
//! The `actix-web` prelude for library developers
|
||||
//!
|
||||
//! The purpose of this module is to alleviate imports of many common actix
|
||||
//! traits by adding a glob import to the top of actix heavy modules:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![allow(unused_imports)]
|
||||
//! use actix_web::dev::*;
|
||||
//! ```
|
||||
|
||||
pub use crate::web::config::{AppConfig, AppService, ServiceConfig};
|
||||
pub use crate::web::config::{AppConfig, AppService};
|
||||
#[doc(hidden)]
|
||||
pub use crate::web::handler::Factory;
|
||||
pub use crate::web::info::ConnectionInfo;
|
||||
|
|
|
@ -140,8 +140,7 @@ impl HttpRequest {
|
|||
/// Generate url for named resource
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// # use actix_web::{web, App, HttpRequest, HttpResponse};
|
||||
/// # use ntex::web::{self, App, HttpRequest, HttpResponse};
|
||||
/// #
|
||||
/// fn index(req: HttpRequest) -> HttpResponse {
|
||||
/// let url = req.url_for("foo", &["1", "2", "3"]); // <- generate url for "foo" resource
|
||||
|
@ -270,7 +269,7 @@ impl Drop for HttpRequest {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpRequest};
|
||||
/// use ntex::web::{self, App, HttpRequest};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// /// extract `Thing` from request
|
||||
|
@ -346,10 +345,10 @@ impl HttpRequestPool {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::dev::{ResourceDef, ResourceMap};
|
||||
use crate::http::{header, StatusCode};
|
||||
use crate::test::{call_service, init_service, TestRequest};
|
||||
use crate::{web, App, HttpResponse};
|
||||
use crate::web::dev::{ResourceDef, ResourceMap};
|
||||
use crate::web::test::{call_service, init_service, TestRequest};
|
||||
use crate::web::{self, App, HttpResponse};
|
||||
|
||||
#[test]
|
||||
fn test_debug() {
|
||||
|
@ -359,12 +358,14 @@ mod tests {
|
|||
assert!(dbg.contains("HttpRequest"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "cookie")]
|
||||
#[test]
|
||||
fn test_no_request_cookies() {
|
||||
let req = TestRequest::default().to_http_request();
|
||||
assert!(req.cookies().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[cfg(feature = "cookie")]
|
||||
#[test]
|
||||
fn test_request_cookies() {
|
||||
let req = TestRequest::default()
|
||||
|
|
|
@ -36,7 +36,7 @@ type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Err
|
|||
/// guards, route considered matched and route handler get called.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
|
@ -96,9 +96,9 @@ where
|
|||
/// Add match guard to a resource.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard, App, HttpResponse};
|
||||
/// use ntex::web::{self, guard, App, HttpResponse};
|
||||
///
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::types::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -129,7 +129,7 @@ where
|
|||
/// Register a new route.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard, App, HttpResponse};
|
||||
/// use ntex::web::{self, guard, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
|
@ -146,7 +146,7 @@ where
|
|||
/// match guards for route selection.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard, App};
|
||||
/// use ntex::web::{self, guard, App};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
|
@ -156,9 +156,9 @@ where
|
|||
/// .route(web::delete().to(delete_handler))
|
||||
/// );
|
||||
/// }
|
||||
/// # async fn get_handler() -> impl actix_web::Responder { actix_web::HttpResponse::Ok() }
|
||||
/// # async fn post_handler() -> impl actix_web::Responder { actix_web::HttpResponse::Ok() }
|
||||
/// # async fn delete_handler() -> impl actix_web::Responder { actix_web::HttpResponse::Ok() }
|
||||
/// # async fn get_handler() -> impl web::Responder { web::HttpResponse::Ok() }
|
||||
/// # async fn post_handler() -> impl web::Responder { web::HttpResponse::Ok() }
|
||||
/// # async fn delete_handler() -> impl web::Responder { web::HttpResponse::Ok() }
|
||||
/// ```
|
||||
pub fn route(mut self, route: Route) -> Self {
|
||||
self.routes.push(route);
|
||||
|
@ -171,7 +171,7 @@ where
|
|||
/// Resource data overrides data registered by `App::data()` method.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, FromRequest};
|
||||
/// use ntex::web::{self, App, FromRequest};
|
||||
///
|
||||
/// /// extract text data from request
|
||||
/// async fn index(body: String) -> String {
|
||||
|
@ -210,7 +210,7 @@ where
|
|||
/// Register a new route and add handler. This route matches all requests.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::*;
|
||||
/// use ntex::web::{self, App, HttpRequest, HttpResponse};
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> HttpResponse {
|
||||
/// unimplemented!()
|
||||
|
@ -222,8 +222,7 @@ where
|
|||
/// This is shortcut for:
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// # use actix_web::*;
|
||||
/// # use ntex::web::{self, *};
|
||||
/// # fn index(req: HttpRequest) -> HttpResponse { unimplemented!() }
|
||||
/// App::new().service(web::resource("/").route(web::route().to(index)));
|
||||
/// ```
|
||||
|
@ -288,9 +287,9 @@ where
|
|||
/// type (i.e modify response's body).
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
/// use ntex::service::Service;
|
||||
/// use ntex::web::{self, App};
|
||||
/// use ntex::http::header::{CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
|
@ -586,11 +585,12 @@ mod tests {
|
|||
use actix_service::Service;
|
||||
use futures::future::ok;
|
||||
|
||||
use crate::http::{header, HeaderValue, Method, StatusCode};
|
||||
use crate::middleware::DefaultHeaders;
|
||||
use crate::service::ServiceRequest;
|
||||
use crate::test::{call_service, init_service, TestRequest};
|
||||
use crate::{guard, web, App, Error, HttpResponse};
|
||||
use crate::http::header::{self, HeaderValue};
|
||||
use crate::http::{Error, Method, StatusCode};
|
||||
use crate::web::middleware::DefaultHeaders;
|
||||
use crate::web::service::ServiceRequest;
|
||||
use crate::web::test::{call_service, init_service, TestRequest};
|
||||
use crate::web::{self, guard, App, HttpResponse};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_middleware() {
|
||||
|
|
|
@ -30,7 +30,8 @@ pub trait Responder {
|
|||
/// Override a status code for a Responder.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{HttpRequest, Responder, http::StatusCode};
|
||||
/// use ntex::http::StatusCode;
|
||||
/// use ntex::web::{HttpRequest, Responder};
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> impl Responder {
|
||||
/// "Welcome!".with_status(StatusCode::OK)
|
||||
|
@ -47,7 +48,7 @@ pub trait Responder {
|
|||
/// Add header to the Responder's response.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, HttpRequest, Responder};
|
||||
/// use ntex::web::{self, HttpRequest, Responder};
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
|
@ -56,7 +57,7 @@ pub trait Responder {
|
|||
/// }
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> impl Responder {
|
||||
/// web::Json(
|
||||
/// web::types::Json(
|
||||
/// MyObj{name: "Name".to_string()}
|
||||
/// )
|
||||
/// .with_header("x-version", "1.2.3")
|
||||
|
@ -233,7 +234,8 @@ impl<T: Responder> CustomResponder<T> {
|
|||
/// Override a status code for the Responder's response.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{HttpRequest, Responder, http::StatusCode};
|
||||
/// use ntex::http::StatusCode;
|
||||
/// use ntex::web::{HttpRequest, Responder};
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> impl Responder {
|
||||
/// "Welcome!".with_status(StatusCode::OK)
|
||||
|
@ -248,7 +250,7 @@ impl<T: Responder> CustomResponder<T> {
|
|||
/// Add header to the Responder's response.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, HttpRequest, Responder};
|
||||
/// use ntex::web::{self, HttpRequest, Responder};
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
|
@ -257,7 +259,7 @@ impl<T: Responder> CustomResponder<T> {
|
|||
/// }
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> impl Responder {
|
||||
/// web::Json(
|
||||
/// web::types::Json(
|
||||
/// MyObj{name: "Name".to_string()}
|
||||
/// )
|
||||
/// .with_header("x-version", "1.2.3")
|
||||
|
@ -333,7 +335,8 @@ impl<T: Responder> Future for CustomResponderFut<T> {
|
|||
/// Combines two different responder types into a single type
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{Either, Error, HttpResponse};
|
||||
/// use ntex::http::Error;
|
||||
/// use ntex::web::{Either, HttpResponse};
|
||||
///
|
||||
/// type RegisterResult = Either<HttpResponse, Result<HttpResponse, Error>>;
|
||||
///
|
||||
|
@ -455,15 +458,16 @@ pub(crate) mod tests {
|
|||
use bytes::{Bytes, BytesMut};
|
||||
|
||||
use super::*;
|
||||
use crate::dev::{Body, ResponseBody};
|
||||
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
|
||||
use crate::test::{init_service, TestRequest};
|
||||
use crate::{error, web, App, HttpResponse};
|
||||
use crate::http::body::{Body, ResponseBody};
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
||||
use crate::http::{error, Response as HttpResponse, StatusCode};
|
||||
use crate::web;
|
||||
use crate::web::test::{init_service, TestRequest};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_option_responder() {
|
||||
let mut srv = init_service(
|
||||
App::new()
|
||||
web::App::new()
|
||||
.service(
|
||||
web::resource("/none").to(|| async { Option::<&'static str>::None }),
|
||||
)
|
||||
|
@ -487,32 +491,6 @@ pub(crate) mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) trait BodyTest {
|
||||
fn bin_ref(&self) -> &[u8];
|
||||
fn body(&self) -> &Body;
|
||||
}
|
||||
|
||||
impl BodyTest for ResponseBody<Body> {
|
||||
fn bin_ref(&self) -> &[u8] {
|
||||
match self {
|
||||
ResponseBody::Body(ref b) => match b {
|
||||
Body::Bytes(ref bin) => &bin,
|
||||
_ => panic!(),
|
||||
},
|
||||
ResponseBody::Other(ref b) => match b {
|
||||
Body::Bytes(ref bin) => &bin,
|
||||
_ => panic!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
fn body(&self) -> &Body {
|
||||
match self {
|
||||
ResponseBody::Body(ref b) => b,
|
||||
ResponseBody::Other(ref b) => b,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_responder() {
|
||||
let req = TestRequest::default().to_http_request();
|
||||
|
|
|
@ -141,7 +141,7 @@ impl Route {
|
|||
/// Add method guard to the route.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use actix_web::*;
|
||||
/// # use ntex::web::{self, *};
|
||||
/// # fn main() {
|
||||
/// App::new().service(web::resource("/path").route(
|
||||
/// web::get()
|
||||
|
@ -161,7 +161,7 @@ impl Route {
|
|||
/// Add guard to the route.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use actix_web::*;
|
||||
/// # use ntex::web::{self, *};
|
||||
/// # fn main() {
|
||||
/// App::new().service(web::resource("/path").route(
|
||||
/// web::route()
|
||||
|
@ -179,7 +179,7 @@ impl Route {
|
|||
/// Set handler function, use request extractors for parameters.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, http, App};
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -188,12 +188,12 @@ impl Route {
|
|||
/// }
|
||||
///
|
||||
/// /// extract path info using serde
|
||||
/// async fn index(info: web::Path<Info>) -> String {
|
||||
/// async fn index(info: web::types::Path<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{username}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to(index)) // <- register handler
|
||||
/// );
|
||||
|
@ -205,7 +205,7 @@ impl Route {
|
|||
/// ```rust
|
||||
/// # use std::collections::HashMap;
|
||||
/// # use serde_derive::Deserialize;
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Info {
|
||||
|
@ -213,12 +213,12 @@ impl Route {
|
|||
/// }
|
||||
///
|
||||
/// /// extract path info using serde
|
||||
/// async fn index(path: web::Path<Info>, query: web::Query<HashMap<String, String>>, body: web::Json<Info>) -> String {
|
||||
/// async fn index(path: web::types::Path<Info>, query: web::types::Query<HashMap<String, String>>, body: web::types::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", path.username)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{username}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to(index))
|
||||
/// );
|
||||
|
@ -319,7 +319,6 @@ where
|
|||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
// let mut fut = self.service.call(req);
|
||||
self.service
|
||||
.call(req)
|
||||
.map(|res| match res {
|
||||
|
@ -327,15 +326,6 @@ where
|
|||
Err((err, req)) => Ok(req.error_response(err)),
|
||||
})
|
||||
.boxed_local()
|
||||
|
||||
// match fut.poll() {
|
||||
// Poll::Ready(Ok(res)) => Either::Left(ok(res)),
|
||||
// Poll::Ready(Err((e, req))) => Either::Left(ok(req.error_response(e))),
|
||||
// Poll::Pending => Either::Right(Box::new(fut.then(|res| match res {
|
||||
// Ok(res) => Ok(res),
|
||||
// Err((err, req)) => Ok(req.error_response(err)),
|
||||
// }))),
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,9 +337,9 @@ mod tests {
|
|||
use bytes::Bytes;
|
||||
use serde_derive::Serialize;
|
||||
|
||||
use crate::http::{Method, StatusCode};
|
||||
use crate::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::{error, web, App, HttpResponse};
|
||||
use crate::http::{error, Method, StatusCode};
|
||||
use crate::web::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::web::{self, App, HttpResponse};
|
||||
|
||||
#[derive(Serialize, PartialEq, Debug)]
|
||||
struct MyObject {
|
||||
|
@ -377,7 +367,7 @@ mod tests {
|
|||
)
|
||||
.service(web::resource("/json").route(web::get().to(|| async {
|
||||
delay_for(Duration::from_millis(25)).await;
|
||||
web::Json(MyObject {
|
||||
web::types::Json(MyObject {
|
||||
name: "test".to_string(),
|
||||
})
|
||||
}))),
|
||||
|
|
|
@ -40,7 +40,7 @@ type BoxedResponse = LocalBoxFuture<'static, Result<ServiceResponse, Error>>;
|
|||
/// `Path` extractor also is able to extract scope level variable segments.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
|
@ -98,9 +98,9 @@ where
|
|||
/// Add match guard to a scope.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard, App, HttpRequest, HttpResponse};
|
||||
/// use ntex::web::{self, guard, App, HttpRequest, HttpResponse};
|
||||
///
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::types::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -125,7 +125,7 @@ where
|
|||
///
|
||||
/// ```rust
|
||||
/// use std::cell::Cell;
|
||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
||||
/// use ntex::web::{self, App, HttpResponse, Responder};
|
||||
///
|
||||
/// struct MyData {
|
||||
/// counter: Cell<usize>,
|
||||
|
@ -169,8 +169,7 @@ where
|
|||
/// some of the resource's configuration could be moved to different module.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// use actix_web::{web, middleware, App, HttpResponse};
|
||||
/// use ntex::web::{self, middleware, App, HttpResponse};
|
||||
///
|
||||
/// // this function could be located in different module
|
||||
/// fn config(cfg: &mut web::ServiceConfig) {
|
||||
|
@ -222,7 +221,7 @@ where
|
|||
/// * "StaticFiles" is a service for static files support
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpRequest};
|
||||
/// use ntex::web::{self, App, HttpRequest};
|
||||
///
|
||||
/// struct AppState;
|
||||
///
|
||||
|
@ -254,9 +253,9 @@ where
|
|||
/// multiple resources with one route would be registered for same resource path.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::types::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -350,16 +349,16 @@ where
|
|||
/// can not modify ServiceResponse.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
/// use ntex::service::Service;
|
||||
/// use ntex::web;
|
||||
/// use ntex::http::header::{CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::scope("/app")
|
||||
/// .wrap_fn(|req, srv| {
|
||||
/// let fut = srv.call(req);
|
||||
|
@ -664,12 +663,13 @@ mod tests {
|
|||
use bytes::Bytes;
|
||||
use futures::future::ok;
|
||||
|
||||
use crate::dev::{Body, ResponseBody};
|
||||
use crate::http::{header, HeaderValue, Method, StatusCode};
|
||||
use crate::middleware::DefaultHeaders;
|
||||
use crate::service::ServiceRequest;
|
||||
use crate::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::{guard, web, App, HttpRequest, HttpResponse};
|
||||
use crate::http::body::{Body, ResponseBody};
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
||||
use crate::http::{Method, StatusCode};
|
||||
use crate::web::middleware::DefaultHeaders;
|
||||
use crate::web::service::ServiceRequest;
|
||||
use crate::web::test::{call_service, init_service, read_body, TestRequest};
|
||||
use crate::web::{self, guard, App, HttpRequest, HttpResponse};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_scope() {
|
||||
|
@ -1038,27 +1038,26 @@ mod tests {
|
|||
|
||||
#[actix_rt::test]
|
||||
async fn test_middleware() {
|
||||
let mut srv =
|
||||
init_service(
|
||||
App::new().service(
|
||||
web::scope("app")
|
||||
.wrap(DefaultHeaders::new().header(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
))
|
||||
.service(
|
||||
web::resource("/test")
|
||||
.route(web::get().to(|| HttpResponse::Ok())),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let mut srv = init_service(
|
||||
App::new().service(
|
||||
web::scope("app")
|
||||
.wrap(
|
||||
DefaultHeaders::new()
|
||||
.header(CONTENT_TYPE, HeaderValue::from_static("0001")),
|
||||
)
|
||||
.service(
|
||||
web::resource("/test")
|
||||
.route(web::get().to(|| HttpResponse::Ok())),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/app/test").to_request();
|
||||
let resp = call_service(&mut srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
HeaderValue::from_static("0001")
|
||||
);
|
||||
}
|
||||
|
@ -1072,10 +1071,8 @@ mod tests {
|
|||
let fut = srv.call(req);
|
||||
async move {
|
||||
let mut res = fut.await?;
|
||||
res.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("0001"),
|
||||
);
|
||||
res.headers_mut()
|
||||
.insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
|
||||
Ok(res)
|
||||
}
|
||||
})
|
||||
|
@ -1088,7 +1085,7 @@ mod tests {
|
|||
let resp = call_service(&mut srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
HeaderValue::from_static("0001")
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ struct Config {
|
|||
/// Create new http server with application factory.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use actix_web::{web, App, HttpResponse, HttpServer};
|
||||
/// use ntex::web::{self, App, HttpResponse, HttpServer};
|
||||
///
|
||||
/// #[actix_rt::main]
|
||||
/// #[ntex::main]
|
||||
/// async fn main() -> std::io::Result<()> {
|
||||
/// HttpServer::new(
|
||||
/// || App::new()
|
||||
|
@ -546,11 +546,10 @@ where
|
|||
/// configured.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use std::io;
|
||||
/// use actix_web::{web, App, HttpResponse, HttpServer};
|
||||
/// use ntex::web::{self, App, HttpResponse, HttpServer};
|
||||
///
|
||||
/// #[actix_rt::main]
|
||||
/// async fn main() -> io::Result<()> {
|
||||
/// #[ntex::main]
|
||||
/// async fn main() -> std::io::Result<()> {
|
||||
/// HttpServer::new(|| App::new().service(web::resource("/").to(|| HttpResponse::Ok())))
|
||||
/// .bind("127.0.0.1:0")?
|
||||
/// .run()
|
||||
|
|
|
@ -448,9 +448,10 @@ impl WebService {
|
|||
/// Add match guard to a web service.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, guard, dev, App, Error, HttpResponse};
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, guard, dev, App, HttpResponse};
|
||||
///
|
||||
/// async fn index(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
|
||||
/// async fn index(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, http::Error> {
|
||||
/// Ok(req.into_response(HttpResponse::Ok().finish()))
|
||||
/// }
|
||||
///
|
||||
|
@ -527,12 +528,14 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::{init_service, TestRequest};
|
||||
use crate::{guard, http, web, App, HttpResponse};
|
||||
use actix_service::Service;
|
||||
use futures::future::ok;
|
||||
|
||||
use super::*;
|
||||
use crate::http::{Method, StatusCode};
|
||||
use crate::service::Service;
|
||||
use crate::web::test::{init_service, TestRequest};
|
||||
use crate::web::{self, guard, App, HttpResponse};
|
||||
|
||||
#[test]
|
||||
fn test_service_request() {
|
||||
let req = TestRequest::default().to_srv_request();
|
||||
|
@ -564,7 +567,7 @@ mod tests {
|
|||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), http::StatusCode::OK);
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let mut srv = init_service(
|
||||
App::new().service(web::service("/test").guard(guard::Get()).finish(
|
||||
|
@ -573,10 +576,10 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test")
|
||||
.method(http::Method::PUT)
|
||||
.method(Method::PUT)
|
||||
.to_request();
|
||||
let resp = srv.call(req).await.unwrap();
|
||||
assert_eq!(resp.status(), http::StatusCode::NOT_FOUND);
|
||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -61,10 +61,11 @@ pub fn default_service(
|
|||
/// service.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
|
||||
/// use ntex::service::Service;
|
||||
/// use ntex::http::StatusCode;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_init_service() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new()
|
||||
|
@ -99,9 +100,10 @@ where
|
|||
/// Calls service and waits for response future completion.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
|
||||
/// use ntex::http::StatusCode;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_response() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new()
|
||||
|
@ -129,10 +131,11 @@ where
|
|||
/// Helper function that returns a response body of a TestRequest
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{test, web, App, HttpResponse, http::header};
|
||||
/// use bytes::Bytes;
|
||||
/// use ntex::http::header;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_index() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new().service(
|
||||
|
@ -172,10 +175,11 @@ where
|
|||
/// Helper function that returns a response body of a ServiceResponse.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{test, web, App, HttpResponse, http::header};
|
||||
/// use bytes::Bytes;
|
||||
/// use ntex::http::header;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_index() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new().service(
|
||||
|
@ -221,7 +225,8 @@ where
|
|||
/// Helper function that returns a deserialized response body of a TestRequest
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{App, test, web, HttpResponse, http::header};
|
||||
/// use ntex::http::header;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
/// use serde::{Serialize, Deserialize};
|
||||
///
|
||||
/// #[derive(Serialize, Deserialize)]
|
||||
|
@ -230,7 +235,7 @@ where
|
|||
/// name: String
|
||||
/// }
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_add_person() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new().service(
|
||||
|
@ -274,8 +279,8 @@ where
|
|||
/// * `TestRequest::to_http_request` creates `HttpRequest` instance, which is used for testing handlers.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
|
||||
/// use actix_web::http::{header, StatusCode};
|
||||
/// use ntex::http::{header, StatusCode, HttpMessage};
|
||||
/// use ntex::web::{self, test, HttpRequest, HttpResponse};
|
||||
///
|
||||
/// async fn index(req: HttpRequest) -> HttpResponse {
|
||||
/// if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
|
||||
|
@ -525,13 +530,14 @@ impl TestRequest {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, test, App, HttpResponse, Error};
|
||||
/// use ntex::http::Error;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
///
|
||||
/// async fn my_handler() -> Result<HttpResponse, Error> {
|
||||
/// Ok(HttpResponse::Ok().into())
|
||||
/// }
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_example() {
|
||||
/// let mut srv = test::start(
|
||||
/// || App::new().service(
|
||||
|
@ -565,13 +571,14 @@ where
|
|||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, test, App, HttpResponse, Error};
|
||||
/// use ntex::http::Error;
|
||||
/// use ntex::web::{self, test, App, HttpResponse};
|
||||
///
|
||||
/// async fn my_handler() -> Result<HttpResponse, Error> {
|
||||
/// Ok(HttpResponse::Ok().into())
|
||||
/// }
|
||||
///
|
||||
/// #[actix_rt::test]
|
||||
/// #[ntex::test]
|
||||
/// async fn test_example() {
|
||||
/// let mut srv = test::start_with(test::config().h1(), ||
|
||||
/// App::new().service(web::resource("/").to(my_handler))
|
||||
|
@ -940,22 +947,20 @@ impl Drop for TestServer {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_http::httpmessage::HttpMessage;
|
||||
use futures::FutureExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use super::*;
|
||||
use crate::{http::header, web, App, HttpResponse, Responder};
|
||||
use crate::http::header;
|
||||
use crate::http::HttpMessage;
|
||||
use crate::web::{self, App, Data, HttpResponse, Responder};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_basics() {
|
||||
let req = TestRequest::with_hdr(header::ContentType::json())
|
||||
let req = TestRequest::with_header(header::CONTENT_TYPE, "application/json")
|
||||
.version(Version::HTTP_2)
|
||||
.set(header::Date(SystemTime::now().into()))
|
||||
.header(header::DATE, "some date")
|
||||
.param("test", "123")
|
||||
.data(10u32)
|
||||
.app_data(20u64)
|
||||
.data(Data::new(20u64))
|
||||
.peer_addr("127.0.0.1:8081".parse().unwrap())
|
||||
.to_http_request();
|
||||
assert!(req.headers().contains_key(header::CONTENT_TYPE));
|
||||
|
@ -966,13 +971,8 @@ mod tests {
|
|||
);
|
||||
assert_eq!(&req.match_info()["test"], "123");
|
||||
assert_eq!(req.version(), Version::HTTP_2);
|
||||
let data = req.app_data::<Data<u32>>().unwrap();
|
||||
assert!(req.app_data::<Data<u64>>().is_none());
|
||||
assert_eq!(*data.get_ref(), 10);
|
||||
|
||||
assert!(req.app_data::<u32>().is_none());
|
||||
let data = req.app_data::<u64>().unwrap();
|
||||
assert_eq!(*data, 20);
|
||||
let data = req.app_data::<Data<u64>>().unwrap();
|
||||
assert_eq!(*data.get_ref(), 20);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
|
@ -1039,7 +1039,7 @@ mod tests {
|
|||
#[actix_rt::test]
|
||||
async fn test_response_json() {
|
||||
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| async {
|
||||
web::post().to(|person: web::types::Json<Person>| async {
|
||||
HttpResponse::Ok().json(person.into_inner())
|
||||
}),
|
||||
)))
|
||||
|
@ -1060,7 +1060,7 @@ mod tests {
|
|||
#[actix_rt::test]
|
||||
async fn test_request_response_form() {
|
||||
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Form<Person>| async {
|
||||
web::post().to(|person: web::types::Form<Person>| async {
|
||||
HttpResponse::Ok().json(person.into_inner())
|
||||
}),
|
||||
)))
|
||||
|
@ -1086,7 +1086,7 @@ mod tests {
|
|||
#[actix_rt::test]
|
||||
async fn test_request_response_json() {
|
||||
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| async {
|
||||
web::post().to(|person: web::types::Json<Person>| async {
|
||||
HttpResponse::Ok().json(person.into_inner())
|
||||
}),
|
||||
)))
|
||||
|
@ -1150,47 +1150,4 @@ mod tests {
|
|||
let res = app.call(req).await.unwrap();
|
||||
assert!(res.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_actor() {
|
||||
use actix::Actor;
|
||||
|
||||
struct MyActor;
|
||||
|
||||
struct Num(usize);
|
||||
impl actix::Message for Num {
|
||||
type Result = usize;
|
||||
}
|
||||
impl actix::Actor for MyActor {
|
||||
type Context = actix::Context<Self>;
|
||||
}
|
||||
impl actix::Handler<Num> for MyActor {
|
||||
type Result = usize;
|
||||
fn handle(&mut self, msg: Num, _: &mut Self::Context) -> Self::Result {
|
||||
msg.0
|
||||
}
|
||||
}
|
||||
|
||||
let addr = MyActor.start();
|
||||
|
||||
let mut app = init_service(App::new().service(web::resource("/index.html").to(
|
||||
move || {
|
||||
addr.send(Num(1)).map(|res| match res {
|
||||
Ok(res) => {
|
||||
if res == 1 {
|
||||
Ok(HttpResponse::Ok())
|
||||
} else {
|
||||
Ok(HttpResponse::BadRequest())
|
||||
}
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
})
|
||||
},
|
||||
)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::post().uri("/index.html").to_request();
|
||||
let res = app.call(req).await.unwrap();
|
||||
assert!(res.status().is_success());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use serde::de::DeserializeOwned;
|
|||
use serde::Serialize;
|
||||
|
||||
#[cfg(feature = "compress")]
|
||||
use crate::http::encoding::Decompress;
|
||||
use crate::http::encoding::Decoder;
|
||||
use crate::http::header::{CONTENT_LENGTH, CONTENT_TYPE};
|
||||
use crate::http::{Error, HttpMessage, Payload, Response, StatusCode};
|
||||
use crate::web::error::UrlencodedError;
|
||||
|
@ -37,7 +37,7 @@ use crate::web::responder::Responder;
|
|||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// use actix_web::web;
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -48,7 +48,7 @@ use crate::web::responder::Responder;
|
|||
/// /// Extract form data using serde.
|
||||
/// /// This handler get called only if content type is *x-www-form-urlencoded*
|
||||
/// /// and content of the request could be deserialized to a `FormData` struct
|
||||
/// fn index(form: web::Form<FormData>) -> String {
|
||||
/// fn index(form: web::types::Form<FormData>) -> String {
|
||||
/// format!("Welcome {}!", form.username)
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
|
@ -62,7 +62,7 @@ use crate::web::responder::Responder;
|
|||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// use actix_web::*;
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
|
@ -74,8 +74,8 @@ use crate::web::responder::Responder;
|
|||
/// // Will return a 200 response with header
|
||||
/// // `Content-Type: application/x-www-form-urlencoded`
|
||||
/// // and body "name=actix&age=123"
|
||||
/// fn index() -> web::Form<SomeForm> {
|
||||
/// web::Form(SomeForm {
|
||||
/// fn index() -> web::types::Form<SomeForm> {
|
||||
/// web::types::Form(SomeForm {
|
||||
/// name: "actix".into(),
|
||||
/// age: 123
|
||||
/// })
|
||||
|
@ -161,7 +161,7 @@ impl<T: Serialize> Responder for Form<T> {
|
|||
};
|
||||
|
||||
ok(Response::build(StatusCode::OK)
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
.header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.body(body))
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,8 @@ impl<T: Serialize> Responder for Form<T> {
|
|||
/// Form extractor configuration
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, FromRequest, Result};
|
||||
/// use ntex::http::Error;
|
||||
/// use ntex::web::{self, App, FromRequest};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -179,7 +180,7 @@ impl<T: Serialize> Responder for Form<T> {
|
|||
///
|
||||
/// /// Extract form data using serde.
|
||||
/// /// Custom configuration is used for this handler, max payload size is 4k
|
||||
/// async fn index(form: web::Form<FormData>) -> Result<String> {
|
||||
/// async fn index(form: web::types::Form<FormData>) -> Result<String, Error> {
|
||||
/// Ok(format!("Welcome {}!", form.username))
|
||||
/// }
|
||||
///
|
||||
|
@ -188,7 +189,7 @@ impl<T: Serialize> Responder for Form<T> {
|
|||
/// web::resource("/index.html")
|
||||
/// // change `Form` extractor configuration
|
||||
/// .app_data(
|
||||
/// web::Form::<FormData>::configure(|cfg| cfg.limit(4097))
|
||||
/// web::types::Form::<FormData>::configure(|cfg| cfg.limit(4097))
|
||||
/// )
|
||||
/// .route(web::get().to(index))
|
||||
/// );
|
||||
|
@ -239,7 +240,7 @@ impl Default for FormConfig {
|
|||
///
|
||||
pub struct UrlEncoded<U> {
|
||||
#[cfg(feature = "compress")]
|
||||
stream: Option<Decompress<Payload>>,
|
||||
stream: Option<Decoder<Payload>>,
|
||||
#[cfg(not(feature = "compress"))]
|
||||
stream: Option<Payload>,
|
||||
limit: usize,
|
||||
|
@ -275,7 +276,7 @@ impl<U> UrlEncoded<U> {
|
|||
};
|
||||
|
||||
#[cfg(feature = "compress")]
|
||||
let payload = Decompress::from_headers(payload.take(), req.headers());
|
||||
let payload = Decoder::from_headers(payload.take(), req.headers());
|
||||
#[cfg(not(feature = "compress"))]
|
||||
let payload = payload.take();
|
||||
|
||||
|
@ -375,7 +376,7 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
||||
use crate::test::TestRequest;
|
||||
use crate::web::test::TestRequest;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
||||
struct Info {
|
||||
|
@ -495,7 +496,6 @@ mod tests {
|
|||
HeaderValue::from_static("application/x-www-form-urlencoded")
|
||||
);
|
||||
|
||||
use crate::responder::tests::BodyTest;
|
||||
assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::http::{header::CONTENT_LENGTH, StatusCode};
|
|||
use crate::http::{Error, HttpMessage, Payload, Response};
|
||||
|
||||
#[cfg(feature = "compress")]
|
||||
use crate::http::encoding::Decompress;
|
||||
use crate::http::encoding::Decoder;
|
||||
|
||||
use crate::web::error::JsonPayloadError;
|
||||
use crate::web::extract::FromRequest;
|
||||
|
@ -39,7 +39,7 @@ use crate::web::responder::Responder;
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -48,12 +48,12 @@ use crate::web::responder::Responder;
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's body
|
||||
/// async fn index(info: web::Json<Info>) -> String {
|
||||
/// async fn index(info: web::types::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::post().to(index))
|
||||
/// );
|
||||
|
@ -66,7 +66,8 @@ use crate::web::responder::Responder;
|
|||
/// trait from *serde*.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::*;
|
||||
/// use ntex::web;
|
||||
/// use ntex::http::Error;
|
||||
/// use serde_derive::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
|
@ -74,8 +75,8 @@ use crate::web::responder::Responder;
|
|||
/// name: String,
|
||||
/// }
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> Result<web::Json<MyObj>> {
|
||||
/// Ok(web::Json(MyObj {
|
||||
/// fn index(req: web::HttpRequest) -> Result<web::types::Json<MyObj>, Error> {
|
||||
/// Ok(web::types::Json(MyObj {
|
||||
/// name: req.match_info().get("name").unwrap().to_string(),
|
||||
/// }))
|
||||
/// }
|
||||
|
@ -150,7 +151,7 @@ impl<T: Serialize> Responder for Json<T> {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -159,12 +160,12 @@ impl<T: Serialize> Responder for Json<T> {
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's body
|
||||
/// async fn index(info: web::Json<Info>) -> String {
|
||||
/// async fn index(info: web::types::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::post().to(index))
|
||||
/// );
|
||||
|
@ -210,7 +211,8 @@ where
|
|||
/// Json extractor configuration
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{error, web, App, FromRequest, HttpResponse};
|
||||
/// use ntex::http::error;
|
||||
/// use ntex::web::{self, App, FromRequest, HttpResponse};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -219,7 +221,7 @@ where
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's body, max payload size is 4kb
|
||||
/// async fn index(info: web::Json<Info>) -> String {
|
||||
/// async fn index(info: web::types::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
@ -228,7 +230,7 @@ where
|
|||
/// web::resource("/index.html")
|
||||
/// .app_data(
|
||||
/// // change json extractor configuration
|
||||
/// web::Json::<Info>::configure(|cfg| {
|
||||
/// web::types::Json::<Info>::configure(|cfg| {
|
||||
/// cfg.limit(4096)
|
||||
/// .content_type(|mime| { // <- accept text/plain content type
|
||||
/// mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN
|
||||
|
@ -297,7 +299,7 @@ pub struct JsonBody<U> {
|
|||
limit: usize,
|
||||
length: Option<usize>,
|
||||
#[cfg(feature = "compress")]
|
||||
stream: Option<Decompress<Payload>>,
|
||||
stream: Option<Decoder<Payload>>,
|
||||
#[cfg(not(feature = "compress"))]
|
||||
stream: Option<Payload>,
|
||||
err: Option<JsonPayloadError>,
|
||||
|
@ -340,7 +342,7 @@ where
|
|||
.and_then(|s| s.parse::<usize>().ok());
|
||||
|
||||
#[cfg(feature = "compress")]
|
||||
let payload = Decompress::from_headers(payload.take(), req.headers());
|
||||
let payload = Decoder::from_headers(payload.take(), req.headers());
|
||||
#[cfg(not(feature = "compress"))]
|
||||
let payload = payload.take();
|
||||
|
||||
|
@ -410,10 +412,10 @@ mod tests {
|
|||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
use super::*;
|
||||
use crate::error::InternalError;
|
||||
use crate::http::error::InternalError;
|
||||
use crate::http::header;
|
||||
use crate::test::{load_stream, TestRequest};
|
||||
use crate::HttpResponse;
|
||||
use crate::web::test::{load_stream, TestRequest};
|
||||
use crate::web::HttpResponse;
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct MyObject {
|
||||
|
@ -448,7 +450,6 @@ mod tests {
|
|||
header::HeaderValue::from_static("application/json")
|
||||
);
|
||||
|
||||
use crate::responder::tests::BodyTest;
|
||||
assert_eq!(resp.body().bin_ref(), b"{\"name\":\"test\"}");
|
||||
}
|
||||
|
||||
|
@ -464,7 +465,7 @@ mod tests {
|
|||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.app_data(JsonConfig::default().limit(10).error_handler(|err, _| {
|
||||
.data(JsonConfig::default().limit(10).error_handler(|err, _| {
|
||||
let msg = MyObject {
|
||||
name: "invalid request".to_string(),
|
||||
};
|
||||
|
@ -516,7 +517,7 @@ mod tests {
|
|||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.app_data(JsonConfig::default().limit(10))
|
||||
.data(JsonConfig::default().limit(10))
|
||||
.to_http_parts();
|
||||
|
||||
let s = Json::<MyObject>::from_request(&req, &mut pl).await;
|
||||
|
@ -533,7 +534,7 @@ mod tests {
|
|||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.app_data(
|
||||
.data(
|
||||
JsonConfig::default()
|
||||
.limit(10)
|
||||
.error_handler(|_, _| JsonPayloadError::ContentType.into()),
|
||||
|
@ -606,7 +607,7 @@ mod tests {
|
|||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.app_data(JsonConfig::default().limit(4096))
|
||||
.data(JsonConfig::default().limit(4096))
|
||||
.to_http_parts();
|
||||
|
||||
let s = Json::<MyObject>::from_request(&req, &mut pl).await;
|
||||
|
@ -624,7 +625,7 @@ mod tests {
|
|||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.app_data(JsonConfig::default().content_type(|mime: mime::Mime| {
|
||||
.data(JsonConfig::default().content_type(|mime: mime::Mime| {
|
||||
mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN
|
||||
}))
|
||||
.to_http_parts();
|
||||
|
@ -644,7 +645,7 @@ mod tests {
|
|||
header::HeaderValue::from_static("16"),
|
||||
)
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.app_data(JsonConfig::default().content_type(|mime: mime::Mime| {
|
||||
.data(JsonConfig::default().content_type(|mime: mime::Mime| {
|
||||
mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN
|
||||
}))
|
||||
.to_http_parts();
|
||||
|
|
|
@ -21,17 +21,17 @@ use crate::web::FromRequest;
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// /// extract path info from "/{username}/{count}/index.html" url
|
||||
/// /// {username} - deserializes to a String
|
||||
/// /// {count} - - deserializes to a u32
|
||||
/// async fn index(info: web::Path<(String, u32)>) -> String {
|
||||
/// async fn index(info: web::types::Path<(String, u32)>) -> String {
|
||||
/// format!("Welcome {}! {}", info.0, info.1)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{username}/{count}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to(index)) // <- register handler with `Path` extractor
|
||||
/// );
|
||||
|
@ -42,7 +42,7 @@ use crate::web::FromRequest;
|
|||
/// implements `Deserialize` trait from *serde*.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, Error};
|
||||
/// use ntex::{http, web};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -51,12 +51,12 @@ use crate::web::FromRequest;
|
|||
/// }
|
||||
///
|
||||
/// /// extract `Info` from a path using serde
|
||||
/// async fn index(info: web::Path<Info>) -> Result<String, Error> {
|
||||
/// async fn index(info: web::types::Path<Info>) -> Result<String, http::Error> {
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{username}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to(index)) // <- use handler with Path` extractor
|
||||
/// );
|
||||
|
@ -116,17 +116,17 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// /// extract path info from "/{username}/{count}/index.html" url
|
||||
/// /// {username} - deserializes to a String
|
||||
/// /// {count} - - deserializes to a u32
|
||||
/// async fn index(info: web::Path<(String, u32)>) -> String {
|
||||
/// async fn index(info: web::types::Path<(String, u32)>) -> String {
|
||||
/// format!("Welcome {}! {}", info.0, info.1)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{username}/{count}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to(index)) // <- register handler with `Path` extractor
|
||||
/// );
|
||||
|
@ -137,7 +137,7 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
|||
/// implements `Deserialize` trait from *serde*.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, Error};
|
||||
/// use ntex::{web, http};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -146,12 +146,12 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
|||
/// }
|
||||
///
|
||||
/// /// extract `Info` from a path using serde
|
||||
/// async fn index(info: web::Path<Info>) -> Result<String, Error> {
|
||||
/// async fn index(info: web::types::Path<Info>) -> Result<String, http::Error> {
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{username}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to(index)) // <- use handler with Path` extractor
|
||||
/// );
|
||||
|
@ -195,8 +195,8 @@ where
|
|||
/// Path extractor configuration
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::web::PathConfig;
|
||||
/// use actix_web::{error, web, App, FromRequest, HttpResponse};
|
||||
/// use ntex::http::error;
|
||||
/// use ntex::web::{self, App, FromRequest, HttpResponse};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize, Debug)]
|
||||
|
@ -208,14 +208,14 @@ where
|
|||
/// }
|
||||
///
|
||||
/// // deserialize `Info` from request's path
|
||||
/// async fn index(folder: web::Path<Folder>) -> String {
|
||||
/// async fn index(folder: web::types::Path<Folder>) -> String {
|
||||
/// format!("Selected folder: {:?}!", folder)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/messages/{folder}")
|
||||
/// .app_data(PathConfig::default().error_handler(|err, req| {
|
||||
/// .app_data(web::types::PathConfig::default().error_handler(|err, req| {
|
||||
/// error::InternalError::from_response(
|
||||
/// err,
|
||||
/// HttpResponse::Conflict().finish(),
|
||||
|
@ -255,8 +255,9 @@ mod tests {
|
|||
use serde_derive::Deserialize;
|
||||
|
||||
use super::*;
|
||||
use crate::test::TestRequest;
|
||||
use crate::{error, http, HttpResponse};
|
||||
use crate::http::{error, StatusCode};
|
||||
use crate::web::test::TestRequest;
|
||||
use crate::web::HttpResponse;
|
||||
|
||||
#[derive(Deserialize, Debug, Display)]
|
||||
#[display(fmt = "MyStruct({}, {})", key, value)]
|
||||
|
@ -361,7 +362,7 @@ mod tests {
|
|||
#[actix_rt::test]
|
||||
async fn test_custom_err_handler() {
|
||||
let (req, mut pl) = TestRequest::with_uri("/name/user1/")
|
||||
.app_data(PathConfig::default().error_handler(|err, _| {
|
||||
.data(PathConfig::default().error_handler(|err, _| {
|
||||
error::InternalError::from_response(
|
||||
err,
|
||||
HttpResponse::Conflict().finish(),
|
||||
|
@ -375,6 +376,6 @@ mod tests {
|
|||
.unwrap_err();
|
||||
let res: HttpResponse = s.into();
|
||||
|
||||
assert_eq!(res.status(), http::StatusCode::CONFLICT);
|
||||
assert_eq!(res.status(), StatusCode::CONFLICT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,15 @@ use crate::web::request::HttpRequest;
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::BytesMut;
|
||||
/// use futures::{Future, Stream, StreamExt};
|
||||
/// use actix_web::{web, error, App, Error, HttpResponse};
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// /// extract binary data from request
|
||||
/// async fn index(mut body: web::Payload) -> Result<HttpResponse, Error>
|
||||
/// async fn index(mut body: web::types::Payload) -> Result<HttpResponse, http::Error>
|
||||
/// {
|
||||
/// let mut bytes = web::BytesMut::new();
|
||||
/// let mut bytes = BytesMut::new();
|
||||
/// while let Some(item) = body.next().await {
|
||||
/// bytes.extend_from_slice(&item?);
|
||||
/// }
|
||||
|
@ -68,13 +70,15 @@ impl Stream for Payload {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::BytesMut;
|
||||
/// use futures::{Future, Stream, StreamExt};
|
||||
/// use actix_web::{web, error, App, Error, HttpResponse};
|
||||
/// use ntex::http;
|
||||
/// use ntex::web::{self, App, HttpResponse};
|
||||
///
|
||||
/// /// extract binary data from request
|
||||
/// async fn index(mut body: web::Payload) -> Result<HttpResponse, Error>
|
||||
/// async fn index(mut body: web::types::Payload) -> Result<HttpResponse, http::Error>
|
||||
/// {
|
||||
/// let mut bytes = web::BytesMut::new();
|
||||
/// let mut bytes = BytesMut::new();
|
||||
/// while let Some(item) = body.next().await {
|
||||
/// bytes.extend_from_slice(&item?);
|
||||
/// }
|
||||
|
@ -115,7 +119,7 @@ impl FromRequest for Payload {
|
|||
///
|
||||
/// ```rust
|
||||
/// use bytes::Bytes;
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// /// extract binary data from request
|
||||
/// async fn index(body: Bytes) -> String {
|
||||
|
@ -123,7 +127,7 @@ impl FromRequest for Payload {
|
|||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::get().to(index))
|
||||
/// );
|
||||
|
@ -170,7 +174,7 @@ impl FromRequest for Bytes {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, FromRequest};
|
||||
/// use ntex::web::{self, App, FromRequest};
|
||||
///
|
||||
/// /// extract text data from request
|
||||
/// async fn index(text: String) -> String {
|
||||
|
@ -309,7 +313,7 @@ pub struct HttpMessageBody {
|
|||
limit: usize,
|
||||
length: Option<usize>,
|
||||
#[cfg(feature = "compress")]
|
||||
stream: Option<crate::http::encoding::Decompress<crate::http::Payload>>,
|
||||
stream: Option<crate::http::encoding::Decoder<crate::http::Payload>>,
|
||||
#[cfg(not(feature = "compress"))]
|
||||
stream: Option<crate::http::Payload>,
|
||||
err: Option<PayloadError>,
|
||||
|
@ -336,7 +340,7 @@ impl HttpMessageBody {
|
|||
}
|
||||
|
||||
#[cfg(feature = "compress")]
|
||||
let stream = Some(crate::http::encoding::Decompress::from_headers(
|
||||
let stream = Some(crate::http::encoding::Decoder::from_headers(
|
||||
payload.take(),
|
||||
req.headers(),
|
||||
));
|
||||
|
@ -416,7 +420,7 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::http::header;
|
||||
use crate::test::TestRequest;
|
||||
use crate::web::test::TestRequest;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_payload_config() {
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::web::request::HttpRequest;
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Debug, Deserialize)]
|
||||
|
@ -41,12 +41,12 @@ use crate::web::request::HttpRequest;
|
|||
/// // Use `Query` extractor for query information (and destructure it within the signature).
|
||||
/// // This handler gets called only if the request's query string contains a `username` field.
|
||||
/// // The correct request for this handler would be `/index.html?id=64&response_type=Code"`.
|
||||
/// async fn index(web::Query(info): web::Query<AuthRequest>) -> String {
|
||||
/// async fn index(web::types::Query(info): web::types::Query<AuthRequest>) -> String {
|
||||
/// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/index.html").route(web::get().to(index))); // <- use `Query` extractor
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -101,7 +101,7 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App};
|
||||
/// use ntex::web;
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Debug, Deserialize)]
|
||||
|
@ -119,12 +119,12 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
|
|||
/// // Use `Query` extractor for query information.
|
||||
/// // This handler get called only if request's query contains `username` field
|
||||
/// // The correct request for this handler would be `/index.html?id=64&response_type=Code"`
|
||||
/// async fn index(info: web::Query<AuthRequest>) -> String {
|
||||
/// async fn index(info: web::types::Query<AuthRequest>) -> String {
|
||||
/// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/index.html")
|
||||
/// .route(web::get().to(index))); // <- use `Query` extractor
|
||||
/// }
|
||||
|
@ -171,7 +171,8 @@ where
|
|||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{error, web, App, FromRequest, HttpResponse};
|
||||
/// use ntex::http::error;
|
||||
/// use ntex::web::{self, App, FromRequest, HttpResponse};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -180,7 +181,7 @@ where
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's querystring
|
||||
/// async fn index(info: web::Query<Info>) -> String {
|
||||
/// async fn index(info: web::types::Query<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
@ -188,7 +189,7 @@ where
|
|||
/// let app = App::new().service(
|
||||
/// web::resource("/index.html").app_data(
|
||||
/// // change query extractor configuration
|
||||
/// web::Query::<Info>::configure(|cfg| {
|
||||
/// web::types::Query::<Info>::configure(|cfg| {
|
||||
/// cfg.error_handler(|err, req| { // <- create custom error response
|
||||
/// error::InternalError::from_response(
|
||||
/// err, HttpResponse::Conflict().finish()).into()
|
||||
|
@ -223,14 +224,14 @@ impl Default for QueryConfig {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_http::http::StatusCode;
|
||||
use derive_more::Display;
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use super::*;
|
||||
use crate::error::InternalError;
|
||||
use crate::test::TestRequest;
|
||||
use crate::HttpResponse;
|
||||
use crate::http::error::InternalError;
|
||||
use crate::http::StatusCode;
|
||||
use crate::web::test::TestRequest;
|
||||
use crate::web::HttpResponse;
|
||||
|
||||
#[derive(Deserialize, Debug, Display)]
|
||||
struct Id {
|
||||
|
@ -274,7 +275,7 @@ mod tests {
|
|||
#[actix_rt::test]
|
||||
async fn test_custom_error_responder() {
|
||||
let req = TestRequest::with_uri("/name/user1/")
|
||||
.app_data(QueryConfig::default().error_handler(|e, _| {
|
||||
.data(QueryConfig::default().error_handler(|e, _| {
|
||||
let resp = HttpResponse::UnprocessableEntity().finish();
|
||||
InternalError::from_response(e, resp).into()
|
||||
}))
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
//! Essentials helper functions and types for application registration.
|
||||
use std::fmt;
|
||||
use std::future::Future;
|
||||
|
||||
use actix_router::IntoPattern;
|
||||
use actix_service::{IntoServiceFactory, Service, ServiceFactory};
|
||||
|
||||
use crate::http::{error::BlockingError, Method};
|
||||
use crate::http::body::MessageBody;
|
||||
use crate::http::error::{BlockingError, Error};
|
||||
use crate::http::{Method, Request, Response};
|
||||
|
||||
use super::config::AppConfig;
|
||||
use super::extract::FromRequest;
|
||||
use super::handler::Factory;
|
||||
use super::resource::Resource;
|
||||
use super::responder::Responder;
|
||||
use super::route::Route;
|
||||
use super::scope::Scope;
|
||||
use super::server::HttpServer;
|
||||
use super::service::WebService;
|
||||
|
||||
/// Create resource for a specific path.
|
||||
|
@ -34,13 +40,12 @@ use super::service::WebService;
|
|||
/// the exposed `Params` object:
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/users/{userid}/{friend}")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// .route(web::get().to(|| web::HttpResponse::Ok()))
|
||||
/// .route(web::head().to(|| web::HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn resource<T: IntoPattern>(path: T) -> Resource {
|
||||
|
@ -53,13 +58,13 @@ pub fn resource<T: IntoPattern>(path: T) -> Resource {
|
|||
/// Scope path can contain variable path segments as resources.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::scope("/{project_id}")
|
||||
/// .service(web::resource("/path1").to(|| HttpResponse::Ok()))
|
||||
/// .service(web::resource("/path2").to(|| HttpResponse::Ok()))
|
||||
/// .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// .service(web::resource("/path1").to(|| web::HttpResponse::Ok()))
|
||||
/// .service(web::resource("/path2").to(|| web::HttpResponse::Ok()))
|
||||
/// .service(web::resource("/path3").to(|| web::HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -80,11 +85,11 @@ pub fn route() -> Route {
|
|||
/// Create *route* with `GET` method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::get().to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -98,11 +103,11 @@ pub fn get() -> Route {
|
|||
/// Create *route* with `POST` method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::post().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::post().to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -116,11 +121,11 @@ pub fn post() -> Route {
|
|||
/// Create *route* with `PUT` method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::put().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::put().to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -134,11 +139,11 @@ pub fn put() -> Route {
|
|||
/// Create *route* with `PATCH` method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::patch().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::patch().to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -152,11 +157,11 @@ pub fn patch() -> Route {
|
|||
/// Create *route* with `DELETE` method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::delete().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::delete().to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -170,11 +175,11 @@ pub fn delete() -> Route {
|
|||
/// Create *route* with `HEAD` method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::head().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::head().to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -188,11 +193,11 @@ pub fn head() -> Route {
|
|||
/// Create *route* and add method guard.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, http, App, HttpResponse};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// let app = App::new().service(
|
||||
/// let app = web::App::new().service(
|
||||
/// web::resource("/{project_id}")
|
||||
/// .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
|
||||
/// .route(web::method(http::Method::GET).to(|| web::HttpResponse::Ok()))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
|
@ -206,15 +211,14 @@ pub fn method(method: Method) -> Route {
|
|||
/// Create a new route and add handler.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// async fn index() -> impl Responder {
|
||||
/// HttpResponse::Ok()
|
||||
/// async fn index() -> impl web::Responder {
|
||||
/// web::HttpResponse::Ok()
|
||||
/// }
|
||||
///
|
||||
/// App::new().service(
|
||||
/// web::resource("/").route(
|
||||
/// web::to(index))
|
||||
/// web::App::new().service(
|
||||
/// web::resource("/").route(web::to(index))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn to<F, I, R, U>(handler: F) -> Route
|
||||
|
@ -230,7 +234,8 @@ where
|
|||
/// Create raw service for a specific path.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{dev, web, guard, App, Error, HttpResponse};
|
||||
/// use ntex::http::Error;
|
||||
/// use ntex::web::{self, dev, guard, App, HttpResponse};
|
||||
///
|
||||
/// async fn my_service(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
|
||||
/// Ok(req.into_response(HttpResponse::Ok().finish()))
|
||||
|
@ -256,3 +261,32 @@ where
|
|||
{
|
||||
actix_threadpool::run(f).await
|
||||
}
|
||||
|
||||
/// Create new http server with application factory.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use ntex::web;
|
||||
///
|
||||
/// #[ntex::main]
|
||||
/// async fn main() -> std::io::Result<()> {
|
||||
/// web::server(
|
||||
/// || web::App::new()
|
||||
/// .service(web::resource("/").to(|| web::HttpResponse::Ok())))
|
||||
/// .bind("127.0.0.1:59090")?
|
||||
/// .run()
|
||||
/// .await
|
||||
/// }
|
||||
/// ```
|
||||
pub fn server<F, I, S, B>(factory: F) -> HttpServer<F, I, S, B>
|
||||
where
|
||||
F: Fn() -> I + Send + Clone + 'static,
|
||||
I: IntoServiceFactory<S>,
|
||||
S: ServiceFactory<Config = AppConfig, Request = Request>,
|
||||
S::Error: Into<Error> + 'static,
|
||||
S::InitError: fmt::Debug,
|
||||
S::Response: Into<Response<B>> + 'static,
|
||||
<S::Service as Service>::Future: 'static,
|
||||
B: MessageBody + 'static,
|
||||
{
|
||||
HttpServer::new(factory)
|
||||
}
|
|
@ -6,22 +6,20 @@ use std::time::Duration;
|
|||
|
||||
use brotli2::write::BrotliEncoder;
|
||||
use bytes::Bytes;
|
||||
use coo_kie::Cookie;
|
||||
use flate2::read::GzDecoder;
|
||||
use flate2::write::GzEncoder;
|
||||
use flate2::Compression;
|
||||
use futures::future::ok;
|
||||
use rand::Rng;
|
||||
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{map_config, pipeline_factory};
|
||||
use actix_web::dev::{AppConfig, BodyEncoding};
|
||||
use actix_web::http::Cookie;
|
||||
use actix_web::middleware::Compress;
|
||||
use actix_web::{
|
||||
http::header, test, web, App, Error, HttpMessage, HttpRequest, HttpResponse,
|
||||
};
|
||||
use awc::error::SendRequestError;
|
||||
use ntex::http::client::{error::SendRequestError, Client, Connector};
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::{header, Error, HttpMessage, HttpService};
|
||||
use ntex::service::{map_config, pipeline_factory};
|
||||
use ntex::web::dev::{AppConfig, BodyEncoding};
|
||||
use ntex::web::middleware::Compress;
|
||||
use ntex::web::{self, test, App, HttpRequest, HttpResponse};
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World \
|
||||
|
@ -45,7 +43,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
|||
Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World";
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_simple() {
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
|
@ -72,11 +70,12 @@ async fn test_simple() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_json() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(
|
||||
web::resource("/").route(web::to(|_: web::Json<String>| HttpResponse::Ok())),
|
||||
web::resource("/")
|
||||
.route(web::to(|_: web::types::Json<String>| HttpResponse::Ok())),
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -88,11 +87,11 @@ async fn test_json() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_form() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(
|
||||
|_: web::Form<HashMap<String, String>>| HttpResponse::Ok(),
|
||||
|_: web::types::Form<HashMap<String, String>>| HttpResponse::Ok(),
|
||||
)))
|
||||
});
|
||||
|
||||
|
@ -104,7 +103,7 @@ async fn test_form() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_timeout() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| async {
|
||||
|
@ -113,14 +112,14 @@ async fn test_timeout() {
|
|||
})))
|
||||
});
|
||||
|
||||
let connector = awc::Connector::new()
|
||||
let connector = Connector::new()
|
||||
.connector(actix_connect::new_connector(
|
||||
actix_connect::start_default_resolver(),
|
||||
))
|
||||
.timeout(Duration::from_secs(15))
|
||||
.finish();
|
||||
|
||||
let client = awc::Client::build()
|
||||
let client = Client::build()
|
||||
.connector(connector)
|
||||
.timeout(Duration::from_millis(50))
|
||||
.finish();
|
||||
|
@ -132,7 +131,7 @@ async fn test_timeout() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_timeout_override() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| async {
|
||||
|
@ -141,7 +140,7 @@ async fn test_timeout_override() {
|
|||
})))
|
||||
});
|
||||
|
||||
let client = awc::Client::build()
|
||||
let client = Client::build()
|
||||
.timeout(Duration::from_millis(50000))
|
||||
.finish();
|
||||
let request = client
|
||||
|
@ -154,7 +153,7 @@ async fn test_timeout_override() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_reuse() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
@ -175,7 +174,7 @@ async fn test_connection_reuse() {
|
|||
)
|
||||
});
|
||||
|
||||
let client = awc::Client::default();
|
||||
let client = Client::default();
|
||||
|
||||
// req 1
|
||||
let request = client.get(srv.url("/")).send();
|
||||
|
@ -191,7 +190,7 @@ async fn test_connection_reuse() {
|
|||
assert_eq!(num.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_force_close() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
@ -212,7 +211,7 @@ async fn test_connection_force_close() {
|
|||
)
|
||||
});
|
||||
|
||||
let client = awc::Client::default();
|
||||
let client = Client::default();
|
||||
|
||||
// req 1
|
||||
let request = client.get(srv.url("/")).force_close().send();
|
||||
|
@ -228,7 +227,7 @@ async fn test_connection_force_close() {
|
|||
assert_eq!(num.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_server_close() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
@ -251,7 +250,7 @@ async fn test_connection_server_close() {
|
|||
)
|
||||
});
|
||||
|
||||
let client = awc::Client::default();
|
||||
let client = Client::default();
|
||||
|
||||
// req 1
|
||||
let request = client.get(srv.url("/")).send();
|
||||
|
@ -267,7 +266,7 @@ async fn test_connection_server_close() {
|
|||
assert_eq!(num.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_wait_queue() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
@ -289,8 +288,8 @@ async fn test_connection_wait_queue() {
|
|||
)
|
||||
});
|
||||
|
||||
let client = awc::Client::build()
|
||||
.connector(awc::Connector::new().limit(1).finish())
|
||||
let client = Client::build()
|
||||
.connector(Connector::new().limit(1).finish())
|
||||
.finish();
|
||||
|
||||
// req 1
|
||||
|
@ -314,7 +313,7 @@ async fn test_connection_wait_queue() {
|
|||
assert_eq!(num.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_wait_queue_force_close() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
@ -337,8 +336,8 @@ async fn test_connection_wait_queue_force_close() {
|
|||
)
|
||||
});
|
||||
|
||||
let client = awc::Client::build()
|
||||
.connector(awc::Connector::new().limit(1).finish())
|
||||
let client = Client::build()
|
||||
.connector(Connector::new().limit(1).finish())
|
||||
.finish();
|
||||
|
||||
// req 1
|
||||
|
@ -362,7 +361,7 @@ async fn test_connection_wait_queue_force_close() {
|
|||
assert_eq!(num.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_with_query_parameter() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").to(|req: HttpRequest| {
|
||||
|
@ -374,15 +373,11 @@ async fn test_with_query_parameter() {
|
|||
}))
|
||||
});
|
||||
|
||||
let res = awc::Client::new()
|
||||
.get(srv.url("/?qp=5"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
let res = Client::new().get(srv.url("/?qp=5")).send().await.unwrap();
|
||||
assert!(res.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_no_decompress() {
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
|
@ -394,7 +389,7 @@ async fn test_no_decompress() {
|
|||
})))
|
||||
});
|
||||
|
||||
let mut res = awc::Client::new()
|
||||
let mut res = Client::new()
|
||||
.get(srv.url("/"))
|
||||
.no_decompress()
|
||||
.send()
|
||||
|
@ -411,7 +406,7 @@ async fn test_no_decompress() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
|
||||
// POST
|
||||
let mut res = awc::Client::new()
|
||||
let mut res = Client::new()
|
||||
.post(srv.url("/"))
|
||||
.no_decompress()
|
||||
.send()
|
||||
|
@ -426,7 +421,7 @@ async fn test_no_decompress() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_client_gzip_encoding() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| {
|
||||
|
@ -449,7 +444,7 @@ async fn test_client_gzip_encoding() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_client_gzip_encoding_large() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| {
|
||||
|
@ -472,7 +467,7 @@ async fn test_client_gzip_encoding_large() {
|
|||
assert_eq!(bytes, Bytes::from(STR.repeat(10)));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_client_gzip_encoding_large_random() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
|
@ -499,7 +494,7 @@ async fn test_client_gzip_encoding_large_random() {
|
|||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_client_brotli_encoding() {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|data: Bytes| {
|
||||
|
@ -521,7 +516,7 @@ async fn test_client_brotli_encoding() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_client_brotli_encoding_large_random() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
|
@ -549,7 +544,7 @@ async fn test_client_brotli_encoding_large_random() {
|
|||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
// #[actix_rt::test]
|
||||
// #[ntex::test]
|
||||
// async fn test_client_deflate_encoding() {
|
||||
// let srv = test::TestServer::start(|app| {
|
||||
// app.handler(|req: &HttpRequest| {
|
||||
|
@ -577,7 +572,7 @@ async fn test_client_brotli_encoding_large_random() {
|
|||
// assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
// }
|
||||
|
||||
// #[actix_rt::test]
|
||||
// #[ntex::test]
|
||||
// async fn test_client_deflate_encoding_large_random() {
|
||||
// let data = rand::thread_rng()
|
||||
// .sample_iter(&rand::distributions::Alphanumeric)
|
||||
|
@ -610,7 +605,7 @@ async fn test_client_brotli_encoding_large_random() {
|
|||
// assert_eq!(bytes, Bytes::from(data));
|
||||
// }
|
||||
|
||||
// #[actix_rt::test]
|
||||
// #[ntex::test]
|
||||
// async fn test_client_streaming_explicit() {
|
||||
// let srv = test::TestServer::start(|app| {
|
||||
// app.handler(|req: &HttpRequest| {
|
||||
|
@ -637,7 +632,7 @@ async fn test_client_brotli_encoding_large_random() {
|
|||
// assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
// }
|
||||
|
||||
// #[actix_rt::test]
|
||||
// #[ntex::test]
|
||||
// async fn test_body_streaming_implicit() {
|
||||
// let srv = test::TestServer::start(|app| {
|
||||
// app.handler(|_| {
|
||||
|
@ -657,7 +652,7 @@ async fn test_client_brotli_encoding_large_random() {
|
|||
// assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
// }
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_client_cookie_handling() {
|
||||
use std::io::{Error as IoError, ErrorKind};
|
||||
|
||||
|
@ -726,7 +721,7 @@ async fn test_client_cookie_handling() {
|
|||
assert_eq!(c2, cookie2);
|
||||
}
|
||||
|
||||
// #[actix_rt::test]
|
||||
// #[ntex::test]
|
||||
// fn client_read_until_eof() {
|
||||
// let addr = test::TestServer::unused_addr();
|
||||
|
||||
|
@ -756,7 +751,7 @@ async fn test_client_cookie_handling() {
|
|||
// assert_eq!(bytes, Bytes::from_static(b"welcome!"));
|
||||
// }
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn client_basic_auth() {
|
||||
let srv = test::start(|| {
|
||||
App::new().route(
|
||||
|
@ -784,7 +779,7 @@ async fn client_basic_auth() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn client_bearer_auth() {
|
||||
let srv = test::start(|| {
|
||||
App::new().route(
|
|
@ -2,22 +2,23 @@
|
|||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{map_config, pipeline_factory, ServiceFactory};
|
||||
use actix_web::http::Version;
|
||||
use actix_web::{dev::AppConfig, web, App, HttpResponse};
|
||||
use futures::future::ok;
|
||||
use open_ssl::ssl::{SslAcceptor, SslConnector, SslFiletype, SslMethod, SslVerifyMode};
|
||||
|
||||
use ntex::http::client::{Client, Connector};
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::{HttpService, Version};
|
||||
use ntex::service::{map_config, pipeline_factory, ServiceFactory};
|
||||
use ntex::web::{self, dev::AppConfig, App, HttpResponse};
|
||||
|
||||
fn ssl_acceptor() -> SslAcceptor {
|
||||
// load ssl keys
|
||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
|
||||
builder
|
||||
.set_private_key_file("../tests/key.pem", SslFiletype::PEM)
|
||||
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
|
||||
.unwrap();
|
||||
builder
|
||||
.set_certificate_chain_file("../tests/cert.pem")
|
||||
.set_certificate_chain_file("./tests/cert.pem")
|
||||
.unwrap();
|
||||
builder.set_alpn_select_callback(|_, protos| {
|
||||
const H2: &[u8] = b"\x02h2";
|
||||
|
@ -31,7 +32,7 @@ fn ssl_acceptor() -> SslAcceptor {
|
|||
builder.build()
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_reuse_h2() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
@ -62,8 +63,8 @@ async fn test_connection_reuse_h2() {
|
|||
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
||||
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
||||
|
||||
let client = awc::Client::build()
|
||||
.connector(awc::Connector::new().ssl(builder.build()).finish())
|
||||
let client = Client::build()
|
||||
.connector(Connector::new().ssl(builder.build()).finish())
|
||||
.finish();
|
||||
|
||||
// req 1
|
|
@ -2,24 +2,25 @@
|
|||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{map_config, pipeline_factory, ServiceFactory};
|
||||
use actix_web::http::Version;
|
||||
use actix_web::{dev::AppConfig, web, App, HttpResponse};
|
||||
use futures::future::ok;
|
||||
use open_ssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslVerifyMode};
|
||||
use rust_tls::ClientConfig;
|
||||
|
||||
use ntex::http::client::{Client, Connector};
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::HttpService;
|
||||
use ntex::service::{map_config, pipeline_factory, ServiceFactory};
|
||||
use ntex::web::{self, dev::AppConfig, App, HttpResponse};
|
||||
|
||||
fn ssl_acceptor() -> SslAcceptor {
|
||||
// load ssl keys
|
||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
|
||||
builder.set_verify_callback(SslVerifyMode::NONE, |_, _| true);
|
||||
builder
|
||||
.set_private_key_file("../tests/key.pem", SslFiletype::PEM)
|
||||
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
|
||||
.unwrap();
|
||||
builder
|
||||
.set_certificate_chain_file("../tests/cert.pem")
|
||||
.set_certificate_chain_file("./tests/cert.pem")
|
||||
.unwrap();
|
||||
builder.set_alpn_select_callback(|_, protos| {
|
||||
const H2: &[u8] = b"\x02h2";
|
||||
|
@ -49,8 +50,8 @@ mod danger {
|
|||
}
|
||||
}
|
||||
|
||||
// #[actix_rt::test]
|
||||
async fn _test_connection_reuse_h2() {
|
||||
#[ntex::test]
|
||||
async fn test_connection_reuse_h2() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
|
@ -81,21 +82,22 @@ async fn _test_connection_reuse_h2() {
|
|||
.dangerous()
|
||||
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification {}));
|
||||
|
||||
let client = awc::Client::build()
|
||||
.connector(awc::Connector::new().rustls(Arc::new(config)).finish())
|
||||
let client = Client::build()
|
||||
.connector(Connector::new().rustls(Arc::new(config)).finish())
|
||||
.finish();
|
||||
|
||||
// req 1
|
||||
let request = client.get(srv.surl("/")).send();
|
||||
let response = request.await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
let _response = client.get(srv.surl("/")).send().await;
|
||||
|
||||
// let response = request.await.unwrap();
|
||||
// assert!(response.status().is_success());
|
||||
|
||||
// req 2
|
||||
let req = client.post(srv.surl("/"));
|
||||
let response = req.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
assert_eq!(response.version(), Version::HTTP_2);
|
||||
let _response = client.post(srv.surl("/")).send().await;
|
||||
// let response = req.send().await.unwrap();
|
||||
//assert!(response.status().is_success());
|
||||
//assert_eq!(response.version(), Version::HTTP_2);
|
||||
|
||||
// one connection
|
||||
assert_eq!(num.load(Ordering::Relaxed), 1);
|
||||
// assert_eq!(num.load(Ordering::Relaxed), 1);
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
use std::io;
|
||||
|
||||
use actix_codec::Framed;
|
||||
use actix_http::{body::BodySize, h1, ws, Error, HttpService, Request, Response};
|
||||
use actix_http_test::test_server;
|
||||
use bytes::Bytes;
|
||||
use futures::future::ok;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::ws::handshake_response;
|
||||
use ntex::http::{body::BodySize, h1, Error, HttpService, Request, Response};
|
||||
use ntex::ws;
|
||||
|
||||
async fn ws_service(req: ws::Frame) -> Result<ws::Message, io::Error> {
|
||||
match req {
|
||||
ws::Frame::Ping(msg) => Ok(ws::Message::Pong(msg)),
|
||||
|
@ -19,13 +22,13 @@ async fn ws_service(req: ws::Frame) -> Result<ws::Message, io::Error> {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_simple() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.upgrade(|(req, mut framed): (Request, Framed<_, _>)| {
|
||||
async move {
|
||||
let res = ws::handshake_response(req.head()).finish();
|
||||
let res = handshake_response(req.head()).finish();
|
||||
// send handshake response
|
||||
framed
|
||||
.send(h1::Message::Item((res.drop_body(), BodySize::None)))
|
|
@ -2,8 +2,8 @@ use actix_service::ServiceFactory;
|
|||
use bytes::Bytes;
|
||||
use futures::future::{self, ok};
|
||||
|
||||
use actix_http::{http, HttpService, Request, Response};
|
||||
use actix_http_test::test_server;
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::{HttpService, Method, Request, Response};
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World \
|
||||
|
@ -27,7 +27,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
|||
Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World";
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_v2() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -54,7 +54,7 @@ async fn test_h1_v2() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_connection_close() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -67,7 +67,7 @@ async fn test_connection_close() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_with_query_parameter() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -82,7 +82,7 @@ async fn test_with_query_parameter() {
|
|||
.map(|_| ())
|
||||
});
|
||||
|
||||
let request = srv.request(http::Method::GET, srv.url("/?qp=5"));
|
||||
let request = srv.request(Method::GET, srv.url("/?qp=5"));
|
||||
let response = request.send().await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
#![cfg(feature = "openssl")]
|
||||
use std::io;
|
||||
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_service, ServiceFactory};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::future::{err, ok, ready};
|
||||
use futures::stream::{once, Stream, StreamExt};
|
||||
use open_ssl::ssl::{AlpnError, SslAcceptor, SslFiletype, SslMethod};
|
||||
|
||||
use actix_http::error::{ErrorBadRequest, PayloadError};
|
||||
use actix_http::http::header::{self, HeaderName, HeaderValue};
|
||||
use actix_http::http::{Method, StatusCode, Version};
|
||||
use actix_http::httpmessage::HttpMessage;
|
||||
use actix_http::{body, Error, HttpService, Request, Response};
|
||||
use ntex::http::error::{ErrorBadRequest, PayloadError};
|
||||
use ntex::http::header::{self, HeaderName, HeaderValue};
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::{
|
||||
body, Error, HttpMessage, HttpService, Method, Request, Response, StatusCode,
|
||||
Version,
|
||||
};
|
||||
use ntex::service::{fn_service, ServiceFactory};
|
||||
|
||||
async fn load_body<S>(stream: S) -> Result<BytesMut, PayloadError>
|
||||
where
|
||||
|
@ -37,10 +37,10 @@ fn ssl_acceptor() -> SslAcceptor {
|
|||
// load ssl keys
|
||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
|
||||
builder
|
||||
.set_private_key_file("../tests/key.pem", SslFiletype::PEM)
|
||||
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
|
||||
.unwrap();
|
||||
builder
|
||||
.set_certificate_chain_file("../tests/cert.pem")
|
||||
.set_certificate_chain_file("./tests/cert.pem")
|
||||
.unwrap();
|
||||
builder.set_alpn_select_callback(|_, protos| {
|
||||
const H2: &[u8] = b"\x02h2";
|
||||
|
@ -60,7 +60,7 @@ fn ssl_acceptor() -> SslAcceptor {
|
|||
builder.build()
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2() -> io::Result<()> {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -74,7 +74,7 @@ async fn test_h2() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_1() -> io::Result<()> {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -92,7 +92,7 @@ async fn test_h2_1() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body() -> io::Result<()> {
|
||||
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
||||
let mut srv = test_server(move || {
|
||||
|
@ -113,7 +113,7 @@ async fn test_h2_body() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_content_length() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -161,7 +161,7 @@ async fn test_h2_content_length() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_headers() {
|
||||
let data = STR.repeat(10);
|
||||
let data2 = data.clone();
|
||||
|
@ -224,7 +224,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
|||
Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World";
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body2() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -241,7 +241,7 @@ async fn test_h2_body2() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_head_empty() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -264,7 +264,7 @@ async fn test_h2_head_empty() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_head_binary() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -288,7 +288,7 @@ async fn test_h2_head_binary() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_head_binary2() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -306,7 +306,7 @@ async fn test_h2_head_binary2() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body_length() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -328,7 +328,7 @@ async fn test_h2_body_length() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body_chunked_explicit() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -355,7 +355,7 @@ async fn test_h2_body_chunked_explicit() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_response_http_error_handling() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -379,7 +379,7 @@ async fn test_h2_response_http_error_handling() {
|
|||
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_service_error() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -396,7 +396,7 @@ async fn test_h2_service_error() {
|
|||
assert_eq!(bytes, Bytes::from_static(b"error"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_on_connect() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
|
@ -1,10 +1,6 @@
|
|||
#![cfg(feature = "rustls")]
|
||||
use actix_http::error::PayloadError;
|
||||
use actix_http::http::header::{self, HeaderName, HeaderValue};
|
||||
use actix_http::http::{Method, StatusCode, Version};
|
||||
use actix_http::{body, error, Error, HttpService, Request, Response};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_factory_with_config, fn_service};
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufReader};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::future::{self, err, ok};
|
||||
|
@ -14,8 +10,11 @@ use rust_tls::{
|
|||
NoClientAuth, ServerConfig as RustlsServerConfig,
|
||||
};
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufReader};
|
||||
use ntex::http::error::{self, Error, PayloadError};
|
||||
use ntex::http::header::{self, HeaderName, HeaderValue};
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::{body, HttpService, Method, Request, Response, StatusCode, Version};
|
||||
use ntex::service::{fn_factory_with_config, fn_service};
|
||||
|
||||
async fn load_body<S>(mut stream: S) -> Result<BytesMut, PayloadError>
|
||||
where
|
||||
|
@ -31,15 +30,15 @@ where
|
|||
fn ssl_acceptor() -> RustlsServerConfig {
|
||||
// load ssl keys
|
||||
let mut config = RustlsServerConfig::new(NoClientAuth::new());
|
||||
let cert_file = &mut BufReader::new(File::open("../tests/cert.pem").unwrap());
|
||||
let key_file = &mut BufReader::new(File::open("../tests/key.pem").unwrap());
|
||||
let cert_file = &mut BufReader::new(File::open("./tests/cert.pem").unwrap());
|
||||
let key_file = &mut BufReader::new(File::open("./tests/key.pem").unwrap());
|
||||
let cert_chain = certs(cert_file).unwrap();
|
||||
let mut keys = pkcs8_private_keys(key_file).unwrap();
|
||||
config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
|
||||
config
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1() -> io::Result<()> {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -52,7 +51,7 @@ async fn test_h1() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2() -> io::Result<()> {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -65,7 +64,7 @@ async fn test_h2() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_1() -> io::Result<()> {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -82,7 +81,7 @@ async fn test_h1_1() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_1() -> io::Result<()> {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -99,7 +98,7 @@ async fn test_h2_1() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body1() -> io::Result<()> {
|
||||
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
||||
let mut srv = test_server(move || {
|
||||
|
@ -119,7 +118,7 @@ async fn test_h2_body1() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_content_length() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -165,7 +164,7 @@ async fn test_h2_content_length() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_headers() {
|
||||
let data = STR.repeat(10);
|
||||
let data2 = data.clone();
|
||||
|
@ -227,7 +226,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
|||
Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World";
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body2() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -243,7 +242,7 @@ async fn test_h2_body2() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_head_empty() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -268,7 +267,7 @@ async fn test_h2_head_empty() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_head_binary() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -294,7 +293,7 @@ async fn test_h2_head_binary() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_head_binary2() {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -314,7 +313,7 @@ async fn test_h2_head_binary2() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body_length() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -335,7 +334,7 @@ async fn test_h2_body_length() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_body_chunked_explicit() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -361,7 +360,7 @@ async fn test_h2_body_chunked_explicit() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_response_http_error_handling() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -386,7 +385,7 @@ async fn test_h2_response_http_error_handling() {
|
|||
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h2_service_error() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
|
@ -402,7 +401,7 @@ async fn test_h2_service_error() {
|
|||
assert_eq!(bytes, Bytes::from_static(b"error"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_service_error() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
|
@ -2,7 +2,6 @@ use std::io::{Read, Write};
|
|||
use std::time::Duration;
|
||||
use std::{net, thread};
|
||||
|
||||
use actix_http_test::test_server;
|
||||
use actix_rt::time::delay_for;
|
||||
use actix_service::fn_service;
|
||||
use bytes::Bytes;
|
||||
|
@ -10,12 +9,12 @@ use futures::future::{self, err, ok, ready, FutureExt};
|
|||
use futures::stream::{once, StreamExt};
|
||||
use regex::Regex;
|
||||
|
||||
use actix_http::httpmessage::HttpMessage;
|
||||
use actix_http::{
|
||||
body, error, http, http::header, Error, HttpService, KeepAlive, Request, Response,
|
||||
use ntex::http::test::server as test_server;
|
||||
use ntex::http::{
|
||||
body, error, header, Error, HttpMessage, HttpService, KeepAlive, Request, Response,
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -33,7 +32,7 @@ async fn test_h1() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_2() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -52,7 +51,7 @@ async fn test_h1_2() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_expect_continue() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -80,7 +79,7 @@ async fn test_expect_continue() {
|
|||
assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_expect_continue_h1() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -110,7 +109,7 @@ async fn test_expect_continue_h1() {
|
|||
assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_chunked_payload() {
|
||||
let chunk_sizes = vec![32768, 32, 32768];
|
||||
let total_size: usize = chunk_sizes.iter().sum();
|
||||
|
@ -165,7 +164,7 @@ async fn test_chunked_payload() {
|
|||
assert_eq!(returned_size, total_size);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_slow_request() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -181,7 +180,7 @@ async fn test_slow_request() {
|
|||
assert!(data.starts_with("HTTP/1.1 408 Request Timeout"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http1_malformed_request() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -196,7 +195,7 @@ async fn test_http1_malformed_request() {
|
|||
assert!(data.starts_with("HTTP/1.1 400 Bad Request"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http1_keepalive() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -216,7 +215,7 @@ async fn test_http1_keepalive() {
|
|||
assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http1_keepalive_timeout() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -237,7 +236,7 @@ async fn test_http1_keepalive_timeout() {
|
|||
assert_eq!(res, 0);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http1_keepalive_close() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -257,7 +256,7 @@ async fn test_http1_keepalive_close() {
|
|||
assert_eq!(res, 0);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http10_keepalive_default_close() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -276,7 +275,7 @@ async fn test_http10_keepalive_default_close() {
|
|||
assert_eq!(res, 0);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http10_keepalive() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -302,7 +301,7 @@ async fn test_http10_keepalive() {
|
|||
assert_eq!(res, 0);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_http1_keepalive_disabled() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -322,9 +321,9 @@ async fn test_http1_keepalive_disabled() {
|
|||
assert_eq!(res, 0);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_content_length() {
|
||||
use actix_http::http::{
|
||||
use ntex::http::{
|
||||
header::{HeaderName, HeaderValue},
|
||||
StatusCode,
|
||||
};
|
||||
|
@ -368,7 +367,7 @@ async fn test_content_length() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_headers() {
|
||||
let data = STR.repeat(10);
|
||||
let data2 = data.clone();
|
||||
|
@ -429,7 +428,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
|||
Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World";
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_body() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -445,7 +444,7 @@ async fn test_h1_body() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_head_empty() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -469,7 +468,7 @@ async fn test_h1_head_empty() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_head_binary() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -495,7 +494,7 @@ async fn test_h1_head_binary() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_head_binary2() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -515,7 +514,7 @@ async fn test_h1_head_binary2() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_body_length() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -536,7 +535,7 @@ async fn test_h1_body_length() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_body_chunked_explicit() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -570,7 +569,7 @@ async fn test_h1_body_chunked_explicit() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_body_chunked_implicit() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -598,7 +597,7 @@ async fn test_h1_body_chunked_implicit() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_response_http_error_handling() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -621,7 +620,7 @@ async fn test_h1_response_http_error_handling() {
|
|||
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_service_error() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
|
@ -637,7 +636,7 @@ async fn test_h1_service_error() {
|
|||
assert_eq!(bytes, Bytes::from_static(b"error"));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_h1_on_connect() {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
|
@ -4,8 +4,6 @@ use std::pin::Pin;
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_http::{body, h1, ws, Error, HttpService, Request, Response};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_factory, Service};
|
||||
use actix_utils::framed::Dispatcher;
|
||||
use bytes::Bytes;
|
||||
|
@ -13,6 +11,10 @@ use futures::future;
|
|||
use futures::task::{Context, Poll};
|
||||
use futures::{Future, SinkExt, StreamExt};
|
||||
|
||||
use ntex::http::ws::handshake;
|
||||
use ntex::http::{body, h1, test, Error, HttpService, Request, Response};
|
||||
use ntex::ws;
|
||||
|
||||
struct WsService<T>(Arc<Mutex<(PhantomData<T>, Cell<bool>)>>);
|
||||
|
||||
impl<T> WsService<T> {
|
||||
|
@ -51,7 +53,7 @@ where
|
|||
|
||||
fn call(&mut self, (req, mut framed): Self::Request) -> Self::Future {
|
||||
let fut = async move {
|
||||
let res = ws::handshake(req.head()).unwrap().message_body(());
|
||||
let res = handshake(req.head()).unwrap().message_body(());
|
||||
|
||||
framed
|
||||
.send((res, body::BodySize::None).into())
|
||||
|
@ -81,10 +83,10 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
|||
Ok(msg)
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_simple() {
|
||||
let ws_service = WsService::new();
|
||||
let mut srv = test_server({
|
||||
let mut srv = test::server({
|
||||
let ws_service = ws_service.clone();
|
||||
move || {
|
||||
let ws_service = ws_service.clone();
|
|
@ -5,7 +5,7 @@ use std::{net, thread, time::Duration};
|
|||
#[cfg(feature = "openssl")]
|
||||
use open_ssl::ssl::SslAcceptorBuilder;
|
||||
|
||||
use actix_web::{web, App, HttpResponse, HttpServer};
|
||||
use ntex::web::{self, App, HttpResponse, HttpServer};
|
||||
|
||||
fn unused_addr() -> net::SocketAddr {
|
||||
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||
|
@ -17,7 +17,7 @@ fn unused_addr() -> net::SocketAddr {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_start() {
|
||||
let addr = unused_addr();
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
@ -87,10 +87,10 @@ fn ssl_acceptor() -> std::io::Result<SslAcceptorBuilder> {
|
|||
Ok(builder)
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
#[cfg(feature = "openssl")]
|
||||
async fn test_start_ssl() {
|
||||
use actix_web::HttpRequest;
|
||||
use ntex::web::HttpRequest;
|
||||
|
||||
let addr = unused_addr();
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
@ -125,9 +125,9 @@ async fn test_start_ssl() {
|
|||
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
||||
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
||||
|
||||
let client = awc::Client::build()
|
||||
let client = ntex::http::client::Client::build()
|
||||
.connector(
|
||||
awc::Connector::new()
|
||||
ntex::http::client::Connector::new()
|
||||
.ssl(builder.build())
|
||||
.timeout(Duration::from_millis(100))
|
||||
.finish(),
|
|
@ -2,10 +2,6 @@ use std::io::{Read, Write};
|
|||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_http::http::header::{
|
||||
ContentEncoding, ACCEPT_ENCODING, CONTENT_ENCODING, CONTENT_LENGTH,
|
||||
TRANSFER_ENCODING,
|
||||
};
|
||||
use brotli2::write::{BrotliDecoder, BrotliEncoder};
|
||||
use bytes::Bytes;
|
||||
use flate2::read::GzDecoder;
|
||||
|
@ -14,9 +10,17 @@ use flate2::Compression;
|
|||
use futures::{ready, Future};
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
|
||||
use actix_web::dev::BodyEncoding;
|
||||
use actix_web::middleware::Compress;
|
||||
use actix_web::{dev, test, web, App, Error, HttpResponse};
|
||||
use ntex::http::body::Body;
|
||||
use ntex::http::error::Error;
|
||||
use ntex::http::header::{
|
||||
ContentEncoding, ACCEPT_ENCODING, CONTENT_ENCODING, CONTENT_LENGTH,
|
||||
TRANSFER_ENCODING,
|
||||
};
|
||||
use ntex::http::{Method, StatusCode};
|
||||
|
||||
use ntex::web::dev::BodyEncoding;
|
||||
use ntex::web::middleware::Compress;
|
||||
use ntex::web::{self, test, App, HttpResponse};
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World \
|
||||
|
@ -76,7 +80,7 @@ impl futures::Stream for TestBody {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body() {
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
|
@ -91,7 +95,7 @@ async fn test_body() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_gzip() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new()
|
||||
|
@ -118,14 +122,15 @@ async fn test_body_gzip() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_gzip2() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new()
|
||||
.wrap(Compress::new(ContentEncoding::Gzip))
|
||||
.service(web::resource("/").route(web::to(|| {
|
||||
HttpResponse::Ok().body(STR).into_body::<dev::Body>()
|
||||
})))
|
||||
.service(
|
||||
web::resource("/")
|
||||
.route(web::to(|| HttpResponse::Ok().body(STR).into_body::<Body>())),
|
||||
)
|
||||
});
|
||||
|
||||
let mut response = srv
|
||||
|
@ -147,7 +152,7 @@ async fn test_body_gzip2() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_encoding_override() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new()
|
||||
|
@ -158,9 +163,8 @@ async fn test_body_encoding_override() {
|
|||
.body(STR)
|
||||
})))
|
||||
.service(web::resource("/raw").route(web::to(|| {
|
||||
let body = actix_web::dev::Body::Bytes(STR.into());
|
||||
let mut response =
|
||||
HttpResponse::with_body(actix_web::http::StatusCode::OK, body);
|
||||
let body = Body::Bytes(STR.into());
|
||||
let mut response = HttpResponse::with_body(StatusCode::OK, body);
|
||||
|
||||
response.encoding(ContentEncoding::Deflate);
|
||||
|
||||
|
@ -189,7 +193,7 @@ async fn test_body_encoding_override() {
|
|||
|
||||
// Raw Response
|
||||
let mut response = srv
|
||||
.request(actix_web::http::Method::GET, srv.url("/raw"))
|
||||
.request(Method::GET, srv.url("/raw"))
|
||||
.no_decompress()
|
||||
.header(ACCEPT_ENCODING, "deflate")
|
||||
.send()
|
||||
|
@ -207,7 +211,7 @@ async fn test_body_encoding_override() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_gzip_large() {
|
||||
let data = STR.repeat(10);
|
||||
let srv_data = data.clone();
|
||||
|
@ -241,7 +245,7 @@ async fn test_body_gzip_large() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_gzip_large_random() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
|
@ -279,7 +283,7 @@ async fn test_body_gzip_large_random() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_chunked_implicit() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new()
|
||||
|
@ -313,7 +317,7 @@ async fn test_body_chunked_implicit() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_br_streaming() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().wrap(Compress::new(ContentEncoding::Br)).service(
|
||||
|
@ -345,7 +349,7 @@ async fn test_body_br_streaming() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_head_binary() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().service(web::resource("/").route(
|
||||
|
@ -366,7 +370,7 @@ async fn test_head_binary() {
|
|||
assert!(bytes.is_empty());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_no_chunking() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().service(web::resource("/").route(web::to(move || {
|
||||
|
@ -386,7 +390,7 @@ async fn test_no_chunking() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_deflate() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new()
|
||||
|
@ -415,7 +419,7 @@ async fn test_body_deflate() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_body_brotli() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().wrap(Compress::new(ContentEncoding::Br)).service(
|
||||
|
@ -443,7 +447,7 @@ async fn test_body_brotli() {
|
|||
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_encoding() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().wrap(Compress::default()).service(
|
||||
|
@ -469,7 +473,7 @@ async fn test_encoding() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_gzip_encoding() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().service(
|
||||
|
@ -495,7 +499,7 @@ async fn test_gzip_encoding() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_gzip_encoding_large() {
|
||||
let data = STR.repeat(10);
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
|
@ -522,7 +526,7 @@ async fn test_gzip_encoding_large() {
|
|||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_reading_gzip_encoding_large_random() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
|
@ -554,7 +558,7 @@ async fn test_reading_gzip_encoding_large_random() {
|
|||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_reading_deflate_encoding() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().service(
|
||||
|
@ -580,7 +584,7 @@ async fn test_reading_deflate_encoding() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_reading_deflate_encoding_large() {
|
||||
let data = STR.repeat(10);
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
|
@ -607,7 +611,7 @@ async fn test_reading_deflate_encoding_large() {
|
|||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_reading_deflate_encoding_large_random() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
|
@ -639,7 +643,7 @@ async fn test_reading_deflate_encoding_large_random() {
|
|||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_brotli_encoding() {
|
||||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().service(
|
||||
|
@ -665,7 +669,7 @@ async fn test_brotli_encoding() {
|
|||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_brotli_encoding_large() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
|
@ -675,7 +679,7 @@ async fn test_brotli_encoding_large() {
|
|||
let srv = test::start_with(test::config().h1(), || {
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.app_data(web::PayloadConfig::new(320_000))
|
||||
.app_data(web::types::PayloadConfig::new(320_000))
|
||||
.route(web::to(move |body: Bytes| {
|
||||
HttpResponse::Ok().streaming(TestBody::new(body, 10240))
|
||||
})),
|
||||
|
@ -700,7 +704,7 @@ async fn test_brotli_encoding_large() {
|
|||
}
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_brotli_encoding_large_openssl() {
|
||||
// load ssl keys
|
||||
use open_ssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
||||
|
@ -716,7 +720,7 @@ async fn test_brotli_encoding_large_openssl() {
|
|||
let srv = test::start_with(test::config().openssl(builder.build()), move || {
|
||||
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
|
||||
HttpResponse::Ok()
|
||||
.encoding(actix_web::http::ContentEncoding::Identity)
|
||||
.encoding(ContentEncoding::Identity)
|
||||
.body(bytes)
|
||||
})))
|
||||
});
|
||||
|
@ -729,7 +733,7 @@ async fn test_brotli_encoding_large_openssl() {
|
|||
// client request
|
||||
let mut response = srv
|
||||
.post("/")
|
||||
.header(actix_web::http::header::CONTENT_ENCODING, "br")
|
||||
.header(CONTENT_ENCODING, "br")
|
||||
.send_body(enc)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -741,7 +745,7 @@ async fn test_brotli_encoding_large_openssl() {
|
|||
}
|
||||
|
||||
#[cfg(all(feature = "rustls", feature = "openssl"))]
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_reading_deflate_encoding_large_random_rustls() {
|
||||
use rust_tls::internal::pemfile::{certs, pkcs8_private_keys};
|
||||
use rust_tls::{NoClientAuth, ServerConfig};
|
||||
|
@ -764,7 +768,7 @@ async fn test_reading_deflate_encoding_large_random_rustls() {
|
|||
let srv = test::start_with(test::config().rustls(config), || {
|
||||
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
|
||||
HttpResponse::Ok()
|
||||
.encoding(actix_web::http::ContentEncoding::Identity)
|
||||
.encoding(ContentEncoding::Identity)
|
||||
.body(bytes)
|
||||
})))
|
||||
});
|
||||
|
@ -777,7 +781,7 @@ async fn test_reading_deflate_encoding_large_random_rustls() {
|
|||
// client request
|
||||
let req = srv
|
||||
.post("/")
|
||||
.header(actix_web::http::header::CONTENT_ENCODING, "deflate")
|
||||
.header(CONTENT_ENCODING, "deflate")
|
||||
.send_stream(TestBody::new(Bytes::from(enc), 1024));
|
||||
|
||||
let mut response = req.await.unwrap();
|
||||
|
@ -845,7 +849,7 @@ async fn test_reading_deflate_encoding_large_random_rustls() {
|
|||
// }
|
||||
// }
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ntex::test]
|
||||
async fn test_slow_request() {
|
||||
use std::net;
|
||||
|
||||
|
@ -866,7 +870,7 @@ async fn test_slow_request() {
|
|||
}
|
||||
|
||||
// #[cfg(feature = "openssl")]
|
||||
// #[actix_rt::test]
|
||||
// #[ntex::test]
|
||||
// async fn test_ssl_handshake_timeout() {
|
||||
// use open_ssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
||||
// use std::net;
|
Loading…
Add table
Add a link
Reference in a new issue