1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-07-23 17:28:19 +02:00

Compare commits

...

43 Commits

Author SHA1 Message Date
Nikolay Kim
d006a7b31f update changes 2019-12-13 12:10:45 +06:00
Nikolay Kim
3d64d565d9 fix warnings 2019-12-13 11:46:02 +06:00
Nikolay Kim
c1deaaeb2f cleanup imports 2019-12-13 11:24:57 +06:00
Nikolay Kim
b81417c2fa fix warnings 2019-12-13 10:59:02 +06:00
Nikolay Kim
4937c9f9c2 refactor http-test server 2019-12-12 23:08:38 +06:00
Nikolay Kim
db1d6b7963 refactor test server impl 2019-12-12 22:28:47 +06:00
Nikolay Kim
fa07415721 Replace flate2-xxx features with compress 2019-12-12 15:08:08 +06:00
Nikolay Kim
b4b3350b3e Add websockets continuation frame support 2019-12-12 14:06:54 +06:00
Jonathan Speiser
4a1695f719 fixes missing import in example (#1210) 2019-12-12 07:06:22 +06:00
0x1793d1
1b8d747937 Fix extra line feed (#1209) 2019-12-12 07:05:39 +06:00
Emilio González
a43a005f59 Log path if it is not a directory (#1208) 2019-12-12 07:04:53 +06:00
Alexander Larsson
a612b74aeb actix-multipart: Fix multipart boundary reading (#1205)
* actix-multipart: Fix multipart boundary reading

If we're not ready to read the first line after the multipart field
(which should be a "\r\n" line) then return Pending instead of Ready(None)
so that we will get called again to read that line.

Without this I was getting MultipartError::Boundary from read_boundary()
because it got the "\r\n" line instead of the boundary.

Also tweaks the test_stream test to test partial reads.

This is a forward port of #1189 from 1.0

* actix-multipart: Update changes for boundary fix
2019-12-12 07:03:44 +06:00
Nikolay Kim
131c897099 upgrade to actix-net release 2019-12-11 19:20:20 +06:00
Nikolay Kim
ef3a33b9d6 use std mutext instead of parking_lot 2019-12-10 09:00:51 +06:00
Nikolay Kim
5132257b0d Fix buffer remaining capacity calcualtion 2019-12-09 21:55:22 +06:00
Nikolay Kim
0c1f5f9edc Check Upgrade service readiness before calling it 2019-12-09 17:40:15 +06:00
Sameer Dhar
e4382e4fc1 Fix broken docs (#1204)
Fixed un escaped brackets in lib.rs, and reflowed links to ConnectionInfo in app, config, and server.rs
2019-12-09 10:02:43 +06:00
Nikolay Kim
a3ce371312 ws ping and pong uses bytes #1049 2019-12-09 07:01:22 +06:00
Nikolay Kim
42258ee289 deps 2019-12-08 20:22:39 +06:00
Nikolay Kim
b92eafb839 prepare actix-http release 2019-12-08 20:15:51 +06:00
Nikolay Kim
3b2e78db47 add link to chat 2019-12-08 19:27:06 +06:00
Nikolay Kim
63da1a5560 Merge branch 'master' of github.com:actix/actix-web 2019-12-08 19:26:12 +06:00
Nikolay Kim
1f3ffe38e8 update actix-service dep 2019-12-08 19:25:24 +06:00
krircc
c23b6b3879 Merge pull request #1192 from krircc/master
Add rich project metadata
2019-12-08 16:03:39 +08:00
Yuki Okushi
909c7c8b5b Merge branch 'master' into master 2019-12-08 16:26:35 +09:00
Nikolay Kim
4a8a9ef405 update tests and clippy warnings 2019-12-08 12:31:16 +06:00
Nikolay Kim
6c9f9fff73 clippy warnings 2019-12-08 00:46:51 +06:00
Nikolay Kim
8df33f7a81 remove HttpServer::run() as it is not useful with async/await 2019-12-08 00:06:04 +06:00
Nikolay Kim
7ec5ca88a1 update changes 2019-12-07 22:01:55 +06:00
daxpedda
e5f3d88a4e Switch brotli compressor to rust. (#1197)
* Switch to a rustified version of brotli.

* Some memory optimizations.

* Make brotli not optional anymore.
2019-12-07 21:55:41 +06:00
Nikolay Kim
0ba125444a Add impl ResponseBuilder for Error 2019-12-07 21:41:34 +06:00
Nikolay Kim
6c226e47bd prepare actix-web-actors release 2019-12-07 20:10:36 +06:00
Vlad Frolov
8c3f58db9d Allow comma-separated websocket subprotocols without spaces (#1172)
* Allow comma-separated websocket subprotocols without spaces

* [CHANGES] Added an entry to CHANGES.md
2019-12-07 20:08:06 +06:00
daxpedda
4921243add Fix rustls build. (#1195) 2019-12-07 16:14:09 +06:00
daxpedda
91b3fcf85c Fix dependency features. (#1196) 2019-12-07 16:13:26 +06:00
Yuki Okushi
f2ba389496 Merge branch 'master' into master 2019-12-06 16:57:42 +09:00
krircc
439f02b6b1 Update README.md 2019-12-06 14:59:11 +08:00
krircc
e32da08a26 Update README.md 2019-12-06 14:34:14 +08:00
krircc
82110e0927 Update README.md 2019-12-06 14:29:10 +08:00
krircc
7b3354a9ad Update README.md 2019-12-06 14:26:23 +08:00
krircc
5243e8baca Update README.md 2019-12-06 14:23:28 +08:00
krircc
98903028c7 Update README.md 2019-12-06 14:22:29 +08:00
krircc
b7d44d6c4c Merge pull request #1 from actix/master
git pull
2019-12-01 16:56:42 +08:00
131 changed files with 2064 additions and 1647 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -1,4 +1,28 @@
# Actix web [![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) [![crates.io](https://meritbadge.herokuapp.com/actix-web)](https://crates.io/crates/actix-web) [![Join the chat at https://gitter.im/actix/actix](https://badges.gitter.im/actix/actix.svg)](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>
[![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web)
[![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web)
[![crates.io](https://meritbadge.herokuapp.com/actix-web)](https://crates.io/crates/actix-web)
[![Join the chat at https://gitter.im/actix/actix](https://badges.gitter.im/actix/actix.svg)](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Documentation](https://docs.rs/actix-web/badge.svg)](https://docs.rs/actix-web)
[![Download](https://img.shields.io/crates/d/actix-web.svg)](https://crates.io/crates/actix-web)
[![Version](https://img.shields.io/badge/rustc-1.39+-lightgray.svg)](https://blog.rust-lang.org/2019/11/07/Rust-1.39.0.html)
![License](https://img.shields.io/crates/l/actix-web.svg)
</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 {

View File

@@ -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"

View File

@@ -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(),
))

View File

@@ -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"] }

View File

@@ -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(),

View File

@@ -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"

View File

@@ -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();

View File

@@ -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

View File

@@ -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" }

View File

@@ -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] {

View File

@@ -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]

View File

@@ -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),
)
}
}

View File

@@ -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)? {

View File

@@ -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};

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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()

View File

@@ -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 {

View File

@@ -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"),

View File

@@ -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)
}
}

View File

@@ -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)
}

View File

@@ -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())
}
}

View File

@@ -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);

View File

@@ -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());

View File

@@ -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)),
}
}
}

View File

@@ -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) => {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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()
}
}

View File

@@ -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(),
},
}

View File

@@ -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() {

View File

@@ -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

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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(()))
}

View File

@@ -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() {

View File

@@ -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) => {

View File

@@ -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(()))
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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(

View File

@@ -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 {

View File

@@ -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()

View File

@@ -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,

View File

@@ -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),

View File

@@ -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(

View File

@@ -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())
}

View File

@@ -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)
}

View File

@@ -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())
}
}

View File

@@ -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",

View File

@@ -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 {

View File

@@ -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)
}
}

View File

@@ -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(()),

View File

@@ -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()
}
}

View File

@@ -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;

View File

@@ -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()
}

View File

@@ -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),

View File

@@ -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 {:?} {}:{}",

View File

@@ -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!(

View File

@@ -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() {

View File

@@ -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>);

View File

@@ -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),

View File

@@ -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)
}
}

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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),

View File

@@ -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

View File

@@ -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=") {

View File

@@ -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| {

View File

@@ -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())

View File

@@ -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| {

View File

@@ -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

View File

@@ -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"

View File

@@ -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`

View File

@@ -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"

View File

@@ -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!(),
}

View File

@@ -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"

View File

@@ -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;

View File

@@ -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

View File

@@ -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"

View File

@@ -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)
);
}
}

View File

@@ -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" }

View File

@@ -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();

View File

@@ -1,5 +1,9 @@
# Changes
## [1.0.0] - 2019-12-13
* Release
## [1.0.0-alpha.3]
* Migrate to `std::future`

View File

@@ -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"

View File

@@ -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")
}
}

View File

@@ -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;

View File

@@ -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)]

View File

@@ -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 {:?} {}:{}",

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {}:{}",

View File

@@ -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>

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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