mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-23 17:28:19 +02:00
Compare commits
43 Commits
v2.0.0-alp
...
http-test-
Author | SHA1 | Date | |
---|---|---|---|
|
d006a7b31f | ||
|
3d64d565d9 | ||
|
c1deaaeb2f | ||
|
b81417c2fa | ||
|
4937c9f9c2 | ||
|
db1d6b7963 | ||
|
fa07415721 | ||
|
b4b3350b3e | ||
|
4a1695f719 | ||
|
1b8d747937 | ||
|
a43a005f59 | ||
|
a612b74aeb | ||
|
131c897099 | ||
|
ef3a33b9d6 | ||
|
5132257b0d | ||
|
0c1f5f9edc | ||
|
e4382e4fc1 | ||
|
a3ce371312 | ||
|
42258ee289 | ||
|
b92eafb839 | ||
|
3b2e78db47 | ||
|
63da1a5560 | ||
|
1f3ffe38e8 | ||
|
c23b6b3879 | ||
|
909c7c8b5b | ||
|
4a8a9ef405 | ||
|
6c9f9fff73 | ||
|
8df33f7a81 | ||
|
7ec5ca88a1 | ||
|
e5f3d88a4e | ||
|
0ba125444a | ||
|
6c226e47bd | ||
|
8c3f58db9d | ||
|
4921243add | ||
|
91b3fcf85c | ||
|
f2ba389496 | ||
|
439f02b6b1 | ||
|
e32da08a26 | ||
|
82110e0927 | ||
|
7b3354a9ad | ||
|
5243e8baca | ||
|
98903028c7 | ||
|
b7d44d6c4c |
@@ -1,5 +1,11 @@
|
||||
# Changes
|
||||
|
||||
## [2.0.0-alpha.4] - 2019-12-08
|
||||
|
||||
### Deleted
|
||||
|
||||
* Delete HttpServer::run(), it is not useful witht async/await
|
||||
|
||||
## [2.0.0-alpha.3] - 2019-12-07
|
||||
|
||||
### Changed
|
||||
|
57
Cargo.toml
57
Cargo.toml
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-web"
|
||||
version = "2.0.0-alpha.3"
|
||||
version = "2.0.0-alpha.5"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust."
|
||||
readme = "README.md"
|
||||
@@ -16,7 +16,7 @@ exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["openssl", "brotli", "flate2-zlib", "secure-cookies", "client"]
|
||||
features = ["openssl", "compress", "secure-cookies", "client"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "actix/actix-web", branch = "master" }
|
||||
@@ -43,45 +43,37 @@ members = [
|
||||
]
|
||||
|
||||
[features]
|
||||
default = ["brotli", "flate2-zlib", "client", "fail"]
|
||||
default = ["compress", "failure"]
|
||||
|
||||
# http client
|
||||
client = ["awc"]
|
||||
|
||||
# brotli encoding, requires c compiler
|
||||
brotli = ["actix-http/brotli"]
|
||||
|
||||
# miniz-sys backend for flate2 crate
|
||||
flate2-zlib = ["actix-http/flate2-zlib"]
|
||||
|
||||
# rust backend for flate2 crate
|
||||
flate2-rust = ["actix-http/flate2-rust"]
|
||||
# content-encoding support
|
||||
compress = ["actix-http/compress", "awc/compress"]
|
||||
|
||||
# sessions feature, session require "ring" crate and c compiler
|
||||
secure-cookies = ["actix-http/secure-cookies"]
|
||||
|
||||
fail = ["actix-http/fail"]
|
||||
failure = ["actix-http/failure"]
|
||||
|
||||
# openssl
|
||||
openssl = ["open-ssl", "actix-tls/openssl", "awc/openssl"]
|
||||
openssl = ["actix-tls/openssl", "awc/openssl", "open-ssl"]
|
||||
|
||||
# rustls
|
||||
rustls = ["rust-tls", "actix-tls/rustls", "awc/rustls"]
|
||||
rustls = ["actix-tls/rustls", "awc/rustls", "rust-tls"]
|
||||
|
||||
[dependencies]
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0"
|
||||
actix-service = "1.0.0"
|
||||
actix-utils = "1.0.3"
|
||||
actix-router = "0.2.0"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-server = "1.0.0-alpha.3"
|
||||
actix-testing = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
actix-server = "1.0.0"
|
||||
actix-testing = "1.0.0"
|
||||
actix-macros = "0.1.0"
|
||||
actix-threadpool = "0.3.0"
|
||||
actix-tls = { version = "1.0.0-alpha.3" }
|
||||
actix-tls = "1.0.0"
|
||||
|
||||
actix-web-codegen = "0.2.0-alpha.2"
|
||||
actix-http = "1.0.0-alpha.3"
|
||||
awc = { version = "1.0.0-alpha.3", optional = true }
|
||||
actix-http = "1.0.0"
|
||||
awc = { version = "1.0.0", default-features = false }
|
||||
|
||||
bytes = "0.5.2"
|
||||
derive_more = "0.99.2"
|
||||
@@ -91,7 +83,6 @@ fxhash = "0.2.1"
|
||||
log = "0.4"
|
||||
mime = "0.3"
|
||||
net2 = "0.2.33"
|
||||
parking_lot = "0.9"
|
||||
pin-project = "0.4.6"
|
||||
regex = "1.3"
|
||||
serde = { version = "1.0", features=["derive"] }
|
||||
@@ -99,20 +90,16 @@ serde_json = "1.0"
|
||||
serde_urlencoded = "0.6.1"
|
||||
time = "0.1.42"
|
||||
url = "2.1"
|
||||
|
||||
# ssl support
|
||||
open-ssl = { version="0.10", package="openssl", optional = true }
|
||||
rust-tls = { version = "0.16", package="rustls", optional = true }
|
||||
open-ssl = { version="0.10", package = "openssl", optional = true }
|
||||
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# actix = "0.8.3"
|
||||
actix-connect = "1.0.0-alpha.3"
|
||||
actix-http-test = "1.0.0-alpha.3"
|
||||
rand = "0.7"
|
||||
env_logger = "0.6"
|
||||
serde_derive = "1.0"
|
||||
brotli2 = "0.3.2"
|
||||
flate2 = "1.0.2"
|
||||
brotli = "3.3.0"
|
||||
flate2 = "1.0.13"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
36
README.md
36
README.md
@@ -1,4 +1,28 @@
|
||||
# Actix web [](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)
|
||||
<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>
|
||||
|
||||
[](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.
|
||||
|
||||
@@ -15,18 +39,10 @@ Actix web is a simple, pragmatic and extremely fast web framework for Rust.
|
||||
* Includes an asynchronous [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html)
|
||||
* Supports [Actix actor framework](https://github.com/actix/actix)
|
||||
|
||||
## Documentation & community resources
|
||||
|
||||
* [User Guide](https://actix.rs/docs/)
|
||||
* [API Documentation (1.0)](https://docs.rs/actix-web/)
|
||||
* [Chat on gitter](https://gitter.im/actix/actix)
|
||||
* Cargo package: [actix-web](https://crates.io/crates/actix-web)
|
||||
* Minimum supported Rust version: 1.39 or later
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
use actix_web::{get, App, HttpServer, Responder};
|
||||
use actix_web::{get, web, App, HttpServer, Responder};
|
||||
|
||||
#[get("/{id}/{name}/index.html")]
|
||||
async fn index(info: web::Path<(u32, String)>) -> impl Responder {
|
||||
|
@@ -18,9 +18,9 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "2.0.0-alpha.3"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-service = "1.0.0"
|
||||
derive_more = "0.99.2"
|
||||
futures = "0.3.1"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
|
@@ -822,7 +822,7 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_service::{service_fn2, Transform};
|
||||
use actix_service::{fn_service, Transform};
|
||||
use actix_web::test::{self, TestRequest};
|
||||
|
||||
use super::*;
|
||||
@@ -1083,7 +1083,7 @@ mod tests {
|
||||
.expose_headers(exposed_headers.clone())
|
||||
.allowed_header(header::CONTENT_TYPE)
|
||||
.finish()
|
||||
.new_transform(service_fn2(|req: ServiceRequest| {
|
||||
.new_transform(fn_service(|req: ServiceRequest| {
|
||||
ok(req.into_response(
|
||||
HttpResponse::Ok().header(header::VARY, "Accept").finish(),
|
||||
))
|
||||
|
@@ -20,7 +20,7 @@ path = "src/lib.rs"
|
||||
[dependencies]
|
||||
actix-web = { version = "2.0.0-alpha.3", default-features = false }
|
||||
actix-http = "1.0.0-alpha.3"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-service = "1.0.0"
|
||||
bitflags = "1"
|
||||
bytes = "0.5.2"
|
||||
futures = "0.3.1"
|
||||
@@ -32,5 +32,5 @@ percent-encoding = "2.1"
|
||||
v_htmlescape = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
actix-web = { version = "2.0.0-alpha.3", features=["openssl"] }
|
||||
|
@@ -274,10 +274,14 @@ impl Files {
|
||||
/// By default pool with 5x threads of available cpus is used.
|
||||
/// Pool size can be changed by setting ACTIX_CPU_POOL environment variable.
|
||||
pub fn new<T: Into<PathBuf>>(path: &str, dir: T) -> Files {
|
||||
let dir = dir.into().canonicalize().unwrap_or_else(|_| PathBuf::new());
|
||||
if !dir.is_dir() {
|
||||
log::error!("Specified path is not a directory: {:?}", dir);
|
||||
}
|
||||
let orig_dir = dir.into();
|
||||
let dir = match orig_dir.canonicalize() {
|
||||
Ok(canon_dir) => canon_dir,
|
||||
Err(_) => {
|
||||
log::error!("Specified path is not a directory: {:?}", orig_dir);
|
||||
PathBuf::new()
|
||||
}
|
||||
};
|
||||
|
||||
Files {
|
||||
path: path.to_string(),
|
||||
|
@@ -20,10 +20,10 @@ name = "actix_framed"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0"
|
||||
actix-service = "1.0.0"
|
||||
actix-router = "0.2.0"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
actix-http = "1.0.0-alpha.3"
|
||||
|
||||
bytes = "0.5.2"
|
||||
@@ -32,7 +32,7 @@ pin-project = "0.4.6"
|
||||
log = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-server = { version = "1.0.0-alpha.3" }
|
||||
actix-connect = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-server = "1.0.0"
|
||||
actix-connect = { version = "1.0.0", features=["openssl"] }
|
||||
actix-http-test = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-utils = "1.0.0"
|
||||
|
@@ -1,9 +1,9 @@
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use actix_http::{body, http::StatusCode, ws, Error, HttpService, Response};
|
||||
use actix_http_test::TestServer;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{pipeline_factory, IntoServiceFactory, ServiceFactory};
|
||||
use actix_utils::framed::FramedTransport;
|
||||
use bytes::BytesMut;
|
||||
use actix_utils::framed::Dispatcher;
|
||||
use bytes::Bytes;
|
||||
use futures::{future, SinkExt, StreamExt};
|
||||
|
||||
use actix_framed::{FramedApp, FramedRequest, FramedRoute, SendError, VerifyWebSockets};
|
||||
@@ -18,7 +18,7 @@ async fn ws_service<T: AsyncRead + AsyncWrite>(
|
||||
.send((res, body::BodySize::None).into())
|
||||
.await
|
||||
.unwrap();
|
||||
FramedTransport::new(framed.into_framed(ws::Codec::new()), service)
|
||||
Dispatcher::new(framed.into_framed(ws::Codec::new()), service)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -29,9 +29,9 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
||||
let msg = match msg {
|
||||
ws::Frame::Ping(msg) => ws::Message::Pong(msg),
|
||||
ws::Frame::Text(text) => {
|
||||
ws::Message::Text(String::from_utf8_lossy(&text.unwrap()).to_string())
|
||||
ws::Message::Text(String::from_utf8_lossy(&text).to_string())
|
||||
}
|
||||
ws::Frame::Binary(bin) => ws::Message::Binary(bin.unwrap().freeze()),
|
||||
ws::Frame::Binary(bin) => ws::Message::Binary(bin),
|
||||
ws::Frame::Close(reason) => ws::Message::Close(reason),
|
||||
_ => panic!(),
|
||||
};
|
||||
@@ -40,7 +40,7 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_simple() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.upgrade(
|
||||
FramedApp::new().service(FramedRoute::get("/index.html").to(ws_service)),
|
||||
@@ -60,7 +60,7 @@ async fn test_simple() {
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Text(Some(BytesMut::from("text")))
|
||||
ws::Frame::Text(Bytes::from_static(b"text"))
|
||||
);
|
||||
|
||||
framed
|
||||
@@ -70,7 +70,7 @@ async fn test_simple() {
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Binary(Some(BytesMut::from(&b"text"[..])))
|
||||
ws::Frame::Binary(Bytes::from_static(b"text"))
|
||||
);
|
||||
|
||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||
@@ -94,7 +94,7 @@ async fn test_simple() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
pipeline_factory(actix_http::h1::OneRequest::new().map_err(|_| ())).and_then(
|
||||
pipeline_factory(
|
||||
pipeline_factory(VerifyWebSockets::default())
|
||||
@@ -126,7 +126,7 @@ async fn test_service() {
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Text(Some(BytesMut::from("text")))
|
||||
ws::Frame::Text(Bytes::from_static(b"text"))
|
||||
);
|
||||
|
||||
framed
|
||||
@@ -136,7 +136,7 @@ async fn test_service() {
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Binary(Some(BytesMut::from(&b"text"[..])))
|
||||
ws::Frame::Binary(Bytes::from_static(b"text"))
|
||||
);
|
||||
|
||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||
|
@@ -1,5 +1,37 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.0] - 2019-12-13
|
||||
|
||||
### Added
|
||||
|
||||
* Add websockets continuation frame support
|
||||
|
||||
### Changed
|
||||
|
||||
* Replace `flate2-xxx` features with `compress`
|
||||
|
||||
## [1.0.0-alpha.5] - 2019-12-09
|
||||
|
||||
### Fixed
|
||||
|
||||
* Check `Upgrade` service readiness before calling it
|
||||
|
||||
* Fix buffer remaining capacity calcualtion
|
||||
|
||||
### Changed
|
||||
|
||||
* Websockets: Ping and Pong should have binary data #1049
|
||||
|
||||
## [1.0.0-alpha.4] - 2019-12-08
|
||||
|
||||
### Added
|
||||
|
||||
* Add impl ResponseBuilder for Error
|
||||
|
||||
### Changed
|
||||
|
||||
* Use rust based brotli compression library
|
||||
|
||||
## [1.0.0-alpha.3] - 2019-12-07
|
||||
|
||||
### Changed
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-http"
|
||||
version = "1.0.0-alpha.3"
|
||||
version = "1.0.0"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix http primitives"
|
||||
readme = "README.md"
|
||||
@@ -13,10 +13,9 @@ categories = ["network-programming", "asynchronous",
|
||||
"web-programming::websocket"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
workspace = ".."
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["openssl", "rustls", "fail", "brotli", "flate2-zlib", "secure-cookies"]
|
||||
features = ["openssl", "rustls", "fail", "compress", "secure-cookies"]
|
||||
|
||||
[lib]
|
||||
name = "actix_http"
|
||||
@@ -31,45 +30,41 @@ openssl = ["actix-tls/openssl", "actix-connect/openssl"]
|
||||
# rustls support
|
||||
rustls = ["actix-tls/rustls", "actix-connect/rustls"]
|
||||
|
||||
# brotli encoding, requires c compiler
|
||||
brotli = ["brotli2"]
|
||||
|
||||
# miniz-sys backend for flate2 crate
|
||||
flate2-zlib = ["flate2/miniz-sys"]
|
||||
|
||||
# rust backend for flate2 crate
|
||||
flate2-rust = ["flate2/rust_backend"]
|
||||
# enable compressison support
|
||||
compress = ["flate2", "brotli"]
|
||||
|
||||
# failure integration. actix does not use failure anymore
|
||||
fail = ["failure"]
|
||||
failure = ["fail-ure"]
|
||||
|
||||
# support for secure cookies
|
||||
secure-cookies = ["ring"]
|
||||
|
||||
[dependencies]
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-connect = "1.0.0-alpha.3"
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-threadpool = "0.3.0"
|
||||
actix-tls = { version = "1.0.0-alpha.3", optional = true }
|
||||
actix-service = "1.0.0"
|
||||
actix-codec = "0.2.0"
|
||||
actix-connect = "1.0.0"
|
||||
actix-utils = "1.0.3"
|
||||
actix-rt = "1.0.0"
|
||||
actix-threadpool = "0.3.1"
|
||||
actix-tls = { version = "1.0.0", optional = true }
|
||||
|
||||
base64 = "0.11"
|
||||
bitflags = "1.0"
|
||||
bytes = "0.5.2"
|
||||
bitflags = "1.2"
|
||||
bytes = "0.5.3"
|
||||
copyless = "0.1.4"
|
||||
chrono = "0.4.6"
|
||||
derive_more = "0.99.2"
|
||||
either = "1.5.2"
|
||||
either = "1.5.3"
|
||||
encoding_rs = "0.8"
|
||||
futures = "0.3.1"
|
||||
futures-core = "0.3.1"
|
||||
futures-util = "0.3.1"
|
||||
futures-channel = "0.3.1"
|
||||
fxhash = "0.2.1"
|
||||
h2 = "0.2.1"
|
||||
http = "0.2.0"
|
||||
httparse = "1.3"
|
||||
indexmap = "1.2"
|
||||
lazy_static = "1.0"
|
||||
indexmap = "1.3"
|
||||
lazy_static = "1.4"
|
||||
language-tags = "0.2"
|
||||
log = "0.4"
|
||||
mime = "0.3"
|
||||
@@ -88,17 +83,18 @@ time = "0.1.42"
|
||||
ring = { version = "0.16.9", optional = true }
|
||||
|
||||
# compression
|
||||
brotli2 = { version="0.3.2", optional = true }
|
||||
flate2 = { version="1.0.7", optional = true, default-features = false }
|
||||
brotli = { version = "3.3.0", optional = true }
|
||||
flate2 = { version = "1.0.13", optional = true }
|
||||
|
||||
# optional deps
|
||||
failure = { version = "0.1.5", optional = true }
|
||||
fail-ure = { version = "0.1.5", package="failure", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
actix-server = { version = "1.0.0-alpha.3" }
|
||||
actix-connect = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-server = "1.0.0"
|
||||
actix-connect = { version = "1.0.0", features=["openssl"] }
|
||||
actix-http-test = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-tls = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-tls = { version = "1.0.0", features=["openssl"] }
|
||||
futures = "0.3.1"
|
||||
env_logger = "0.6"
|
||||
serde_derive = "1.0"
|
||||
open-ssl = { version="0.10", package = "openssl" }
|
||||
|
@@ -4,7 +4,7 @@ use std::task::{Context, Poll};
|
||||
use std::{fmt, mem};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::Stream;
|
||||
use futures_core::Stream;
|
||||
use pin_project::{pin_project, project};
|
||||
|
||||
use crate::error::Error;
|
||||
@@ -35,7 +35,7 @@ impl BodySize {
|
||||
pub trait MessageBody {
|
||||
fn size(&self) -> BodySize;
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>>;
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>>;
|
||||
}
|
||||
|
||||
impl MessageBody for () {
|
||||
@@ -43,7 +43,7 @@ impl MessageBody for () {
|
||||
BodySize::Empty
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
Poll::Ready(None)
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ impl<T: MessageBody> MessageBody for Box<T> {
|
||||
self.as_ref().size()
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
self.as_mut().poll_next(cx)
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ impl<B: MessageBody> MessageBody for ResponseBody<B> {
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
match self {
|
||||
ResponseBody::Body(ref mut body) => body.poll_next(cx),
|
||||
ResponseBody::Other(ref mut body) => body.poll_next(cx),
|
||||
@@ -109,7 +109,10 @@ impl<B: MessageBody> Stream for ResponseBody<B> {
|
||||
type Item = Result<Bytes, Error>;
|
||||
|
||||
#[project]
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
#[project]
|
||||
match self.project() {
|
||||
ResponseBody::Body(ref mut body) => body.poll_next(cx),
|
||||
@@ -152,7 +155,7 @@ impl MessageBody for Body {
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
match self {
|
||||
Body::None => Poll::Ready(None),
|
||||
Body::Empty => Poll::Ready(None),
|
||||
@@ -190,7 +193,7 @@ impl PartialEq for Body {
|
||||
}
|
||||
|
||||
impl fmt::Debug for Body {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
Body::None => write!(f, "Body::None"),
|
||||
Body::Empty => write!(f, "Body::Empty"),
|
||||
@@ -272,7 +275,7 @@ impl MessageBody for Bytes {
|
||||
BodySize::Sized(self.len())
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -286,7 +289,7 @@ impl MessageBody for BytesMut {
|
||||
BodySize::Sized(self.len())
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -300,7 +303,7 @@ impl MessageBody for &'static str {
|
||||
BodySize::Sized(self.len())
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -316,7 +319,7 @@ impl MessageBody for &'static [u8] {
|
||||
BodySize::Sized(self.len())
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -330,7 +333,7 @@ impl MessageBody for Vec<u8> {
|
||||
BodySize::Sized(self.len())
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -344,7 +347,7 @@ impl MessageBody for String {
|
||||
BodySize::Sized(self.len())
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, _: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, _: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -386,7 +389,7 @@ where
|
||||
BodySize::Stream
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
unsafe { Pin::new_unchecked(self) }
|
||||
.project()
|
||||
.stream
|
||||
@@ -421,7 +424,7 @@ where
|
||||
BodySize::Sized64(self.size)
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
unsafe { Pin::new_unchecked(self) }
|
||||
.project()
|
||||
.stream
|
||||
@@ -432,7 +435,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use futures::future::poll_fn;
|
||||
use futures_util::future::poll_fn;
|
||||
|
||||
impl Body {
|
||||
pub(crate) fn get_ref(&self) -> &[u8] {
|
||||
|
@@ -4,7 +4,7 @@ use std::{fmt, io, mem, time};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use bytes::{Buf, Bytes};
|
||||
use futures::future::{err, Either, Future, FutureExt, LocalBoxFuture, Ready};
|
||||
use futures_util::future::{err, Either, Future, FutureExt, LocalBoxFuture, Ready};
|
||||
use h2::client::SendRequest;
|
||||
use pin_project::{pin_project, project};
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<T> fmt::Debug for IoConnection<T>
|
||||
where
|
||||
T: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.io {
|
||||
Some(ConnectionType::H1(ref io)) => write!(f, "H1Connection({:?})", io),
|
||||
Some(ConnectionType::H2(_)) => write!(f, "H2Connection"),
|
||||
@@ -247,7 +247,7 @@ where
|
||||
#[project]
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
#[project]
|
||||
|
@@ -62,7 +62,7 @@ trait Io: AsyncRead + AsyncWrite + Unpin {}
|
||||
impl<T: AsyncRead + AsyncWrite + Unpin> Io for T {}
|
||||
|
||||
impl Connector<(), ()> {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
#[allow(clippy::new_ret_no_self, clippy::let_unit_value)]
|
||||
pub fn new() -> Connector<
|
||||
impl Service<
|
||||
Request = TcpConnect<Uri>,
|
||||
@@ -87,9 +87,9 @@ impl Connector<(), ()> {
|
||||
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||
let mut config = ClientConfig::new();
|
||||
config.set_protocols(&protos);
|
||||
config.root_store.add_server_trust_anchors(
|
||||
&actix_connect::ssl::rustls::TLS_SERVER_ROOTS,
|
||||
);
|
||||
config
|
||||
.root_store
|
||||
.add_server_trust_anchors(&actix_tls::rustls::TLS_SERVER_ROOTS);
|
||||
SslConnector::Rustls(Arc::new(config))
|
||||
}
|
||||
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
|
||||
@@ -337,7 +337,7 @@ where
|
||||
mod connect_impl {
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use futures::future::{err, Either, Ready};
|
||||
use futures_util::future::{err, Either, Ready};
|
||||
|
||||
use super::*;
|
||||
use crate::client::connection::IoConnection;
|
||||
@@ -378,7 +378,7 @@ mod connect_impl {
|
||||
Ready<Result<IoConnection<Io>, ConnectError>>,
|
||||
>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.tcp_pool.poll_ready(cx)
|
||||
}
|
||||
|
||||
@@ -400,8 +400,8 @@ mod connect_impl {
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use futures::future::Either;
|
||||
use futures::ready;
|
||||
use futures_core::ready;
|
||||
use futures_util::future::Either;
|
||||
|
||||
use super::*;
|
||||
use crate::client::connection::EitherConnection;
|
||||
@@ -451,7 +451,7 @@ mod connect_impl {
|
||||
InnerConnectorResponseB<T2, Io1, Io2>,
|
||||
>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.tcp_pool.poll_ready(cx)
|
||||
}
|
||||
|
||||
@@ -490,10 +490,10 @@ mod connect_impl {
|
||||
{
|
||||
type Output = Result<EitherConnection<Io1, Io2>, ConnectError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.get_mut().fut).poll(cx))
|
||||
.map(|res| EitherConnection::A(res)),
|
||||
.map(EitherConnection::A),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -519,10 +519,10 @@ mod connect_impl {
|
||||
{
|
||||
type Output = Result<EitherConnection<Io1, Io2>, ConnectError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.get_mut().fut).poll(cx))
|
||||
.map(|res| EitherConnection::B(res)),
|
||||
.map(EitherConnection::B),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -6,8 +6,9 @@ use std::{io, mem, time};
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use bytes::buf::BufMutExt;
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::future::poll_fn;
|
||||
use futures::{SinkExt, Stream, StreamExt};
|
||||
use futures_core::Stream;
|
||||
use futures_util::future::poll_fn;
|
||||
use futures_util::{SinkExt, StreamExt};
|
||||
|
||||
use crate::error::PayloadError;
|
||||
use crate::h1;
|
||||
@@ -234,7 +235,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin + 'static> AsyncWrite for H1Connection<T>
|
||||
|
||||
fn poll_shutdown(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), io::Error>> {
|
||||
Pin::new(self.io.as_mut().unwrap()).poll_shutdown(cx)
|
||||
}
|
||||
@@ -255,7 +256,10 @@ impl<Io: ConnectionLifetime> PlStream<Io> {
|
||||
impl<Io: ConnectionLifetime> Stream for PlStream<Io> {
|
||||
type Item = Result<Bytes, PayloadError>;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
let this = self.get_mut();
|
||||
|
||||
match this.framed.as_mut().unwrap().next_item(cx)? {
|
||||
|
@@ -3,7 +3,7 @@ use std::time;
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use bytes::Bytes;
|
||||
use futures::future::poll_fn;
|
||||
use futures_util::future::poll_fn;
|
||||
use h2::{client::SendRequest, SendStream};
|
||||
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING};
|
||||
use http::{request::Request, Method, Version};
|
||||
|
@@ -11,7 +11,7 @@ use actix_rt::time::{delay_for, Delay};
|
||||
use actix_service::Service;
|
||||
use actix_utils::{oneshot, task::LocalWaker};
|
||||
use bytes::Bytes;
|
||||
use futures::future::{poll_fn, FutureExt, LocalBoxFuture};
|
||||
use futures_util::future::{poll_fn, FutureExt, LocalBoxFuture};
|
||||
use fxhash::FxHashMap;
|
||||
use h2::client::{handshake, Connection, SendRequest};
|
||||
use http::uri::Authority;
|
||||
@@ -93,7 +93,7 @@ where
|
||||
type Error = ConnectError;
|
||||
type Future = LocalBoxFuture<'static, Result<IoConnection<Io>, ConnectError>>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.0.poll_ready(cx)
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ where
|
||||
(rx, token)
|
||||
}
|
||||
|
||||
fn acquire(&mut self, key: &Key, cx: &mut Context) -> Acquire<Io> {
|
||||
fn acquire(&mut self, key: &Key, cx: &mut Context<'_>) -> Acquire<Io> {
|
||||
// check limits
|
||||
if self.limit > 0 && self.acquired >= self.limit {
|
||||
return Acquire::NotAvailable;
|
||||
@@ -409,7 +409,7 @@ where
|
||||
{
|
||||
type Output = ();
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||
let this = self.get_mut();
|
||||
|
||||
match Pin::new(&mut this.timeout).poll(cx) {
|
||||
@@ -438,7 +438,7 @@ where
|
||||
{
|
||||
type Output = ();
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = unsafe { self.get_unchecked_mut() };
|
||||
|
||||
let mut inner = this.inner.as_ref().borrow_mut();
|
||||
@@ -545,7 +545,7 @@ where
|
||||
{
|
||||
type Output = ();
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = unsafe { self.get_unchecked_mut() };
|
||||
|
||||
if let Some(ref mut h2) = this.h2 {
|
||||
|
@@ -32,7 +32,7 @@ where
|
||||
type Error = T::Error;
|
||||
type Future = T::Future;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
unsafe { &mut *self.0.as_ref().get() }.poll_ready(cx)
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@ use std::{fmt, net};
|
||||
|
||||
use actix_rt::time::{delay_for, delay_until, Delay, Instant};
|
||||
use bytes::BytesMut;
|
||||
use futures::{future, FutureExt};
|
||||
use futures_util::{future, FutureExt};
|
||||
use time;
|
||||
|
||||
// "Sun, 06 Nov 1994 08:49:37 GMT".len()
|
||||
|
@@ -18,7 +18,6 @@ use super::{Cookie, SameSite};
|
||||
/// ```rust
|
||||
/// use actix_http::cookie::Cookie;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let cookie: Cookie = Cookie::build("name", "value")
|
||||
/// .domain("www.rust-lang.org")
|
||||
/// .path("/")
|
||||
@@ -26,7 +25,6 @@ use super::{Cookie, SameSite};
|
||||
/// .http_only(true)
|
||||
/// .max_age(84600)
|
||||
/// .finish();
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CookieBuilder {
|
||||
@@ -65,13 +63,11 @@ impl CookieBuilder {
|
||||
/// ```rust
|
||||
/// use actix_http::cookie::Cookie;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let c = Cookie::build("foo", "bar")
|
||||
/// .expires(time::now())
|
||||
/// .finish();
|
||||
///
|
||||
/// assert!(c.expires().is_some());
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn expires(mut self, when: Tm) -> CookieBuilder {
|
||||
@@ -86,13 +82,11 @@ impl CookieBuilder {
|
||||
/// ```rust
|
||||
/// use actix_http::cookie::Cookie;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let c = Cookie::build("foo", "bar")
|
||||
/// .max_age(1800)
|
||||
/// .finish();
|
||||
///
|
||||
/// assert_eq!(c.max_age(), Some(time::Duration::seconds(30 * 60)));
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn max_age(self, seconds: i64) -> CookieBuilder {
|
||||
@@ -106,13 +100,11 @@ impl CookieBuilder {
|
||||
/// ```rust
|
||||
/// use actix_http::cookie::Cookie;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let c = Cookie::build("foo", "bar")
|
||||
/// .max_age_time(time::Duration::minutes(30))
|
||||
/// .finish();
|
||||
///
|
||||
/// assert_eq!(c.max_age(), Some(time::Duration::seconds(30 * 60)));
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn max_age_time(mut self, value: Duration) -> CookieBuilder {
|
||||
@@ -222,14 +214,12 @@ impl CookieBuilder {
|
||||
/// use actix_http::cookie::Cookie;
|
||||
/// use chrono::Duration;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let c = Cookie::build("foo", "bar")
|
||||
/// .permanent()
|
||||
/// .finish();
|
||||
///
|
||||
/// assert_eq!(c.max_age(), Some(Duration::days(365 * 20)));
|
||||
/// # assert!(c.expires().is_some());
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn permanent(mut self) -> CookieBuilder {
|
||||
|
@@ -88,7 +88,7 @@ impl SameSite {
|
||||
}
|
||||
|
||||
impl fmt::Display for SameSite {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
SameSite::Strict => write!(f, "Strict"),
|
||||
SameSite::Lax => write!(f, "Lax"),
|
||||
|
@@ -190,7 +190,6 @@ impl CookieJar {
|
||||
/// use actix_http::cookie::{CookieJar, Cookie};
|
||||
/// use chrono::Duration;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let mut jar = CookieJar::new();
|
||||
///
|
||||
/// // Assume this cookie originally had a path of "/" and domain of "a.b".
|
||||
@@ -204,7 +203,6 @@ impl CookieJar {
|
||||
/// assert_eq!(delta.len(), 1);
|
||||
/// assert_eq!(delta[0].name(), "name");
|
||||
/// assert_eq!(delta[0].max_age(), Some(Duration::seconds(0)));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Removing a new cookie does not result in a _removal_ cookie:
|
||||
@@ -243,7 +241,6 @@ impl CookieJar {
|
||||
/// use actix_http::cookie::{CookieJar, Cookie};
|
||||
/// use chrono::Duration;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let mut jar = CookieJar::new();
|
||||
///
|
||||
/// // Add an original cookie and a new cookie.
|
||||
@@ -261,7 +258,6 @@ impl CookieJar {
|
||||
/// jar.force_remove(Cookie::new("key", "value"));
|
||||
/// assert_eq!(jar.delta().count(), 0);
|
||||
/// assert_eq!(jar.iter().count(), 0);
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn force_remove<'a>(&mut self, cookie: Cookie<'a>) {
|
||||
self.original_cookies.remove(cookie.name());
|
||||
@@ -307,7 +303,7 @@ impl CookieJar {
|
||||
/// // Delta contains two new cookies ("new", "yac") and a removal ("name").
|
||||
/// assert_eq!(jar.delta().count(), 3);
|
||||
/// ```
|
||||
pub fn delta(&self) -> Delta {
|
||||
pub fn delta(&self) -> Delta<'_> {
|
||||
Delta {
|
||||
iter: self.delta_cookies.iter(),
|
||||
}
|
||||
@@ -343,7 +339,7 @@ impl CookieJar {
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn iter(&self) -> Iter {
|
||||
pub fn iter(&self) -> Iter<'_> {
|
||||
Iter {
|
||||
delta_cookies: self
|
||||
.delta_cookies
|
||||
@@ -386,7 +382,7 @@ impl CookieJar {
|
||||
/// assert!(jar.get("private").is_some());
|
||||
/// ```
|
||||
#[cfg(feature = "secure-cookies")]
|
||||
pub fn private(&mut self, key: &Key) -> PrivateJar {
|
||||
pub fn private(&mut self, key: &Key) -> PrivateJar<'_> {
|
||||
PrivateJar::new(self, key)
|
||||
}
|
||||
|
||||
@@ -424,7 +420,7 @@ impl CookieJar {
|
||||
/// assert!(jar.get("signed").is_some());
|
||||
/// ```
|
||||
#[cfg(feature = "secure-cookies")]
|
||||
pub fn signed(&mut self, key: &Key) -> SignedJar {
|
||||
pub fn signed(&mut self, key: &Key) -> SignedJar<'_> {
|
||||
SignedJar::new(self, key)
|
||||
}
|
||||
}
|
||||
|
@@ -110,7 +110,7 @@ impl CookieStr {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `self` is an indexed string and `string` is None.
|
||||
fn to_str<'s>(&'s self, string: Option<&'s Cow<str>>) -> &'s str {
|
||||
fn to_str<'s>(&'s self, string: Option<&'s Cow<'_, str>>) -> &'s str {
|
||||
match *self {
|
||||
CookieStr::Indexed(i, j) => {
|
||||
let s = string.expect(
|
||||
@@ -647,13 +647,11 @@ impl<'c> Cookie<'c> {
|
||||
/// use actix_http::cookie::Cookie;
|
||||
/// use chrono::Duration;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let mut c = Cookie::new("name", "value");
|
||||
/// assert_eq!(c.max_age(), None);
|
||||
///
|
||||
/// c.set_max_age(Duration::hours(10));
|
||||
/// assert_eq!(c.max_age(), Some(Duration::hours(10)));
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_max_age(&mut self, value: Duration) {
|
||||
@@ -701,7 +699,6 @@ impl<'c> Cookie<'c> {
|
||||
/// ```rust
|
||||
/// use actix_http::cookie::Cookie;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let mut c = Cookie::new("name", "value");
|
||||
/// assert_eq!(c.expires(), None);
|
||||
///
|
||||
@@ -710,7 +707,6 @@ impl<'c> Cookie<'c> {
|
||||
///
|
||||
/// c.set_expires(now);
|
||||
/// assert!(c.expires().is_some())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_expires(&mut self, time: Tm) {
|
||||
@@ -726,7 +722,6 @@ impl<'c> Cookie<'c> {
|
||||
/// use actix_http::cookie::Cookie;
|
||||
/// use chrono::Duration;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let mut c = Cookie::new("foo", "bar");
|
||||
/// assert!(c.expires().is_none());
|
||||
/// assert!(c.max_age().is_none());
|
||||
@@ -734,7 +729,6 @@ impl<'c> Cookie<'c> {
|
||||
/// c.make_permanent();
|
||||
/// assert!(c.expires().is_some());
|
||||
/// assert_eq!(c.max_age(), Some(Duration::days(365 * 20)));
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn make_permanent(&mut self) {
|
||||
let twenty_years = Duration::days(365 * 20);
|
||||
@@ -742,7 +736,7 @@ impl<'c> Cookie<'c> {
|
||||
self.set_expires(time::now() + twenty_years);
|
||||
}
|
||||
|
||||
fn fmt_parameters(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt_parameters(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if let Some(true) = self.http_only() {
|
||||
write!(f, "; HttpOnly")?;
|
||||
}
|
||||
@@ -924,10 +918,10 @@ impl<'c> Cookie<'c> {
|
||||
/// let mut c = Cookie::new("my name", "this; value?");
|
||||
/// assert_eq!(&c.encoded().to_string(), "my%20name=this%3B%20value%3F");
|
||||
/// ```
|
||||
pub struct EncodedCookie<'a, 'c: 'a>(&'a Cookie<'c>);
|
||||
pub struct EncodedCookie<'a, 'c>(&'a Cookie<'c>);
|
||||
|
||||
impl<'a, 'c: 'a> fmt::Display for EncodedCookie<'a, 'c> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// Percent-encode the name and value.
|
||||
let name = percent_encode(self.0.name().as_bytes(), USERINFO);
|
||||
let value = percent_encode(self.0.value().as_bytes(), USERINFO);
|
||||
@@ -952,7 +946,7 @@ impl<'c> fmt::Display for Cookie<'c> {
|
||||
///
|
||||
/// assert_eq!(&cookie.to_string(), "foo=bar; Path=/");
|
||||
/// ```
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}={}", self.name(), self.value())?;
|
||||
self.fmt_parameters(f)
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ impl ParseError {
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.as_str())
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ use crate::cookie::{Cookie, CookieJar};
|
||||
|
||||
// Keep these in sync, and keep the key len synced with the `private` docs as
|
||||
// well as the `KEYS_INFO` const in secure::Key.
|
||||
static ALGO: &'static Algorithm = &AES_256_GCM;
|
||||
static ALGO: &Algorithm = &AES_256_GCM;
|
||||
const NONCE_LEN: usize = 12;
|
||||
pub const KEY_LEN: usize = 32;
|
||||
|
||||
@@ -159,7 +159,7 @@ Please change it as soon as possible."
|
||||
|
||||
/// Encrypts the cookie's value with
|
||||
/// authenticated encryption assuring confidentiality, integrity, and authenticity.
|
||||
fn encrypt_cookie(&self, cookie: &mut Cookie) {
|
||||
fn encrypt_cookie(&self, cookie: &mut Cookie<'_>) {
|
||||
let name = cookie.name().as_bytes();
|
||||
let value = cookie.value().as_bytes();
|
||||
let data = encrypt_name_value(name, value, &self.key);
|
||||
|
@@ -129,7 +129,7 @@ impl<'a> SignedJar<'a> {
|
||||
}
|
||||
|
||||
/// Signs the cookie's value assuring integrity and authenticity.
|
||||
fn sign_cookie(&self, cookie: &mut Cookie) {
|
||||
fn sign_cookie(&self, cookie: &mut Cookie<'_>) {
|
||||
let digest = sign(&self.key, cookie.value().as_bytes());
|
||||
let mut new_value = base64::encode(digest.as_ref());
|
||||
new_value.push_str(cookie.value());
|
||||
|
@@ -4,12 +4,10 @@ use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_threadpool::{run, CpuFuture};
|
||||
#[cfg(feature = "brotli")]
|
||||
use brotli2::write::BrotliDecoder;
|
||||
use brotli::DecompressorWriter;
|
||||
use bytes::Bytes;
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
use flate2::write::{GzDecoder, ZlibDecoder};
|
||||
use futures::{ready, Stream};
|
||||
use futures_core::{ready, Stream};
|
||||
|
||||
use super::Writer;
|
||||
use crate::error::PayloadError;
|
||||
@@ -32,15 +30,12 @@ where
|
||||
#[inline]
|
||||
pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
|
||||
let decoder = match encoding {
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(
|
||||
BrotliDecoder::new(Writer::new()),
|
||||
DecompressorWriter::new(Writer::new(), 0),
|
||||
))),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(
|
||||
ZlibDecoder::new(Writer::new()),
|
||||
))),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(
|
||||
GzDecoder::new(Writer::new()),
|
||||
))),
|
||||
@@ -80,7 +75,7 @@ where
|
||||
|
||||
fn poll_next(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
loop {
|
||||
if let Some(ref mut fut) = self.fut {
|
||||
@@ -140,22 +135,17 @@ where
|
||||
}
|
||||
|
||||
enum ContentDecoder {
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
Deflate(Box<ZlibDecoder<Writer>>),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
Gzip(Box<GzDecoder<Writer>>),
|
||||
#[cfg(feature = "brotli")]
|
||||
Br(Box<BrotliDecoder<Writer>>),
|
||||
Br(Box<DecompressorWriter<Writer>>),
|
||||
}
|
||||
|
||||
impl ContentDecoder {
|
||||
#[allow(unreachable_patterns)]
|
||||
fn feed_eof(&mut self) -> io::Result<Option<Bytes>> {
|
||||
match self {
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentDecoder::Br(ref mut decoder) => match decoder.finish() {
|
||||
Ok(mut writer) => {
|
||||
let b = writer.take();
|
||||
ContentDecoder::Br(ref mut decoder) => match decoder.flush() {
|
||||
Ok(()) => {
|
||||
let b = decoder.get_mut().take();
|
||||
if !b.is_empty() {
|
||||
Ok(Some(b))
|
||||
} else {
|
||||
@@ -164,7 +154,6 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentDecoder::Gzip(ref mut decoder) => match decoder.try_finish() {
|
||||
Ok(_) => {
|
||||
let b = decoder.get_mut().take();
|
||||
@@ -176,7 +165,6 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentDecoder::Deflate(ref mut decoder) => match decoder.try_finish() {
|
||||
Ok(_) => {
|
||||
let b = decoder.get_mut().take();
|
||||
@@ -188,14 +176,11 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {
|
||||
match self {
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentDecoder::Br(ref mut decoder) => match decoder.write_all(&data) {
|
||||
Ok(_) => {
|
||||
decoder.flush()?;
|
||||
@@ -208,7 +193,6 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentDecoder::Gzip(ref mut decoder) => match decoder.write_all(&data) {
|
||||
Ok(_) => {
|
||||
decoder.flush()?;
|
||||
@@ -221,7 +205,6 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentDecoder::Deflate(ref mut decoder) => match decoder.write_all(&data) {
|
||||
Ok(_) => {
|
||||
decoder.flush()?;
|
||||
@@ -234,7 +217,6 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
_ => Ok(Some(data)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,11 +5,10 @@ use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_threadpool::{run, CpuFuture};
|
||||
#[cfg(feature = "brotli")]
|
||||
use brotli2::write::BrotliEncoder;
|
||||
use brotli::CompressorWriter;
|
||||
use bytes::Bytes;
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
use flate2::write::{GzEncoder, ZlibEncoder};
|
||||
use futures_core::ready;
|
||||
|
||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||
use crate::http::header::{ContentEncoding, CONTENT_ENCODING};
|
||||
@@ -96,14 +95,14 @@ impl<B: MessageBody> MessageBody for Encoder<B> {
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_next(&mut self, cx: &mut Context) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
loop {
|
||||
if self.eof {
|
||||
return Poll::Ready(None);
|
||||
}
|
||||
|
||||
if let Some(ref mut fut) = self.fut {
|
||||
let mut encoder = match futures::ready!(Pin::new(fut).poll(cx)) {
|
||||
let mut encoder = match ready!(Pin::new(fut).poll(cx)) {
|
||||
Ok(item) => item,
|
||||
Err(e) => return Poll::Ready(Some(Err(e.into()))),
|
||||
};
|
||||
@@ -173,31 +172,25 @@ fn update_head(encoding: ContentEncoding, head: &mut ResponseHead) {
|
||||
}
|
||||
|
||||
enum ContentEncoder {
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
Deflate(ZlibEncoder<Writer>),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
Gzip(GzEncoder<Writer>),
|
||||
#[cfg(feature = "brotli")]
|
||||
Br(BrotliEncoder<Writer>),
|
||||
Br(Box<CompressorWriter<Writer>>),
|
||||
}
|
||||
|
||||
impl ContentEncoder {
|
||||
fn encoder(encoding: ContentEncoding) -> Option<Self> {
|
||||
match encoding {
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoding::Deflate => Some(ContentEncoder::Deflate(ZlibEncoder::new(
|
||||
Writer::new(),
|
||||
flate2::Compression::fast(),
|
||||
))),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoding::Gzip => Some(ContentEncoder::Gzip(GzEncoder::new(
|
||||
Writer::new(),
|
||||
flate2::Compression::fast(),
|
||||
))),
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentEncoding::Br => {
|
||||
Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3)))
|
||||
}
|
||||
ContentEncoding::Br => Some(ContentEncoder::Br(Box::new(
|
||||
CompressorWriter::new(Writer::new(), 0, 3, 0),
|
||||
))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -205,28 +198,24 @@ impl ContentEncoder {
|
||||
#[inline]
|
||||
pub(crate) fn take(&mut self) -> Bytes {
|
||||
match *self {
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentEncoder::Br(ref mut encoder) => encoder.get_mut().take(),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoder::Br(ref mut encoder) => {
|
||||
let mut encoder_new =
|
||||
Box::new(CompressorWriter::new(Writer::new(), 0, 3, 0));
|
||||
std::mem::swap(encoder, &mut encoder_new);
|
||||
encoder_new.into_inner().freeze()
|
||||
}
|
||||
ContentEncoder::Deflate(ref mut encoder) => encoder.get_mut().take(),
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoder::Gzip(ref mut encoder) => encoder.get_mut().take(),
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(self) -> Result<Bytes, io::Error> {
|
||||
match self {
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentEncoder::Br(encoder) => match encoder.finish() {
|
||||
Ok(writer) => Ok(writer.buf.freeze()),
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoder::Br(encoder) => Ok(encoder.into_inner().buf.freeze()),
|
||||
ContentEncoder::Gzip(encoder) => match encoder.finish() {
|
||||
Ok(writer) => Ok(writer.buf.freeze()),
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoder::Deflate(encoder) => match encoder.finish() {
|
||||
Ok(writer) => Ok(writer.buf.freeze()),
|
||||
Err(err) => Err(err),
|
||||
@@ -236,7 +225,6 @@ impl ContentEncoder {
|
||||
|
||||
fn write(&mut self, data: &[u8]) -> Result<(), io::Error> {
|
||||
match *self {
|
||||
#[cfg(feature = "brotli")]
|
||||
ContentEncoder::Br(ref mut encoder) => match encoder.write_all(data) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
@@ -244,7 +232,6 @@ impl ContentEncoder {
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoder::Gzip(ref mut encoder) => match encoder.write_all(data) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
@@ -252,7 +239,6 @@ impl ContentEncoder {
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
ContentEncoder::Deflate(ref mut encoder) => match encoder.write_all(data) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
|
@@ -22,6 +22,9 @@ impl Writer {
|
||||
fn take(&mut self) -> Bytes {
|
||||
self.buf.split().freeze()
|
||||
}
|
||||
fn freeze(self) -> Bytes {
|
||||
self.buf.freeze()
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Writer {
|
||||
|
@@ -10,7 +10,7 @@ pub use actix_threadpool::BlockingError;
|
||||
use actix_utils::timeout::TimeoutError;
|
||||
use bytes::BytesMut;
|
||||
use derive_more::{Display, From};
|
||||
pub use futures::channel::oneshot::Canceled;
|
||||
pub use futures_channel::oneshot::Canceled;
|
||||
use http::uri::InvalidUri;
|
||||
use http::{header, Error as HttpError, StatusCode};
|
||||
use httparse;
|
||||
@@ -22,7 +22,7 @@ use serde_urlencoded::ser::Error as FormError;
|
||||
use crate::body::Body;
|
||||
pub use crate::cookie::ParseError as CookieParseError;
|
||||
use crate::helpers::Writer;
|
||||
use crate::response::Response;
|
||||
use crate::response::{Response, ResponseBuilder};
|
||||
|
||||
/// A specialized [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html)
|
||||
/// for actix web operations
|
||||
@@ -102,14 +102,14 @@ impl dyn ResponseError + 'static {
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.cause, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "{:?}", &self.cause)
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", &self.cause)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,20 @@ impl<T: ResponseError + 'static> From<T> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert Response to a Error
|
||||
impl From<Response> for Error {
|
||||
fn from(res: Response) -> Error {
|
||||
InternalError::from_response("", res).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert ResponseBuilder to a Error
|
||||
impl From<ResponseBuilder> for Error {
|
||||
fn from(mut res: ResponseBuilder) -> Error {
|
||||
InternalError::from_response("", res.finish()).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `GATEWAY_TIMEOUT` for `TimeoutError`
|
||||
impl<E: ResponseError> ResponseError for TimeoutError<E> {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
@@ -460,14 +474,12 @@ impl ResponseError for ContentTypeError {
|
||||
/// default.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_http;
|
||||
/// # use std::io;
|
||||
/// # use actix_http::*;
|
||||
///
|
||||
/// fn index(req: Request) -> Result<&'static str> {
|
||||
/// Err(error::ErrorBadRequest(io::Error::new(io::ErrorKind::Other, "error")))
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
pub struct InternalError<T> {
|
||||
cause: T,
|
||||
@@ -501,7 +513,7 @@ impl<T> fmt::Debug for InternalError<T>
|
||||
where
|
||||
T: fmt::Debug + 'static,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(&self.cause, f)
|
||||
}
|
||||
}
|
||||
@@ -510,7 +522,7 @@ impl<T> fmt::Display for InternalError<T>
|
||||
where
|
||||
T: fmt::Display + 'static,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.cause, f)
|
||||
}
|
||||
}
|
||||
@@ -555,13 +567,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert Response to a Error
|
||||
impl From<Response> for Error {
|
||||
fn from(res: Response) -> Error {
|
||||
InternalError::from_response("", res).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function that creates wrapper of any error and generate *BAD
|
||||
/// REQUEST* response.
|
||||
#[allow(non_snake_case)]
|
||||
@@ -952,13 +957,9 @@ where
|
||||
InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED).into()
|
||||
}
|
||||
|
||||
#[cfg(feature = "fail")]
|
||||
mod failure_integration {
|
||||
use super::*;
|
||||
|
||||
/// Compatibility for `failure::Error`
|
||||
impl ResponseError for failure::Error {}
|
||||
}
|
||||
#[cfg(feature = "failure")]
|
||||
/// Compatibility for `failure::Error`
|
||||
impl ResponseError for fail_ure::Error {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@@ -65,7 +65,7 @@ impl Extensions {
|
||||
}
|
||||
|
||||
impl fmt::Debug for Extensions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Extensions").finish()
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,8 @@
|
||||
#![allow(unused_imports, unused_variables, dead_code)]
|
||||
use std::io::{self, Write};
|
||||
use std::rc::Rc;
|
||||
use std::io;
|
||||
|
||||
use actix_codec::{Decoder, Encoder};
|
||||
use bitflags::bitflags;
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use http::header::{
|
||||
HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING, UPGRADE,
|
||||
};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use http::{Method, Version};
|
||||
|
||||
use super::decoder::{PayloadDecoder, PayloadItem, PayloadType};
|
||||
@@ -16,11 +11,7 @@ use super::{Message, MessageType};
|
||||
use crate::body::BodySize;
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::error::{ParseError, PayloadError};
|
||||
use crate::header::HeaderMap;
|
||||
use crate::helpers;
|
||||
use crate::message::{
|
||||
ConnectionType, Head, MessagePool, RequestHead, RequestHeadType, ResponseHead,
|
||||
};
|
||||
use crate::message::{ConnectionType, RequestHeadType, ResponseHead};
|
||||
|
||||
bitflags! {
|
||||
struct Flags: u8 {
|
||||
@@ -30,8 +21,6 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
const AVERAGE_HEADER_SIZE: usize = 30;
|
||||
|
||||
/// HTTP/1 Codec
|
||||
pub struct ClientCodec {
|
||||
inner: ClientCodecInner,
|
||||
@@ -51,7 +40,6 @@ struct ClientCodecInner {
|
||||
|
||||
// encoder part
|
||||
flags: Flags,
|
||||
headers_size: u32,
|
||||
encoder: encoder::MessageEncoder<RequestHeadType>,
|
||||
}
|
||||
|
||||
@@ -80,7 +68,6 @@ impl ClientCodec {
|
||||
ctype: ConnectionType::Close,
|
||||
|
||||
flags,
|
||||
headers_size: 0,
|
||||
encoder: encoder::MessageEncoder::default(),
|
||||
},
|
||||
}
|
||||
|
@@ -1,12 +1,9 @@
|
||||
#![allow(unused_imports, unused_variables, dead_code)]
|
||||
use std::io::Write;
|
||||
use std::{fmt, io, net};
|
||||
use std::{fmt, io};
|
||||
|
||||
use actix_codec::{Decoder, Encoder};
|
||||
use bitflags::bitflags;
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING};
|
||||
use http::{Method, StatusCode, Version};
|
||||
use bytes::BytesMut;
|
||||
use http::{Method, Version};
|
||||
|
||||
use super::decoder::{PayloadDecoder, PayloadItem, PayloadType};
|
||||
use super::{decoder, encoder};
|
||||
@@ -14,8 +11,7 @@ use super::{Message, MessageType};
|
||||
use crate::body::BodySize;
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::error::ParseError;
|
||||
use crate::helpers;
|
||||
use crate::message::{ConnectionType, Head, ResponseHead};
|
||||
use crate::message::ConnectionType;
|
||||
use crate::request::Request;
|
||||
use crate::response::Response;
|
||||
|
||||
@@ -27,8 +23,6 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
const AVERAGE_HEADER_SIZE: usize = 30;
|
||||
|
||||
/// HTTP/1 Codec
|
||||
pub struct Codec {
|
||||
config: ServiceConfig,
|
||||
@@ -49,7 +43,7 @@ impl Default for Codec {
|
||||
}
|
||||
|
||||
impl fmt::Debug for Codec {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "h1::Codec({:?})", self.flags)
|
||||
}
|
||||
}
|
||||
@@ -176,7 +170,6 @@ impl Encoder for Codec {
|
||||
};
|
||||
|
||||
// encode message
|
||||
let len = dst.len();
|
||||
self.encoder.encode(
|
||||
dst,
|
||||
&mut res,
|
||||
@@ -202,17 +195,11 @@ impl Encoder for Codec {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{cmp, io};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use bytes::{Buf, Bytes, BytesMut};
|
||||
use http::{Method, Version};
|
||||
use bytes::BytesMut;
|
||||
use http::Method;
|
||||
|
||||
use super::*;
|
||||
use crate::error::ParseError;
|
||||
use crate::h1::Message;
|
||||
use crate::httpmessage::HttpMessage;
|
||||
use crate::request::Request;
|
||||
|
||||
#[test]
|
||||
fn test_http_request_chunked_payload_and_next_message() {
|
||||
|
@@ -185,6 +185,7 @@ impl MessageType for Request {
|
||||
&mut self.head_mut().headers
|
||||
}
|
||||
|
||||
#[allow(clippy::uninit_assumed_init)]
|
||||
fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
|
||||
// Unsafe: we read only this data only after httparse parses headers into.
|
||||
// performance bump for pipeline benchmarks.
|
||||
@@ -192,7 +193,7 @@ impl MessageType for Request {
|
||||
unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
let (len, method, uri, ver, h_len) = {
|
||||
let mut parsed: [httparse::Header; MAX_HEADERS] =
|
||||
let mut parsed: [httparse::Header<'_>; MAX_HEADERS] =
|
||||
unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
let mut req = httparse::Request::new(&mut parsed);
|
||||
@@ -260,6 +261,7 @@ impl MessageType for ResponseHead {
|
||||
&mut self.headers
|
||||
}
|
||||
|
||||
#[allow(clippy::uninit_assumed_init)]
|
||||
fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
|
||||
// Unsafe: we read only this data only after httparse parses headers into.
|
||||
// performance bump for pipeline benchmarks.
|
||||
@@ -267,7 +269,7 @@ impl MessageType for ResponseHead {
|
||||
unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
let (len, ver, status, h_len) = {
|
||||
let mut parsed: [httparse::Header; MAX_HEADERS] =
|
||||
let mut parsed: [httparse::Header<'_>; MAX_HEADERS] =
|
||||
unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
let mut res = httparse::Response::new(&mut parsed);
|
||||
@@ -326,7 +328,7 @@ pub(crate) struct HeaderIndex {
|
||||
impl HeaderIndex {
|
||||
pub(crate) fn record(
|
||||
bytes: &[u8],
|
||||
headers: &[httparse::Header],
|
||||
headers: &[httparse::Header<'_>],
|
||||
indices: &mut [HeaderIndex],
|
||||
) {
|
||||
let bytes_ptr = bytes.as_ptr() as usize;
|
||||
@@ -475,7 +477,7 @@ macro_rules! byte (
|
||||
($rdr:ident) => ({
|
||||
if $rdr.len() > 0 {
|
||||
let b = $rdr[0];
|
||||
$rdr.split_to(1);
|
||||
let _ = $rdr.split_to(1);
|
||||
b
|
||||
} else {
|
||||
return Poll::Pending
|
||||
|
@@ -8,7 +8,7 @@ use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed, FramedParts};
|
||||
use actix_rt::time::{delay_until, Delay, Instant};
|
||||
use actix_service::Service;
|
||||
use bitflags::bitflags;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BytesMut;
|
||||
use log::{error, trace};
|
||||
|
||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||
@@ -66,6 +66,7 @@ where
|
||||
U::Error: fmt::Display,
|
||||
{
|
||||
Normal(InnerDispatcher<T, S, B, X, U>),
|
||||
UpgradeReadiness(InnerDispatcher<T, S, B, X, U>, Request),
|
||||
Upgrade(U::Future),
|
||||
None,
|
||||
}
|
||||
@@ -264,7 +265,7 @@ where
|
||||
U: Service<Request = (Request, Framed<T, Codec>), Response = ()>,
|
||||
U::Error: fmt::Display,
|
||||
{
|
||||
fn can_read(&self, cx: &mut Context) -> bool {
|
||||
fn can_read(&self, cx: &mut Context<'_>) -> bool {
|
||||
if self
|
||||
.flags
|
||||
.intersects(Flags::READ_DISCONNECT | Flags::UPGRADE)
|
||||
@@ -290,7 +291,7 @@ where
|
||||
///
|
||||
/// true - got whouldblock
|
||||
/// false - didnt get whouldblock
|
||||
fn poll_flush(&mut self, cx: &mut Context) -> Result<bool, DispatchError> {
|
||||
fn poll_flush(&mut self, cx: &mut Context<'_>) -> Result<bool, DispatchError> {
|
||||
if self.write_buf.is_empty() {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -355,7 +356,7 @@ where
|
||||
|
||||
fn poll_response(
|
||||
&mut self,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Result<PollResponse, DispatchError> {
|
||||
loop {
|
||||
let state = match self.state {
|
||||
@@ -459,7 +460,7 @@ where
|
||||
fn handle_request(
|
||||
&mut self,
|
||||
req: Request,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Result<State<S, B, X>, DispatchError> {
|
||||
// Handle `EXPECT: 100-Continue` header
|
||||
let req = if req.head().expect() {
|
||||
@@ -500,7 +501,7 @@ where
|
||||
/// Process one incoming requests
|
||||
pub(self) fn poll_request(
|
||||
&mut self,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Result<bool, DispatchError> {
|
||||
// limit a mount of non processed requests
|
||||
if self.messages.len() >= MAX_PIPELINED_MESSAGES || !self.can_read(cx) {
|
||||
@@ -604,7 +605,7 @@ where
|
||||
}
|
||||
|
||||
/// keep-alive timer
|
||||
fn poll_keepalive(&mut self, cx: &mut Context) -> Result<(), DispatchError> {
|
||||
fn poll_keepalive(&mut self, cx: &mut Context<'_>) -> Result<(), DispatchError> {
|
||||
if self.ka_timer.is_none() {
|
||||
// shutdown timeout
|
||||
if self.flags.contains(Flags::SHUTDOWN) {
|
||||
@@ -710,7 +711,7 @@ where
|
||||
type Output = Result<(), DispatchError>;
|
||||
|
||||
#[inline]
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
match self.as_mut().inner {
|
||||
DispatcherState::Normal(ref mut inner) => {
|
||||
inner.poll_keepalive(cx)?;
|
||||
@@ -750,8 +751,10 @@ where
|
||||
};
|
||||
|
||||
loop {
|
||||
if inner.write_buf.remaining_mut() < LW_BUFFER_SIZE {
|
||||
inner.write_buf.reserve(HW_BUFFER_SIZE);
|
||||
let remaining =
|
||||
inner.write_buf.capacity() - inner.write_buf.len();
|
||||
if remaining < LW_BUFFER_SIZE {
|
||||
inner.write_buf.reserve(HW_BUFFER_SIZE - remaining);
|
||||
}
|
||||
let result = inner.poll_response(cx)?;
|
||||
let drain = result == PollResponse::DrainWriteBuf;
|
||||
@@ -761,16 +764,8 @@ where
|
||||
if let DispatcherState::Normal(inner) =
|
||||
std::mem::replace(&mut self.inner, DispatcherState::None)
|
||||
{
|
||||
let mut parts = FramedParts::with_read_buf(
|
||||
inner.io,
|
||||
inner.codec,
|
||||
inner.read_buf,
|
||||
);
|
||||
parts.write_buf = inner.write_buf;
|
||||
let framed = Framed::from_parts(parts);
|
||||
self.inner = DispatcherState::Upgrade(
|
||||
inner.upgrade.unwrap().call((req, framed)),
|
||||
);
|
||||
self.inner =
|
||||
DispatcherState::UpgradeReadiness(inner, req);
|
||||
return self.poll(cx);
|
||||
} else {
|
||||
panic!()
|
||||
@@ -820,6 +815,35 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
DispatcherState::UpgradeReadiness(ref mut inner, _) => {
|
||||
let upgrade = inner.upgrade.as_mut().unwrap();
|
||||
match upgrade.poll_ready(cx) {
|
||||
Poll::Ready(Ok(_)) => {
|
||||
if let DispatcherState::UpgradeReadiness(inner, req) =
|
||||
std::mem::replace(&mut self.inner, DispatcherState::None)
|
||||
{
|
||||
let mut parts = FramedParts::with_read_buf(
|
||||
inner.io,
|
||||
inner.codec,
|
||||
inner.read_buf,
|
||||
);
|
||||
parts.write_buf = inner.write_buf;
|
||||
let framed = Framed::from_parts(parts);
|
||||
self.inner = DispatcherState::Upgrade(
|
||||
inner.upgrade.unwrap().call((req, framed)),
|
||||
);
|
||||
self.poll(cx)
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(Err(e)) => {
|
||||
error!("Upgrade handler readiness check error: {}", e);
|
||||
Poll::Ready(Err(DispatchError::Upgrade))
|
||||
}
|
||||
}
|
||||
}
|
||||
DispatcherState::Upgrade(ref mut fut) => {
|
||||
unsafe { Pin::new_unchecked(fut) }.poll(cx).map_err(|e| {
|
||||
error!("Upgrade handler error: {}", e);
|
||||
@@ -832,7 +856,7 @@ where
|
||||
}
|
||||
|
||||
fn read_available<T>(
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
io: &mut T,
|
||||
buf: &mut BytesMut,
|
||||
) -> Result<Option<bool>, io::Error>
|
||||
@@ -841,8 +865,9 @@ where
|
||||
{
|
||||
let mut read_some = false;
|
||||
loop {
|
||||
if buf.remaining_mut() < LW_BUFFER_SIZE {
|
||||
buf.reserve(HW_BUFFER_SIZE);
|
||||
let remaining = buf.capacity() - buf.len();
|
||||
if remaining < LW_BUFFER_SIZE {
|
||||
buf.reserve(HW_BUFFER_SIZE - remaining);
|
||||
}
|
||||
|
||||
match read(cx, io, buf) {
|
||||
@@ -874,7 +899,7 @@ where
|
||||
}
|
||||
|
||||
fn read<T>(
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
io: &mut T,
|
||||
buf: &mut BytesMut,
|
||||
) -> Poll<Result<usize, io::Error>>
|
||||
@@ -887,7 +912,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_service::IntoService;
|
||||
use futures::future::{lazy, ok};
|
||||
use futures_util::future::{lazy, ok};
|
||||
|
||||
use super::*;
|
||||
use crate::error::Error;
|
||||
|
@@ -1,25 +1,18 @@
|
||||
#![allow(unused_imports, unused_variables, dead_code)]
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
use std::rc::Rc;
|
||||
use std::slice::from_raw_parts_mut;
|
||||
use std::str::FromStr;
|
||||
use std::{cmp, fmt, io, mem};
|
||||
use std::{cmp, io};
|
||||
|
||||
use bytes::{buf::BufMutExt, BufMut, Bytes, BytesMut};
|
||||
use bytes::{buf::BufMutExt, BufMut, BytesMut};
|
||||
|
||||
use crate::body::BodySize;
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::header::{map, ContentEncoding};
|
||||
use crate::header::map;
|
||||
use crate::helpers;
|
||||
use crate::http::header::{
|
||||
HeaderValue, ACCEPT_ENCODING, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING,
|
||||
};
|
||||
use crate::http::{HeaderMap, Method, StatusCode, Version};
|
||||
use crate::message::{ConnectionType, Head, RequestHead, RequestHeadType, ResponseHead};
|
||||
use crate::request::Request;
|
||||
use crate::http::header::{CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING};
|
||||
use crate::http::{HeaderMap, StatusCode, Version};
|
||||
use crate::message::{ConnectionType, RequestHeadType};
|
||||
use crate::response::Response;
|
||||
|
||||
const AVERAGE_HEADER_SIZE: usize = 30;
|
||||
@@ -108,6 +101,7 @@ pub(crate) trait MessageType: Sized {
|
||||
} else {
|
||||
dst.put_slice(b"\r\ncontent-length: ");
|
||||
}
|
||||
#[allow(clippy::write_with_newline)]
|
||||
write!(dst.writer(), "{}\r\n", len)?;
|
||||
}
|
||||
BodySize::None => dst.put_slice(b"\r\n"),
|
||||
@@ -527,12 +521,14 @@ fn write_camel_case(value: &[u8], buffer: &mut [u8]) {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rc::Rc;
|
||||
|
||||
use bytes::Bytes;
|
||||
//use std::rc::Rc;
|
||||
use http::header::AUTHORIZATION;
|
||||
|
||||
use super::*;
|
||||
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
||||
use http::header::AUTHORIZATION;
|
||||
use crate::RequestHead;
|
||||
|
||||
#[test]
|
||||
fn test_chunked_te() {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_service::{Service, ServiceFactory};
|
||||
use futures::future::{ok, Ready};
|
||||
use futures_util::future::{ok, Ready};
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::request::Request;
|
||||
@@ -28,7 +28,7 @@ impl Service for ExpectHandler {
|
||||
type Error = Error;
|
||||
type Future = Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ use std::task::{Context, Poll};
|
||||
|
||||
use actix_utils::task::LocalWaker;
|
||||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
use futures_core::Stream;
|
||||
|
||||
use crate::error::PayloadError;
|
||||
|
||||
@@ -82,7 +82,7 @@ impl Payload {
|
||||
#[inline]
|
||||
pub fn readany(
|
||||
&mut self,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, PayloadError>>> {
|
||||
self.inner.borrow_mut().readany(cx)
|
||||
}
|
||||
@@ -93,7 +93,7 @@ impl Stream for Payload {
|
||||
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, PayloadError>>> {
|
||||
self.inner.borrow_mut().readany(cx)
|
||||
}
|
||||
@@ -127,7 +127,7 @@ impl PayloadSender {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn need_read(&self, cx: &mut Context) -> PayloadStatus {
|
||||
pub fn need_read(&self, cx: &mut Context<'_>) -> PayloadStatus {
|
||||
// we check need_read only if Payload (other side) is alive,
|
||||
// otherwise always return true (consume payload)
|
||||
if let Some(shared) = self.inner.upgrade() {
|
||||
@@ -194,7 +194,7 @@ impl Inner {
|
||||
|
||||
fn readany(
|
||||
&mut self,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, PayloadError>>> {
|
||||
if let Some(data) = self.items.pop_front() {
|
||||
self.len -= data.len();
|
||||
@@ -226,7 +226,7 @@ impl Inner {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use futures::future::poll_fn;
|
||||
use futures_util::future::poll_fn;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_unread_data() {
|
||||
|
@@ -8,8 +8,8 @@ use std::{fmt, net};
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_service::{pipeline_factory, IntoServiceFactory, Service, ServiceFactory};
|
||||
use futures::future::{ok, Ready};
|
||||
use futures::ready;
|
||||
use futures_core::ready;
|
||||
use futures_util::future::{ok, Ready};
|
||||
|
||||
use crate::body::MessageBody;
|
||||
use crate::cloneable::CloneableService;
|
||||
@@ -324,7 +324,7 @@ where
|
||||
{
|
||||
type Output = Result<H1ServiceHandler<T, S::Service, B, X::Service, U::Service>, ()>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let mut this = self.as_mut().project();
|
||||
|
||||
if let Some(fut) = this.fut_ex.as_pin_mut() {
|
||||
@@ -419,7 +419,7 @@ where
|
||||
type Error = DispatchError;
|
||||
type Future = Dispatcher<T, S, B, X, U>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
let ready = self
|
||||
.expect
|
||||
.poll_ready(cx)
|
||||
@@ -523,7 +523,7 @@ where
|
||||
type Error = ParseError;
|
||||
type Future = OneRequestServiceResponse<T>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ where
|
||||
{
|
||||
type Output = Result<(Request, Framed<T, Codec>), ParseError>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
match self.framed.as_mut().unwrap().next_item(cx) {
|
||||
Poll::Ready(Some(Ok(req))) => match req {
|
||||
Message::Item(req) => {
|
||||
|
@@ -3,7 +3,7 @@ use std::task::{Context, Poll};
|
||||
|
||||
use actix_codec::Framed;
|
||||
use actix_service::{Service, ServiceFactory};
|
||||
use futures::future::Ready;
|
||||
use futures_util::future::Ready;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::h1::Codec;
|
||||
@@ -31,7 +31,7 @@ impl<T> Service for UpgradeHandler<T> {
|
||||
type Error = Error;
|
||||
type Future = Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ where
|
||||
{
|
||||
type Output = Result<Framed<T, Codec>, Error>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.get_mut();
|
||||
|
||||
loop {
|
||||
|
@@ -1,28 +1,23 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::net;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{fmt, mem, net};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use actix_rt::time::{Delay, Instant};
|
||||
use actix_service::Service;
|
||||
use bitflags::bitflags;
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::{ready, Sink, Stream};
|
||||
use h2::server::{Connection, SendResponse};
|
||||
use h2::{RecvStream, SendStream};
|
||||
use http::header::{
|
||||
HeaderValue, ACCEPT_ENCODING, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING,
|
||||
};
|
||||
use log::{debug, error, trace};
|
||||
use h2::SendStream;
|
||||
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING};
|
||||
use log::{error, trace};
|
||||
|
||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||
use crate::body::{BodySize, MessageBody, ResponseBody};
|
||||
use crate::cloneable::CloneableService;
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::error::{DispatchError, Error, ParseError, PayloadError, ResponseError};
|
||||
use crate::error::{DispatchError, Error};
|
||||
use crate::helpers::DataFactory;
|
||||
use crate::httpmessage::HttpMessage;
|
||||
use crate::message::ResponseHead;
|
||||
@@ -106,7 +101,7 @@ where
|
||||
type Output = Result<(), DispatchError>;
|
||||
|
||||
#[inline]
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.get_mut();
|
||||
|
||||
loop {
|
||||
@@ -252,7 +247,7 @@ where
|
||||
{
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let mut this = self.as_mut().project();
|
||||
|
||||
match this.state {
|
||||
|
@@ -1,11 +1,9 @@
|
||||
#![allow(dead_code, unused_imports)]
|
||||
use std::fmt;
|
||||
use std::future::Future;
|
||||
//! HTTP/2 implementation
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
use futures_core::Stream;
|
||||
use h2::RecvStream;
|
||||
|
||||
mod dispatcher;
|
||||
@@ -29,7 +27,10 @@ impl Payload {
|
||||
impl Stream for Payload {
|
||||
type Item = Result<Bytes, PayloadError>;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
let this = self.get_mut();
|
||||
|
||||
match Pin::new(&mut this.pl).poll_data(cx) {
|
||||
|
@@ -1,32 +1,28 @@
|
||||
use std::fmt::Debug;
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{io, net, rc};
|
||||
use std::{net, rc};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_service::{
|
||||
factory_fn, pipeline_factory, service_fn2, IntoServiceFactory, Service,
|
||||
fn_factory, fn_service, pipeline_factory, IntoServiceFactory, Service,
|
||||
ServiceFactory,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use futures::future::{ok, Ready};
|
||||
use futures::{ready, Stream};
|
||||
use h2::server::{self, Connection, Handshake};
|
||||
use h2::RecvStream;
|
||||
use futures_core::ready;
|
||||
use futures_util::future::ok;
|
||||
use h2::server::{self, Handshake};
|
||||
use log::error;
|
||||
|
||||
use crate::body::MessageBody;
|
||||
use crate::cloneable::CloneableService;
|
||||
use crate::config::{KeepAlive, ServiceConfig};
|
||||
use crate::error::{DispatchError, Error, ParseError, ResponseError};
|
||||
use crate::config::ServiceConfig;
|
||||
use crate::error::{DispatchError, Error};
|
||||
use crate::helpers::DataFactory;
|
||||
use crate::payload::Payload;
|
||||
use crate::request::Request;
|
||||
use crate::response::Response;
|
||||
use crate::Protocol;
|
||||
|
||||
use super::dispatcher::Dispatcher;
|
||||
|
||||
@@ -87,9 +83,9 @@ where
|
||||
Error = DispatchError,
|
||||
InitError = S::InitError,
|
||||
> {
|
||||
pipeline_factory(factory_fn(|| {
|
||||
pipeline_factory(fn_factory(|| {
|
||||
async {
|
||||
Ok::<_, S::InitError>(service_fn2(|io: TcpStream| {
|
||||
Ok::<_, S::InitError>(fn_service(|io: TcpStream| {
|
||||
let peer_addr = io.peer_addr().ok();
|
||||
ok::<_, DispatchError>((io, peer_addr))
|
||||
}))
|
||||
@@ -101,7 +97,7 @@ where
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
mod openssl {
|
||||
use actix_service::{factory_fn, service_fn2};
|
||||
use actix_service::{fn_factory, fn_service};
|
||||
use actix_tls::openssl::{Acceptor, SslAcceptor, SslStream};
|
||||
use actix_tls::{openssl::HandshakeError, SslError};
|
||||
|
||||
@@ -131,8 +127,8 @@ mod openssl {
|
||||
.map_err(SslError::Ssl)
|
||||
.map_init_err(|_| panic!()),
|
||||
)
|
||||
.and_then(factory_fn(|| {
|
||||
ok::<_, S::InitError>(service_fn2(|io: SslStream<TcpStream>| {
|
||||
.and_then(fn_factory(|| {
|
||||
ok::<_, S::InitError>(fn_service(|io: SslStream<TcpStream>| {
|
||||
let peer_addr = io.get_ref().peer_addr().ok();
|
||||
ok((io, peer_addr))
|
||||
}))
|
||||
@@ -145,9 +141,9 @@ mod openssl {
|
||||
#[cfg(feature = "rustls")]
|
||||
mod rustls {
|
||||
use super::*;
|
||||
use actix_tls::rustls::{Acceptor, ServerConfig, Session, TlsStream};
|
||||
use actix_tls::rustls::{Acceptor, ServerConfig, TlsStream};
|
||||
use actix_tls::SslError;
|
||||
use std::{fmt, io};
|
||||
use std::io;
|
||||
|
||||
impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
|
||||
where
|
||||
@@ -176,8 +172,8 @@ mod rustls {
|
||||
.map_err(SslError::Ssl)
|
||||
.map_init_err(|_| panic!()),
|
||||
)
|
||||
.and_then(factory_fn(|| {
|
||||
ok::<_, S::InitError>(service_fn2(|io: TlsStream<TcpStream>| {
|
||||
.and_then(fn_factory(|| {
|
||||
ok::<_, S::InitError>(fn_service(|io: TlsStream<TcpStream>| {
|
||||
let peer_addr = io.get_ref().0.peer_addr().ok();
|
||||
ok((io, peer_addr))
|
||||
}))
|
||||
@@ -235,7 +231,7 @@ where
|
||||
{
|
||||
type Output = Result<H2ServiceHandler<T, S::Service, B>, S::InitError>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.as_mut().project();
|
||||
|
||||
Poll::Ready(ready!(this.fut.poll(cx)).map(|service| {
|
||||
@@ -293,7 +289,7 @@ where
|
||||
type Error = DispatchError;
|
||||
type Future = H2ServiceHandlerResponse<T, S, B>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.srv.poll_ready(cx).map_err(|e| {
|
||||
let e = e.into();
|
||||
error!("Service readiness error: {:?}", e);
|
||||
@@ -358,7 +354,7 @@ where
|
||||
{
|
||||
type Output = Result<(), DispatchError>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
match self.state {
|
||||
State::Incoming(ref mut disp) => Pin::new(disp).poll(cx),
|
||||
State::Handshake(
|
||||
|
@@ -74,7 +74,7 @@ impl Header for CacheControl {
|
||||
}
|
||||
|
||||
impl fmt::Display for CacheControl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt_comma_delimited(f, &self[..])
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ pub enum CacheDirective {
|
||||
}
|
||||
|
||||
impl fmt::Display for CacheDirective {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use self::CacheDirective::*;
|
||||
fmt::Display::fmt(
|
||||
match *self {
|
||||
|
@@ -486,7 +486,7 @@ impl Header for ContentDisposition {
|
||||
}
|
||||
|
||||
impl fmt::Display for DispositionType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
DispositionType::Inline => write!(f, "inline"),
|
||||
DispositionType::Attachment => write!(f, "attachment"),
|
||||
@@ -497,7 +497,7 @@ impl fmt::Display for DispositionType {
|
||||
}
|
||||
|
||||
impl fmt::Display for DispositionParam {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// All ASCII control characters (0-30, 127) including horizontal tab, double quote, and
|
||||
// backslash should be escaped in quoted-string (i.e. "foobar").
|
||||
// Ref: RFC6266 S4.1 -> RFC2616 S3.6
|
||||
@@ -555,7 +555,7 @@ impl fmt::Display for DispositionParam {
|
||||
}
|
||||
|
||||
impl fmt::Display for ContentDisposition {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.disposition)?;
|
||||
self.parameters
|
||||
.iter()
|
||||
|
@@ -166,7 +166,7 @@ impl FromStr for ContentRangeSpec {
|
||||
}
|
||||
|
||||
impl Display for ContentRangeSpec {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
ContentRangeSpec::Bytes {
|
||||
range,
|
||||
|
@@ -87,7 +87,7 @@ impl Header for IfRange {
|
||||
}
|
||||
|
||||
impl Display for IfRange {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
IfRange::EntityTag(ref x) => Display::fmt(x, f),
|
||||
IfRange::Date(ref x) => Display::fmt(x, f),
|
||||
|
@@ -159,7 +159,7 @@ macro_rules! header {
|
||||
}
|
||||
impl std::fmt::Display for $id {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
$crate::http::header::fmt_comma_delimited(f, &self.0[..])
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ macro_rules! header {
|
||||
}
|
||||
impl std::fmt::Display for $id {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
$crate::http::header::fmt_comma_delimited(f, &self.0[..])
|
||||
}
|
||||
}
|
||||
@@ -231,7 +231,7 @@ macro_rules! header {
|
||||
}
|
||||
impl std::fmt::Display for $id {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@ macro_rules! header {
|
||||
}
|
||||
impl std::fmt::Display for $id {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match *self {
|
||||
$id::Any => f.write_str("*"),
|
||||
$id::Items(ref fields) => $crate::http::header::fmt_comma_delimited(
|
||||
|
@@ -143,7 +143,7 @@ impl HeaderMap {
|
||||
/// Returns `None` if there are no values associated with the key.
|
||||
///
|
||||
/// [`GetAll`]: struct.GetAll.html
|
||||
pub fn get_all<N: AsName>(&self, name: N) -> GetAll {
|
||||
pub fn get_all<N: AsName>(&self, name: N) -> GetAll<'_> {
|
||||
GetAll {
|
||||
idx: 0,
|
||||
item: self.get2(name),
|
||||
@@ -187,7 +187,7 @@ impl HeaderMap {
|
||||
/// The iteration order is arbitrary, but consistent across platforms for
|
||||
/// the same crate version. Each key will be yielded once per associated
|
||||
/// value. So, if a key has 3 associated values, it will be yielded 3 times.
|
||||
pub fn iter(&self) -> Iter {
|
||||
pub fn iter(&self) -> Iter<'_> {
|
||||
Iter::new(self.inner.iter())
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ impl HeaderMap {
|
||||
/// The iteration order is arbitrary, but consistent across platforms for
|
||||
/// the same crate version. Each key will be yielded only once even if it
|
||||
/// has multiple associated values.
|
||||
pub fn keys(&self) -> Keys {
|
||||
pub fn keys(&self) -> Keys<'_> {
|
||||
Keys(self.inner.keys())
|
||||
}
|
||||
|
||||
|
@@ -217,7 +217,7 @@ impl fmt::Write for Writer {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
|
||||
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
|
||||
fmt::write(self, args)
|
||||
}
|
||||
}
|
||||
@@ -259,7 +259,7 @@ pub fn from_one_raw_str<T: FromStr>(val: Option<&HeaderValue>) -> Result<T, Pars
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
/// Format an array into a comma-delimited string.
|
||||
pub fn fmt_comma_delimited<T>(f: &mut fmt::Formatter, parts: &[T]) -> fmt::Result
|
||||
pub fn fmt_comma_delimited<T>(f: &mut fmt::Formatter<'_>, parts: &[T]) -> fmt::Result
|
||||
where
|
||||
T: fmt::Display,
|
||||
{
|
||||
@@ -361,7 +361,7 @@ pub fn parse_extended_value(
|
||||
}
|
||||
|
||||
impl fmt::Display for ExtendedValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let encoded_value =
|
||||
percent_encoding::percent_encode(&self.value[..], HTTP_VALUE);
|
||||
if let Some(ref lang) = self.language_tag {
|
||||
@@ -376,7 +376,7 @@ impl fmt::Display for ExtendedValue {
|
||||
/// [https://tools.ietf.org/html/rfc5987#section-3.2][url]
|
||||
///
|
||||
/// [url]: https://tools.ietf.org/html/rfc5987#section-3.2
|
||||
pub fn http_percent_encode(f: &mut fmt::Formatter, bytes: &[u8]) -> fmt::Result {
|
||||
pub fn http_percent_encode(f: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result {
|
||||
let encoded = percent_encoding::percent_encode(bytes, HTTP_VALUE);
|
||||
fmt::Display::fmt(&encoded, f)
|
||||
}
|
||||
|
@@ -98,7 +98,7 @@ impl Charset {
|
||||
}
|
||||
|
||||
impl Display for Charset {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.label())
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ pub enum Encoding {
|
||||
}
|
||||
|
||||
impl fmt::Display for Encoding {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(match *self {
|
||||
Chunked => "chunked",
|
||||
Brotli => "br",
|
||||
|
@@ -113,7 +113,7 @@ impl EntityTag {
|
||||
}
|
||||
|
||||
impl Display for EntityTag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if self.weak {
|
||||
write!(f, "W/\"{}\"", self.tag)
|
||||
} else {
|
||||
|
@@ -28,7 +28,7 @@ impl FromStr for HttpDate {
|
||||
}
|
||||
|
||||
impl Display for HttpDate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.0.to_utc().rfc822(), f)
|
||||
}
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ impl<T: PartialEq> cmp::PartialOrd for QualityItem<T> {
|
||||
}
|
||||
|
||||
impl<T: fmt::Display> fmt::Display for QualityItem<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.item, f)?;
|
||||
match self.quality.0 {
|
||||
1000 => Ok(()),
|
||||
|
@@ -25,10 +25,10 @@ pub trait HttpMessage: Sized {
|
||||
fn take_payload(&mut self) -> Payload<Self::Stream>;
|
||||
|
||||
/// Request's extensions container
|
||||
fn extensions(&self) -> Ref<Extensions>;
|
||||
fn extensions(&self) -> Ref<'_, Extensions>;
|
||||
|
||||
/// Mutable reference to a the request's extensions container
|
||||
fn extensions_mut(&self) -> RefMut<Extensions>;
|
||||
fn extensions_mut(&self) -> RefMut<'_, Extensions>;
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Get a header
|
||||
@@ -105,7 +105,7 @@ pub trait HttpMessage: Sized {
|
||||
|
||||
/// Load request cookies.
|
||||
#[inline]
|
||||
fn cookies(&self) -> Result<Ref<Vec<Cookie<'static>>>, CookieParseError> {
|
||||
fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
|
||||
if self.extensions().get::<Cookies>().is_none() {
|
||||
let mut cookies = Vec::new();
|
||||
for hdr in self.headers().get_all(header::COOKIE) {
|
||||
@@ -153,12 +153,12 @@ where
|
||||
}
|
||||
|
||||
/// Request's extensions container
|
||||
fn extensions(&self) -> Ref<Extensions> {
|
||||
fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
(**self).extensions()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the request's extensions container
|
||||
fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||
fn extensions_mut(&self) -> RefMut<'_, Extensions> {
|
||||
(**self).extensions_mut()
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
//! Basic http primitives for actix-net framework.
|
||||
#![deny(rust_2018_idioms, warnings)]
|
||||
#![allow(
|
||||
clippy::type_complexity,
|
||||
clippy::too_many_arguments,
|
||||
clippy::new_without_default,
|
||||
clippy::borrow_interior_mutable_const,
|
||||
clippy::write_with_newline
|
||||
clippy::borrow_interior_mutable_const
|
||||
)]
|
||||
|
||||
#[macro_use]
|
||||
@@ -15,6 +15,7 @@ mod builder;
|
||||
pub mod client;
|
||||
mod cloneable;
|
||||
mod config;
|
||||
#[cfg(feature = "compress")]
|
||||
pub mod encoding;
|
||||
mod extensions;
|
||||
mod header;
|
||||
|
@@ -78,13 +78,13 @@ impl Head for RequestHead {
|
||||
impl RequestHead {
|
||||
/// Message extensions
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<Extensions> {
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the message's extensions
|
||||
#[inline]
|
||||
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||
pub fn extensions_mut(&self) -> RefMut<'_, Extensions> {
|
||||
self.extensions.borrow_mut()
|
||||
}
|
||||
|
||||
@@ -237,13 +237,13 @@ impl ResponseHead {
|
||||
|
||||
/// Message extensions
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<Extensions> {
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the message's extensions
|
||||
#[inline]
|
||||
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||
pub fn extensions_mut(&self) -> RefMut<'_, Extensions> {
|
||||
self.extensions.borrow_mut()
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@ use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
use futures_core::Stream;
|
||||
use h2::RecvStream;
|
||||
|
||||
use crate::error::PayloadError;
|
||||
@@ -56,7 +56,10 @@ where
|
||||
type Item = Result<Bytes, PayloadError>;
|
||||
|
||||
#[inline]
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
match self.get_mut() {
|
||||
Payload::None => Poll::Ready(None),
|
||||
Payload::H1(ref mut pl) => pl.readany(cx),
|
||||
|
@@ -25,13 +25,13 @@ impl<P> HttpMessage for Request<P> {
|
||||
|
||||
/// Request extensions
|
||||
#[inline]
|
||||
fn extensions(&self) -> Ref<Extensions> {
|
||||
fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.head.extensions()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the request's extensions
|
||||
#[inline]
|
||||
fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||
fn extensions_mut(&self) -> RefMut<'_, Extensions> {
|
||||
self.head.extensions_mut()
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ impl<P> Request<P> {
|
||||
}
|
||||
|
||||
impl<P> fmt::Debug for Request<P> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(
|
||||
f,
|
||||
"\nRequest {:?} {}:{}",
|
||||
|
@@ -7,7 +7,7 @@ use std::task::{Context, Poll};
|
||||
use std::{fmt, str};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::stream::Stream;
|
||||
use futures_core::Stream;
|
||||
use serde::Serialize;
|
||||
use serde_json;
|
||||
|
||||
@@ -130,7 +130,7 @@ impl<B> Response<B> {
|
||||
|
||||
/// Get an iterator for the cookies set by this response
|
||||
#[inline]
|
||||
pub fn cookies(&self) -> CookieIter {
|
||||
pub fn cookies(&self) -> CookieIter<'_> {
|
||||
CookieIter {
|
||||
iter: self.head.headers.get_all(header::SET_COOKIE),
|
||||
}
|
||||
@@ -138,7 +138,7 @@ impl<B> Response<B> {
|
||||
|
||||
/// Add a cookie to this response
|
||||
#[inline]
|
||||
pub fn add_cookie(&mut self, cookie: &Cookie) -> Result<(), HttpError> {
|
||||
pub fn add_cookie(&mut self, cookie: &Cookie<'_>) -> Result<(), HttpError> {
|
||||
let h = &mut self.head.headers;
|
||||
HeaderValue::from_str(&cookie.to_string())
|
||||
.map(|c| {
|
||||
@@ -186,13 +186,13 @@ impl<B> Response<B> {
|
||||
|
||||
/// Responses extensions
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<Extensions> {
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.head.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the response's extensions
|
||||
#[inline]
|
||||
pub fn extensions_mut(&mut self) -> RefMut<Extensions> {
|
||||
pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
|
||||
self.head.extensions.borrow_mut()
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ impl<B> Response<B> {
|
||||
}
|
||||
|
||||
impl<B: MessageBody> fmt::Debug for Response<B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let res = writeln!(
|
||||
f,
|
||||
"\nResponse {:?} {}{}",
|
||||
@@ -285,7 +285,7 @@ impl<B: MessageBody> fmt::Debug for Response<B> {
|
||||
impl Future for Response {
|
||||
type Output = Result<Response, Error>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(Response {
|
||||
head: self.head.take(),
|
||||
body: self.body.take_body(),
|
||||
@@ -354,7 +354,6 @@ impl ResponseBuilder {
|
||||
/// ))
|
||||
/// .finish())
|
||||
/// }
|
||||
/// fn main() {}
|
||||
/// ```
|
||||
#[doc(hidden)]
|
||||
pub fn set<H: Header>(&mut self, hdr: H) -> &mut Self {
|
||||
@@ -380,7 +379,6 @@ impl ResponseBuilder {
|
||||
/// .header(http::header::CONTENT_TYPE, "application/json")
|
||||
/// .finish()
|
||||
/// }
|
||||
/// fn main() {}
|
||||
/// ```
|
||||
pub fn header<K, V>(&mut self, key: K, value: V) -> &mut Self
|
||||
where
|
||||
@@ -413,7 +411,6 @@ impl ResponseBuilder {
|
||||
/// .set_header(http::header::CONTENT_TYPE, "application/json")
|
||||
/// .finish()
|
||||
/// }
|
||||
/// fn main() {}
|
||||
/// ```
|
||||
pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
|
||||
where
|
||||
@@ -588,14 +585,14 @@ impl ResponseBuilder {
|
||||
|
||||
/// Responses extensions
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<Extensions> {
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
let head = self.head.as_ref().expect("cannot reuse response builder");
|
||||
head.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the response's extensions
|
||||
#[inline]
|
||||
pub fn extensions_mut(&mut self) -> RefMut<Extensions> {
|
||||
pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
|
||||
let head = self.head.as_ref().expect("cannot reuse response builder");
|
||||
head.extensions.borrow_mut()
|
||||
}
|
||||
@@ -765,13 +762,13 @@ impl<'a> From<&'a ResponseHead> for ResponseBuilder {
|
||||
impl Future for ResponseBuilder {
|
||||
type Output = Result<Response, Error>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(self.finish()))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ResponseBuilder {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let head = self.head.as_ref().unwrap();
|
||||
|
||||
let res = writeln!(
|
||||
|
@@ -7,7 +7,8 @@ use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_service::{pipeline_factory, IntoServiceFactory, Service, ServiceFactory};
|
||||
use bytes::Bytes;
|
||||
use futures::{future::ok, ready, Future};
|
||||
use futures_core::{ready, Future};
|
||||
use futures_util::future::ok;
|
||||
use h2::server::{self, Handshake};
|
||||
use pin_project::{pin_project, project};
|
||||
|
||||
@@ -403,7 +404,7 @@ where
|
||||
type Output =
|
||||
Result<HttpServiceHandler<T, S::Service, B, X::Service, U::Service>, ()>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let mut this = self.as_mut().project();
|
||||
|
||||
if let Some(fut) = this.fut_ex.as_pin_mut() {
|
||||
@@ -499,7 +500,7 @@ where
|
||||
type Error = DispatchError;
|
||||
type Future = HttpServiceHandlerResponse<T, S, B, X, U>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
let ready = self
|
||||
.expect
|
||||
.poll_ready(cx)
|
||||
@@ -619,7 +620,7 @@ where
|
||||
{
|
||||
type Output = Result<(), DispatchError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
self.project().state.poll(cx)
|
||||
}
|
||||
}
|
||||
@@ -639,7 +640,7 @@ where
|
||||
#[project]
|
||||
fn poll(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), DispatchError>> {
|
||||
#[project]
|
||||
match self.as_mut().project() {
|
||||
|
@@ -21,8 +21,6 @@ use crate::Request;
|
||||
/// Test `Request` builder
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// # extern crate http;
|
||||
/// # extern crate actix_web;
|
||||
/// # use http::{header, StatusCode};
|
||||
/// # use actix_web::*;
|
||||
/// use actix_web::test::TestRequest;
|
||||
@@ -35,15 +33,13 @@ use crate::Request;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let resp = TestRequest::with_header("content-type", "text/plain")
|
||||
/// .run(&index)
|
||||
/// .unwrap();
|
||||
/// assert_eq!(resp.status(), StatusCode::OK);
|
||||
/// let resp = TestRequest::with_header("content-type", "text/plain")
|
||||
/// .run(&index)
|
||||
/// .unwrap();
|
||||
/// assert_eq!(resp.status(), StatusCode::OK);
|
||||
///
|
||||
/// let resp = TestRequest::default().run(&index).unwrap();
|
||||
/// assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
/// }
|
||||
/// let resp = TestRequest::default().run(&index).unwrap();
|
||||
/// assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
/// ```
|
||||
pub struct TestRequest(Option<Inner>);
|
||||
|
||||
|
@@ -12,10 +12,12 @@ pub enum Message {
|
||||
Text(String),
|
||||
/// Binary message
|
||||
Binary(Bytes),
|
||||
/// Continuation
|
||||
Continuation(Item),
|
||||
/// Ping message
|
||||
Ping(String),
|
||||
Ping(Bytes),
|
||||
/// Pong message
|
||||
Pong(String),
|
||||
Pong(Bytes),
|
||||
/// Close message with optional reason
|
||||
Close(Option<CloseReason>),
|
||||
/// No-op. Useful for actix-net services
|
||||
@@ -26,22 +28,41 @@ pub enum Message {
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Frame {
|
||||
/// Text frame, codec does not verify utf8 encoding
|
||||
Text(Option<BytesMut>),
|
||||
Text(Bytes),
|
||||
/// Binary frame
|
||||
Binary(Option<BytesMut>),
|
||||
Binary(Bytes),
|
||||
/// Continuation
|
||||
Continuation(Item),
|
||||
/// Ping message
|
||||
Ping(String),
|
||||
Ping(Bytes),
|
||||
/// Pong message
|
||||
Pong(String),
|
||||
Pong(Bytes),
|
||||
/// Close message with optional reason
|
||||
Close(Option<CloseReason>),
|
||||
}
|
||||
|
||||
/// `WebSocket` continuation item
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Item {
|
||||
FirstText(Bytes),
|
||||
FirstBinary(Bytes),
|
||||
Continue(Bytes),
|
||||
Last(Bytes),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
/// WebSockets protocol codec
|
||||
pub struct Codec {
|
||||
flags: Flags,
|
||||
max_size: usize,
|
||||
server: bool,
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
struct Flags: u8 {
|
||||
const SERVER = 0b0000_0001;
|
||||
const CONTINUATION = 0b0000_0010;
|
||||
const W_CONTINUATION = 0b0000_0100;
|
||||
}
|
||||
}
|
||||
|
||||
impl Codec {
|
||||
@@ -49,7 +70,7 @@ impl Codec {
|
||||
pub fn new() -> Codec {
|
||||
Codec {
|
||||
max_size: 65_536,
|
||||
server: true,
|
||||
flags: Flags::SERVER,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +86,7 @@ impl Codec {
|
||||
///
|
||||
/// By default decoder works in server mode.
|
||||
pub fn client_mode(mut self) -> Self {
|
||||
self.server = false;
|
||||
self.flags.remove(Flags::SERVER);
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -76,19 +97,94 @@ impl Encoder for Codec {
|
||||
|
||||
fn encode(&mut self, item: Message, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
match item {
|
||||
Message::Text(txt) => {
|
||||
Parser::write_message(dst, txt, OpCode::Text, true, !self.server)
|
||||
Message::Text(txt) => Parser::write_message(
|
||||
dst,
|
||||
txt,
|
||||
OpCode::Text,
|
||||
true,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
),
|
||||
Message::Binary(bin) => Parser::write_message(
|
||||
dst,
|
||||
bin,
|
||||
OpCode::Binary,
|
||||
true,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
),
|
||||
Message::Ping(txt) => Parser::write_message(
|
||||
dst,
|
||||
txt,
|
||||
OpCode::Ping,
|
||||
true,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
),
|
||||
Message::Pong(txt) => Parser::write_message(
|
||||
dst,
|
||||
txt,
|
||||
OpCode::Pong,
|
||||
true,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
),
|
||||
Message::Close(reason) => {
|
||||
Parser::write_close(dst, reason, !self.flags.contains(Flags::SERVER))
|
||||
}
|
||||
Message::Binary(bin) => {
|
||||
Parser::write_message(dst, bin, OpCode::Binary, true, !self.server)
|
||||
}
|
||||
Message::Ping(txt) => {
|
||||
Parser::write_message(dst, txt, OpCode::Ping, true, !self.server)
|
||||
}
|
||||
Message::Pong(txt) => {
|
||||
Parser::write_message(dst, txt, OpCode::Pong, true, !self.server)
|
||||
}
|
||||
Message::Close(reason) => Parser::write_close(dst, reason, !self.server),
|
||||
Message::Continuation(cont) => match cont {
|
||||
Item::FirstText(data) => {
|
||||
if self.flags.contains(Flags::W_CONTINUATION) {
|
||||
return Err(ProtocolError::ContinuationStarted);
|
||||
} else {
|
||||
self.flags.insert(Flags::W_CONTINUATION);
|
||||
Parser::write_message(
|
||||
dst,
|
||||
&data[..],
|
||||
OpCode::Binary,
|
||||
false,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
)
|
||||
}
|
||||
}
|
||||
Item::FirstBinary(data) => {
|
||||
if self.flags.contains(Flags::W_CONTINUATION) {
|
||||
return Err(ProtocolError::ContinuationStarted);
|
||||
} else {
|
||||
self.flags.insert(Flags::W_CONTINUATION);
|
||||
Parser::write_message(
|
||||
dst,
|
||||
&data[..],
|
||||
OpCode::Text,
|
||||
false,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
)
|
||||
}
|
||||
}
|
||||
Item::Continue(data) => {
|
||||
if self.flags.contains(Flags::W_CONTINUATION) {
|
||||
Parser::write_message(
|
||||
dst,
|
||||
&data[..],
|
||||
OpCode::Continue,
|
||||
false,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
)
|
||||
} else {
|
||||
return Err(ProtocolError::ContinuationNotStarted);
|
||||
}
|
||||
}
|
||||
Item::Last(data) => {
|
||||
if self.flags.contains(Flags::W_CONTINUATION) {
|
||||
self.flags.remove(Flags::W_CONTINUATION);
|
||||
Parser::write_message(
|
||||
dst,
|
||||
&data[..],
|
||||
OpCode::Continue,
|
||||
true,
|
||||
!self.flags.contains(Flags::SERVER),
|
||||
)
|
||||
} else {
|
||||
return Err(ProtocolError::ContinuationNotStarted);
|
||||
}
|
||||
}
|
||||
},
|
||||
Message::Nop => (),
|
||||
}
|
||||
Ok(())
|
||||
@@ -100,15 +196,64 @@ impl Decoder for Codec {
|
||||
type Error = ProtocolError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
match Parser::parse(src, self.server, self.max_size) {
|
||||
match Parser::parse(src, self.flags.contains(Flags::SERVER), self.max_size) {
|
||||
Ok(Some((finished, opcode, payload))) => {
|
||||
// continuation is not supported
|
||||
if !finished {
|
||||
return Err(ProtocolError::NoContinuation);
|
||||
return match opcode {
|
||||
OpCode::Continue => {
|
||||
if self.flags.contains(Flags::CONTINUATION) {
|
||||
Ok(Some(Frame::Continuation(Item::Continue(
|
||||
payload
|
||||
.map(|pl| pl.freeze())
|
||||
.unwrap_or_else(Bytes::new),
|
||||
))))
|
||||
} else {
|
||||
Err(ProtocolError::ContinuationNotStarted)
|
||||
}
|
||||
}
|
||||
OpCode::Binary => {
|
||||
if !self.flags.contains(Flags::CONTINUATION) {
|
||||
self.flags.insert(Flags::CONTINUATION);
|
||||
Ok(Some(Frame::Continuation(Item::FirstBinary(
|
||||
payload
|
||||
.map(|pl| pl.freeze())
|
||||
.unwrap_or_else(Bytes::new),
|
||||
))))
|
||||
} else {
|
||||
Err(ProtocolError::ContinuationStarted)
|
||||
}
|
||||
}
|
||||
OpCode::Text => {
|
||||
if !self.flags.contains(Flags::CONTINUATION) {
|
||||
self.flags.insert(Flags::CONTINUATION);
|
||||
Ok(Some(Frame::Continuation(Item::FirstText(
|
||||
payload
|
||||
.map(|pl| pl.freeze())
|
||||
.unwrap_or_else(Bytes::new),
|
||||
))))
|
||||
} else {
|
||||
Err(ProtocolError::ContinuationStarted)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
error!("Unfinished fragment {:?}", opcode);
|
||||
Err(ProtocolError::ContinuationFragment(opcode))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
match opcode {
|
||||
OpCode::Continue => Err(ProtocolError::NoContinuation),
|
||||
OpCode::Continue => {
|
||||
if self.flags.contains(Flags::CONTINUATION) {
|
||||
self.flags.remove(Flags::CONTINUATION);
|
||||
Ok(Some(Frame::Continuation(Item::Last(
|
||||
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
|
||||
))))
|
||||
} else {
|
||||
Err(ProtocolError::ContinuationNotStarted)
|
||||
}
|
||||
}
|
||||
OpCode::Bad => Err(ProtocolError::BadOpCode),
|
||||
OpCode::Close => {
|
||||
if let Some(ref pl) = payload {
|
||||
@@ -118,29 +263,18 @@ impl Decoder for Codec {
|
||||
Ok(Some(Frame::Close(None)))
|
||||
}
|
||||
}
|
||||
OpCode::Ping => {
|
||||
if let Some(ref pl) = payload {
|
||||
Ok(Some(Frame::Ping(String::from_utf8_lossy(pl).into())))
|
||||
} else {
|
||||
Ok(Some(Frame::Ping(String::new())))
|
||||
}
|
||||
}
|
||||
OpCode::Pong => {
|
||||
if let Some(ref pl) = payload {
|
||||
Ok(Some(Frame::Pong(String::from_utf8_lossy(pl).into())))
|
||||
} else {
|
||||
Ok(Some(Frame::Pong(String::new())))
|
||||
}
|
||||
}
|
||||
OpCode::Binary => Ok(Some(Frame::Binary(payload))),
|
||||
OpCode::Text => {
|
||||
Ok(Some(Frame::Text(payload)))
|
||||
//let tmp = Vec::from(payload.as_ref());
|
||||
//match String::from_utf8(tmp) {
|
||||
// Ok(s) => Ok(Some(Message::Text(s))),
|
||||
// Err(_) => Err(ProtocolError::BadEncoding),
|
||||
//}
|
||||
}
|
||||
OpCode::Ping => Ok(Some(Frame::Ping(
|
||||
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
|
||||
))),
|
||||
OpCode::Pong => Ok(Some(Frame::Pong(
|
||||
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
|
||||
))),
|
||||
OpCode::Binary => Ok(Some(Frame::Binary(
|
||||
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
|
||||
))),
|
||||
OpCode::Text => Ok(Some(Frame::Text(
|
||||
payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
|
||||
))),
|
||||
}
|
||||
}
|
||||
Ok(None) => Ok(None),
|
||||
|
@@ -4,19 +4,19 @@ use std::task::{Context, Poll};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_service::{IntoService, Service};
|
||||
use actix_utils::framed::{FramedTransport, FramedTransportError};
|
||||
use actix_utils::framed;
|
||||
|
||||
use super::{Codec, Frame, Message};
|
||||
|
||||
pub struct Transport<S, T>
|
||||
pub struct Dispatcher<S, T>
|
||||
where
|
||||
S: Service<Request = Frame, Response = Message> + 'static,
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
inner: FramedTransport<S, T, Codec>,
|
||||
inner: framed::Dispatcher<S, T, Codec>,
|
||||
}
|
||||
|
||||
impl<S, T> Transport<S, T>
|
||||
impl<S, T> Dispatcher<S, T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
S: Service<Request = Frame, Response = Message>,
|
||||
@@ -24,28 +24,28 @@ where
|
||||
S::Error: 'static,
|
||||
{
|
||||
pub fn new<F: IntoService<S>>(io: T, service: F) -> Self {
|
||||
Transport {
|
||||
inner: FramedTransport::new(Framed::new(io, Codec::new()), service),
|
||||
Dispatcher {
|
||||
inner: framed::Dispatcher::new(Framed::new(io, Codec::new()), service),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<F: IntoService<S>>(framed: Framed<T, Codec>, service: F) -> Self {
|
||||
Transport {
|
||||
inner: FramedTransport::new(framed, service),
|
||||
Dispatcher {
|
||||
inner: framed::Dispatcher::new(framed, service),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> Future for Transport<S, T>
|
||||
impl<S, T> Future for Dispatcher<S, T>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
S: Service<Request = Frame, Response = Message>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
{
|
||||
type Output = Result<(), FramedTransportError<S::Error, Codec>>;
|
||||
type Output = Result<(), framed::DispatcherError<S::Error, Codec>>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Pin::new(&mut self.inner).poll(cx)
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use log::debug;
|
||||
use rand;
|
||||
|
||||
@@ -108,7 +108,7 @@ impl Parser {
|
||||
}
|
||||
|
||||
// remove prefix
|
||||
src.split_to(idx);
|
||||
let _ = src.split_to(idx);
|
||||
|
||||
// no need for body
|
||||
if length == 0 {
|
||||
@@ -154,14 +154,14 @@ impl Parser {
|
||||
}
|
||||
|
||||
/// Generate binary representation
|
||||
pub fn write_message<B: Into<Bytes>>(
|
||||
pub fn write_message<B: AsRef<[u8]>>(
|
||||
dst: &mut BytesMut,
|
||||
pl: B,
|
||||
op: OpCode,
|
||||
fin: bool,
|
||||
mask: bool,
|
||||
) {
|
||||
let payload = pl.into();
|
||||
let payload = pl.as_ref();
|
||||
let one: u8 = if fin {
|
||||
0x80 | Into::<u8>::into(op)
|
||||
} else {
|
||||
|
@@ -51,7 +51,7 @@ pub(crate) fn apply_mask(buf: &mut [u8], mask_u32: u32) {
|
||||
// inefficient, it could be done better. The compiler does not understand that
|
||||
// a `ShortSlice` must be smaller than a u64.
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn xor_short(buf: ShortSlice, mask: u64) {
|
||||
fn xor_short(buf: ShortSlice<'_>, mask: u64) {
|
||||
// Unsafe: we know that a `ShortSlice` fits in a u64
|
||||
unsafe {
|
||||
let (ptr, len) = (buf.0.as_mut_ptr(), buf.0.len());
|
||||
@@ -77,7 +77,7 @@ unsafe fn cast_slice(buf: &mut [u8]) -> &mut [u64] {
|
||||
#[inline]
|
||||
// Splits a slice into three parts: an unaligned short head and tail, plus an aligned
|
||||
// u64 mid section.
|
||||
fn align_buf(buf: &mut [u8]) -> (ShortSlice, &mut [u64], ShortSlice) {
|
||||
fn align_buf(buf: &mut [u8]) -> (ShortSlice<'_>, &mut [u64], ShortSlice<'_>) {
|
||||
let start_ptr = buf.as_ptr() as usize;
|
||||
let end_ptr = start_ptr + buf.len();
|
||||
|
||||
|
@@ -13,15 +13,15 @@ use crate::message::RequestHead;
|
||||
use crate::response::{Response, ResponseBuilder};
|
||||
|
||||
mod codec;
|
||||
mod dispatcher;
|
||||
mod frame;
|
||||
mod mask;
|
||||
mod proto;
|
||||
mod transport;
|
||||
|
||||
pub use self::codec::{Codec, Frame, Message};
|
||||
pub use self::codec::{Codec, Frame, Item, Message};
|
||||
pub use self::dispatcher::Dispatcher;
|
||||
pub use self::frame::Parser;
|
||||
pub use self::proto::{hash_key, CloseCode, CloseReason, OpCode};
|
||||
pub use self::transport::Transport;
|
||||
|
||||
/// Websocket protocol errors
|
||||
#[derive(Debug, Display, From)]
|
||||
@@ -44,12 +44,15 @@ pub enum ProtocolError {
|
||||
/// A payload reached size limit.
|
||||
#[display(fmt = "A payload reached size limit.")]
|
||||
Overflow,
|
||||
/// Continuation is not supported
|
||||
#[display(fmt = "Continuation is not supported.")]
|
||||
NoContinuation,
|
||||
/// Bad utf-8 encoding
|
||||
#[display(fmt = "Bad utf-8 encoding.")]
|
||||
BadEncoding,
|
||||
/// Continuation is not started
|
||||
#[display(fmt = "Continuation is not started.")]
|
||||
ContinuationNotStarted,
|
||||
/// Received new continuation but it is already started
|
||||
#[display(fmt = "Received new continuation but it is already started")]
|
||||
ContinuationStarted,
|
||||
/// Unknown continuation fragment
|
||||
#[display(fmt = "Unknown continuation fragment.")]
|
||||
ContinuationFragment(OpCode),
|
||||
/// Io error
|
||||
#[display(fmt = "io error: {}", _0)]
|
||||
Io(io::Error),
|
||||
|
@@ -24,7 +24,7 @@ pub enum OpCode {
|
||||
}
|
||||
|
||||
impl fmt::Display for OpCode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
Continue => write!(f, "CONTINUE"),
|
||||
Text => write!(f, "TEXT"),
|
||||
@@ -95,7 +95,7 @@ pub enum CloseCode {
|
||||
Abnormal,
|
||||
/// Indicates that an endpoint is terminating the connection
|
||||
/// because it has received data within a message that was not
|
||||
/// consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
|
||||
/// consistent with the type of the message (e.g., non-UTF-8 \[RFC3629\]
|
||||
/// data within a text message).
|
||||
Invalid,
|
||||
/// Indicates that an endpoint is terminating the connection
|
||||
|
@@ -3,7 +3,7 @@ use bytes::Bytes;
|
||||
use futures::future::{self, ok};
|
||||
|
||||
use actix_http::{http, HttpService, Request, Response};
|
||||
use actix_http_test::TestServer;
|
||||
use actix_http_test::test_server;
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World \
|
||||
@@ -29,7 +29,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_v2() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.tcp()
|
||||
@@ -56,7 +56,7 @@ async fn test_h1_v2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_connection_close() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.tcp()
|
||||
@@ -69,7 +69,7 @@ async fn test_connection_close() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_with_query_parameter() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|req: Request| {
|
||||
if req.uri().query().unwrap().contains("qp=") {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#![cfg(feature = "openssl")]
|
||||
use std::io;
|
||||
|
||||
use actix_http_test::TestServer;
|
||||
use actix_service::{service_fn, ServiceFactory};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_service, ServiceFactory};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::future::{err, ok, ready};
|
||||
@@ -62,7 +62,7 @@ fn ssl_acceptor() -> SslAcceptor {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2() -> io::Result<()> {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| ok::<_, Error>(Response::Ok().finish()))
|
||||
.openssl(ssl_acceptor())
|
||||
@@ -76,7 +76,7 @@ async fn test_h2() -> io::Result<()> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_1() -> io::Result<()> {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|req: Request| {
|
||||
assert!(req.peer_addr().is_some());
|
||||
@@ -95,7 +95,7 @@ async fn test_h2_1() -> io::Result<()> {
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body() -> io::Result<()> {
|
||||
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|mut req: Request<_>| {
|
||||
async move {
|
||||
@@ -117,7 +117,7 @@ async fn test_h2_body() -> io::Result<()> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_content_length() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|req: Request| {
|
||||
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||
@@ -168,7 +168,7 @@ async fn test_h2_headers() {
|
||||
let data = STR.repeat(10);
|
||||
let data2 = data.clone();
|
||||
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
let data = data.clone();
|
||||
HttpService::build().h2(move |_| {
|
||||
let mut builder = Response::Ok();
|
||||
@@ -228,7 +228,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body2() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.openssl(ssl_acceptor())
|
||||
@@ -245,7 +245,7 @@ async fn test_h2_body2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_head_empty() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.openssl(ssl_acceptor())
|
||||
@@ -268,7 +268,7 @@ async fn test_h2_head_empty() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_head_binary() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR))
|
||||
@@ -292,7 +292,7 @@ async fn test_h2_head_binary() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_head_binary2() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.openssl(ssl_acceptor())
|
||||
@@ -310,7 +310,7 @@ async fn test_h2_head_binary2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body_length() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
@@ -332,7 +332,7 @@ async fn test_h2_body_length() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body_chunked_explicit() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref())));
|
||||
@@ -359,9 +359,9 @@ async fn test_h2_body_chunked_explicit() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_response_http_error_handling() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(service_fn(|_| {
|
||||
.h2(fn_service(|_| {
|
||||
let broken_header = Bytes::from_static(b"\0\0\0");
|
||||
ok::<_, ()>(
|
||||
Response::Ok()
|
||||
@@ -383,7 +383,7 @@ async fn test_h2_response_http_error_handling() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_service_error() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| err::<Response, Error>(ErrorBadRequest("error")))
|
||||
.openssl(ssl_acceptor())
|
||||
@@ -400,7 +400,7 @@ async fn test_h2_service_error() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_on_connect() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.on_connect(|_| 10usize)
|
||||
.h2(|req: Request| {
|
||||
|
@@ -3,8 +3,8 @@ 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::TestServer;
|
||||
use actix_service::{factory_fn_cfg, service_fn2};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_factory_with_config, fn_service};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::future::{self, err, ok};
|
||||
@@ -41,7 +41,7 @@ fn ssl_acceptor() -> RustlsServerConfig {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1() -> io::Result<()> {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h1(|_| future::ok::<_, Error>(Response::Ok().finish()))
|
||||
.rustls(ssl_acceptor())
|
||||
@@ -54,7 +54,7 @@ async fn test_h1() -> io::Result<()> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2() -> io::Result<()> {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| future::ok::<_, Error>(Response::Ok().finish()))
|
||||
.rustls(ssl_acceptor())
|
||||
@@ -67,7 +67,7 @@ async fn test_h2() -> io::Result<()> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_1() -> io::Result<()> {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h1(|req: Request| {
|
||||
assert!(req.peer_addr().is_some());
|
||||
@@ -84,7 +84,7 @@ async fn test_h1_1() -> io::Result<()> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_1() -> io::Result<()> {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|req: Request| {
|
||||
assert!(req.peer_addr().is_some());
|
||||
@@ -102,7 +102,7 @@ async fn test_h2_1() -> io::Result<()> {
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body1() -> io::Result<()> {
|
||||
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|mut req: Request<_>| {
|
||||
async move {
|
||||
@@ -123,7 +123,7 @@ async fn test_h2_body1() -> io::Result<()> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_content_length() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|req: Request| {
|
||||
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||
@@ -172,7 +172,7 @@ async fn test_h2_headers() {
|
||||
let data = STR.repeat(10);
|
||||
let data2 = data.clone();
|
||||
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
let data = data.clone();
|
||||
HttpService::build().h2(move |_| {
|
||||
let mut config = Response::Ok();
|
||||
@@ -231,7 +231,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body2() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.rustls(ssl_acceptor())
|
||||
@@ -247,7 +247,7 @@ async fn test_h2_body2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_head_empty() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.rustls(ssl_acceptor())
|
||||
@@ -272,7 +272,7 @@ async fn test_h2_head_empty() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_head_binary() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR))
|
||||
@@ -298,7 +298,7 @@ async fn test_h2_head_binary() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_head_binary2() {
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.rustls(ssl_acceptor())
|
||||
@@ -318,7 +318,7 @@ async fn test_h2_head_binary2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body_length() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
@@ -339,7 +339,7 @@ async fn test_h2_body_length() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_body_chunked_explicit() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref())));
|
||||
@@ -365,10 +365,10 @@ async fn test_h2_body_chunked_explicit() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_response_http_error_handling() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(factory_fn_cfg(|_: ()| {
|
||||
ok::<_, ()>(service_fn2(|_| {
|
||||
.h2(fn_factory_with_config(|_: ()| {
|
||||
ok::<_, ()>(fn_service(|_| {
|
||||
let broken_header = Bytes::from_static(b"\0\0\0");
|
||||
ok::<_, ()>(
|
||||
Response::Ok()
|
||||
@@ -390,7 +390,7 @@ async fn test_h2_response_http_error_handling() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h2_service_error() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| err::<Response, Error>(error::ErrorBadRequest("error")))
|
||||
.rustls(ssl_acceptor())
|
||||
@@ -406,7 +406,7 @@ async fn test_h2_service_error() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_service_error() {
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h1(|_| err::<Response, Error>(error::ErrorBadRequest("error")))
|
||||
.rustls(ssl_acceptor())
|
||||
|
@@ -2,9 +2,9 @@ use std::io::{Read, Write};
|
||||
use std::time::Duration;
|
||||
use std::{net, thread};
|
||||
|
||||
use actix_http_test::TestServer;
|
||||
use actix_http_test::test_server;
|
||||
use actix_rt::time::delay_for;
|
||||
use actix_service::service_fn;
|
||||
use actix_service::fn_service;
|
||||
use bytes::Bytes;
|
||||
use futures::future::{self, err, ok, ready, FutureExt};
|
||||
use futures::stream::{once, StreamExt};
|
||||
@@ -17,7 +17,7 @@ use actix_http::{
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.keep_alive(KeepAlive::Disabled)
|
||||
.client_timeout(1000)
|
||||
@@ -35,7 +35,7 @@ async fn test_h1() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_2() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.keep_alive(KeepAlive::Disabled)
|
||||
.client_timeout(1000)
|
||||
@@ -54,9 +54,9 @@ async fn test_h1_2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_expect_continue() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.expect(service_fn(|req: Request| {
|
||||
.expect(fn_service(|req: Request| {
|
||||
if req.head().uri.query() == Some("yes=") {
|
||||
ok(req)
|
||||
} else {
|
||||
@@ -82,9 +82,9 @@ async fn test_expect_continue() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_expect_continue_h1() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.expect(service_fn(|req: Request| {
|
||||
.expect(fn_service(|req: Request| {
|
||||
delay_for(Duration::from_millis(20)).then(move |_| {
|
||||
if req.head().uri.query() == Some("yes=") {
|
||||
ok(req)
|
||||
@@ -93,7 +93,7 @@ async fn test_expect_continue_h1() {
|
||||
}
|
||||
})
|
||||
}))
|
||||
.h1(service_fn(|_| future::ok::<_, ()>(Response::Ok().finish())))
|
||||
.h1(fn_service(|_| future::ok::<_, ()>(Response::Ok().finish())))
|
||||
.tcp()
|
||||
});
|
||||
|
||||
@@ -115,9 +115,9 @@ async fn test_chunked_payload() {
|
||||
let chunk_sizes = vec![32768, 32, 32768];
|
||||
let total_size: usize = chunk_sizes.iter().sum();
|
||||
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(service_fn(|mut request: Request| {
|
||||
.h1(fn_service(|mut request: Request| {
|
||||
request
|
||||
.take_payload()
|
||||
.map(|res| match res {
|
||||
@@ -167,7 +167,7 @@ async fn test_chunked_payload() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_slow_request() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.client_timeout(100)
|
||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
@@ -183,7 +183,7 @@ async fn test_slow_request() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http1_malformed_request() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
.tcp()
|
||||
@@ -198,7 +198,7 @@ async fn test_http1_malformed_request() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http1_keepalive() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
.tcp()
|
||||
@@ -218,7 +218,7 @@ async fn test_http1_keepalive() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http1_keepalive_timeout() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.keep_alive(1)
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
@@ -239,7 +239,7 @@ async fn test_http1_keepalive_timeout() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http1_keepalive_close() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
.tcp()
|
||||
@@ -259,7 +259,7 @@ async fn test_http1_keepalive_close() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http10_keepalive_default_close() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
.tcp()
|
||||
@@ -278,7 +278,7 @@ async fn test_http10_keepalive_default_close() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http10_keepalive() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
.tcp()
|
||||
@@ -304,7 +304,7 @@ async fn test_http10_keepalive() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_http1_keepalive_disabled() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.keep_alive(KeepAlive::Disabled)
|
||||
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||
@@ -329,7 +329,7 @@ async fn test_content_length() {
|
||||
StatusCode,
|
||||
};
|
||||
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|req: Request| {
|
||||
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||
@@ -373,7 +373,7 @@ async fn test_h1_headers() {
|
||||
let data = STR.repeat(10);
|
||||
let data2 = data.clone();
|
||||
|
||||
let mut srv = TestServer::start(move || {
|
||||
let mut srv = test_server(move || {
|
||||
let data = data.clone();
|
||||
HttpService::build().h1(move |_| {
|
||||
let mut builder = Response::Ok();
|
||||
@@ -431,7 +431,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_body() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.tcp()
|
||||
@@ -447,7 +447,7 @@ async fn test_h1_body() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_head_empty() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.tcp()
|
||||
@@ -471,7 +471,7 @@ async fn test_h1_head_empty() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_head_binary() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| {
|
||||
ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR))
|
||||
@@ -497,7 +497,7 @@ async fn test_h1_head_binary() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_head_binary2() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||
.tcp()
|
||||
@@ -517,7 +517,7 @@ async fn test_h1_head_binary2() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_body_length() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
@@ -538,7 +538,7 @@ async fn test_h1_body_length() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_body_chunked_explicit() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| {
|
||||
let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref())));
|
||||
@@ -572,7 +572,7 @@ async fn test_h1_body_chunked_explicit() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_body_chunked_implicit() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| {
|
||||
let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref())));
|
||||
@@ -600,9 +600,9 @@ async fn test_h1_body_chunked_implicit() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_response_http_error_handling() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(service_fn(|_| {
|
||||
.h1(fn_service(|_| {
|
||||
let broken_header = Bytes::from_static(b"\0\0\0");
|
||||
ok::<_, ()>(
|
||||
Response::Ok()
|
||||
@@ -623,7 +623,7 @@ async fn test_h1_response_http_error_handling() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_service_error() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| future::err::<Response, Error>(error::ErrorBadRequest("error")))
|
||||
.tcp()
|
||||
@@ -639,7 +639,7 @@ async fn test_h1_service_error() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_h1_on_connect() {
|
||||
let srv = TestServer::start(|| {
|
||||
let srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.on_connect(|_| 10usize)
|
||||
.h1(|req: Request| {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_http::{body, h1, ws, Error, HttpService, Request, Response};
|
||||
use actix_http_test::TestServer;
|
||||
use actix_utils::framed::FramedTransport;
|
||||
use bytes::BytesMut;
|
||||
use actix_http_test::test_server;
|
||||
use actix_utils::framed::Dispatcher;
|
||||
use bytes::Bytes;
|
||||
use futures::future;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
|
||||
@@ -16,7 +16,7 @@ async fn ws_service<T: AsyncRead + AsyncWrite + Unpin>(
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
FramedTransport::new(framed.into_framed(ws::Codec::new()), service)
|
||||
Dispatcher::new(framed.into_framed(ws::Codec::new()), service)
|
||||
.await
|
||||
.map_err(|_| panic!())
|
||||
}
|
||||
@@ -25,9 +25,10 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
||||
let msg = match msg {
|
||||
ws::Frame::Ping(msg) => ws::Message::Pong(msg),
|
||||
ws::Frame::Text(text) => {
|
||||
ws::Message::Text(String::from_utf8_lossy(&text.unwrap()).to_string())
|
||||
ws::Message::Text(String::from_utf8_lossy(&text).to_string())
|
||||
}
|
||||
ws::Frame::Binary(bin) => ws::Message::Binary(bin.unwrap().freeze()),
|
||||
ws::Frame::Binary(bin) => ws::Message::Binary(bin),
|
||||
ws::Frame::Continuation(item) => ws::Message::Continuation(item),
|
||||
ws::Frame::Close(reason) => ws::Message::Close(reason),
|
||||
_ => panic!(),
|
||||
};
|
||||
@@ -36,9 +37,9 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_simple() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.upgrade(actix_service::service_fn(ws_service))
|
||||
.upgrade(actix_service::fn_service(ws_service))
|
||||
.finish(|_| future::ok::<_, ()>(Response::NotFound()))
|
||||
.tcp()
|
||||
});
|
||||
@@ -52,7 +53,7 @@ async fn test_simple() {
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Text(Some(BytesMut::from("text")))
|
||||
ws::Frame::Text(Bytes::from_static(b"text"))
|
||||
);
|
||||
|
||||
framed
|
||||
@@ -62,7 +63,7 @@ async fn test_simple() {
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Binary(Some(BytesMut::from(&b"text"[..]).into()))
|
||||
ws::Frame::Binary(Bytes::from_static(&b"text"[..]))
|
||||
);
|
||||
|
||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||
@@ -72,6 +73,61 @@ async fn test_simple() {
|
||||
ws::Frame::Pong("text".to_string().into())
|
||||
);
|
||||
|
||||
framed
|
||||
.send(ws::Message::Continuation(ws::Item::FirstText(
|
||||
"text".into(),
|
||||
)))
|
||||
.await
|
||||
.unwrap();
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Continuation(ws::Item::FirstText(Bytes::from_static(b"text")))
|
||||
);
|
||||
|
||||
assert!(framed
|
||||
.send(ws::Message::Continuation(ws::Item::FirstText(
|
||||
"text".into()
|
||||
)))
|
||||
.await
|
||||
.is_err());
|
||||
assert!(framed
|
||||
.send(ws::Message::Continuation(ws::Item::FirstBinary(
|
||||
"text".into()
|
||||
)))
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
framed
|
||||
.send(ws::Message::Continuation(ws::Item::Continue("text".into())))
|
||||
.await
|
||||
.unwrap();
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Continuation(ws::Item::Continue(Bytes::from_static(b"text")))
|
||||
);
|
||||
|
||||
framed
|
||||
.send(ws::Message::Continuation(ws::Item::Last("text".into())))
|
||||
.await
|
||||
.unwrap();
|
||||
let (item, mut framed) = framed.into_future().await;
|
||||
assert_eq!(
|
||||
item.unwrap().unwrap(),
|
||||
ws::Frame::Continuation(ws::Item::Last(Bytes::from_static(b"text")))
|
||||
);
|
||||
|
||||
assert!(framed
|
||||
.send(ws::Message::Continuation(ws::Item::Continue("text".into())))
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
assert!(framed
|
||||
.send(ws::Message::Continuation(ws::Item::Last("text".into())))
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
framed
|
||||
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
||||
.await
|
||||
|
@@ -18,13 +18,13 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-web = { version = "2.0.0-alpha.3", default-features = false, features = ["secure-cookies"] }
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-service = "1.0.0"
|
||||
futures = "0.3.1"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
time = "0.1.42"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
actix-http = "1.0.0-alpha.3"
|
||||
bytes = "0.5.2"
|
@@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [2.0.0-alpha.4] - 2019-12-xx
|
||||
|
||||
* Multipart handling now handles Pending during read of boundary #1205
|
||||
|
||||
## [0.2.0-alpha.2] - 2019-12-03
|
||||
|
||||
* Migrate to `std::future`
|
||||
|
@@ -19,8 +19,8 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-web = { version = "2.0.0-alpha.3", default-features = false }
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-service = "1.0.0"
|
||||
actix-utils = "1.0.0"
|
||||
bytes = "0.5.2"
|
||||
derive_more = "0.99.2"
|
||||
httparse = "1.3"
|
||||
@@ -31,5 +31,5 @@ time = "0.1"
|
||||
twoway = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
actix-http = "1.0.0-alpha.3"
|
@@ -610,7 +610,7 @@ impl InnerField {
|
||||
}
|
||||
|
||||
match payload.readline() {
|
||||
Ok(None) => Poll::Ready(None),
|
||||
Ok(None) => Poll::Pending,
|
||||
Ok(Some(line)) => {
|
||||
if line.as_ref() != b"\r\n" {
|
||||
log::warn!("multipart field did not read all the data or it is malformed");
|
||||
@@ -867,6 +867,45 @@ mod tests {
|
||||
|
||||
(tx, rx.map(|res| res.map_err(|_| panic!())))
|
||||
}
|
||||
// Stream that returns from a Bytes, one char at a time and Pending every other poll()
|
||||
struct SlowStream {
|
||||
bytes: Bytes,
|
||||
pos: usize,
|
||||
ready: bool,
|
||||
}
|
||||
|
||||
impl SlowStream {
|
||||
fn new(bytes: Bytes) -> SlowStream {
|
||||
return SlowStream {
|
||||
bytes: bytes,
|
||||
pos: 0,
|
||||
ready: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for SlowStream {
|
||||
type Item = Result<Bytes, PayloadError>;
|
||||
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
let this = self.get_mut();
|
||||
if !this.ready {
|
||||
this.ready = true;
|
||||
cx.waker().wake_by_ref();
|
||||
return Poll::Pending;
|
||||
}
|
||||
if this.pos == this.bytes.len() {
|
||||
return Poll::Ready(None);
|
||||
}
|
||||
let res = Poll::Ready(Some(Ok(this.bytes.slice(this.pos..(this.pos + 1)))));
|
||||
this.pos += 1;
|
||||
this.ready = false;
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
fn create_simple_request_with_header() -> (Bytes, HeaderMap) {
|
||||
let bytes = Bytes::from(
|
||||
@@ -969,12 +1008,22 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// Loops, collecting all bytes until end-of-field
|
||||
async fn get_whole_field(field: &mut Field) -> BytesMut {
|
||||
let mut b = BytesMut::new();
|
||||
loop {
|
||||
match field.next().await {
|
||||
Some(Ok(chunk)) => b.extend_from_slice(&chunk),
|
||||
None => return b,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_stream() {
|
||||
let (sender, payload) = create_stream();
|
||||
let (bytes, headers) = create_simple_request_with_header();
|
||||
|
||||
sender.send(Ok(bytes)).unwrap();
|
||||
let payload = SlowStream::new(bytes);
|
||||
|
||||
let mut multipart = Multipart::new(&headers, payload);
|
||||
match multipart.next().await.unwrap() {
|
||||
@@ -986,14 +1035,7 @@ mod tests {
|
||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||
|
||||
match field.next().await.unwrap() {
|
||||
Ok(chunk) => assert_eq!(chunk, "test"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
match field.next().await {
|
||||
None => (),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert_eq!(get_whole_field(&mut field).await, "test");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@@ -1003,14 +1045,7 @@ mod tests {
|
||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||
|
||||
match field.next().await {
|
||||
Some(Ok(chunk)) => assert_eq!(chunk, "data"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
match field.next().await {
|
||||
None => (),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert_eq!(get_whole_field(&mut field).await, "data");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ cookie-session = ["actix-web/secure-cookies"]
|
||||
|
||||
[dependencies]
|
||||
actix-web = "2.0.0-alpha.3"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-service = "1.0.0"
|
||||
bytes = "0.5.2"
|
||||
derive_more = "0.99.2"
|
||||
futures = "0.3.1"
|
||||
@@ -34,4 +34,4 @@ serde_json = "1.0"
|
||||
time = "0.1.42"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0"
|
||||
|
@@ -12,7 +12,7 @@
|
||||
//! [*Session*](struct.Session.html) extractor must be used. Session
|
||||
//! extractor allows us to get or set session data.
|
||||
//!
|
||||
//! ```rust
|
||||
//! ```rust,no_run
|
||||
//! use actix_web::{web, App, HttpServer, HttpResponse, Error};
|
||||
//! use actix_session::{Session, CookieSession};
|
||||
//!
|
||||
@@ -28,8 +28,8 @@
|
||||
//! Ok("Welcome!")
|
||||
//! }
|
||||
//!
|
||||
//! fn main() -> std::io::Result<()> {
|
||||
//! # std::thread::spawn(||
|
||||
//! #[actix_rt::main]
|
||||
//! async fn main() -> std::io::Result<()> {
|
||||
//! HttpServer::new(
|
||||
//! || App::new().wrap(
|
||||
//! CookieSession::signed(&[0; 32]) // <- create cookie based session middleware
|
||||
@@ -37,9 +37,8 @@
|
||||
//! )
|
||||
//! .service(web::resource("/").to(|| HttpResponse::Ok())))
|
||||
//! .bind("127.0.0.1:59880")?
|
||||
//! .run()
|
||||
//! # );
|
||||
//! # Ok(())
|
||||
//! .start()
|
||||
//! .await
|
||||
//! }
|
||||
//! ```
|
||||
use std::cell::RefCell;
|
||||
|
@@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.4] - 2019-12-07
|
||||
|
||||
* Allow comma-separated websocket subprotocols without spaces (#1172)
|
||||
|
||||
## [1.0.3] - 2019-11-14
|
||||
|
||||
* Update actix-web and actix-http dependencies
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-web-actors"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix actors support for actix web framework."
|
||||
readme = "README.md"
|
||||
|
@@ -152,7 +152,8 @@ pub fn handshake_with_protocols(
|
||||
.and_then(|req_protocols| {
|
||||
let req_protocols = req_protocols.to_str().ok()?;
|
||||
req_protocols
|
||||
.split(", ")
|
||||
.split(',')
|
||||
.map(|req_p| req_p.trim())
|
||||
.find(|req_p| protocols.iter().any(|p| p == req_p))
|
||||
});
|
||||
|
||||
@@ -736,5 +737,46 @@ mod tests {
|
||||
.headers()
|
||||
.get(&header::SEC_WEBSOCKET_PROTOCOL)
|
||||
);
|
||||
|
||||
let req = TestRequest::default()
|
||||
.header(
|
||||
header::UPGRADE,
|
||||
header::HeaderValue::from_static("websocket"),
|
||||
)
|
||||
.header(
|
||||
header::CONNECTION,
|
||||
header::HeaderValue::from_static("upgrade"),
|
||||
)
|
||||
.header(
|
||||
header::SEC_WEBSOCKET_VERSION,
|
||||
header::HeaderValue::from_static("13"),
|
||||
)
|
||||
.header(
|
||||
header::SEC_WEBSOCKET_KEY,
|
||||
header::HeaderValue::from_static("13"),
|
||||
)
|
||||
.header(
|
||||
header::SEC_WEBSOCKET_PROTOCOL,
|
||||
header::HeaderValue::from_static("p1,p2,p3"),
|
||||
)
|
||||
.to_http_request();
|
||||
|
||||
let protocols = vec!["p3", "p2"];
|
||||
|
||||
assert_eq!(
|
||||
StatusCode::SWITCHING_PROTOCOLS,
|
||||
handshake_with_protocols(&req, &protocols)
|
||||
.unwrap()
|
||||
.finish()
|
||||
.status()
|
||||
);
|
||||
assert_eq!(
|
||||
Some(&header::HeaderValue::from_static("p2")),
|
||||
handshake_with_protocols(&req, &protocols)
|
||||
.unwrap()
|
||||
.finish()
|
||||
.headers()
|
||||
.get(&header::SEC_WEBSOCKET_PROTOCOL)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-web-codegen"
|
||||
version = "0.2.0-alpha.2"
|
||||
version = "0.2.0"
|
||||
description = "Actix web proc macros"
|
||||
readme = "README.md"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
@@ -17,8 +17,6 @@ syn = { version = "^1", features = ["full", "parsing"] }
|
||||
proc-macro2 = "^1"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = { version = "1.0.0-alpha.2" }
|
||||
actix-web = { version = "2.0.0-alpha.2" }
|
||||
actix-http = { version = "0.3.0-alpha.2", features=["openssl"] }
|
||||
actix-http-test = { version = "0.3.0-alpha.2", features=["openssl"] }
|
||||
actix-rt = { version = "1.0.0" }
|
||||
actix-web = { version = "2.0.0-alpha.4" }
|
||||
futures = { version = "0.3.1" }
|
||||
|
@@ -1,11 +1,9 @@
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::TestServer;
|
||||
use actix_web::{http, web::Path, App, HttpResponse, Responder};
|
||||
use actix_web::{http, test, web::Path, App, HttpResponse, Responder};
|
||||
use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, trace};
|
||||
use futures::{future, Future};
|
||||
|
||||
#[get("/test")]
|
||||
async fn test() -> impl Responder {
|
||||
async fn test_handler() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
|
||||
@@ -71,14 +69,11 @@ async fn get_param_test(_: Path<String>) -> impl Responder {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_params() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(
|
||||
App::new()
|
||||
.service(get_param_test)
|
||||
.service(put_param_test)
|
||||
.service(delete_param_test),
|
||||
)
|
||||
.tcp()
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
.service(get_param_test)
|
||||
.service(put_param_test)
|
||||
.service(delete_param_test)
|
||||
});
|
||||
|
||||
let request = srv.request(http::Method::GET, srv.url("/test/it"));
|
||||
@@ -96,19 +91,16 @@ async fn test_params() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_body() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(
|
||||
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),
|
||||
)
|
||||
.tcp()
|
||||
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(http::Method::GET, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
@@ -151,8 +143,7 @@ async fn test_body() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_auto_async() {
|
||||
let srv =
|
||||
TestServer::start(|| HttpService::new(App::new().service(auto_async)).tcp());
|
||||
let srv = test::start(|| App::new().service(auto_async));
|
||||
|
||||
let request = srv.request(http::Method::GET, srv.url("/test"));
|
||||
let response = request.send().await.unwrap();
|
||||
|
@@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.0] - 2019-12-13
|
||||
|
||||
* Release
|
||||
|
||||
## [1.0.0-alpha.3]
|
||||
|
||||
* Migrate to `std::future`
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "awc"
|
||||
version = "1.0.0-alpha.3"
|
||||
version = "1.0.0"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix http client."
|
||||
readme = "README.md"
|
||||
@@ -12,19 +12,17 @@ categories = ["network-programming", "asynchronous",
|
||||
"web-programming::http-client",
|
||||
"web-programming::websocket"]
|
||||
license = "MIT/Apache-2.0"
|
||||
exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
|
||||
edition = "2018"
|
||||
workspace = ".."
|
||||
|
||||
[lib]
|
||||
name = "awc"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["openssl", "rustls", "brotli", "flate2-zlib"]
|
||||
features = ["openssl", "rustls", "compress"]
|
||||
|
||||
[features]
|
||||
default = ["brotli", "flate2-zlib"]
|
||||
default = ["compress"]
|
||||
|
||||
# openssl
|
||||
openssl = ["open-ssl", "actix-http/openssl"]
|
||||
@@ -32,25 +30,19 @@ openssl = ["open-ssl", "actix-http/openssl"]
|
||||
# rustls
|
||||
rustls = ["rust-tls", "actix-http/rustls"]
|
||||
|
||||
# brotli encoding, requires c compiler
|
||||
brotli = ["actix-http/brotli"]
|
||||
|
||||
# miniz-sys backend for flate2 crate
|
||||
flate2-zlib = ["actix-http/flate2-zlib"]
|
||||
|
||||
# rust backend for flate2 crate
|
||||
flate2-rust = ["actix-http/flate2-rust"]
|
||||
# content-encoding support
|
||||
compress = ["actix-http/compress"]
|
||||
|
||||
[dependencies]
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-http = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0"
|
||||
actix-service = "1.0.0"
|
||||
actix-http = "1.0.0"
|
||||
actix-rt = "1.0.0"
|
||||
|
||||
base64 = "0.11"
|
||||
bytes = "0.5.2"
|
||||
derive_more = "0.99.2"
|
||||
futures = "0.3.1"
|
||||
futures-core = "0.3.1"
|
||||
log =" 0.4"
|
||||
mime = "0.3"
|
||||
percent-encoding = "2.1"
|
||||
@@ -62,14 +54,15 @@ open-ssl = { version="0.10", package="openssl", optional = true }
|
||||
rust-tls = { version = "0.16.0", package="rustls", optional = true, features = ["dangerous_configuration"] }
|
||||
|
||||
[dev-dependencies]
|
||||
actix-connect = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-web = { version = "2.0.0-alpha.3", features=["openssl"] }
|
||||
actix-http = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-http-test = { version = "1.0.0-alpha.3", features=["openssl"] }
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-server = { version = "1.0.0-alpha.3" }
|
||||
actix-tls = { version = "1.0.0-alpha.3", features=["openssl", "rustls"] }
|
||||
brotli2 = { version="0.3.2" }
|
||||
flate2 = { version="1.0.2" }
|
||||
actix-connect = { version = "1.0.0", features=["openssl"] }
|
||||
actix-web = { version = "2.0.0-alpha.5", features=["openssl"] }
|
||||
actix-http = { version = "1.0.0", features=["openssl"] }
|
||||
actix-http-test = { version = "1.0.0", features=["openssl"] }
|
||||
actix-utils = "1.0.3"
|
||||
actix-server = "1.0.0"
|
||||
actix-tls = { version = "1.0.0", features=["openssl", "rustls"] }
|
||||
brotli = "3.3.0"
|
||||
flate2 = "1.0.13"
|
||||
futures = "0.3.1"
|
||||
env_logger = "0.6"
|
||||
webpki = { version = "0.21" }
|
||||
webpki = "0.21"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
@@ -12,7 +13,6 @@ use actix_http::h1::ClientCodec;
|
||||
use actix_http::http::HeaderMap;
|
||||
use actix_http::{RequestHead, RequestHeadType, ResponseHead};
|
||||
use actix_service::Service;
|
||||
use futures::future::{FutureExt, LocalBoxFuture};
|
||||
|
||||
use crate::response::ClientResponse;
|
||||
|
||||
@@ -24,7 +24,7 @@ pub(crate) trait Connect {
|
||||
head: RequestHead,
|
||||
body: Body,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<'static, Result<ClientResponse, SendRequestError>>;
|
||||
) -> Pin<Box<dyn Future<Output = Result<ClientResponse, SendRequestError>>>>;
|
||||
|
||||
fn send_request_extra(
|
||||
&mut self,
|
||||
@@ -32,16 +32,22 @@ pub(crate) trait Connect {
|
||||
extra_headers: Option<HeaderMap>,
|
||||
body: Body,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<'static, Result<ClientResponse, SendRequestError>>;
|
||||
) -> Pin<Box<dyn Future<Output = Result<ClientResponse, SendRequestError>>>>;
|
||||
|
||||
/// Send request, returns Response and Framed
|
||||
fn open_tunnel(
|
||||
&mut self,
|
||||
head: RequestHead,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<
|
||||
'static,
|
||||
Result<(ResponseHead, Framed<BoxedSocket, ClientCodec>), SendRequestError>,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<
|
||||
Output = Result<
|
||||
(ResponseHead, Framed<BoxedSocket, ClientCodec>),
|
||||
SendRequestError,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
>;
|
||||
|
||||
/// Send request and extra headers, returns Response and Framed
|
||||
@@ -50,9 +56,15 @@ pub(crate) trait Connect {
|
||||
head: Rc<RequestHead>,
|
||||
extra_headers: Option<HeaderMap>,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<
|
||||
'static,
|
||||
Result<(ResponseHead, Framed<BoxedSocket, ClientCodec>), SendRequestError>,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<
|
||||
Output = Result<
|
||||
(ResponseHead, Framed<BoxedSocket, ClientCodec>),
|
||||
SendRequestError,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
>;
|
||||
}
|
||||
|
||||
@@ -70,14 +82,14 @@ where
|
||||
head: RequestHead,
|
||||
body: Body,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<'static, Result<ClientResponse, SendRequestError>> {
|
||||
) -> Pin<Box<dyn Future<Output = Result<ClientResponse, SendRequestError>>>> {
|
||||
// connect to the host
|
||||
let fut = self.0.call(ClientConnect {
|
||||
uri: head.uri.clone(),
|
||||
addr,
|
||||
});
|
||||
|
||||
async move {
|
||||
Box::pin(async move {
|
||||
let connection = fut.await?;
|
||||
|
||||
// send request
|
||||
@@ -85,8 +97,7 @@ where
|
||||
.send_request(RequestHeadType::from(head), body)
|
||||
.await
|
||||
.map(|(head, payload)| ClientResponse::new(head, payload))
|
||||
}
|
||||
.boxed_local()
|
||||
})
|
||||
}
|
||||
|
||||
fn send_request_extra(
|
||||
@@ -95,14 +106,14 @@ where
|
||||
extra_headers: Option<HeaderMap>,
|
||||
body: Body,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<'static, Result<ClientResponse, SendRequestError>> {
|
||||
) -> Pin<Box<dyn Future<Output = Result<ClientResponse, SendRequestError>>>> {
|
||||
// connect to the host
|
||||
let fut = self.0.call(ClientConnect {
|
||||
uri: head.uri.clone(),
|
||||
addr,
|
||||
});
|
||||
|
||||
async move {
|
||||
Box::pin(async move {
|
||||
let connection = fut.await?;
|
||||
|
||||
// send request
|
||||
@@ -111,17 +122,22 @@ where
|
||||
.await?;
|
||||
|
||||
Ok(ClientResponse::new(head, payload))
|
||||
}
|
||||
.boxed_local()
|
||||
})
|
||||
}
|
||||
|
||||
fn open_tunnel(
|
||||
&mut self,
|
||||
head: RequestHead,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<
|
||||
'static,
|
||||
Result<(ResponseHead, Framed<BoxedSocket, ClientCodec>), SendRequestError>,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<
|
||||
Output = Result<
|
||||
(ResponseHead, Framed<BoxedSocket, ClientCodec>),
|
||||
SendRequestError,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
> {
|
||||
// connect to the host
|
||||
let fut = self.0.call(ClientConnect {
|
||||
@@ -129,7 +145,7 @@ where
|
||||
addr,
|
||||
});
|
||||
|
||||
async move {
|
||||
Box::pin(async move {
|
||||
let connection = fut.await?;
|
||||
|
||||
// send request
|
||||
@@ -138,8 +154,7 @@ where
|
||||
|
||||
let framed = framed.map_io(|io| BoxedSocket(Box::new(Socket(io))));
|
||||
Ok((head, framed))
|
||||
}
|
||||
.boxed_local()
|
||||
})
|
||||
}
|
||||
|
||||
fn open_tunnel_extra(
|
||||
@@ -147,9 +162,15 @@ where
|
||||
head: Rc<RequestHead>,
|
||||
extra_headers: Option<HeaderMap>,
|
||||
addr: Option<net::SocketAddr>,
|
||||
) -> LocalBoxFuture<
|
||||
'static,
|
||||
Result<(ResponseHead, Framed<BoxedSocket, ClientCodec>), SendRequestError>,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<
|
||||
Output = Result<
|
||||
(ResponseHead, Framed<BoxedSocket, ClientCodec>),
|
||||
SendRequestError,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
> {
|
||||
// connect to the host
|
||||
let fut = self.0.call(ClientConnect {
|
||||
@@ -157,7 +178,7 @@ where
|
||||
addr,
|
||||
});
|
||||
|
||||
async move {
|
||||
Box::pin(async move {
|
||||
let connection = fut.await?;
|
||||
|
||||
// send request
|
||||
@@ -167,8 +188,7 @@ where
|
||||
|
||||
let framed = framed.map_io(|io| BoxedSocket(Box::new(Socket(io))));
|
||||
Ok((head, framed))
|
||||
}
|
||||
.boxed_local()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +215,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> AsyncSocket for Socket<T> {
|
||||
pub struct BoxedSocket(Box<dyn AsyncSocket>);
|
||||
|
||||
impl fmt::Debug for BoxedSocket {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "BoxedSocket")
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
use futures_core::Stream;
|
||||
use serde::Serialize;
|
||||
|
||||
use actix_http::body::Body;
|
||||
|
@@ -1,4 +1,9 @@
|
||||
#![allow(clippy::borrow_interior_mutable_const)]
|
||||
#![deny(rust_2018_idioms, warnings)]
|
||||
#![allow(
|
||||
clippy::type_complexity,
|
||||
clippy::borrow_interior_mutable_const,
|
||||
clippy::needless_doctest_main
|
||||
)]
|
||||
//! An HTTP Client
|
||||
//!
|
||||
//! ```rust
|
||||
@@ -11,9 +16,9 @@
|
||||
//! let mut client = Client::default();
|
||||
//!
|
||||
//! let response = client.get("http://www.rust-lang.org") // <- Create request builder
|
||||
//! .header("User-Agent", "Actix-web")
|
||||
//! .send() // <- Send http request
|
||||
//! .await;
|
||||
//! .header("User-Agent", "Actix-web")
|
||||
//! .send() // <- Send http request
|
||||
//! .await;
|
||||
//!
|
||||
//! println!("Response: {:?}", response);
|
||||
//! }
|
||||
@@ -50,22 +55,18 @@ use self::connect::{Connect, ConnectorWrapper};
|
||||
/// An HTTP Client
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_rt::System;
|
||||
/// use awc::Client;
|
||||
///
|
||||
/// fn main() {
|
||||
/// System::new("test").block_on(async {
|
||||
/// let mut client = Client::default();
|
||||
/// #[actix_rt::main]
|
||||
/// async fn main() {
|
||||
/// let mut client = Client::default();
|
||||
///
|
||||
/// client.get("http://www.rust-lang.org") // <- Create request builder
|
||||
/// .header("User-Agent", "Actix-web")
|
||||
/// .send() // <- Send http request
|
||||
/// .await
|
||||
/// .and_then(|response| { // <- server http response
|
||||
/// println!("Response: {:?}", response);
|
||||
/// Ok(())
|
||||
/// })
|
||||
/// });
|
||||
/// let res = client.get("http://www.rust-lang.org") // <- Create request builder
|
||||
/// .header("User-Agent", "Actix-web")
|
||||
/// .send() // <- Send http request
|
||||
/// .await; // <- send request and wait for response
|
||||
///
|
||||
/// println!("Response: {:?}", res);
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
|
@@ -5,7 +5,7 @@ use std::time::Duration;
|
||||
use std::{fmt, net};
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
use futures_core::Stream;
|
||||
use percent_encoding::percent_encode;
|
||||
use serde::Serialize;
|
||||
|
||||
@@ -23,13 +23,10 @@ use crate::frozen::FrozenClientRequest;
|
||||
use crate::sender::{PrepForSendingError, RequestSender, SendClientRequest};
|
||||
use crate::ClientConfig;
|
||||
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
const HTTPS_ENCODING: &str = "br, gzip, deflate";
|
||||
#[cfg(all(
|
||||
any(feature = "flate2-zlib", feature = "flate2-rust"),
|
||||
not(feature = "brotli")
|
||||
))]
|
||||
const HTTPS_ENCODING: &str = "gzip, deflate";
|
||||
#[cfg(not(any(feature = "flate2-zlib", feature = "flate2-rust")))]
|
||||
const HTTPS_ENCODING: &str = "br";
|
||||
|
||||
/// An HTTP Client request builder
|
||||
///
|
||||
@@ -544,31 +541,23 @@ impl ClientRequest {
|
||||
|
||||
let mut slf = self;
|
||||
|
||||
// enable br only for https
|
||||
#[cfg(any(
|
||||
feature = "brotli",
|
||||
feature = "flate2-zlib",
|
||||
feature = "flate2-rust"
|
||||
))]
|
||||
{
|
||||
if slf.response_decompress {
|
||||
let https = slf
|
||||
.head
|
||||
.uri
|
||||
.scheme()
|
||||
.map(|s| s == &uri::Scheme::HTTPS)
|
||||
.unwrap_or(true);
|
||||
if slf.response_decompress {
|
||||
let https = slf
|
||||
.head
|
||||
.uri
|
||||
.scheme()
|
||||
.map(|s| s == &uri::Scheme::HTTPS)
|
||||
.unwrap_or(true);
|
||||
|
||||
if https {
|
||||
slf = slf.set_header_if_none(header::ACCEPT_ENCODING, HTTPS_ENCODING)
|
||||
} else {
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
{
|
||||
slf = slf
|
||||
.set_header_if_none(header::ACCEPT_ENCODING, "gzip, deflate")
|
||||
}
|
||||
};
|
||||
}
|
||||
if https {
|
||||
slf = slf.set_header_if_none(header::ACCEPT_ENCODING, HTTPS_ENCODING)
|
||||
} else {
|
||||
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
{
|
||||
slf =
|
||||
slf.set_header_if_none(header::ACCEPT_ENCODING, "gzip, deflate")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(slf)
|
||||
@@ -576,7 +565,7 @@ impl ClientRequest {
|
||||
}
|
||||
|
||||
impl fmt::Debug for ClientRequest {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(
|
||||
f,
|
||||
"\nClientRequest {:?} {}:{}",
|
||||
|
@@ -5,7 +5,7 @@ use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::{ready, Future, Stream};
|
||||
use futures_core::{ready, Future, Stream};
|
||||
|
||||
use actix_http::cookie::Cookie;
|
||||
use actix_http::error::{CookieParseError, PayloadError};
|
||||
@@ -29,11 +29,11 @@ impl<S> HttpMessage for ClientResponse<S> {
|
||||
&self.head.headers
|
||||
}
|
||||
|
||||
fn extensions(&self) -> Ref<Extensions> {
|
||||
fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.head.extensions()
|
||||
}
|
||||
|
||||
fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||
fn extensions_mut(&self) -> RefMut<'_, Extensions> {
|
||||
self.head.extensions_mut()
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl<S> HttpMessage for ClientResponse<S> {
|
||||
|
||||
/// Load request cookies.
|
||||
#[inline]
|
||||
fn cookies(&self) -> Result<Ref<Vec<Cookie<'static>>>, CookieParseError> {
|
||||
fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
|
||||
struct Cookies(Vec<Cookie<'static>>);
|
||||
|
||||
if self.extensions().get::<Cookies>().is_none() {
|
||||
@@ -131,13 +131,16 @@ where
|
||||
{
|
||||
type Item = Result<Bytes, PayloadError>;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
Pin::new(&mut self.get_mut().payload).poll_next(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> fmt::Debug for ClientResponse<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "\nClientResponse {:?} {}", self.version(), self.status(),)?;
|
||||
writeln!(f, " headers:")?;
|
||||
for (key, val) in self.headers().iter() {
|
||||
@@ -203,7 +206,7 @@ where
|
||||
{
|
||||
type Output = Result<Bytes, PayloadError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.get_mut();
|
||||
|
||||
if let Some(err) = this.err.take() {
|
||||
@@ -295,7 +298,7 @@ where
|
||||
{
|
||||
type Output = Result<U, JsonPayloadError>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
if let Some(err) = self.err.take() {
|
||||
return Poll::Ready(Err(err));
|
||||
}
|
||||
@@ -335,7 +338,7 @@ where
|
||||
{
|
||||
type Output = Result<Bytes, PayloadError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.get_mut();
|
||||
|
||||
loop {
|
||||
|
@@ -7,7 +7,7 @@ use std::time::Duration;
|
||||
use actix_rt::time::{delay_for, Delay};
|
||||
use bytes::Bytes;
|
||||
use derive_more::From;
|
||||
use futures::{future::LocalBoxFuture, ready, Future, Stream};
|
||||
use futures_core::{ready, Future, Stream};
|
||||
use serde::Serialize;
|
||||
use serde_json;
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Into<SendRequestError> for PrepForSendingError {
|
||||
#[must_use = "futures do nothing unless polled"]
|
||||
pub enum SendClientRequest {
|
||||
Fut(
|
||||
LocalBoxFuture<'static, Result<ClientResponse, SendRequestError>>,
|
||||
Pin<Box<dyn Future<Output = Result<ClientResponse, SendRequestError>>>>,
|
||||
Option<Delay>,
|
||||
bool,
|
||||
),
|
||||
@@ -58,11 +58,11 @@ pub enum SendClientRequest {
|
||||
|
||||
impl SendClientRequest {
|
||||
pub(crate) fn new(
|
||||
send: LocalBoxFuture<'static, Result<ClientResponse, SendRequestError>>,
|
||||
send: Pin<Box<dyn Future<Output = Result<ClientResponse, SendRequestError>>>>,
|
||||
response_decompress: bool,
|
||||
timeout: Option<Duration>,
|
||||
) -> SendClientRequest {
|
||||
let delay = timeout.map(|t| delay_for(t));
|
||||
let delay = timeout.map(delay_for);
|
||||
SendClientRequest::Fut(send, delay, response_decompress)
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ impl Future for SendClientRequest {
|
||||
type Output =
|
||||
Result<ClientResponse<Decoder<Payload<PayloadStream>>>, SendRequestError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.get_mut();
|
||||
|
||||
match this {
|
||||
|
@@ -304,7 +304,7 @@ impl WebsocketsRequest {
|
||||
let (head, framed) = if let Some(to) = self.config.timeout {
|
||||
timeout(to, fut)
|
||||
.await
|
||||
.map_err(|_| SendRequestError::Timeout.into())
|
||||
.map_err(|_| SendRequestError::Timeout)
|
||||
.and_then(|res| res)?
|
||||
} else {
|
||||
fut.await?
|
||||
@@ -379,7 +379,7 @@ impl WebsocketsRequest {
|
||||
}
|
||||
|
||||
impl fmt::Debug for WebsocketsRequest {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(
|
||||
f,
|
||||
"\nWebsocketsRequest {}:{}",
|
||||
|
@@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use brotli2::write::BrotliEncoder;
|
||||
use brotli::CompressorWriter;
|
||||
use bytes::Bytes;
|
||||
use flate2::read::GzDecoder;
|
||||
use flate2::write::GzEncoder;
|
||||
@@ -13,11 +13,13 @@ use futures::future::ok;
|
||||
use rand::Rng;
|
||||
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::TestServer;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::pipeline_factory;
|
||||
use actix_web::http::Cookie;
|
||||
use actix_web::middleware::{BodyEncoding, Compress};
|
||||
use actix_web::{http::header, web, App, Error, HttpMessage, HttpRequest, HttpResponse};
|
||||
use actix_web::{
|
||||
http::header, test, web, App, Error, HttpMessage, HttpRequest, HttpResponse,
|
||||
};
|
||||
use awc::error::SendRequestError;
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
@@ -44,13 +46,10 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_simple() {
|
||||
let srv =
|
||||
TestServer::start(|| {
|
||||
HttpService::new(App::new().service(
|
||||
web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))),
|
||||
))
|
||||
.tcp()
|
||||
});
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
.service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))))
|
||||
});
|
||||
|
||||
let request = srv.get("/").header("x-test", "111").send();
|
||||
let mut response = request.await.unwrap();
|
||||
@@ -74,11 +73,10 @@ async fn test_simple() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_json() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(
|
||||
let srv = test::start(|| {
|
||||
App::new().service(
|
||||
web::resource("/").route(web::to(|_: web::Json<String>| HttpResponse::Ok())),
|
||||
))
|
||||
.tcp()
|
||||
)
|
||||
});
|
||||
|
||||
let request = srv
|
||||
@@ -91,11 +89,10 @@ async fn test_json() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_form() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(
|
||||
|_: web::Form<HashMap<String, String>>| HttpResponse::Ok(),
|
||||
))))
|
||||
.tcp()
|
||||
)))
|
||||
});
|
||||
|
||||
let mut data = HashMap::new();
|
||||
@@ -108,14 +105,13 @@ async fn test_form() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_timeout() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(|| {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| {
|
||||
async {
|
||||
actix_rt::time::delay_for(Duration::from_millis(200)).await;
|
||||
Ok::<_, Error>(HttpResponse::Ok().body(STR))
|
||||
}
|
||||
}))))
|
||||
.tcp()
|
||||
})))
|
||||
});
|
||||
|
||||
let connector = awc::Connector::new()
|
||||
@@ -139,14 +135,13 @@ async fn test_timeout() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_timeout_override() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(|| {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| {
|
||||
async {
|
||||
actix_rt::time::delay_for(Duration::from_millis(200)).await;
|
||||
Ok::<_, Error>(HttpResponse::Ok().body(STR))
|
||||
}
|
||||
}))))
|
||||
.tcp()
|
||||
})))
|
||||
});
|
||||
|
||||
let client = awc::Client::build()
|
||||
@@ -167,7 +162,7 @@ async fn test_connection_reuse() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -203,7 +198,7 @@ async fn test_connection_force_close() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -239,7 +234,7 @@ async fn test_connection_server_close() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -277,7 +272,7 @@ async fn test_connection_wait_queue() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -321,7 +316,7 @@ async fn test_connection_wait_queue_force_close() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -365,17 +360,14 @@ async fn test_connection_wait_queue_force_close() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_with_query_parameter() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").to(
|
||||
|req: HttpRequest| {
|
||||
if req.query_string().contains("qp") {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
},
|
||||
)))
|
||||
.tcp()
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").to(|req: HttpRequest| {
|
||||
if req.query_string().contains("qp") {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}))
|
||||
});
|
||||
|
||||
let res = awc::Client::new()
|
||||
@@ -388,15 +380,14 @@ async fn test_with_query_parameter() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_no_decompress() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().wrap(Compress::default()).service(
|
||||
web::resource("/").route(web::to(|| {
|
||||
let srv = test::start(|| {
|
||||
App::new()
|
||||
.wrap(Compress::default())
|
||||
.service(web::resource("/").route(web::to(|| {
|
||||
let mut res = HttpResponse::Ok().body(STR);
|
||||
res.encoding(header::ContentEncoding::Gzip);
|
||||
res
|
||||
})),
|
||||
))
|
||||
.tcp()
|
||||
})))
|
||||
});
|
||||
|
||||
let mut res = awc::Client::new()
|
||||
@@ -433,8 +424,8 @@ async fn test_no_decompress() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_client_gzip_encoding() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(|| {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| {
|
||||
let mut e = GzEncoder::new(Vec::new(), Compression::default());
|
||||
e.write_all(STR.as_ref()).unwrap();
|
||||
let data = e.finish().unwrap();
|
||||
@@ -442,8 +433,7 @@ async fn test_client_gzip_encoding() {
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "gzip")
|
||||
.body(data)
|
||||
}))))
|
||||
.tcp()
|
||||
})))
|
||||
});
|
||||
|
||||
// client request
|
||||
@@ -457,8 +447,8 @@ async fn test_client_gzip_encoding() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_client_gzip_encoding_large() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(|| {
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|| {
|
||||
let mut e = GzEncoder::new(Vec::new(), Compression::default());
|
||||
e.write_all(STR.repeat(10).as_ref()).unwrap();
|
||||
let data = e.finish().unwrap();
|
||||
@@ -466,8 +456,7 @@ async fn test_client_gzip_encoding_large() {
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "gzip")
|
||||
.body(data)
|
||||
}))))
|
||||
.tcp()
|
||||
})))
|
||||
});
|
||||
|
||||
// client request
|
||||
@@ -486,18 +475,15 @@ async fn test_client_gzip_encoding_large_random() {
|
||||
.take(100_000)
|
||||
.collect::<String>();
|
||||
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(
|
||||
|data: Bytes| {
|
||||
let mut e = GzEncoder::new(Vec::new(), Compression::default());
|
||||
e.write_all(&data).unwrap();
|
||||
let data = e.finish().unwrap();
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "gzip")
|
||||
.body(data)
|
||||
},
|
||||
))))
|
||||
.tcp()
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|data: Bytes| {
|
||||
let mut e = GzEncoder::new(Vec::new(), Compression::default());
|
||||
e.write_all(&data).unwrap();
|
||||
let data = e.finish().unwrap();
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "gzip")
|
||||
.body(data)
|
||||
})))
|
||||
});
|
||||
|
||||
// client request
|
||||
@@ -511,18 +497,15 @@ async fn test_client_gzip_encoding_large_random() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_client_brotli_encoding() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().service(web::resource("/").route(web::to(
|
||||
|data: Bytes| {
|
||||
let mut e = BrotliEncoder::new(Vec::new(), 5);
|
||||
e.write_all(&data).unwrap();
|
||||
let data = e.finish().unwrap();
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "br")
|
||||
.body(data)
|
||||
},
|
||||
))))
|
||||
.tcp()
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|data: Bytes| {
|
||||
let mut e = CompressorWriter::new(Vec::new(), 0, 5, 0);
|
||||
e.write_all(&data).unwrap();
|
||||
let data = e.into_inner();
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "br")
|
||||
.body(data)
|
||||
})))
|
||||
});
|
||||
|
||||
// client request
|
||||
@@ -534,41 +517,34 @@ async fn test_client_brotli_encoding() {
|
||||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||
}
|
||||
|
||||
// #[actix_rt::test]
|
||||
// async fn test_client_brotli_encoding_large_random() {
|
||||
// let data = rand::thread_rng()
|
||||
// .sample_iter(&rand::distributions::Alphanumeric)
|
||||
// .take(70_000)
|
||||
// .collect::<String>();
|
||||
#[actix_rt::test]
|
||||
async fn test_client_brotli_encoding_large_random() {
|
||||
let data = rand::thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
.take(70_000)
|
||||
.collect::<String>();
|
||||
|
||||
// let srv = test::TestServer::start(|app| {
|
||||
// app.handler(|req: &HttpRequest| {
|
||||
// req.body()
|
||||
// .and_then(move |bytes: Bytes| {
|
||||
// Ok(HttpResponse::Ok()
|
||||
// .content_encoding(http::ContentEncoding::Gzip)
|
||||
// .body(bytes))
|
||||
// })
|
||||
// .responder()
|
||||
// })
|
||||
// });
|
||||
let srv = test::start(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|data: Bytes| {
|
||||
let mut e = CompressorWriter::new(Vec::new(), 0, 5, 0);
|
||||
e.write_all(&data).unwrap();
|
||||
let data = e.into_inner();
|
||||
HttpResponse::Ok()
|
||||
.header("content-encoding", "br")
|
||||
.body(data)
|
||||
})))
|
||||
});
|
||||
|
||||
// // client request
|
||||
// let request = srv
|
||||
// .client(http::Method::POST, "/")
|
||||
// .content_encoding(http::ContentEncoding::Br)
|
||||
// .body(data.clone())
|
||||
// .unwrap();
|
||||
// let response = request.send().await.unwrap();
|
||||
// assert!(response.status().is_success());
|
||||
// client request
|
||||
let mut response = srv.post("/").send_body(data.clone()).await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// // read response
|
||||
// let bytes = response.body().await.unwrap();
|
||||
// assert_eq!(bytes.len(), data.len());
|
||||
// assert_eq!(bytes, Bytes::from(data));
|
||||
// }
|
||||
// read response
|
||||
let bytes = response.body().await.unwrap();
|
||||
assert_eq!(bytes.len(), data.len());
|
||||
assert_eq!(bytes, Bytes::from(data));
|
||||
}
|
||||
|
||||
// #[cfg(feature = "brotli")]
|
||||
// #[actix_rt::test]
|
||||
// async fn test_client_deflate_encoding() {
|
||||
// let srv = test::TestServer::start(|app| {
|
||||
@@ -692,11 +668,11 @@ async fn test_client_cookie_handling() {
|
||||
let cookie1b = cookie1.clone();
|
||||
let cookie2b = cookie2.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test::start(move || {
|
||||
let cookie1 = cookie1b.clone();
|
||||
let cookie2 = cookie2b.clone();
|
||||
|
||||
HttpService::new(App::new().route(
|
||||
App::new().route(
|
||||
"/",
|
||||
web::to(move |req: HttpRequest| {
|
||||
let cookie1 = cookie1.clone();
|
||||
@@ -734,8 +710,7 @@ async fn test_client_cookie_handling() {
|
||||
}
|
||||
}
|
||||
}),
|
||||
))
|
||||
.tcp()
|
||||
)
|
||||
});
|
||||
|
||||
let request = srv.get("/").cookie(cookie1.clone()).cookie(cookie2.clone());
|
||||
@@ -779,8 +754,8 @@ async fn test_client_cookie_handling() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn client_basic_auth() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().route(
|
||||
let srv = test::start(|| {
|
||||
App::new().route(
|
||||
"/",
|
||||
web::to(|req: HttpRequest| {
|
||||
if req
|
||||
@@ -796,8 +771,7 @@ async fn client_basic_auth() {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}),
|
||||
))
|
||||
.tcp()
|
||||
)
|
||||
});
|
||||
|
||||
// set authorization header to Basic <base64 encoded username:password>
|
||||
@@ -808,8 +782,8 @@ async fn client_basic_auth() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn client_bearer_auth() {
|
||||
let srv = TestServer::start(|| {
|
||||
HttpService::new(App::new().route(
|
||||
let srv = test::start(|| {
|
||||
App::new().route(
|
||||
"/",
|
||||
web::to(|req: HttpRequest| {
|
||||
if req
|
||||
@@ -825,8 +799,7 @@ async fn client_bearer_auth() {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}),
|
||||
))
|
||||
.tcp()
|
||||
)
|
||||
});
|
||||
|
||||
// set authorization header to Bearer <token>
|
||||
|
@@ -3,7 +3,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::TestServer;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{pipeline_factory, ServiceFactory};
|
||||
use actix_web::http::Version;
|
||||
use actix_web::{web, App, HttpResponse};
|
||||
@@ -54,7 +54,7 @@ async fn _test_connection_reuse_h2() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
|
@@ -3,7 +3,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_http::HttpService;
|
||||
use actix_http_test::TestServer;
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{pipeline_factory, ServiceFactory};
|
||||
use actix_web::http::Version;
|
||||
use actix_web::{web, App, HttpResponse};
|
||||
@@ -36,7 +36,7 @@ async fn test_connection_reuse_h2() {
|
||||
let num = Arc::new(AtomicUsize::new(0));
|
||||
let num2 = num.clone();
|
||||
|
||||
let srv = TestServer::start(move || {
|
||||
let srv = test_server(move || {
|
||||
let num2 = num2.clone();
|
||||
pipeline_factory(move |io| {
|
||||
num2.fetch_add(1, Ordering::Relaxed);
|
||||
|
@@ -2,27 +2,18 @@ use std::io;
|
||||
|
||||
use actix_codec::Framed;
|
||||
use actix_http::{body::BodySize, h1, ws, Error, HttpService, Request, Response};
|
||||
use actix_http_test::TestServer;
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use actix_http_test::test_server;
|
||||
use bytes::Bytes;
|
||||
use futures::future::ok;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
|
||||
async fn ws_service(req: ws::Frame) -> Result<ws::Message, io::Error> {
|
||||
match req {
|
||||
ws::Frame::Ping(msg) => Ok(ws::Message::Pong(msg)),
|
||||
ws::Frame::Text(text) => {
|
||||
let text = if let Some(pl) = text {
|
||||
String::from_utf8(Vec::from(pl.as_ref())).unwrap()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
Ok(ws::Message::Text(text))
|
||||
}
|
||||
ws::Frame::Binary(bin) => Ok(ws::Message::Binary(
|
||||
bin.map(|e| e.freeze())
|
||||
.unwrap_or_else(|| Bytes::from(""))
|
||||
.into(),
|
||||
ws::Frame::Text(text) => Ok(ws::Message::Text(
|
||||
String::from_utf8(Vec::from(text.as_ref())).unwrap(),
|
||||
)),
|
||||
ws::Frame::Binary(bin) => Ok(ws::Message::Binary(bin)),
|
||||
ws::Frame::Close(reason) => Ok(ws::Message::Close(reason)),
|
||||
_ => Ok(ws::Message::Close(None)),
|
||||
}
|
||||
@@ -30,7 +21,7 @@ async fn ws_service(req: ws::Frame) -> Result<ws::Message, io::Error> {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_simple() {
|
||||
let mut srv = TestServer::start(|| {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.upgrade(|(req, mut framed): (Request, Framed<_, _>)| {
|
||||
async move {
|
||||
@@ -42,7 +33,7 @@ async fn test_simple() {
|
||||
|
||||
// start websocket service
|
||||
let framed = framed.into_framed(ws::Codec::new());
|
||||
ws::Transport::with(framed, ws_service).await
|
||||
ws::Dispatcher::with(framed, ws_service).await
|
||||
}
|
||||
})
|
||||
.finish(|_| ok::<_, Error>(Response::NotFound()))
|
||||
@@ -56,14 +47,14 @@ async fn test_simple() {
|
||||
.await
|
||||
.unwrap();
|
||||
let item = framed.next().await.unwrap().unwrap();
|
||||
assert_eq!(item, ws::Frame::Text(Some(BytesMut::from("text"))));
|
||||
assert_eq!(item, ws::Frame::Text(Bytes::from_static(b"text")));
|
||||
|
||||
framed
|
||||
.send(ws::Message::Binary("text".into()))
|
||||
.await
|
||||
.unwrap();
|
||||
let item = framed.next().await.unwrap().unwrap();
|
||||
assert_eq!(item, ws::Frame::Binary(Some(BytesMut::from(&b"text"[..]))));
|
||||
assert_eq!(item, ws::Frame::Binary(Bytes::from_static(b"text")));
|
||||
|
||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||
let item = framed.next().await.unwrap().unwrap();
|
||||
|
20
src/app.rs
20
src/app.rs
@@ -38,7 +38,7 @@ pub struct App<T, B> {
|
||||
data_factories: Vec<FnDataFactory>,
|
||||
config: AppConfigInner,
|
||||
external: Vec<ResourceDef>,
|
||||
_t: PhantomData<(B)>,
|
||||
_t: PhantomData<B>,
|
||||
}
|
||||
|
||||
impl App<AppEntry, Body> {
|
||||
@@ -93,13 +93,11 @@ where
|
||||
/// HttpResponse::Ok()
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .data(MyData{ counter: Cell::new(0) })
|
||||
/// .service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::get().to(index)));
|
||||
/// }
|
||||
/// let app = App::new()
|
||||
/// .data(MyData{ counter: Cell::new(0) })
|
||||
/// .service(
|
||||
/// 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)));
|
||||
@@ -229,9 +227,9 @@ where
|
||||
|
||||
/// Set server host name.
|
||||
///
|
||||
/// Host name is used by application router as a hostname for url
|
||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
||||
/// html#method.host) documentation for more information.
|
||||
/// Host name is used by application router as a hostname for url generation.
|
||||
/// Check [ConnectionInfo](./dev/struct.ConnectionInfo.html#method.host)
|
||||
/// documentation for more information.
|
||||
///
|
||||
/// By default host name is set to a "localhost" value.
|
||||
pub fn hostname(mut self, val: &str) -> Self {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user