mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-15 06:26:11 +02:00
Compare commits
5 Commits
files-v0.6
...
test-v0.1.
Author | SHA1 | Date | |
---|---|---|---|
7faeffc5ab | |||
f81d4bdae7 | |||
6893773280 | |||
73a655544e | |||
baa5a663c4 |
@ -1,6 +1,10 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
### Changed
|
||||||
|
* Change compression algorithm features flags. [#2250]
|
||||||
|
|
||||||
|
[#2250]: https://github.com/actix/actix-web/pull/2250
|
||||||
|
|
||||||
|
|
||||||
## 4.0.0-beta.7 - 2021-06-17
|
## 4.0.0-beta.7 - 2021-06-17
|
||||||
@ -8,7 +12,6 @@
|
|||||||
* `HttpServer::worker_max_blocking_threads` for setting block thread pool. [#2200]
|
* `HttpServer::worker_max_blocking_threads` for setting block thread pool. [#2200]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* Adjusted default JSON payload limit to 2MB (from 32kb) and included size and limits in the `JsonPayloadError::Overflow` error variant. [#2162]
|
* Adjusted default JSON payload limit to 2MB (from 32kb) and included size and limits in the `JsonPayloadError::Overflow` error variant. [#2162]
|
||||||
[#2162]: (https://github.com/actix/actix-web/pull/2162)
|
[#2162]: (https://github.com/actix/actix-web/pull/2162)
|
||||||
* `ServiceResponse::error_response` now uses body type of `Body`. [#2201]
|
* `ServiceResponse::error_response` now uses body type of `Body`. [#2201]
|
||||||
|
25
Cargo.toml
25
Cargo.toml
@ -17,7 +17,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# features that docs.rs will build with
|
# features that docs.rs will build with
|
||||||
features = ["openssl", "rustls", "compress", "cookies", "secure-cookies"]
|
features = ["openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "secure-cookies"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "actix_web"
|
name = "actix_web"
|
||||||
@ -39,10 +39,14 @@ members = [
|
|||||||
# resolver = "2"
|
# resolver = "2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["compress", "cookies"]
|
default = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"]
|
||||||
|
|
||||||
# content-encoding support
|
# Brotli algorithm content-encoding support
|
||||||
compress = ["actix-http/compress"]
|
compress-brotli = ["actix-http/compress-brotli", "__compress"]
|
||||||
|
# Gzip and deflate algorithms content-encoding support
|
||||||
|
compress-gzip = ["actix-http/compress-gzip", "__compress"]
|
||||||
|
# Zstd algorithm content-encoding support
|
||||||
|
compress-zstd = ["actix-http/compress-zstd", "__compress"]
|
||||||
|
|
||||||
# support for cookies
|
# support for cookies
|
||||||
cookies = ["cookie"]
|
cookies = ["cookie"]
|
||||||
@ -56,6 +60,10 @@ openssl = ["actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"]
|
|||||||
# rustls
|
# rustls
|
||||||
rustls = ["actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"]
|
rustls = ["actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"]
|
||||||
|
|
||||||
|
# Internal (PRIVATE!) features used to aid testing and cheking feature status.
|
||||||
|
# Don't rely on these whatsoever. They may disappear at anytime.
|
||||||
|
__compress = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.4.0"
|
actix-codec = "0.4.0"
|
||||||
actix-macros = "0.2.1"
|
actix-macros = "0.2.1"
|
||||||
@ -71,6 +79,7 @@ actix-http = "3.0.0-beta.7"
|
|||||||
|
|
||||||
ahash = "0.7"
|
ahash = "0.7"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
|
cfg-if = "1"
|
||||||
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
|
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
|
||||||
derive_more = "0.99.5"
|
derive_more = "0.99.5"
|
||||||
either = "1.5.3"
|
either = "1.5.3"
|
||||||
@ -94,7 +103,7 @@ time = { version = "0.2.23", default-features = false, features = ["std"] }
|
|||||||
url = "2.1"
|
url = "2.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-test = { version = "0.1.0-beta.2", features = ["openssl", "rustls"] }
|
actix-test = { version = "0.1.0-beta.3", features = ["openssl", "rustls"] }
|
||||||
awc = { version = "3.0.0-beta.6", features = ["openssl"] }
|
awc = { version = "3.0.0-beta.6", features = ["openssl"] }
|
||||||
|
|
||||||
brotli2 = "0.3.2"
|
brotli2 = "0.3.2"
|
||||||
@ -126,15 +135,15 @@ awc = { path = "awc" }
|
|||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "test_server"
|
name = "test_server"
|
||||||
required-features = ["compress", "cookies"]
|
required-features = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "basic"
|
name = "basic"
|
||||||
required-features = ["compress"]
|
required-features = ["compress-gzip"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "uds"
|
name = "uds"
|
||||||
required-features = ["compress"]
|
required-features = ["compress-gzip"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "on_connect"
|
name = "on_connect"
|
||||||
|
12
MIGRATION.md
12
MIGRATION.md
@ -10,6 +10,18 @@
|
|||||||
|
|
||||||
Alternatively, explicitly require trailing slashes: `NormalizePath::new(TrailingSlash::Always)`.
|
Alternatively, explicitly require trailing slashes: `NormalizePath::new(TrailingSlash::Always)`.
|
||||||
|
|
||||||
|
* Feature flag `compress` has been split into its supported algorithm (brotli, gzip, zstd).
|
||||||
|
By default all compression algorithms are enabled.
|
||||||
|
To select algorithm you want to include with `middleware::Compress` use following flags:
|
||||||
|
- `compress-brotli`
|
||||||
|
- `compress-gzip`
|
||||||
|
- `compress-zstd`
|
||||||
|
If you have set in your `Cargo.toml` dedicated `actix-web` features and you still want
|
||||||
|
to have compression enabled. Please change features selection like bellow:
|
||||||
|
|
||||||
|
Before: `"compress"`
|
||||||
|
After: `"compress-brotli", "compress-gzip", "compress-zstd"`
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0
|
## 3.0.0
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* Streaming and pipelining
|
* Streaming and pipelining
|
||||||
* Keep-alive and slow requests handling
|
* Keep-alive and slow requests handling
|
||||||
* Client/server [WebSockets](https://actix.rs/docs/websockets/) support
|
* Client/server [WebSockets](https://actix.rs/docs/websockets/) support
|
||||||
* Transparent content compression/decompression (br, gzip, deflate)
|
* Transparent content compression/decompression (br, gzip, deflate, zstd)
|
||||||
* Powerful [request routing](https://actix.rs/docs/url-dispatch/)
|
* Powerful [request routing](https://actix.rs/docs/url-dispatch/)
|
||||||
* Multipart streams
|
* Multipart streams
|
||||||
* Static assets
|
* Static assets
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
* For symbolic links, `Content-Disposition` header no longer shows the filename of the original file. [#2156]
|
* For symbolic links, `Content-Disposition` header no longer shows the filename of the original file. [#2156]
|
||||||
* `Files::redirect_to_slash_directory()` now works as expected when used with `Files::show_files_listing()`. [#2225]
|
* `Files::redirect_to_slash_directory()` now works as expected when used with `Files::show_files_listing()`. [#2225]
|
||||||
* `application/{javascript, json, wasm}` mime type now have `inline` disposition by default. [#2257]
|
* `application/{javascript, json, wasm}` mime type now have `inline` disposition by default. [#2257]
|
||||||
|
* `Files::show_files_listing()` can now be used with `Files::index_file()` to show files listing as a fallback when the index file is not found. [#2228]
|
||||||
|
|
||||||
[#2135]: https://github.com/actix/actix-web/pull/2135
|
[#2135]: https://github.com/actix/actix-web/pull/2135
|
||||||
[#2156]: https://github.com/actix/actix-web/pull/2156
|
[#2156]: https://github.com/actix/actix-web/pull/2156
|
||||||
[#2225]: https://github.com/actix/actix-web/pull/2225
|
[#2225]: https://github.com/actix/actix-web/pull/2225
|
||||||
[#2257]: https://github.com/actix/actix-web/pull/2257
|
[#2257]: https://github.com/actix/actix-web/pull/2257
|
||||||
|
[#2228]: https://github.com/actix/actix-web/pull/2228
|
||||||
|
|
||||||
|
|
||||||
## 0.6.0-beta.4 - 2021-04-02
|
## 0.6.0-beta.4 - 2021-04-02
|
||||||
|
@ -36,4 +36,4 @@ percent-encoding = "2.1"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.2"
|
actix-rt = "2.2"
|
||||||
actix-web = "4.0.0-beta.7"
|
actix-web = "4.0.0-beta.7"
|
||||||
actix-test = "0.1.0-beta.2"
|
actix-test = "0.1.0-beta.3"
|
||||||
|
@ -114,6 +114,9 @@ impl Files {
|
|||||||
/// Show files listing for directories.
|
/// Show files listing for directories.
|
||||||
///
|
///
|
||||||
/// By default show files listing is disabled.
|
/// By default show files listing is disabled.
|
||||||
|
///
|
||||||
|
/// When used with [`Files::index_file()`], files listing is shown as a fallback
|
||||||
|
/// when the index file is not found.
|
||||||
pub fn show_files_listing(mut self) -> Self {
|
pub fn show_files_listing(mut self) -> Self {
|
||||||
self.show_index = true;
|
self.show_index = true;
|
||||||
self
|
self
|
||||||
@ -148,8 +151,11 @@ impl Files {
|
|||||||
|
|
||||||
/// Set index file
|
/// Set index file
|
||||||
///
|
///
|
||||||
/// Shows specific index file for directory "/" instead of
|
/// Shows specific index file for directories instead of
|
||||||
/// showing files listing.
|
/// showing files listing.
|
||||||
|
///
|
||||||
|
/// If the index file is not found, files listing is shown as a fallback if
|
||||||
|
/// [`Files::show_files_listing()`] is set.
|
||||||
pub fn index_file<T: Into<String>>(mut self, index: T) -> Self {
|
pub fn index_file<T: Into<String>>(mut self, index: T) -> Self {
|
||||||
self.index = Some(index.into());
|
self.index = Some(index.into());
|
||||||
self
|
self
|
||||||
|
@ -872,4 +872,33 @@ mod tests {
|
|||||||
"inline; filename=\"symlink-test.png\""
|
"inline; filename=\"symlink-test.png\""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_index_with_show_files_listing() {
|
||||||
|
let service = Files::new(".", ".")
|
||||||
|
.index_file("lib.rs")
|
||||||
|
.show_files_listing()
|
||||||
|
.new_service(())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Serve the index if exists
|
||||||
|
let req = TestRequest::default().uri("/src").to_srv_request();
|
||||||
|
let resp = test::call_service(&service, req).await;
|
||||||
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||||
|
"text/x-rust"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show files listing, otherwise.
|
||||||
|
let req = TestRequest::default().uri("/tests").to_srv_request();
|
||||||
|
let resp = test::call_service(&service, req).await;
|
||||||
|
assert_eq!(
|
||||||
|
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||||
|
"text/html; charset=utf-8"
|
||||||
|
);
|
||||||
|
let bytes = test::read_body(resp).await;
|
||||||
|
assert!(format!("{:?}", bytes).contains("/tests/test.png"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,26 +102,20 @@ impl Service<ServiceRequest> for FilesService {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref redir_index) = self.index {
|
let serve_named_file = |req: ServiceRequest, mut named_file: NamedFile| {
|
||||||
let path = path.join(redir_index);
|
if let Some(ref mime_override) = self.mime_override {
|
||||||
|
let new_disposition = mime_override(&named_file.content_type.type_());
|
||||||
match NamedFile::open(path) {
|
named_file.content_disposition.disposition = new_disposition;
|
||||||
Ok(mut named_file) => {
|
|
||||||
if let Some(ref mime_override) = self.mime_override {
|
|
||||||
let new_disposition =
|
|
||||||
mime_override(&named_file.content_type.type_());
|
|
||||||
named_file.content_disposition.disposition = new_disposition;
|
|
||||||
}
|
|
||||||
named_file.flags = self.file_flags;
|
|
||||||
|
|
||||||
let (req, _) = req.into_parts();
|
|
||||||
let res = named_file.into_response(&req);
|
|
||||||
Box::pin(ok(ServiceResponse::new(req, res)))
|
|
||||||
}
|
|
||||||
Err(err) => self.handle_err(err, req),
|
|
||||||
}
|
}
|
||||||
} else if self.show_index {
|
named_file.flags = self.file_flags;
|
||||||
let dir = Directory::new(self.directory.clone(), path);
|
|
||||||
|
let (req, _) = req.into_parts();
|
||||||
|
let res = named_file.into_response(&req);
|
||||||
|
Box::pin(ok(ServiceResponse::new(req, res)))
|
||||||
|
};
|
||||||
|
|
||||||
|
let show_index = |req: ServiceRequest| {
|
||||||
|
let dir = Directory::new(self.directory.clone(), path.clone());
|
||||||
|
|
||||||
let (req, _) = req.into_parts();
|
let (req, _) = req.into_parts();
|
||||||
let x = (self.renderer)(&dir, &req);
|
let x = (self.renderer)(&dir, &req);
|
||||||
@ -130,11 +124,19 @@ impl Service<ServiceRequest> for FilesService {
|
|||||||
Ok(resp) => ok(resp),
|
Ok(resp) => ok(resp),
|
||||||
Err(err) => ok(ServiceResponse::from_err(err, req)),
|
Err(err) => ok(ServiceResponse::from_err(err, req)),
|
||||||
})
|
})
|
||||||
} else {
|
};
|
||||||
Box::pin(ok(ServiceResponse::from_err(
|
|
||||||
|
match self.index {
|
||||||
|
Some(ref index) => match NamedFile::open(path.join(index)) {
|
||||||
|
Ok(named_file) => serve_named_file(req, named_file),
|
||||||
|
Err(_) if self.show_index => show_index(req),
|
||||||
|
Err(err) => self.handle_err(err, req),
|
||||||
|
},
|
||||||
|
None if self.show_index => show_index(req),
|
||||||
|
_ => Box::pin(ok(ServiceResponse::from_err(
|
||||||
FilesError::IsDirectory,
|
FilesError::IsDirectory,
|
||||||
req.into_parts().0,
|
req.into_parts().0,
|
||||||
)))
|
))),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match NamedFile::open(path) {
|
match NamedFile::open(path) {
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
### Changed
|
||||||
|
* Change compression algorithm features flags. [#2250]
|
||||||
|
|
||||||
|
[#2250]: https://github.com/actix/actix-web/pull/2250
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0-beta.7 - 2021-06-17
|
## 3.0.0-beta.7 - 2021-06-17
|
||||||
|
@ -16,7 +16,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# features that docs.rs will build with
|
# features that docs.rs will build with
|
||||||
features = ["openssl", "rustls", "compress"]
|
features = ["openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "actix_http"
|
name = "actix_http"
|
||||||
@ -32,11 +32,17 @@ openssl = ["actix-tls/openssl"]
|
|||||||
rustls = ["actix-tls/rustls"]
|
rustls = ["actix-tls/rustls"]
|
||||||
|
|
||||||
# enable compression support
|
# enable compression support
|
||||||
compress = ["flate2", "brotli2", "zstd"]
|
compress-brotli = ["brotli2", "__compress"]
|
||||||
|
compress-gzip = ["flate2", "__compress"]
|
||||||
|
compress-zstd = ["zstd", "__compress"]
|
||||||
|
|
||||||
# trust-dns as client dns resolver
|
# trust-dns as client dns resolver
|
||||||
trust-dns = ["trust-dns-resolver"]
|
trust-dns = ["trust-dns-resolver"]
|
||||||
|
|
||||||
|
# Internal (PRIVATE!) features used to aid testing and cheking feature status.
|
||||||
|
# Don't rely on these whatsoever. They may disappear at anytime.
|
||||||
|
__compress = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "2.0.0"
|
actix-service = "2.0.0"
|
||||||
actix-codec = "0.4.0"
|
actix-codec = "0.4.0"
|
||||||
|
@ -8,10 +8,16 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use actix_rt::task::{spawn_blocking, JoinHandle};
|
use actix_rt::task::{spawn_blocking, JoinHandle};
|
||||||
use brotli2::write::BrotliDecoder;
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flate2::write::{GzDecoder, ZlibDecoder};
|
|
||||||
use futures_core::{ready, Stream};
|
use futures_core::{ready, Stream};
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
|
use brotli2::write::BrotliDecoder;
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
|
use flate2::write::{GzDecoder, ZlibDecoder};
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
use zstd::stream::write::Decoder as ZstdDecoder;
|
use zstd::stream::write::Decoder as ZstdDecoder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -37,15 +43,19 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
|
pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
|
||||||
let decoder = match encoding {
|
let decoder = match encoding {
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(
|
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(
|
||||||
BrotliDecoder::new(Writer::new()),
|
BrotliDecoder::new(Writer::new()),
|
||||||
))),
|
))),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(
|
ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(
|
||||||
ZlibDecoder::new(Writer::new()),
|
ZlibDecoder::new(Writer::new()),
|
||||||
))),
|
))),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(
|
ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(
|
||||||
GzDecoder::new(Writer::new()),
|
GzDecoder::new(Writer::new()),
|
||||||
))),
|
))),
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentEncoding::Zstd => Some(ContentDecoder::Zstd(Box::new(
|
ContentEncoding::Zstd => Some(ContentDecoder::Zstd(Box::new(
|
||||||
ZstdDecoder::new(Writer::new()).expect(
|
ZstdDecoder::new(Writer::new()).expect(
|
||||||
"Failed to create zstd decoder. This is a bug. \
|
"Failed to create zstd decoder. This is a bug. \
|
||||||
@ -148,17 +158,22 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ContentDecoder {
|
enum ContentDecoder {
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
Deflate(Box<ZlibDecoder<Writer>>),
|
Deflate(Box<ZlibDecoder<Writer>>),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
Gzip(Box<GzDecoder<Writer>>),
|
Gzip(Box<GzDecoder<Writer>>),
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
Br(Box<BrotliDecoder<Writer>>),
|
Br(Box<BrotliDecoder<Writer>>),
|
||||||
// We need explicit 'static lifetime here because ZstdDecoder need lifetime
|
// We need explicit 'static lifetime here because ZstdDecoder need lifetime
|
||||||
// argument, and we use `spawn_blocking` in `Decoder::poll_next` that require `FnOnce() -> R + Send + 'static`
|
// argument, and we use `spawn_blocking` in `Decoder::poll_next` that require `FnOnce() -> R + Send + 'static`
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
Zstd(Box<ZstdDecoder<'static, Writer>>),
|
Zstd(Box<ZstdDecoder<'static, Writer>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentDecoder {
|
impl ContentDecoder {
|
||||||
fn feed_eof(&mut self) -> io::Result<Option<Bytes>> {
|
fn feed_eof(&mut self) -> io::Result<Option<Bytes>> {
|
||||||
match self {
|
match self {
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentDecoder::Br(ref mut decoder) => match decoder.flush() {
|
ContentDecoder::Br(ref mut decoder) => match decoder.flush() {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let b = decoder.get_mut().take();
|
let b = decoder.get_mut().take();
|
||||||
@ -172,6 +187,7 @@ impl ContentDecoder {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentDecoder::Gzip(ref mut decoder) => match decoder.try_finish() {
|
ContentDecoder::Gzip(ref mut decoder) => match decoder.try_finish() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let b = decoder.get_mut().take();
|
let b = decoder.get_mut().take();
|
||||||
@ -185,6 +201,7 @@ impl ContentDecoder {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentDecoder::Deflate(ref mut decoder) => match decoder.try_finish() {
|
ContentDecoder::Deflate(ref mut decoder) => match decoder.try_finish() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let b = decoder.get_mut().take();
|
let b = decoder.get_mut().take();
|
||||||
@ -197,6 +214,7 @@ impl ContentDecoder {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentDecoder::Zstd(ref mut decoder) => match decoder.flush() {
|
ContentDecoder::Zstd(ref mut decoder) => match decoder.flush() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let b = decoder.get_mut().take();
|
let b = decoder.get_mut().take();
|
||||||
@ -213,6 +231,7 @@ impl ContentDecoder {
|
|||||||
|
|
||||||
fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {
|
fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {
|
||||||
match self {
|
match self {
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentDecoder::Br(ref mut decoder) => match decoder.write_all(&data) {
|
ContentDecoder::Br(ref mut decoder) => match decoder.write_all(&data) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
decoder.flush()?;
|
decoder.flush()?;
|
||||||
@ -227,6 +246,7 @@ impl ContentDecoder {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentDecoder::Gzip(ref mut decoder) => match decoder.write_all(&data) {
|
ContentDecoder::Gzip(ref mut decoder) => match decoder.write_all(&data) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
decoder.flush()?;
|
decoder.flush()?;
|
||||||
@ -241,6 +261,7 @@ impl ContentDecoder {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentDecoder::Deflate(ref mut decoder) => match decoder.write_all(&data) {
|
ContentDecoder::Deflate(ref mut decoder) => match decoder.write_all(&data) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
decoder.flush()?;
|
decoder.flush()?;
|
||||||
@ -255,6 +276,7 @@ impl ContentDecoder {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentDecoder::Zstd(ref mut decoder) => match decoder.write_all(&data) {
|
ContentDecoder::Zstd(ref mut decoder) => match decoder.write_all(&data) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
decoder.flush()?;
|
decoder.flush()?;
|
||||||
|
@ -9,12 +9,18 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use actix_rt::task::{spawn_blocking, JoinHandle};
|
use actix_rt::task::{spawn_blocking, JoinHandle};
|
||||||
use brotli2::write::BrotliEncoder;
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use derive_more::Display;
|
use derive_more::Display;
|
||||||
use flate2::write::{GzEncoder, ZlibEncoder};
|
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
|
use brotli2::write::BrotliEncoder;
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
|
use flate2::write::{GzEncoder, ZlibEncoder};
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
use zstd::stream::write::Encoder as ZstdEncoder;
|
use zstd::stream::write::Encoder as ZstdEncoder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -233,28 +239,36 @@ fn update_head(encoding: ContentEncoding, head: &mut ResponseHead) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ContentEncoder {
|
enum ContentEncoder {
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
Deflate(ZlibEncoder<Writer>),
|
Deflate(ZlibEncoder<Writer>),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
Gzip(GzEncoder<Writer>),
|
Gzip(GzEncoder<Writer>),
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
Br(BrotliEncoder<Writer>),
|
Br(BrotliEncoder<Writer>),
|
||||||
// We need explicit 'static lifetime here because ZstdEncoder need lifetime
|
// We need explicit 'static lifetime here because ZstdEncoder need lifetime
|
||||||
// argument, and we use `spawn_blocking` in `Encoder::poll_next` that require `FnOnce() -> R + Send + 'static`
|
// argument, and we use `spawn_blocking` in `Encoder::poll_next` that require `FnOnce() -> R + Send + 'static`
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
Zstd(ZstdEncoder<'static, Writer>),
|
Zstd(ZstdEncoder<'static, Writer>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentEncoder {
|
impl ContentEncoder {
|
||||||
fn encoder(encoding: ContentEncoding) -> Option<Self> {
|
fn encoder(encoding: ContentEncoding) -> Option<Self> {
|
||||||
match encoding {
|
match encoding {
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoding::Deflate => Some(ContentEncoder::Deflate(ZlibEncoder::new(
|
ContentEncoding::Deflate => Some(ContentEncoder::Deflate(ZlibEncoder::new(
|
||||||
Writer::new(),
|
Writer::new(),
|
||||||
flate2::Compression::fast(),
|
flate2::Compression::fast(),
|
||||||
))),
|
))),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoding::Gzip => Some(ContentEncoder::Gzip(GzEncoder::new(
|
ContentEncoding::Gzip => Some(ContentEncoder::Gzip(GzEncoder::new(
|
||||||
Writer::new(),
|
Writer::new(),
|
||||||
flate2::Compression::fast(),
|
flate2::Compression::fast(),
|
||||||
))),
|
))),
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentEncoding::Br => {
|
ContentEncoding::Br => {
|
||||||
Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3)))
|
Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3)))
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentEncoding::Zstd => {
|
ContentEncoding::Zstd => {
|
||||||
let encoder = ZstdEncoder::new(Writer::new(), 3).ok()?;
|
let encoder = ZstdEncoder::new(Writer::new(), 3).ok()?;
|
||||||
Some(ContentEncoder::Zstd(encoder))
|
Some(ContentEncoder::Zstd(encoder))
|
||||||
@ -266,27 +280,35 @@ impl ContentEncoder {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn take(&mut self) -> Bytes {
|
pub(crate) fn take(&mut self) -> Bytes {
|
||||||
match *self {
|
match *self {
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentEncoder::Br(ref mut encoder) => encoder.get_mut().take(),
|
ContentEncoder::Br(ref mut encoder) => encoder.get_mut().take(),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoder::Deflate(ref mut encoder) => encoder.get_mut().take(),
|
ContentEncoder::Deflate(ref mut encoder) => encoder.get_mut().take(),
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoder::Gzip(ref mut encoder) => encoder.get_mut().take(),
|
ContentEncoder::Gzip(ref mut encoder) => encoder.get_mut().take(),
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentEncoder::Zstd(ref mut encoder) => encoder.get_mut().take(),
|
ContentEncoder::Zstd(ref mut encoder) => encoder.get_mut().take(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(self) -> Result<Bytes, io::Error> {
|
fn finish(self) -> Result<Bytes, io::Error> {
|
||||||
match self {
|
match self {
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentEncoder::Br(encoder) => match encoder.finish() {
|
ContentEncoder::Br(encoder) => match encoder.finish() {
|
||||||
Ok(writer) => Ok(writer.buf.freeze()),
|
Ok(writer) => Ok(writer.buf.freeze()),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoder::Gzip(encoder) => match encoder.finish() {
|
ContentEncoder::Gzip(encoder) => match encoder.finish() {
|
||||||
Ok(writer) => Ok(writer.buf.freeze()),
|
Ok(writer) => Ok(writer.buf.freeze()),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoder::Deflate(encoder) => match encoder.finish() {
|
ContentEncoder::Deflate(encoder) => match encoder.finish() {
|
||||||
Ok(writer) => Ok(writer.buf.freeze()),
|
Ok(writer) => Ok(writer.buf.freeze()),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentEncoder::Zstd(encoder) => match encoder.finish() {
|
ContentEncoder::Zstd(encoder) => match encoder.finish() {
|
||||||
Ok(writer) => Ok(writer.buf.freeze()),
|
Ok(writer) => Ok(writer.buf.freeze()),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
@ -296,6 +318,7 @@ impl ContentEncoder {
|
|||||||
|
|
||||||
fn write(&mut self, data: &[u8]) -> Result<(), io::Error> {
|
fn write(&mut self, data: &[u8]) -> Result<(), io::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
|
#[cfg(feature = "compress-brotli")]
|
||||||
ContentEncoder::Br(ref mut encoder) => match encoder.write_all(data) {
|
ContentEncoder::Br(ref mut encoder) => match encoder.write_all(data) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -303,6 +326,7 @@ impl ContentEncoder {
|
|||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoder::Gzip(ref mut encoder) => match encoder.write_all(data) {
|
ContentEncoder::Gzip(ref mut encoder) => match encoder.write_all(data) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -310,6 +334,7 @@ impl ContentEncoder {
|
|||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "compress-gzip")]
|
||||||
ContentEncoder::Deflate(ref mut encoder) => match encoder.write_all(data) {
|
ContentEncoder::Deflate(ref mut encoder) => match encoder.write_all(data) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -317,6 +342,7 @@ impl ContentEncoder {
|
|||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
ContentEncoder::Zstd(ref mut encoder) => match encoder.write_all(data) {
|
ContentEncoder::Zstd(ref mut encoder) => match encoder.write_all(data) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
//! HTTP primitives for the Actix ecosystem.
|
//! HTTP primitives for the Actix ecosystem.
|
||||||
//!
|
//!
|
||||||
//! ## Crate Features
|
//! ## Crate Features
|
||||||
//! | Feature | Functionality |
|
//! | Feature | Functionality |
|
||||||
//! | ---------------- | ----------------------------------------------------- |
|
//! | ------------------- | ------------------------------------------- |
|
||||||
//! | `openssl` | TLS support via [OpenSSL]. |
|
//! | `openssl` | TLS support via [OpenSSL]. |
|
||||||
//! | `rustls` | TLS support via [rustls]. |
|
//! | `rustls` | TLS support via [rustls]. |
|
||||||
//! | `compress` | Payload compression support. (Deflate, Gzip & Brotli) |
|
//! | `compress-brotli` | Payload compression support: Brotli. |
|
||||||
//! | `trust-dns` | Use [trust-dns] as the client DNS resolver. |
|
//! | `compress-gzip` | Payload compression support: Deflate, Gzip. |
|
||||||
|
//! | `compress-zstd` | Payload compression support: Zstd. |
|
||||||
|
//! | `trust-dns` | Use [trust-dns] as the client DNS resolver. |
|
||||||
//!
|
//!
|
||||||
//! [OpenSSL]: https://crates.io/crates/openssl
|
//! [OpenSSL]: https://crates.io/crates/openssl
|
||||||
//! [rustls]: https://crates.io/crates/rustls
|
//! [rustls]: https://crates.io/crates/rustls
|
||||||
@ -32,7 +34,8 @@ pub mod body;
|
|||||||
mod builder;
|
mod builder;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
mod config;
|
mod config;
|
||||||
#[cfg(feature = "compress")]
|
|
||||||
|
#[cfg(feature = "__compress")]
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
mod extensions;
|
mod extensions;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 0.1.0-beta.3 - 2021-06-20
|
||||||
|
* No significant changes from `0.1.0-beta.2`.
|
||||||
|
|
||||||
|
|
||||||
## 0.1.0-beta.2 - 2021-04-17
|
## 0.1.0-beta.2 - 2021-04-17
|
||||||
* No significant changes from `0.1.0-beta.1`.
|
* No significant changes from `0.1.0-beta.1`.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-test"
|
name = "actix-test"
|
||||||
version = "0.1.0-beta.2"
|
version = "0.1.0-beta.3"
|
||||||
authors = [
|
authors = [
|
||||||
"Nikolay Kim <fafhrd91@gmail.com>",
|
"Nikolay Kim <fafhrd91@gmail.com>",
|
||||||
"Rob Ede <robjtede@icloud.com>",
|
"Rob Ede <robjtede@icloud.com>",
|
||||||
|
@ -29,7 +29,7 @@ tokio = { version = "1", features = ["sync"] }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.2"
|
actix-rt = "2.2"
|
||||||
actix-test = "0.1.0-beta.2"
|
actix-test = "0.1.0-beta.3"
|
||||||
|
|
||||||
awc = { version = "3.0.0-beta.6", default-features = false }
|
awc = { version = "3.0.0-beta.6", default-features = false }
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
|
@ -20,7 +20,7 @@ proc-macro2 = "1"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.2"
|
actix-rt = "2.2"
|
||||||
actix-test = "0.1.0-beta.2"
|
actix-test = "0.1.0-beta.3"
|
||||||
actix-utils = "3.0.0"
|
actix-utils = "3.0.0"
|
||||||
actix-web = "4.0.0-beta.7"
|
actix-web = "4.0.0-beta.7"
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
### Changed
|
||||||
|
* Change compression algorithm features flags. [#2250]
|
||||||
|
|
||||||
|
[#2250]: https://github.com/actix/actix-web/pull/2250
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0-beta.6 - 2021-06-17
|
## 3.0.0-beta.6 - 2021-06-17
|
||||||
|
@ -24,10 +24,10 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# features that docs.rs will build with
|
# features that docs.rs will build with
|
||||||
features = ["openssl", "rustls", "compress", "cookies"]
|
features = ["openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd", "cookies"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["compress", "cookies"]
|
default = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"]
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
openssl = ["tls-openssl", "actix-http/openssl"]
|
openssl = ["tls-openssl", "actix-http/openssl"]
|
||||||
@ -35,8 +35,12 @@ openssl = ["tls-openssl", "actix-http/openssl"]
|
|||||||
# rustls
|
# rustls
|
||||||
rustls = ["tls-rustls", "actix-http/rustls"]
|
rustls = ["tls-rustls", "actix-http/rustls"]
|
||||||
|
|
||||||
# content-encoding support
|
# Brotli algorithm content-encoding support
|
||||||
compress = ["actix-http/compress"]
|
compress-brotli = ["actix-http/compress-brotli", "__compress"]
|
||||||
|
# Gzip and deflate algorithms content-encoding support
|
||||||
|
compress-gzip = ["actix-http/compress-gzip", "__compress"]
|
||||||
|
# Zstd algorithm content-encoding support
|
||||||
|
compress-zstd = ["actix-http/compress-zstd", "__compress"]
|
||||||
|
|
||||||
# cookie parsing and cookie jar
|
# cookie parsing and cookie jar
|
||||||
cookies = ["cookie"]
|
cookies = ["cookie"]
|
||||||
@ -44,6 +48,10 @@ cookies = ["cookie"]
|
|||||||
# trust-dns as dns resolver
|
# trust-dns as dns resolver
|
||||||
trust-dns = ["actix-http/trust-dns"]
|
trust-dns = ["actix-http/trust-dns"]
|
||||||
|
|
||||||
|
# Internal (PRIVATE!) features used to aid testing and cheking feature status.
|
||||||
|
# Don't rely on these whatsoever. They may disappear at anytime.
|
||||||
|
__compress = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.4.0"
|
actix-codec = "0.4.0"
|
||||||
actix-service = "2.0.0"
|
actix-service = "2.0.0"
|
||||||
@ -52,6 +60,7 @@ actix-rt = { version = "2.1", default-features = false }
|
|||||||
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
|
cfg-if = "1"
|
||||||
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
|
cookie = { version = "0.15", features = ["percent-encode"], optional = true }
|
||||||
derive_more = "0.99.5"
|
derive_more = "0.99.5"
|
||||||
futures-core = { version = "0.3.7", default-features = false }
|
futures-core = { version = "0.3.7", default-features = false }
|
||||||
@ -74,7 +83,7 @@ actix-http-test = { version = "3.0.0-beta.4", features = ["openssl"] }
|
|||||||
actix-utils = "3.0.0"
|
actix-utils = "3.0.0"
|
||||||
actix-server = "2.0.0-beta.3"
|
actix-server = "2.0.0-beta.3"
|
||||||
actix-tls = { version = "3.0.0-beta.5", features = ["openssl", "rustls"] }
|
actix-tls = { version = "3.0.0-beta.5", features = ["openssl", "rustls"] }
|
||||||
actix-test = { version = "0.1.0-beta.2", features = ["openssl", "rustls"] }
|
actix-test = { version = "0.1.0-beta.3", features = ["openssl", "rustls"] }
|
||||||
|
|
||||||
brotli2 = "0.3.2"
|
brotli2 = "0.3.2"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
|
@ -2,17 +2,19 @@ use std::error::Error as StdError;
|
|||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> Result<(), Box<dyn StdError>> {
|
async fn main() -> Result<(), Box<dyn StdError>> {
|
||||||
std::env::set_var("RUST_LOG", "actix_http=trace");
|
std::env::set_var("RUST_LOG", "client=trace,awc=trace,actix_http=trace");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let client = awc::Client::new();
|
let client = awc::Client::new();
|
||||||
|
|
||||||
// Create request builder, configure request and send
|
// Create request builder, configure request and send
|
||||||
let mut response = client
|
let request = client
|
||||||
.get("https://www.rust-lang.org/")
|
.get("https://www.rust-lang.org/")
|
||||||
.append_header(("User-Agent", "Actix-web"))
|
.append_header(("User-Agent", "Actix-web"));
|
||||||
.send()
|
|
||||||
.await?;
|
println!("Request: {:?}", request);
|
||||||
|
|
||||||
|
let mut response = request.send().await?;
|
||||||
|
|
||||||
// server http response
|
// server http response
|
||||||
println!("Response: {:?}", response);
|
println!("Response: {:?}", response);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! `awc` is a HTTP and WebSocket client library built on the Actix ecosystem.
|
//! `awc` is a HTTP and WebSocket client library built on the Actix ecosystem.
|
||||||
//!
|
//!
|
||||||
//! ## Making a GET request
|
//! # Making a GET request
|
||||||
//!
|
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
@ -16,10 +15,8 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ## Making POST requests
|
//! # Making POST requests
|
||||||
//!
|
//! ## Raw body contents
|
||||||
//! ### Raw body contents
|
|
||||||
//!
|
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
@ -31,8 +28,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### Forms
|
//! ## Forms
|
||||||
//!
|
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
@ -46,8 +42,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### JSON
|
//! ## JSON
|
||||||
//!
|
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
@ -64,8 +59,24 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ## WebSocket support
|
//! # Response Compression
|
||||||
|
//! All [official][iana-encodings] and common content encoding codecs are supported, optionally.
|
||||||
//!
|
//!
|
||||||
|
//! The `Accept-Encoding` header will automatically be populated with enabled codecs and added to
|
||||||
|
//! outgoing requests, allowing servers to select their `Content-Encoding` accordingly.
|
||||||
|
//!
|
||||||
|
//! Feature flags enable these codecs according to the table below. By default, all `compress-*`
|
||||||
|
//! features are enabled.
|
||||||
|
//!
|
||||||
|
//! | Feature | Codecs |
|
||||||
|
//! | ----------------- | ------------- |
|
||||||
|
//! | `compress-brotli` | brotli |
|
||||||
|
//! | `compress-gzip` | gzip, deflate |
|
||||||
|
//! | `compress-zstd` | zstd |
|
||||||
|
//!
|
||||||
|
//! [iana-encodings]: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#content-coding
|
||||||
|
//!
|
||||||
|
//! # WebSocket support
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@ -128,6 +139,9 @@ pub use self::sender::SendClientRequest;
|
|||||||
|
|
||||||
/// An asynchronous HTTP and WebSocket client.
|
/// An asynchronous HTTP and WebSocket client.
|
||||||
///
|
///
|
||||||
|
/// You should take care to create, at most, one `Client` per thread. Otherwise, expect higher CPU
|
||||||
|
/// and memory usage.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use awc::Client;
|
/// use awc::Client;
|
||||||
@ -136,10 +150,10 @@ pub use self::sender::SendClientRequest;
|
|||||||
/// async fn main() {
|
/// async fn main() {
|
||||||
/// let mut client = Client::default();
|
/// let mut client = Client::default();
|
||||||
///
|
///
|
||||||
/// let res = client.get("http://www.rust-lang.org") // <- Create request builder
|
/// let res = client.get("http://www.rust-lang.org")
|
||||||
/// .insert_header(("User-Agent", "Actix-web"))
|
/// .insert_header(("User-Agent", "my-app/1.2"))
|
||||||
/// .send() // <- Send HTTP request
|
/// .send()
|
||||||
/// .await; // <- send request and wait for response
|
/// .await;
|
||||||
///
|
///
|
||||||
/// println!("Response: {:?}", res);
|
/// println!("Response: {:?}", res);
|
||||||
/// }
|
/// }
|
||||||
|
@ -8,7 +8,7 @@ use actix_http::{
|
|||||||
body::Body,
|
body::Body,
|
||||||
http::{
|
http::{
|
||||||
header::{self, IntoHeaderPair},
|
header::{self, IntoHeaderPair},
|
||||||
uri, ConnectionType, Error as HttpError, HeaderMap, HeaderValue, Method, Uri, Version,
|
ConnectionType, Error as HttpError, HeaderMap, HeaderValue, Method, Uri, Version,
|
||||||
},
|
},
|
||||||
RequestHead,
|
RequestHead,
|
||||||
};
|
};
|
||||||
@ -22,11 +22,6 @@ use crate::{
|
|||||||
ClientConfig,
|
ClientConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
|
||||||
const HTTPS_ENCODING: &str = "br, gzip, deflate";
|
|
||||||
#[cfg(not(feature = "compress"))]
|
|
||||||
const HTTPS_ENCODING: &str = "br";
|
|
||||||
|
|
||||||
/// An HTTP Client request builder
|
/// An HTTP Client request builder
|
||||||
///
|
///
|
||||||
/// This type can be used to construct an instance of `ClientRequest` through a
|
/// This type can be used to construct an instance of `ClientRequest` through a
|
||||||
@ -480,22 +475,37 @@ impl ClientRequest {
|
|||||||
|
|
||||||
let mut slf = self;
|
let mut slf = self;
|
||||||
|
|
||||||
|
// Set Accept-Encoding HTTP header depending on enabled feature.
|
||||||
|
// If decompress is not ask, then we are not able to find which encoding is
|
||||||
|
// supported, so we cannot guess Accept-Encoding HTTP header.
|
||||||
if slf.response_decompress {
|
if slf.response_decompress {
|
||||||
let https = slf
|
// Set Accept-Encoding with compression algorithm awc is built with.
|
||||||
.head
|
#[cfg(feature = "__compress")]
|
||||||
.uri
|
let accept_encoding = {
|
||||||
.scheme()
|
let mut encoding = vec![];
|
||||||
.map(|s| s == &uri::Scheme::HTTPS)
|
|
||||||
.unwrap_or(true);
|
|
||||||
|
|
||||||
if https {
|
#[cfg(feature = "compress-brotli")]
|
||||||
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, HTTPS_ENCODING));
|
encoding.push("br");
|
||||||
} else {
|
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "compress-gzip")]
|
||||||
{
|
{
|
||||||
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, "gzip, deflate"));
|
encoding.push("gzip");
|
||||||
|
encoding.push("deflate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "compress-zstd")]
|
||||||
|
encoding.push("zstd");
|
||||||
|
|
||||||
|
assert!(!encoding.is_empty(), "encoding cannot be empty unless __compress feature has been explictily enabled.");
|
||||||
|
encoding.join(", ")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Otherwise tell the server, we do not support any compression algorithm.
|
||||||
|
// So we clearly indicate that we do want identity encoding.
|
||||||
|
#[cfg(not(feature = "__compress"))]
|
||||||
|
let accept_encoding = "identity";
|
||||||
|
|
||||||
|
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, accept_encoding));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(slf)
|
Ok(slf)
|
||||||
|
@ -22,7 +22,7 @@ use derive_more::From;
|
|||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
use actix_http::{encoding::Decoder, http::header::ContentEncoding, Payload, PayloadStream};
|
use actix_http::{encoding::Decoder, http::header::ContentEncoding, Payload, PayloadStream};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -91,7 +91,7 @@ impl SendClientRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
impl Future for SendClientRequest {
|
impl Future for SendClientRequest {
|
||||||
type Output = Result<ClientResponse<Decoder<Payload<PayloadStream>>>, SendRequestError>;
|
type Output = Result<ClientResponse<Decoder<Payload<PayloadStream>>>, SendRequestError>;
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ impl Future for SendClientRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "compress"))]
|
#[cfg(not(feature = "__compress"))]
|
||||||
impl Future for SendClientRequest {
|
impl Future for SendClientRequest {
|
||||||
type Output = Result<ClientResponse, SendRequestError>;
|
type Output = Result<ClientResponse, SendRequestError>;
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ impl AppConfig {
|
|||||||
AppConfig { secure, host, addr }
|
AppConfig { secure, host, addr }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Needed in actix-test crate.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn __priv_test_new(secure: bool, host: String, addr: SocketAddr) -> Self {
|
pub fn __priv_test_new(secure: bool, host: String, addr: SocketAddr) -> Self {
|
||||||
AppConfig::new(secure, host, addr)
|
AppConfig::new(secure, host, addr)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::{fmt, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
pub use self::Encoding::{
|
pub use self::Encoding::{
|
||||||
Brotli, Chunked, Compress, Deflate, EncodingExt, Gzip, Identity, Trailers,
|
Brotli, Chunked, Compress, Deflate, EncodingExt, Gzip, Identity, Trailers, Zstd,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A value to represent an encoding used in `Transfer-Encoding`
|
/// A value to represent an encoding used in `Transfer-Encoding`
|
||||||
@ -22,6 +22,8 @@ pub enum Encoding {
|
|||||||
Identity,
|
Identity,
|
||||||
/// The `trailers` encoding.
|
/// The `trailers` encoding.
|
||||||
Trailers,
|
Trailers,
|
||||||
|
/// The `zstd` encoding.
|
||||||
|
Zstd,
|
||||||
/// Some other encoding that is less common, can be any String.
|
/// Some other encoding that is less common, can be any String.
|
||||||
EncodingExt(String),
|
EncodingExt(String),
|
||||||
}
|
}
|
||||||
@ -36,6 +38,7 @@ impl fmt::Display for Encoding {
|
|||||||
Compress => "compress",
|
Compress => "compress",
|
||||||
Identity => "identity",
|
Identity => "identity",
|
||||||
Trailers => "trailers",
|
Trailers => "trailers",
|
||||||
|
Zstd => "zstd",
|
||||||
EncodingExt(ref s) => s.as_ref(),
|
EncodingExt(ref s) => s.as_ref(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -52,6 +55,7 @@ impl str::FromStr for Encoding {
|
|||||||
"compress" => Ok(Compress),
|
"compress" => Ok(Compress),
|
||||||
"identity" => Ok(Identity),
|
"identity" => Ok(Identity),
|
||||||
"trailers" => Ok(Trailers),
|
"trailers" => Ok(Trailers),
|
||||||
|
"zstd" => Ok(Zstd),
|
||||||
_ => Ok(EncodingExt(s.to_owned())),
|
_ => Ok(EncodingExt(s.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
//! * Streaming and pipelining
|
//! * Streaming and pipelining
|
||||||
//! * Keep-alive and slow requests handling
|
//! * Keep-alive and slow requests handling
|
||||||
//! * Client/server [WebSockets](https://actix.rs/docs/websockets/) support
|
//! * Client/server [WebSockets](https://actix.rs/docs/websockets/) support
|
||||||
//! * Transparent content compression/decompression (br, gzip, deflate)
|
//! * Transparent content compression/decompression (br, gzip, deflate, zstd)
|
||||||
//! * Powerful [request routing](https://actix.rs/docs/url-dispatch/)
|
//! * Powerful [request routing](https://actix.rs/docs/url-dispatch/)
|
||||||
//! * Multipart streams
|
//! * Multipart streams
|
||||||
//! * Static assets
|
//! * Static assets
|
||||||
@ -57,8 +57,10 @@
|
|||||||
//! * Runs on stable Rust 1.46+
|
//! * Runs on stable Rust 1.46+
|
||||||
//!
|
//!
|
||||||
//! # Crate Features
|
//! # Crate Features
|
||||||
//! * `compress` - content encoding compression support (enabled by default)
|
|
||||||
//! * `cookies` - cookies support (enabled by default)
|
//! * `cookies` - cookies support (enabled by default)
|
||||||
|
//! * `compress-brotli` - brotli content encoding compression support (enabled by default)
|
||||||
|
//! * `compress-gzip` - gzip and deflate content encoding compression support (enabled by default)
|
||||||
|
//! * `compress-zstd` - zstd content encoding compression support (enabled by default)
|
||||||
//! * `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
|
//! * `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
|
||||||
//! * `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2`
|
//! * `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2`
|
||||||
//! * `secure-cookies` - secure cookies support
|
//! * `secure-cookies` - secure cookies support
|
||||||
@ -140,7 +142,8 @@ pub mod dev {
|
|||||||
pub use actix_http::body::{
|
pub use actix_http::body::{
|
||||||
AnyBody, Body, BodySize, MessageBody, ResponseBody, SizedStream,
|
AnyBody, Body, BodySize, MessageBody, ResponseBody, SizedStream,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "compress")]
|
|
||||||
|
#[cfg(feature = "__compress")]
|
||||||
pub use actix_http::encoding::Decoder as Decompress;
|
pub use actix_http::encoding::Decoder as Decompress;
|
||||||
pub use actix_http::ResponseBuilder as BaseHttpResponseBuilder;
|
pub use actix_http::ResponseBuilder as BaseHttpResponseBuilder;
|
||||||
pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, ResponseHead};
|
pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, ResponseHead};
|
||||||
|
@ -144,7 +144,7 @@ mod tests {
|
|||||||
use crate::{web, App, HttpResponse};
|
use crate::{web, App, HttpResponse};
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
#[cfg(all(feature = "cookies", feature = "compress"))]
|
#[cfg(all(feature = "cookies", feature = "__compress"))]
|
||||||
async fn test_scope_middleware() {
|
async fn test_scope_middleware() {
|
||||||
use crate::middleware::Compress;
|
use crate::middleware::Compress;
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
#[cfg(all(feature = "cookies", feature = "compress"))]
|
#[cfg(all(feature = "cookies", feature = "__compress"))]
|
||||||
async fn test_resource_scope_middleware() {
|
async fn test_resource_scope_middleware() {
|
||||||
use crate::middleware::Compress;
|
use crate::middleware::Compress;
|
||||||
|
|
||||||
|
@ -14,7 +14,8 @@ pub use self::err_handlers::{ErrorHandlerResponse, ErrorHandlers};
|
|||||||
pub use self::logger::Logger;
|
pub use self::logger::Logger;
|
||||||
pub use self::normalize::{NormalizePath, TrailingSlash};
|
pub use self::normalize::{NormalizePath, TrailingSlash};
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
mod compress;
|
mod compress;
|
||||||
#[cfg(feature = "compress")]
|
|
||||||
|
#[cfg(feature = "__compress")]
|
||||||
pub use self::compress::Compress;
|
pub use self::compress::Compress;
|
||||||
|
@ -60,18 +60,6 @@ impl HttpRequest {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn __priv_test_new(
|
|
||||||
path: Path<Url>,
|
|
||||||
head: Message<RequestHead>,
|
|
||||||
rmap: Rc<ResourceMap>,
|
|
||||||
config: AppConfig,
|
|
||||||
app_data: Rc<Extensions>,
|
|
||||||
) -> HttpRequest {
|
|
||||||
let app_state = AppInitServiceState::new(rmap, config);
|
|
||||||
Self::new(path, head, app_state, app_data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HttpRequest {
|
impl HttpRequest {
|
||||||
|
@ -74,12 +74,6 @@ impl ServiceRequest {
|
|||||||
Self { req, payload }
|
Self { req, payload }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct service request.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn __priv_test_new(req: HttpRequest, payload: Payload) -> Self {
|
|
||||||
Self::new(req, payload)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deconstruct request into parts
|
/// Deconstruct request into parts
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_parts(self) -> (HttpRequest, Payload) {
|
pub fn into_parts(self) -> (HttpRequest, Payload) {
|
||||||
|
@ -16,7 +16,7 @@ use futures_core::{future::LocalBoxFuture, ready};
|
|||||||
use futures_util::{FutureExt as _, StreamExt as _};
|
use futures_util::{FutureExt as _, StreamExt as _};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
use crate::dev::Decompress;
|
use crate::dev::Decompress;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH, web, Error,
|
error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH, web, Error,
|
||||||
@ -255,9 +255,9 @@ impl Default for FormConfig {
|
|||||||
/// - content type is not `application/x-www-form-urlencoded`
|
/// - content type is not `application/x-www-form-urlencoded`
|
||||||
/// - content length is greater than [limit](UrlEncoded::limit())
|
/// - content length is greater than [limit](UrlEncoded::limit())
|
||||||
pub struct UrlEncoded<T> {
|
pub struct UrlEncoded<T> {
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
stream: Option<Decompress<Payload>>,
|
stream: Option<Decompress<Payload>>,
|
||||||
#[cfg(not(feature = "compress"))]
|
#[cfg(not(feature = "__compress"))]
|
||||||
stream: Option<Payload>,
|
stream: Option<Payload>,
|
||||||
|
|
||||||
limit: usize,
|
limit: usize,
|
||||||
@ -293,10 +293,15 @@ impl<T> UrlEncoded<T> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
let payload = {
|
||||||
let payload = Decompress::from_headers(payload.take(), req.headers());
|
cfg_if::cfg_if! {
|
||||||
#[cfg(not(feature = "compress"))]
|
if #[cfg(feature = "__compress")] {
|
||||||
let payload = payload.take();
|
Decompress::from_headers(payload.take(), req.headers())
|
||||||
|
} else {
|
||||||
|
payload.take()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
UrlEncoded {
|
UrlEncoded {
|
||||||
encoding,
|
encoding,
|
||||||
|
@ -16,7 +16,7 @@ use serde::{de::DeserializeOwned, Serialize};
|
|||||||
|
|
||||||
use actix_http::Payload;
|
use actix_http::Payload;
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
use crate::dev::Decompress;
|
use crate::dev::Decompress;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, JsonPayloadError},
|
error::{Error, JsonPayloadError},
|
||||||
@ -300,9 +300,9 @@ pub enum JsonBody<T> {
|
|||||||
Body {
|
Body {
|
||||||
limit: usize,
|
limit: usize,
|
||||||
length: Option<usize>,
|
length: Option<usize>,
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
payload: Decompress<Payload>,
|
payload: Decompress<Payload>,
|
||||||
#[cfg(not(feature = "compress"))]
|
#[cfg(not(feature = "__compress"))]
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
buf: BytesMut,
|
buf: BytesMut,
|
||||||
_res: PhantomData<T>,
|
_res: PhantomData<T>,
|
||||||
@ -345,10 +345,15 @@ where
|
|||||||
// As the internal usage always call JsonBody::limit after JsonBody::new.
|
// As the internal usage always call JsonBody::limit after JsonBody::new.
|
||||||
// And limit check to return an error variant of JsonBody happens there.
|
// And limit check to return an error variant of JsonBody happens there.
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
let payload = {
|
||||||
let payload = Decompress::from_headers(payload.take(), req.headers());
|
cfg_if::cfg_if! {
|
||||||
#[cfg(not(feature = "compress"))]
|
if #[cfg(feature = "__compress")] {
|
||||||
let payload = payload.take();
|
Decompress::from_headers(payload.take(), req.headers())
|
||||||
|
} else {
|
||||||
|
payload.take()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
JsonBody::Body {
|
JsonBody::Body {
|
||||||
limit: DEFAULT_LIMIT,
|
limit: DEFAULT_LIMIT,
|
||||||
|
@ -282,9 +282,9 @@ impl Default for PayloadConfig {
|
|||||||
pub struct HttpMessageBody {
|
pub struct HttpMessageBody {
|
||||||
limit: usize,
|
limit: usize,
|
||||||
length: Option<usize>,
|
length: Option<usize>,
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "__compress")]
|
||||||
stream: dev::Decompress<dev::Payload>,
|
stream: dev::Decompress<dev::Payload>,
|
||||||
#[cfg(not(feature = "compress"))]
|
#[cfg(not(feature = "__compress"))]
|
||||||
stream: dev::Payload,
|
stream: dev::Payload,
|
||||||
buf: BytesMut,
|
buf: BytesMut,
|
||||||
err: Option<PayloadError>,
|
err: Option<PayloadError>,
|
||||||
@ -312,10 +312,15 @@ impl HttpMessageBody {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "compress")]
|
let stream = {
|
||||||
let stream = dev::Decompress::from_headers(payload.take(), req.headers());
|
cfg_if::cfg_if! {
|
||||||
#[cfg(not(feature = "compress"))]
|
if #[cfg(feature = "__compress")] {
|
||||||
let stream = payload.take();
|
dev::Decompress::from_headers(payload.take(), req.headers())
|
||||||
|
} else {
|
||||||
|
payload.take()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
HttpMessageBody {
|
HttpMessageBody {
|
||||||
stream,
|
stream,
|
||||||
|
Reference in New Issue
Block a user