mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-13 13:43:59 +02:00
Compare commits
10 Commits
http-v2.2.
...
http-v2.2.
Author | SHA1 | Date | |
---|---|---|---|
c9c36679e4 | |||
655d7b4f05 | |||
24d525d978 | |||
1f70ef155d | |||
7981e0068a | |||
32d59ca904 | |||
ea8bf36104 | |||
0b5b463cfa | |||
fe6ad816cc | |||
e72b787ba7 |
21
CHANGES.md
21
CHANGES.md
@ -1,12 +1,31 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 3.3.2 - 2020-12-01
|
||||||
|
### Fixed
|
||||||
|
* Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`. [#1762]
|
||||||
|
* Fix `match_pattern()` returning `None` for scope with empty path resource. [#1798]
|
||||||
|
* Increase minimum `socket2` version. [#1803]
|
||||||
|
|
||||||
|
[#1762]: https://github.com/actix/actix-web/pull/1762
|
||||||
|
[#1798]: https://github.com/actix/actix-web/pull/1798
|
||||||
|
[#1803]: https://github.com/actix/actix-web/pull/1803
|
||||||
|
|
||||||
|
|
||||||
|
## 3.3.1 - 2020-11-29
|
||||||
|
* Ensure `actix-http` dependency uses same `serde_urlencoded`.
|
||||||
|
|
||||||
|
|
||||||
|
## 3.3.0 - 2020-11-25
|
||||||
### Added
|
### Added
|
||||||
* Add `Either<A, B>` extractor helper. [#1788]
|
* Add `Either<A, B>` extractor helper. [#1788]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Upgrade `serde_urlencoded` to `0.7`.
|
* Upgrade `serde_urlencoded` to `0.7`. [#1773]
|
||||||
|
|
||||||
|
[#1773]: https://github.com/actix/actix-web/pull/1773
|
||||||
[#1788]: https://github.com/actix/actix-web/pull/1788
|
[#1788]: https://github.com/actix/actix-web/pull/1788
|
||||||
|
|
||||||
|
|
||||||
|
12
Cargo.toml
12
Cargo.toml
@ -1,8 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-web"
|
name = "actix-web"
|
||||||
version = "3.2.0"
|
version = "3.3.2"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix web is a powerful, pragmatic, and extremely fast web framework for Rust"
|
description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["actix", "http", "web", "framework", "async"]
|
keywords = ["actix", "http", "web", "framework", "async"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
@ -85,11 +85,11 @@ actix-threadpool = "0.3.1"
|
|||||||
actix-tls = "2.0.0"
|
actix-tls = "2.0.0"
|
||||||
|
|
||||||
actix-web-codegen = "0.4.0"
|
actix-web-codegen = "0.4.0"
|
||||||
actix-http = "2.1.0"
|
actix-http = "2.2.0"
|
||||||
awc = { version = "2.0.0", default-features = false }
|
awc = { version = "2.0.3", default-features = false }
|
||||||
|
|
||||||
bytes = "0.5.3"
|
bytes = "0.5.3"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.5"
|
||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
futures-channel = { version = "0.3.5", default-features = false }
|
futures-channel = { version = "0.3.5", default-features = false }
|
||||||
futures-core = { version = "0.3.5", default-features = false }
|
futures-core = { version = "0.3.5", default-features = false }
|
||||||
@ -97,7 +97,7 @@ futures-util = { version = "0.3.5", default-features = false }
|
|||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
socket2 = "0.3"
|
socket2 = "0.3.16"
|
||||||
pin-project = "1.0.0"
|
pin-project = "1.0.0"
|
||||||
regex = "1.4"
|
regex = "1.4"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<h1>Actix web</h1>
|
<h1>Actix web</h1>
|
||||||
<p>
|
<p>
|
||||||
<strong>Actix web is a powerful, pragmatic, and extremely fast web framework for Rust</strong>
|
<strong>Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust</strong>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
[](https://crates.io/crates/actix-web)
|
[](https://crates.io/crates/actix-web)
|
||||||
[](https://docs.rs/actix-web/3.2.0)
|
[](https://docs.rs/actix-web/3.3.2)
|
||||||
[](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html)
|
[](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html)
|
||||||

|

|
||||||
[](https://deps.rs/crate/actix-web/3.2.0)
|
[](https://deps.rs/crate/actix-web/3.3.2)
|
||||||
<br />
|
<br />
|
||||||
[](https://travis-ci.org/actix/actix-web)
|
[](https://travis-ci.org/actix/actix-web)
|
||||||
[](https://codecov.io/gh/actix/actix-web)
|
[](https://codecov.io/gh/actix/actix-web)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "2.2.0"
|
version = "2.2.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "HTTP primitives for the Actix ecosystem"
|
description = "HTTP primitives for the Actix ecosystem"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
> HTTP primitives for the Actix ecosystem.
|
> HTTP primitives for the Actix ecosystem.
|
||||||
|
|
||||||
[](https://crates.io/crates/actix-http)
|
[](https://crates.io/crates/actix-http)
|
||||||
[](https://docs.rs/actix-http/2.2.0)
|
[](https://docs.rs/actix-http/2.2.1)
|
||||||

|

|
||||||
[](https://deps.rs/crate/actix-http/2.2.0)
|
[](https://deps.rs/crate/actix-http/2.2.1)
|
||||||
[](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
## Documentation & Resources
|
## Documentation & Resources
|
||||||
|
@ -67,6 +67,7 @@ pub(crate) trait MessageType: Sized {
|
|||||||
let mut has_upgrade_websocket = false;
|
let mut has_upgrade_websocket = false;
|
||||||
let mut expect = false;
|
let mut expect = false;
|
||||||
let mut chunked = false;
|
let mut chunked = false;
|
||||||
|
let mut seen_te = false;
|
||||||
let mut content_length = None;
|
let mut content_length = None;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -85,8 +86,17 @@ pub(crate) trait MessageType: Sized {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
header::CONTENT_LENGTH => {
|
header::CONTENT_LENGTH if content_length.is_some() => {
|
||||||
if let Ok(s) = value.to_str() {
|
debug!("multiple Content-Length");
|
||||||
|
return Err(ParseError::Header);
|
||||||
|
}
|
||||||
|
|
||||||
|
header::CONTENT_LENGTH => match value.to_str() {
|
||||||
|
Ok(s) if s.trim().starts_with("+") => {
|
||||||
|
debug!("illegal Content-Length: {:?}", s);
|
||||||
|
return Err(ParseError::Header);
|
||||||
|
}
|
||||||
|
Ok(s) => {
|
||||||
if let Ok(len) = s.parse::<u64>() {
|
if let Ok(len) = s.parse::<u64>() {
|
||||||
if len != 0 {
|
if len != 0 {
|
||||||
content_length = Some(len);
|
content_length = Some(len);
|
||||||
@ -95,15 +105,31 @@ pub(crate) trait MessageType: Sized {
|
|||||||
debug!("illegal Content-Length: {:?}", s);
|
debug!("illegal Content-Length: {:?}", s);
|
||||||
return Err(ParseError::Header);
|
return Err(ParseError::Header);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
Err(_) => {
|
||||||
debug!("illegal Content-Length: {:?}", value);
|
debug!("illegal Content-Length: {:?}", value);
|
||||||
return Err(ParseError::Header);
|
return Err(ParseError::Header);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
// transfer-encoding
|
// transfer-encoding
|
||||||
|
header::TRANSFER_ENCODING if seen_te => {
|
||||||
|
debug!("multiple Transfer-Encoding not allowed");
|
||||||
|
return Err(ParseError::Header);
|
||||||
|
}
|
||||||
|
|
||||||
header::TRANSFER_ENCODING => {
|
header::TRANSFER_ENCODING => {
|
||||||
|
seen_te = true;
|
||||||
|
|
||||||
if let Ok(s) = value.to_str().map(|s| s.trim()) {
|
if let Ok(s) = value.to_str().map(|s| s.trim()) {
|
||||||
chunked = s.eq_ignore_ascii_case("chunked");
|
if s.eq_ignore_ascii_case("chunked") {
|
||||||
|
chunked = true;
|
||||||
|
} else if s.eq_ignore_ascii_case("identity") {
|
||||||
|
// allow silently since multiple TE headers are already checked
|
||||||
|
} else {
|
||||||
|
debug!("illegal Transfer-Encoding: {:?}", s);
|
||||||
|
return Err(ParseError::Header);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ParseError::Header);
|
return Err(ParseError::Header);
|
||||||
}
|
}
|
||||||
@ -510,19 +536,11 @@ impl ChunkedState {
|
|||||||
size: &mut u64,
|
size: &mut u64,
|
||||||
) -> Poll<Result<ChunkedState, io::Error>> {
|
) -> Poll<Result<ChunkedState, io::Error>> {
|
||||||
let radix = 16;
|
let radix = 16;
|
||||||
match byte!(rdr) {
|
|
||||||
b @ b'0'..=b'9' => {
|
let rem = match byte!(rdr) {
|
||||||
*size *= radix;
|
b @ b'0'..=b'9' => b - b'0',
|
||||||
*size += u64::from(b - b'0');
|
b @ b'a'..=b'f' => b + 10 - b'a',
|
||||||
}
|
b @ b'A'..=b'F' => b + 10 - b'A',
|
||||||
b @ b'a'..=b'f' => {
|
|
||||||
*size *= radix;
|
|
||||||
*size += u64::from(b + 10 - b'a');
|
|
||||||
}
|
|
||||||
b @ b'A'..=b'F' => {
|
|
||||||
*size *= radix;
|
|
||||||
*size += u64::from(b + 10 - b'A');
|
|
||||||
}
|
|
||||||
b'\t' | b' ' => return Poll::Ready(Ok(ChunkedState::SizeLws)),
|
b'\t' | b' ' => return Poll::Ready(Ok(ChunkedState::SizeLws)),
|
||||||
b';' => return Poll::Ready(Ok(ChunkedState::Extension)),
|
b';' => return Poll::Ready(Ok(ChunkedState::Extension)),
|
||||||
b'\r' => return Poll::Ready(Ok(ChunkedState::SizeLf)),
|
b'\r' => return Poll::Ready(Ok(ChunkedState::SizeLf)),
|
||||||
@ -532,9 +550,24 @@ impl ChunkedState {
|
|||||||
"Invalid chunk size line: Invalid Size",
|
"Invalid chunk size line: Invalid Size",
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
match size.checked_mul(radix) {
|
||||||
|
Some(n) => {
|
||||||
|
*size = n as u64;
|
||||||
|
*size += rem as u64;
|
||||||
|
|
||||||
Poll::Ready(Ok(ChunkedState::Size))
|
Poll::Ready(Ok(ChunkedState::Size))
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
|
debug!("chunk size would overflow");
|
||||||
|
Poll::Ready(Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidInput,
|
||||||
|
"Invalid chunk size line: Invalid Size",
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn read_size_lws(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
|
fn read_size_lws(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
|
||||||
trace!("read_size_lws");
|
trace!("read_size_lws");
|
||||||
@ -552,6 +585,11 @@ impl ChunkedState {
|
|||||||
fn read_extension(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
|
fn read_extension(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
|
||||||
match byte!(rdr) {
|
match byte!(rdr) {
|
||||||
b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
|
b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
|
||||||
|
// strictly 0x20 (space) should be disallowed but we don't parse quoted strings here
|
||||||
|
0x00..=0x08 | 0x0a..=0x1f | 0x7f => Poll::Ready(Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidInput,
|
||||||
|
"Invalid character in chunk extension",
|
||||||
|
))),
|
||||||
_ => Poll::Ready(Ok(ChunkedState::Extension)), // no supported extensions
|
_ => Poll::Ready(Ok(ChunkedState::Extension)), // no supported extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -977,13 +1015,7 @@ mod tests {
|
|||||||
"GET /test HTTP/1.1\r\n\
|
"GET /test HTTP/1.1\r\n\
|
||||||
transfer-encoding: chnked\r\n\r\n",
|
transfer-encoding: chnked\r\n\r\n",
|
||||||
);
|
);
|
||||||
let req = parse_ready!(&mut buf);
|
expect_parse_err!(&mut buf);
|
||||||
|
|
||||||
if let Ok(val) = req.chunked() {
|
|
||||||
assert!(!val);
|
|
||||||
} else {
|
|
||||||
unreachable!("Error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -80,6 +80,7 @@ pub(crate) trait MessageType: Sized {
|
|||||||
match length {
|
match length {
|
||||||
BodySize::Stream => {
|
BodySize::Stream => {
|
||||||
if chunked {
|
if chunked {
|
||||||
|
skip_len = true;
|
||||||
if camel_case {
|
if camel_case {
|
||||||
dst.put_slice(b"\r\nTransfer-Encoding: chunked\r\n")
|
dst.put_slice(b"\r\nTransfer-Encoding: chunked\r\n")
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 2.0.3 - 2020-11-29
|
||||||
|
### Fixed
|
||||||
|
* Ensure `actix-http` dependency uses same `serde_urlencoded`.
|
||||||
|
|
||||||
|
|
||||||
## 2.0.2 - 2020-11-25
|
## 2.0.2 - 2020-11-25
|
||||||
### Changed
|
### Changed
|
||||||
* Upgrade `serde_urlencoded` to `0.7`. [#1773]
|
* Upgrade `serde_urlencoded` to `0.7`. [#1773]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "awc"
|
name = "awc"
|
||||||
version = "2.0.1"
|
version = "2.0.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Async HTTP and WebSocket client library built on the Actix ecosystem"
|
description = "Async HTTP and WebSocket client library built on the Actix ecosystem"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@ -39,7 +39,7 @@ compress = ["actix-http/compress"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.3.0"
|
actix-codec = "0.3.0"
|
||||||
actix-service = "1.0.6"
|
actix-service = "1.0.6"
|
||||||
actix-http = "2.0.0"
|
actix-http = "2.2.0"
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
> Async HTTP and WebSocket client library.
|
> Async HTTP and WebSocket client library.
|
||||||
|
|
||||||
[](https://crates.io/crates/awc)
|
[](https://crates.io/crates/awc)
|
||||||
[](https://docs.rs/awc/2.0.2)
|
[](https://docs.rs/awc/2.0.3)
|
||||||

|

|
||||||
[](https://deps.rs/crate/awc/2.0.2)
|
[](https://deps.rs/crate/awc/2.0.3)
|
||||||
[](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
## Documentation & Resources
|
## Documentation & Resources
|
||||||
|
@ -2,29 +2,31 @@ digraph {
|
|||||||
subgraph cluster_web {
|
subgraph cluster_web {
|
||||||
label="actix/actix-web"
|
label="actix/actix-web"
|
||||||
"awc"
|
"awc"
|
||||||
"actix-web"
|
"web"
|
||||||
"actix-files"
|
"files"
|
||||||
"actix-http"
|
"http"
|
||||||
"actix-multipart"
|
"multipart"
|
||||||
"actix-web-actors"
|
"web-actors"
|
||||||
"actix-web-codegen"
|
"codegen"
|
||||||
|
"http-test"
|
||||||
}
|
}
|
||||||
|
|
||||||
"actix-web" -> { "actix-codec" "actix-service" "actix-utils" "actix-router" "actix-rt" "actix-server" "actix-testing" "actix-macros" "actix-threadpool" "actix-tls" "actix-web-codegen" "actix-http" "awc" }
|
"web" -> { "codec" "service" "utils" "router" "rt" "server" "testing" "macros" "threadpool" "tls" "codegen" "http" "awc" }
|
||||||
"awc" -> { "actix-codec" "actix-service" "actix-http" "actix-rt" }
|
"awc" -> { "codec" "service" "http" "rt" }
|
||||||
"actix-web-actors" -> { "actix" "actix-web" "actix-http" "actix-codec" }
|
"web-actors" -> { "actix" "web" "http" "codec" }
|
||||||
"actix-multipart" -> { "actix-web" "actix-service" "actix-utils" }
|
"multipart" -> { "web" "service" "utils" }
|
||||||
"actix-http" -> { "actix-service" "actix-codec" "actix-connect" "actix-utils" "actix-rt" "actix-threadpool" }
|
"http" -> { "service" "codec" "connect" "utils" "rt" "threadpool" }
|
||||||
"actix-http" -> { "actix" "actix-tls" }[color=blue] // optional
|
"http" -> { "actix" "tls" }[color=blue] // optional
|
||||||
"actix-files" -> { "actix-web" "actix-http" }
|
"files" -> { "web" }
|
||||||
|
"http-test" -> { "service" "codec" "connect" "utils" "rt" "server" "testing" "awc" }
|
||||||
|
|
||||||
// net
|
// net
|
||||||
|
|
||||||
"actix-utils" -> { "actix-service" "actix-rt" "actix-codec" }
|
"utils" -> { "service" "rt" "codec" }
|
||||||
"actix-tracing" -> { "actix-service" }
|
"tracing" -> { "service" }
|
||||||
"actix-tls" -> { "actix-service" "actix-codec" "actix-utils" }
|
"tls" -> { "service" "codec" "utils" }
|
||||||
"actix-testing" -> { "actix-rt" "actix-macros" "actix-server" "actix-service" }
|
"testing" -> { "rt" "macros" "server" "service" }
|
||||||
"actix-server" -> { "actix-service" "actix-rt" "actix-codec" "actix-utils" }
|
"server" -> { "service" "rt" "codec" "utils" }
|
||||||
"actix-rt" -> { "actix-macros" "actix-threadpool" }
|
"rt" -> { "macros" "threadpool" }
|
||||||
"actix-connect" -> { "actix-service" "actix-codec" "actix-utils" "actix-rt" }
|
"connect" -> { "service" "codec" "utils" "rt" }
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ digraph {
|
|||||||
"actix-multipart"
|
"actix-multipart"
|
||||||
"actix-web-actors"
|
"actix-web-actors"
|
||||||
"actix-web-codegen"
|
"actix-web-codegen"
|
||||||
|
"actix-http-test"
|
||||||
}
|
}
|
||||||
|
|
||||||
"actix-web" -> { "actix-web-codegen" "actix-http" "awc" }
|
"actix-web" -> { "actix-web-codegen" "actix-http" "awc" }
|
||||||
@ -15,5 +16,6 @@ digraph {
|
|||||||
"actix-web-actors" -> { "actix" "actix-web" "actix-http" }
|
"actix-web-actors" -> { "actix" "actix-web" "actix-http" }
|
||||||
"actix-multipart" -> { "actix-web" }
|
"actix-multipart" -> { "actix-web" }
|
||||||
"actix-http" -> { "actix" }[color=blue] // optional
|
"actix-http" -> { "actix" }[color=blue] // optional
|
||||||
"actix-files" -> { "actix-web" "actix-http" }
|
"actix-files" -> { "actix-web" }
|
||||||
|
"actix-http-test" -> { "awc" }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Actix web is a powerful, pragmatic, and extremely fast web framework for Rust.
|
//! Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
|
||||||
//!
|
//!
|
||||||
//! ## Example
|
//! ## Example
|
||||||
//!
|
//!
|
||||||
|
@ -137,9 +137,9 @@ where
|
|||||||
// so the change can not be deduced from the length comparison
|
// so the change can not be deduced from the length comparison
|
||||||
if path != original_path {
|
if path != original_path {
|
||||||
let mut parts = head.uri.clone().into_parts();
|
let mut parts = head.uri.clone().into_parts();
|
||||||
let pq = parts.path_and_query.as_ref().unwrap();
|
let query = parts.path_and_query.as_ref().and_then(|pq| pq.query());
|
||||||
|
|
||||||
let path = if let Some(q) = pq.query() {
|
let path = if let Some(q) = query {
|
||||||
Bytes::from(format!("{}?{}", path, q))
|
Bytes::from(format!("{}?{}", path, q))
|
||||||
} else {
|
} else {
|
||||||
Bytes::copy_from_slice(path.as_bytes())
|
Bytes::copy_from_slice(path.as_bytes())
|
||||||
|
@ -675,4 +675,40 @@ mod tests {
|
|||||||
let res = call_service(&mut srv, req).await;
|
let res = call_service(&mut srv, req).await;
|
||||||
assert_eq!(res.status(), StatusCode::OK);
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn extract_path_pattern_complex() {
|
||||||
|
let mut srv = init_service(
|
||||||
|
App::new()
|
||||||
|
.service(web::scope("/user").service(web::scope("/{id}").service(
|
||||||
|
web::resource("").to(move |req: HttpRequest| {
|
||||||
|
assert_eq!(req.match_pattern(), Some("/user/{id}".to_owned()));
|
||||||
|
|
||||||
|
HttpResponse::Ok().finish()
|
||||||
|
}),
|
||||||
|
)))
|
||||||
|
.service(web::resource("/").to(move |req: HttpRequest| {
|
||||||
|
assert_eq!(req.match_pattern(), Some("/".to_owned()));
|
||||||
|
|
||||||
|
HttpResponse::Ok().finish()
|
||||||
|
}))
|
||||||
|
.default_service(web::to(move |req: HttpRequest| {
|
||||||
|
assert!(req.match_pattern().is_none());
|
||||||
|
HttpResponse::Ok().finish()
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let req = TestRequest::get().uri("/user/test").to_request();
|
||||||
|
let res = call_service(&mut srv, req).await;
|
||||||
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
let req = TestRequest::get().uri("/").to_request();
|
||||||
|
let res = call_service(&mut srv, req).await;
|
||||||
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
let req = TestRequest::get().uri("/not-exist").to_request();
|
||||||
|
let res = call_service(&mut srv, req).await;
|
||||||
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ impl ResourceMap {
|
|||||||
if let Some(plen) = pattern.is_prefix_match(path) {
|
if let Some(plen) = pattern.is_prefix_match(path) {
|
||||||
return rmap.has_resource(&path[plen..]);
|
return rmap.has_resource(&path[plen..]);
|
||||||
}
|
}
|
||||||
} else if pattern.is_match(path) {
|
} else if pattern.is_match(path) || pattern.pattern() == "" && path == "/" {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,20 @@
|
|||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
|
||||||
* add ability to set address for `TestServer` [#1645]
|
|
||||||
* Upgrade `base64` to `0.13`.
|
|
||||||
* Upgrade `serde_urlencoded` to `0.7`.
|
|
||||||
|
|
||||||
|
## 2.1.0 - 2020-11-25
|
||||||
|
* Add ability to set address for `TestServer`. [#1645]
|
||||||
|
* Upgrade `base64` to `0.13`.
|
||||||
|
* Upgrade `serde_urlencoded` to `0.7`. [#1773]
|
||||||
|
|
||||||
|
[#1773]: https://github.com/actix/actix-web/pull/1773
|
||||||
[#1645]: https://github.com/actix/actix-web/pull/1645
|
[#1645]: https://github.com/actix/actix-web/pull/1645
|
||||||
|
|
||||||
|
|
||||||
## 2.0.0 - 2020-09-11
|
## 2.0.0 - 2020-09-11
|
||||||
* Update actix-codec and actix-utils dependencies.
|
* Update actix-codec and actix-utils dependencies.
|
||||||
|
|
||||||
|
|
||||||
## 2.0.0-alpha.1 - 2020-05-23
|
## 2.0.0-alpha.1 - 2020-05-23
|
||||||
* Update the `time` dependency to 0.2.7
|
* Update the `time` dependency to 0.2.7
|
||||||
* Update `actix-connect` dependency to 2.0.0-alpha.2
|
* Update `actix-connect` dependency to 2.0.0-alpha.2
|
||||||
@ -20,74 +25,56 @@
|
|||||||
* Update `base64` dependency to 0.12
|
* Update `base64` dependency to 0.12
|
||||||
* Update `env_logger` dependency to 0.7
|
* Update `env_logger` dependency to 0.7
|
||||||
|
|
||||||
## [1.0.0] - 2019-12-13
|
## 1.0.0 - 2019-12-13
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Replaced `TestServer::start()` with `test_server()`
|
* Replaced `TestServer::start()` with `test_server()`
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-alpha.3] - 2019-12-07
|
## 1.0.0-alpha.3 - 2019-12-07
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Migrate to `std::future`
|
* Migrate to `std::future`
|
||||||
|
|
||||||
|
|
||||||
## [0.2.5] - 2019-09-17
|
## 0.2.5 - 2019-09-17
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Update serde_urlencoded to "0.6.1"
|
* Update serde_urlencoded to "0.6.1"
|
||||||
* Increase TestServerRuntime timeouts from 500ms to 3000ms
|
* Increase TestServerRuntime timeouts from 500ms to 3000ms
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Do not override current `System`
|
* Do not override current `System`
|
||||||
|
|
||||||
|
|
||||||
## [0.2.4] - 2019-07-18
|
## 0.2.4 - 2019-07-18
|
||||||
|
|
||||||
* Update actix-server to 0.6
|
* Update actix-server to 0.6
|
||||||
|
|
||||||
## [0.2.3] - 2019-07-16
|
|
||||||
|
|
||||||
|
## 0.2.3 - 2019-07-16
|
||||||
* Add `delete`, `options`, `patch` methods to `TestServerRunner`
|
* Add `delete`, `options`, `patch` methods to `TestServerRunner`
|
||||||
|
|
||||||
## [0.2.2] - 2019-06-16
|
|
||||||
|
|
||||||
|
## 0.2.2 - 2019-06-16
|
||||||
* Add .put() and .sput() methods
|
* Add .put() and .sput() methods
|
||||||
|
|
||||||
## [0.2.1] - 2019-06-05
|
|
||||||
|
|
||||||
|
## 0.2.1 - 2019-06-05
|
||||||
* Add license files
|
* Add license files
|
||||||
|
|
||||||
## [0.2.0] - 2019-05-12
|
|
||||||
|
|
||||||
|
## 0.2.0 - 2019-05-12
|
||||||
* Update awc and actix-http deps
|
* Update awc and actix-http deps
|
||||||
|
|
||||||
## [0.1.1] - 2019-04-24
|
|
||||||
|
|
||||||
|
## 0.1.1 - 2019-04-24
|
||||||
* Always make new connection for http client
|
* Always make new connection for http client
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0] - 2019-04-16
|
## 0.1.0 - 2019-04-16
|
||||||
|
|
||||||
* No changes
|
* No changes
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0-alpha.3] - 2019-04-02
|
## 0.1.0-alpha.3 - 2019-04-02
|
||||||
|
|
||||||
* Request functions accept path #743
|
* Request functions accept path #743
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0-alpha.2] - 2019-03-29
|
## 0.1.0-alpha.2 - 2019-03-29
|
||||||
|
|
||||||
* Added TestServerRuntime::load_body() method
|
* Added TestServerRuntime::load_body() method
|
||||||
|
|
||||||
* Update actix-http and awc libraries
|
* Update actix-http and awc libraries
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0-alpha.1] - 2019-03-28
|
## 0.1.0-alpha.1 - 2019-03-28
|
||||||
|
|
||||||
* Initial impl
|
* Initial impl
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-http-test"
|
name = "actix-http-test"
|
||||||
version = "2.0.0"
|
version = "2.1.0"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix HTTP test server"
|
description = "Various helpers for Actix applications to use during testing"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["http", "web", "framework", "async", "futures"]
|
keywords = ["http", "web", "framework", "async", "futures"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
# Actix http test server [](https://travis-ci.org/actix/actix-web) [](https://codecov.io/gh/actix/actix-web) [](https://crates.io/crates/actix-http-test) [](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
# actix-http-test
|
||||||
|
|
||||||
## Documentation & community resources
|
> Various helpers for Actix applications to use during testing.
|
||||||
|
|
||||||
* [User Guide](https://actix.rs/docs/)
|
[](https://crates.io/crates/actix-http-test)
|
||||||
* [API Documentation](https://docs.rs/actix-http-test/)
|
[](https://docs.rs/actix-http-test/2.1.0)
|
||||||
* [Chat on gitter](https://gitter.im/actix/actix)
|

|
||||||
* Cargo package: [actix-http-test](https://crates.io/crates/actix-http-test)
|
[](https://deps.rs/crate/actix-http-test/2.1.0)
|
||||||
* Minimum supported Rust version: 1.40 or later
|
[](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
|
## Documentation & Resources
|
||||||
|
|
||||||
|
- [API Documentation](https://docs.rs/actix-http-test)
|
||||||
|
- [Chat on Gitter](https://gitter.im/actix/actix-web)
|
||||||
|
- Minimum Supported Rust Version (MSRV): 1.42.0
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
//! Various helpers for Actix applications to use during testing.
|
//! Various helpers for Actix applications to use during testing.
|
||||||
|
|
||||||
|
#![deny(rust_2018_idioms)]
|
||||||
|
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
|
||||||
|
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
|
||||||
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::{net, thread, time};
|
use std::{net, thread, time};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user