mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-21 00:29:56 +02:00
Compare commits
17 Commits
awc-v0.2.3
...
web-v1.0.6
Author | SHA1 | Date | |
---|---|---|---|
|
98bf8ab098 | ||
|
c193137905 | ||
|
a07cdd6533 | ||
|
61e492e7e3 | ||
|
23d768a77b | ||
|
87b7162473 | ||
|
979c4d44f4 | ||
|
5d248cad89 | ||
|
b1cb72d088 | ||
|
55179d6ab2 | ||
|
192dfff680 | ||
|
915010e733 | ||
|
dbe4c9ffb5 | ||
|
0ee69671ba | ||
|
80e1d16ab8 | ||
|
b70de5b991 | ||
|
0b9e692298 |
@@ -10,9 +10,9 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
- rust: stable
|
- rust: stable
|
||||||
- rust: beta
|
- rust: beta
|
||||||
- rust: nightly-2019-04-02
|
- rust: nightly-2019-08-10
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rust: nightly-2019-04-02
|
- rust: nightly-2019-08-10
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
@@ -25,7 +25,7 @@ before_install:
|
|||||||
- sudo apt-get install -y openssl libssl-dev libelf-dev libdw-dev cmake gcc binutils-dev libiberty-dev
|
- sudo apt-get install -y openssl libssl-dev libelf-dev libdw-dev cmake gcc binutils-dev libiberty-dev
|
||||||
|
|
||||||
before_cache: |
|
before_cache: |
|
||||||
if [[ "$TRAVIS_RUST_VERSION" == "nightly-2019-04-02" ]]; then
|
if [[ "$TRAVIS_RUST_VERSION" == "nightly-2019-08-10" ]]; then
|
||||||
RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install --version 0.6.11 cargo-tarpaulin
|
RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install --version 0.6.11 cargo-tarpaulin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ after_success:
|
|||||||
echo "Uploaded documentation"
|
echo "Uploaded documentation"
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [[ "$TRAVIS_RUST_VERSION" == "nightly-2019-04-02" ]]; then
|
if [[ "$TRAVIS_RUST_VERSION" == "nightly-2019-08-10" ]]; then
|
||||||
taskset -c 0 cargo tarpaulin --out Xml --all --all-features
|
taskset -c 0 cargo tarpaulin --out Xml --all --all-features
|
||||||
bash <(curl -s https://codecov.io/bash)
|
bash <(curl -s https://codecov.io/bash)
|
||||||
echo "Uploaded code coverage"
|
echo "Uploaded code coverage"
|
||||||
|
13
CHANGES.md
13
CHANGES.md
@@ -1,6 +1,6 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## [1.0.6] - 2019-xx-xx
|
## [1.0.6] - 2019-08-28
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
@@ -8,10 +8,21 @@
|
|||||||
|
|
||||||
* Form immplements Responder, returning a `application/x-www-form-urlencoded` response
|
* Form immplements Responder, returning a `application/x-www-form-urlencoded` response
|
||||||
|
|
||||||
|
* Add `into_inner` to `Data`
|
||||||
|
|
||||||
|
* Add `test::TestRequest::set_form()` convenience method to automatically serialize data and set
|
||||||
|
the header in test requests.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* `Query` payload made `pub`. Allows user to pattern-match the payload.
|
* `Query` payload made `pub`. Allows user to pattern-match the payload.
|
||||||
|
|
||||||
|
* Enable `rust-tls` feature for client #1045
|
||||||
|
|
||||||
|
* Update serde_urlencoded to 0.6.1
|
||||||
|
|
||||||
|
* Update url to 2.1
|
||||||
|
|
||||||
|
|
||||||
## [1.0.5] - 2019-07-18
|
## [1.0.5] - 2019-07-18
|
||||||
|
|
||||||
|
12
Cargo.toml
12
Cargo.toml
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-web"
|
name = "actix-web"
|
||||||
version = "1.0.5"
|
version = "1.0.6"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust."
|
description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@@ -66,7 +66,7 @@ fail = ["actix-http/fail"]
|
|||||||
ssl = ["openssl", "actix-server/ssl", "awc/ssl"]
|
ssl = ["openssl", "actix-server/ssl", "awc/ssl"]
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
rust-tls = ["rustls", "actix-server/rust-tls"]
|
rust-tls = ["rustls", "actix-server/rust-tls", "awc/rust-tls"]
|
||||||
|
|
||||||
# unix domain sockets support
|
# unix domain sockets support
|
||||||
uds = ["actix-server/uds"]
|
uds = ["actix-server/uds"]
|
||||||
@@ -78,11 +78,11 @@ actix-utils = "0.4.4"
|
|||||||
actix-router = "0.1.5"
|
actix-router = "0.1.5"
|
||||||
actix-rt = "0.2.4"
|
actix-rt = "0.2.4"
|
||||||
actix-web-codegen = "0.1.2"
|
actix-web-codegen = "0.1.2"
|
||||||
actix-http = "0.2.7"
|
actix-http = "0.2.9"
|
||||||
actix-server = "0.6.0"
|
actix-server = "0.6.0"
|
||||||
actix-server-config = "0.1.2"
|
actix-server-config = "0.1.2"
|
||||||
actix-threadpool = "0.1.1"
|
actix-threadpool = "0.1.1"
|
||||||
awc = { version = "0.2.2", optional = true }
|
awc = { version = "0.2.4", optional = true }
|
||||||
|
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
derive_more = "0.15.0"
|
derive_more = "0.15.0"
|
||||||
@@ -96,9 +96,9 @@ parking_lot = "0.9"
|
|||||||
regex = "1.0"
|
regex = "1.0"
|
||||||
serde = { version = "1.0", features=["derive"] }
|
serde = { version = "1.0", features=["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_urlencoded = "0.5.3"
|
serde_urlencoded = "0.6.1"
|
||||||
time = "0.1.42"
|
time = "0.1.42"
|
||||||
url = { version="1.7", features=["query_encoding"] }
|
url = "2.1"
|
||||||
|
|
||||||
# ssl support
|
# ssl support
|
||||||
openssl = { version="0.10", optional = true }
|
openssl = { version="0.10", optional = true }
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Identity service for actix web framework [](https://travis-ci.org/actix/actix-web) [](https://codecov.io/gh/actix/actix-web) [](https://crates.io/crates/actix-identity) [](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
# Cors Middleware for actix web framework [](https://travis-ci.org/actix/actix-web) [](https://codecov.io/gh/actix/actix-web) [](https://crates.io/crates/actix-cors) [](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
## Documentation & community resources
|
## Documentation & community resources
|
||||||
|
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [0.1.5] - unreleased
|
||||||
|
|
||||||
|
* Bump up `mime_guess` crate version to 2.0.1
|
||||||
|
|
||||||
|
* Bump up `percent-encoding` crate version to 2.1
|
||||||
|
|
||||||
## [0.1.4] - 2019-07-20
|
## [0.1.4] - 2019-07-20
|
||||||
|
|
||||||
* Allow to disable `Content-Disposition` header #686
|
* Allow to disable `Content-Disposition` header #686
|
||||||
|
@@ -19,7 +19,7 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "1.0.2", default-features = false }
|
actix-web = { version = "1.0.2", default-features = false }
|
||||||
actix-http = "0.2.4"
|
actix-http = "0.2.9"
|
||||||
actix-service = "0.4.1"
|
actix-service = "0.4.1"
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
@@ -27,8 +27,8 @@ futures = "0.1.25"
|
|||||||
derive_more = "0.15.0"
|
derive_more = "0.15.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
mime_guess = "2.0.0-alpha"
|
mime_guess = "2.0.1"
|
||||||
percent-encoding = "1.0"
|
percent-encoding = "2.1"
|
||||||
v_htmlescape = "0.4"
|
v_htmlescape = "0.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@@ -22,8 +22,8 @@ use bytes::Bytes;
|
|||||||
use futures::future::{ok, Either, FutureResult};
|
use futures::future::{ok, Either, FutureResult};
|
||||||
use futures::{Async, Future, Poll, Stream};
|
use futures::{Async, Future, Poll, Stream};
|
||||||
use mime;
|
use mime;
|
||||||
use mime_guess::get_mime_type;
|
use mime_guess::from_ext;
|
||||||
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
|
use percent_encoding::{utf8_percent_encode, CONTROLS};
|
||||||
use v_htmlescape::escape as escape_html_entity;
|
use v_htmlescape::escape as escape_html_entity;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
@@ -42,7 +42,7 @@ type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error
|
|||||||
/// the type `application/octet-stream`.
|
/// the type `application/octet-stream`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn file_extension_to_mime(ext: &str) -> mime::Mime {
|
pub fn file_extension_to_mime(ext: &str) -> mime::Mime {
|
||||||
get_mime_type(ext)
|
from_ext(ext).first_or_octet_stream()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@@ -144,7 +144,7 @@ impl Directory {
|
|||||||
// show file url as relative to static path
|
// show file url as relative to static path
|
||||||
macro_rules! encode_file_url {
|
macro_rules! encode_file_url {
|
||||||
($path:ident) => {
|
($path:ident) => {
|
||||||
utf8_percent_encode(&$path.to_string_lossy(), DEFAULT_ENCODE_SET)
|
utf8_percent_encode(&$path.to_string_lossy(), CONTROLS)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ use std::os::unix::fs::MetadataExt;
|
|||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use mime;
|
use mime;
|
||||||
use mime_guess::guess_mime_type;
|
use mime_guess::from_path;
|
||||||
|
|
||||||
use actix_http::body::SizedStream;
|
use actix_http::body::SizedStream;
|
||||||
use actix_web::http::header::{
|
use actix_web::http::header::{
|
||||||
@@ -88,7 +88,7 @@ impl NamedFile {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ct = guess_mime_type(&path);
|
let ct = from_path(&path).first_or_octet_stream();
|
||||||
let disposition_type = match ct.type_() {
|
let disposition_type = match ct.type_() {
|
||||||
mime::IMAGE | mime::TEXT | mime::VIDEO => DispositionType::Inline,
|
mime::IMAGE | mime::TEXT | mime::VIDEO => DispositionType::Inline,
|
||||||
_ => DispositionType::Attachment,
|
_ => DispositionType::Attachment,
|
||||||
|
@@ -1,5 +1,20 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [0.2.9] - 2019-08-13
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Dropped the `byteorder`-dependency in favor of `stdlib`-implementation
|
||||||
|
|
||||||
|
* Update percent-encoding to 2.1
|
||||||
|
|
||||||
|
* Update serde_urlencoded to 0.6.1
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* Fixed a panic in the HTTP2 handshake in client HTTP requests (#1031)
|
||||||
|
|
||||||
|
|
||||||
## [0.2.8] - 2019-08-01
|
## [0.2.8] - 2019-08-01
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "0.2.8"
|
version = "0.2.9"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix http primitives"
|
description = "Actix http primitives"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@@ -57,7 +57,6 @@ actix-threadpool = "0.1.1"
|
|||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
byteorder = "1.2"
|
|
||||||
copyless = "0.1.4"
|
copyless = "0.1.4"
|
||||||
derive_more = "0.15.0"
|
derive_more = "0.15.0"
|
||||||
either = "1.5.2"
|
either = "1.5.2"
|
||||||
@@ -72,14 +71,14 @@ lazy_static = "1.0"
|
|||||||
language-tags = "0.2"
|
language-tags = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
percent-encoding = "1.0"
|
percent-encoding = "2.1"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
regex = "1.0"
|
regex = "1.0"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sha1 = "0.6"
|
sha1 = "0.6"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
serde_urlencoded = "0.5.5"
|
serde_urlencoded = "0.6.1"
|
||||||
time = "0.1.42"
|
time = "0.1.42"
|
||||||
tokio-tcp = "0.1.3"
|
tokio-tcp = "0.1.3"
|
||||||
tokio-timer = "0.2.8"
|
tokio-timer = "0.2.8"
|
||||||
|
@@ -269,9 +269,9 @@ where
|
|||||||
.map(|protos| protos.windows(2).any(|w| w == H2))
|
.map(|protos| protos.windows(2).any(|w| w == H2))
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock) as Box<Io>, Protocol::Http2)
|
(Box::new(sock) as Box<dyn Io>, Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
(Box::new(sock) as Box<Io>, Protocol::Http1)
|
(Box::new(sock) as Box<dyn Io>, Protocol::Http1)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@@ -288,9 +288,9 @@ where
|
|||||||
.map(|protos| protos.windows(2).any(|w| w == H2))
|
.map(|protos| protos.windows(2).any(|w| w == H2))
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if h2 {
|
if h2 {
|
||||||
(Box::new(sock) as Box<Io>, Protocol::Http2)
|
(Box::new(sock) as Box<dyn Io>, Protocol::Http2)
|
||||||
} else {
|
} else {
|
||||||
(Box::new(sock) as Box<Io>, Protocol::Http1)
|
(Box::new(sock) as Box<dyn Io>, Protocol::Http1)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@@ -590,6 +590,29 @@ where
|
|||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
if let Some(ref mut h2) = self.h2 {
|
||||||
|
return match h2.poll() {
|
||||||
|
Ok(Async::Ready((snd, connection))) => {
|
||||||
|
tokio_current_thread::spawn(connection.map_err(|_| ()));
|
||||||
|
let rx = self.rx.take().unwrap();
|
||||||
|
let _ = rx.send(Ok(IoConnection::new(
|
||||||
|
ConnectionType::H2(snd),
|
||||||
|
Instant::now(),
|
||||||
|
Some(Acquired(self.key.clone(), self.inner.take())),
|
||||||
|
)));
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||||
|
Err(err) => {
|
||||||
|
let _ = self.inner.take();
|
||||||
|
if let Some(rx) = self.rx.take() {
|
||||||
|
let _ = rx.send(Err(ConnectError::H2(err)));
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
match self.fut.poll() {
|
match self.fut.poll() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let _ = self.inner.take();
|
let _ = self.inner.take();
|
||||||
|
@@ -66,7 +66,7 @@ use std::fmt;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
use percent_encoding::{percent_encode, AsciiSet, CONTROLS};
|
||||||
use time::Tm;
|
use time::Tm;
|
||||||
|
|
||||||
pub use self::builder::CookieBuilder;
|
pub use self::builder::CookieBuilder;
|
||||||
@@ -75,6 +75,25 @@ pub use self::jar::{CookieJar, Delta, Iter};
|
|||||||
use self::parse::parse_cookie;
|
use self::parse::parse_cookie;
|
||||||
pub use self::parse::ParseError;
|
pub use self::parse::ParseError;
|
||||||
|
|
||||||
|
/// https://url.spec.whatwg.org/#fragment-percent-encode-set
|
||||||
|
const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`');
|
||||||
|
|
||||||
|
/// https://url.spec.whatwg.org/#path-percent-encode-set
|
||||||
|
const PATH: &AsciiSet = &FRAGMENT.add(b'#').add(b'?').add(b'{').add(b'}');
|
||||||
|
|
||||||
|
/// https://url.spec.whatwg.org/#userinfo-percent-encode-set
|
||||||
|
pub const USERINFO: &AsciiSet = &PATH
|
||||||
|
.add(b'/')
|
||||||
|
.add(b':')
|
||||||
|
.add(b';')
|
||||||
|
.add(b'=')
|
||||||
|
.add(b'@')
|
||||||
|
.add(b'[')
|
||||||
|
.add(b'\\')
|
||||||
|
.add(b']')
|
||||||
|
.add(b'^')
|
||||||
|
.add(b'|');
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum CookieStr {
|
enum CookieStr {
|
||||||
/// An string derived from indexes (start, end).
|
/// An string derived from indexes (start, end).
|
||||||
@@ -910,8 +929,8 @@ pub struct EncodedCookie<'a, 'c: 'a>(&'a Cookie<'c>);
|
|||||||
impl<'a, 'c: 'a> fmt::Display for EncodedCookie<'a, '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.
|
// Percent-encode the name and value.
|
||||||
let name = percent_encode(self.0.name().as_bytes(), USERINFO_ENCODE_SET);
|
let name = percent_encode(self.0.name().as_bytes(), USERINFO);
|
||||||
let value = percent_encode(self.0.value().as_bytes(), USERINFO_ENCODE_SET);
|
let value = percent_encode(self.0.value().as_bytes(), USERINFO);
|
||||||
|
|
||||||
// Write out the name/value pair and the cookie's parameters.
|
// Write out the name/value pair and the cookie's parameters.
|
||||||
write!(f, "{}={}", name, value)?;
|
write!(f, "{}={}", name, value)?;
|
||||||
|
@@ -1072,7 +1072,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_error_casting() {
|
fn test_error_casting() {
|
||||||
let err = PayloadError::Overflow;
|
let err = PayloadError::Overflow;
|
||||||
let resp_err: &ResponseError = &err;
|
let resp_err: &dyn ResponseError = &err;
|
||||||
let err = resp_err.downcast_ref::<PayloadError>().unwrap();
|
let err = resp_err.downcast_ref::<PayloadError>().unwrap();
|
||||||
assert_eq!(err.to_string(), "A payload reached size limit.");
|
assert_eq!(err.to_string(), "A payload reached size limit.");
|
||||||
let not_err = resp_err.downcast_ref::<ContentTypeError>();
|
let not_err = resp_err.downcast_ref::<ContentTypeError>();
|
||||||
|
@@ -6,6 +6,7 @@ use std::{fmt, str::FromStr};
|
|||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use http::Error as HttpError;
|
use http::Error as HttpError;
|
||||||
use mime::Mime;
|
use mime::Mime;
|
||||||
|
use percent_encoding::{AsciiSet, CONTROLS};
|
||||||
|
|
||||||
pub use http::header::*;
|
pub use http::header::*;
|
||||||
|
|
||||||
@@ -361,10 +362,8 @@ pub fn parse_extended_value(
|
|||||||
|
|
||||||
impl fmt::Display for ExtendedValue {
|
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(
|
let encoded_value =
|
||||||
&self.value[..],
|
percent_encoding::percent_encode(&self.value[..], HTTP_VALUE);
|
||||||
self::percent_encoding_http::HTTP_VALUE,
|
|
||||||
);
|
|
||||||
if let Some(ref lang) = self.language_tag {
|
if let Some(ref lang) = self.language_tag {
|
||||||
write!(f, "{}'{}'{}", self.charset, lang, encoded_value)
|
write!(f, "{}'{}'{}", self.charset, lang, encoded_value)
|
||||||
} else {
|
} else {
|
||||||
@@ -378,8 +377,7 @@ impl fmt::Display for ExtendedValue {
|
|||||||
///
|
///
|
||||||
/// [url]: https://tools.ietf.org/html/rfc5987#section-3.2
|
/// [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 =
|
let encoded = percent_encoding::percent_encode(bytes, HTTP_VALUE);
|
||||||
percent_encoding::percent_encode(bytes, self::percent_encoding_http::HTTP_VALUE);
|
|
||||||
fmt::Display::fmt(&encoded, f)
|
fmt::Display::fmt(&encoded, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,20 +392,29 @@ impl From<http::HeaderMap> for HeaderMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod percent_encoding_http {
|
// This encode set is used for HTTP header values and is defined at
|
||||||
use percent_encoding::{self, define_encode_set};
|
// https://tools.ietf.org/html/rfc5987#section-3.2
|
||||||
|
pub(crate) const HTTP_VALUE: &AsciiSet = &CONTROLS
|
||||||
// internal module because macro is hard-coded to make a public item
|
.add(b' ')
|
||||||
// but we don't want to public export this item
|
.add(b'"')
|
||||||
define_encode_set! {
|
.add(b'%')
|
||||||
// This encode set is used for HTTP header values and is defined at
|
.add(b'\'')
|
||||||
// https://tools.ietf.org/html/rfc5987#section-3.2
|
.add(b'(')
|
||||||
pub HTTP_VALUE = [percent_encoding::SIMPLE_ENCODE_SET] | {
|
.add(b')')
|
||||||
' ', '"', '%', '\'', '(', ')', '*', ',', '/', ':', ';', '<', '-', '>', '?',
|
.add(b'*')
|
||||||
'[', '\\', ']', '{', '}'
|
.add(b',')
|
||||||
}
|
.add(b'/')
|
||||||
}
|
.add(b':')
|
||||||
}
|
.add(b';')
|
||||||
|
.add(b'<')
|
||||||
|
.add(b'-')
|
||||||
|
.add(b'>')
|
||||||
|
.add(b'?')
|
||||||
|
.add(b'[')
|
||||||
|
.add(b'\\')
|
||||||
|
.add(b']')
|
||||||
|
.add(b'{')
|
||||||
|
.add(b'}');
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@@ -9,9 +9,9 @@ use bytes::{Buf, Bytes, BytesMut};
|
|||||||
use futures::{Async, Poll};
|
use futures::{Async, Poll};
|
||||||
use http::header::{self, HeaderName, HeaderValue};
|
use http::header::{self, HeaderName, HeaderValue};
|
||||||
use http::{HttpTryFrom, Method, Uri, Version};
|
use http::{HttpTryFrom, Method, Uri, Version};
|
||||||
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
use percent_encoding::percent_encode;
|
||||||
|
|
||||||
use crate::cookie::{Cookie, CookieJar};
|
use crate::cookie::{Cookie, CookieJar, USERINFO};
|
||||||
use crate::header::HeaderMap;
|
use crate::header::HeaderMap;
|
||||||
use crate::header::{Header, IntoHeaderValue};
|
use crate::header::{Header, IntoHeaderValue};
|
||||||
use crate::payload::Payload;
|
use crate::payload::Payload;
|
||||||
@@ -166,8 +166,8 @@ impl TestRequest {
|
|||||||
|
|
||||||
let mut cookie = String::new();
|
let mut cookie = String::new();
|
||||||
for c in inner.cookies.delta() {
|
for c in inner.cookies.delta() {
|
||||||
let name = percent_encode(c.name().as_bytes(), USERINFO_ENCODE_SET);
|
let name = percent_encode(c.name().as_bytes(), USERINFO);
|
||||||
let value = percent_encode(c.value().as_bytes(), USERINFO_ENCODE_SET);
|
let value = percent_encode(c.value().as_bytes(), USERINFO);
|
||||||
let _ = write!(&mut cookie, "; {}={}", name, value);
|
let _ = write!(&mut cookie, "; {}={}", name, value);
|
||||||
}
|
}
|
||||||
if !cookie.is_empty() {
|
if !cookie.is_empty() {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
use byteorder::{ByteOrder, LittleEndian, NetworkEndian};
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rand;
|
use rand;
|
||||||
@@ -48,14 +49,16 @@ impl Parser {
|
|||||||
if chunk_len < 4 {
|
if chunk_len < 4 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let len = NetworkEndian::read_uint(&src[idx..], 2) as usize;
|
let len = usize::from(u16::from_be_bytes(
|
||||||
|
TryFrom::try_from(&src[idx..idx + 2]).unwrap(),
|
||||||
|
));
|
||||||
idx += 2;
|
idx += 2;
|
||||||
len
|
len
|
||||||
} else if len == 127 {
|
} else if len == 127 {
|
||||||
if chunk_len < 10 {
|
if chunk_len < 10 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let len = NetworkEndian::read_uint(&src[idx..], 8);
|
let len = u64::from_be_bytes(TryFrom::try_from(&src[idx..idx + 8]).unwrap());
|
||||||
if len > max_size as u64 {
|
if len > max_size as u64 {
|
||||||
return Err(ProtocolError::Overflow);
|
return Err(ProtocolError::Overflow);
|
||||||
}
|
}
|
||||||
@@ -75,10 +78,10 @@ impl Parser {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mask: &[u8] = &src[idx..idx + 4];
|
let mask =
|
||||||
let mask_u32 = LittleEndian::read_u32(mask);
|
u32::from_le_bytes(TryFrom::try_from(&src[idx..idx + 4]).unwrap());
|
||||||
idx += 4;
|
idx += 4;
|
||||||
Some(mask_u32)
|
Some(mask)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -137,7 +140,7 @@ impl Parser {
|
|||||||
/// Parse the payload of a close frame.
|
/// Parse the payload of a close frame.
|
||||||
pub fn parse_close_payload(payload: &[u8]) -> Option<CloseReason> {
|
pub fn parse_close_payload(payload: &[u8]) -> Option<CloseReason> {
|
||||||
if payload.len() >= 2 {
|
if payload.len() >= 2 {
|
||||||
let raw_code = NetworkEndian::read_u16(payload);
|
let raw_code = u16::from_be_bytes(TryFrom::try_from(&payload[..2]).unwrap());
|
||||||
let code = CloseCode::from(raw_code);
|
let code = CloseCode::from(raw_code);
|
||||||
let description = if payload.len() > 2 {
|
let description = if payload.len() > 2 {
|
||||||
Some(String::from_utf8_lossy(&payload[2..]).into())
|
Some(String::from_utf8_lossy(&payload[2..]).into())
|
||||||
@@ -201,10 +204,7 @@ impl Parser {
|
|||||||
let payload = match reason {
|
let payload = match reason {
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
Some(reason) => {
|
Some(reason) => {
|
||||||
let mut code_bytes = [0; 2];
|
let mut payload = Into::<u16>::into(reason.code).to_be_bytes().to_vec();
|
||||||
NetworkEndian::write_u16(&mut code_bytes, reason.code.into());
|
|
||||||
|
|
||||||
let mut payload = Vec::from(&code_bytes[..]);
|
|
||||||
if let Some(description) = reason.description {
|
if let Some(description) = reason.description {
|
||||||
payload.extend(description.as_bytes());
|
payload.extend(description.as_bytes());
|
||||||
}
|
}
|
||||||
|
@@ -105,7 +105,6 @@ fn align_buf(buf: &mut [u8]) -> (ShortSlice, &mut [u64], ShortSlice) {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::apply_mask;
|
use super::apply_mask;
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
|
|
||||||
/// A safe unoptimized mask application.
|
/// A safe unoptimized mask application.
|
||||||
fn apply_mask_fallback(buf: &mut [u8], mask: &[u8; 4]) {
|
fn apply_mask_fallback(buf: &mut [u8], mask: &[u8; 4]) {
|
||||||
@@ -117,7 +116,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_apply_mask() {
|
fn test_apply_mask() {
|
||||||
let mask = [0x6d, 0xb6, 0xb2, 0x80];
|
let mask = [0x6d, 0xb6, 0xb2, 0x80];
|
||||||
let mask_u32: u32 = LittleEndian::read_u32(&mask);
|
let mask_u32 = u32::from_le_bytes(mask);
|
||||||
|
|
||||||
let unmasked = vec![
|
let unmasked = vec![
|
||||||
0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17,
|
0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## [0.1.3] - 2019-06-06
|
## [0.1.3] - 2019-08-18
|
||||||
|
|
||||||
* Fix ring dependency from actix-web default features for #741.
|
* Fix ring dependency from actix-web default features for #741.
|
||||||
|
|
||||||
|
@@ -1,5 +1,14 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [0.2.4] - 2019-08-13
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Update percent-encoding to "2.1"
|
||||||
|
|
||||||
|
* Update serde_urlencoded to "0.6.1"
|
||||||
|
|
||||||
|
|
||||||
## [0.2.3] - 2019-08-01
|
## [0.2.3] - 2019-08-01
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "awc"
|
name = "awc"
|
||||||
version = "0.2.3"
|
version = "0.2.4"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix http client."
|
description = "Actix http client."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@@ -44,18 +44,18 @@ flate2-rust = ["actix-http/flate2-rust"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.1.2"
|
actix-codec = "0.1.2"
|
||||||
actix-service = "0.4.1"
|
actix-service = "0.4.1"
|
||||||
actix-http = "0.2.8"
|
actix-http = "0.2.9"
|
||||||
base64 = "0.10.1"
|
base64 = "0.10.1"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
derive_more = "0.15.0"
|
derive_more = "0.15.0"
|
||||||
futures = "0.1.25"
|
futures = "0.1.25"
|
||||||
log =" 0.4"
|
log =" 0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
percent-encoding = "1.0"
|
percent-encoding = "2.1"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_urlencoded = "0.5.3"
|
serde_urlencoded = "0.6.1"
|
||||||
tokio-timer = "0.2.8"
|
tokio-timer = "0.2.8"
|
||||||
openssl = { version="0.10", optional = true }
|
openssl = { version="0.10", optional = true }
|
||||||
rustls = { version = "0.15.2", optional = true }
|
rustls = { version = "0.15.2", optional = true }
|
||||||
|
@@ -7,13 +7,13 @@ use std::{fmt, net};
|
|||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
use futures::future::{err, Either};
|
use futures::future::{err, Either};
|
||||||
use futures::{Future, Stream};
|
use futures::{Future, Stream};
|
||||||
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
use percent_encoding::percent_encode;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use tokio_timer::Timeout;
|
use tokio_timer::Timeout;
|
||||||
|
|
||||||
use actix_http::body::{Body, BodyStream};
|
use actix_http::body::{Body, BodyStream};
|
||||||
use actix_http::cookie::{Cookie, CookieJar};
|
use actix_http::cookie::{Cookie, CookieJar, USERINFO};
|
||||||
use actix_http::encoding::Decoder;
|
use actix_http::encoding::Decoder;
|
||||||
use actix_http::http::header::{self, ContentEncoding, Header, IntoHeaderValue};
|
use actix_http::http::header::{self, ContentEncoding, Header, IntoHeaderValue};
|
||||||
use actix_http::http::{
|
use actix_http::http::{
|
||||||
@@ -399,8 +399,8 @@ impl ClientRequest {
|
|||||||
if let Some(ref mut jar) = self.cookies {
|
if let Some(ref mut jar) = self.cookies {
|
||||||
let mut cookie = String::new();
|
let mut cookie = String::new();
|
||||||
for c in jar.delta() {
|
for c in jar.delta() {
|
||||||
let name = percent_encode(c.name().as_bytes(), USERINFO_ENCODE_SET);
|
let name = percent_encode(c.name().as_bytes(), USERINFO);
|
||||||
let value = percent_encode(c.value().as_bytes(), USERINFO_ENCODE_SET);
|
let value = percent_encode(c.value().as_bytes(), USERINFO);
|
||||||
let _ = write!(&mut cookie, "; {}={}", name, value);
|
let _ = write!(&mut cookie, "; {}={}", name, value);
|
||||||
}
|
}
|
||||||
self.head.headers.insert(
|
self.head.headers.insert(
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
//! Test helpers for actix http client to use during testing.
|
//! Test helpers for actix http client to use during testing.
|
||||||
use std::fmt::Write as FmtWrite;
|
use std::fmt::Write as FmtWrite;
|
||||||
|
|
||||||
use actix_http::cookie::{Cookie, CookieJar};
|
use actix_http::cookie::{Cookie, CookieJar, USERINFO};
|
||||||
use actix_http::http::header::{self, Header, HeaderValue, IntoHeaderValue};
|
use actix_http::http::header::{self, Header, HeaderValue, IntoHeaderValue};
|
||||||
use actix_http::http::{HeaderName, HttpTryFrom, StatusCode, Version};
|
use actix_http::http::{HeaderName, HttpTryFrom, StatusCode, Version};
|
||||||
use actix_http::{h1, Payload, ResponseHead};
|
use actix_http::{h1, Payload, ResponseHead};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
use percent_encoding::percent_encode;
|
||||||
|
|
||||||
use crate::ClientResponse;
|
use crate::ClientResponse;
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ impl TestResponse {
|
|||||||
|
|
||||||
let mut cookie = String::new();
|
let mut cookie = String::new();
|
||||||
for c in self.cookies.delta() {
|
for c in self.cookies.delta() {
|
||||||
let name = percent_encode(c.name().as_bytes(), USERINFO_ENCODE_SET);
|
let name = percent_encode(c.name().as_bytes(), USERINFO);
|
||||||
let value = percent_encode(c.value().as_bytes(), USERINFO_ENCODE_SET);
|
let value = percent_encode(c.value().as_bytes(), USERINFO);
|
||||||
let _ = write!(&mut cookie, "; {}={}", name, value);
|
let _ = write!(&mut cookie, "; {}={}", name, value);
|
||||||
}
|
}
|
||||||
if !cookie.is_empty() {
|
if !cookie.is_empty() {
|
||||||
|
@@ -8,9 +8,10 @@ use actix_codec::Framed;
|
|||||||
use actix_http::cookie::{Cookie, CookieJar};
|
use actix_http::cookie::{Cookie, CookieJar};
|
||||||
use actix_http::{ws, Payload, RequestHead};
|
use actix_http::{ws, Payload, RequestHead};
|
||||||
use futures::future::{err, Either, Future};
|
use futures::future::{err, Either, Future};
|
||||||
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
use percent_encoding::percent_encode;
|
||||||
use tokio_timer::Timeout;
|
use tokio_timer::Timeout;
|
||||||
|
|
||||||
|
use actix_http::cookie::USERINFO;
|
||||||
pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
|
pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
|
||||||
|
|
||||||
use crate::connect::BoxedSocket;
|
use crate::connect::BoxedSocket;
|
||||||
@@ -236,8 +237,8 @@ impl WebsocketsRequest {
|
|||||||
if let Some(ref mut jar) = self.cookies {
|
if let Some(ref mut jar) = self.cookies {
|
||||||
let mut cookie = String::new();
|
let mut cookie = String::new();
|
||||||
for c in jar.delta() {
|
for c in jar.delta() {
|
||||||
let name = percent_encode(c.name().as_bytes(), USERINFO_ENCODE_SET);
|
let name = percent_encode(c.name().as_bytes(), USERINFO);
|
||||||
let value = percent_encode(c.value().as_bytes(), USERINFO_ENCODE_SET);
|
let value = percent_encode(c.value().as_bytes(), USERINFO);
|
||||||
let _ = write!(&mut cookie, "; {}={}", name, value);
|
let _ = write!(&mut cookie, "; {}={}", name, value);
|
||||||
}
|
}
|
||||||
self.head.headers.insert(
|
self.head.headers.insert(
|
||||||
|
@@ -77,6 +77,11 @@ impl<T> Data<T> {
|
|||||||
pub fn get_ref(&self) -> &T {
|
pub fn get_ref(&self) -> &T {
|
||||||
self.0.as_ref()
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert to the internal Arc<T>
|
||||||
|
pub fn into_inner(self) -> Arc<T> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Deref for Data<T> {
|
impl<T> Deref for Data<T> {
|
||||||
|
@@ -151,5 +151,4 @@ mod tests {
|
|||||||
let res = block_on(normalize.call(req)).unwrap();
|
let res = block_on(normalize.call(req)).unwrap();
|
||||||
assert!(res.status().is_success());
|
assert!(res.status().is_success());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -763,5 +763,4 @@ mod tests {
|
|||||||
let resp = call_service(&mut srv, req);
|
let resp = call_service(&mut srv, req);
|
||||||
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
|
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
35
src/test.rs
35
src/test.rs
@@ -478,6 +478,16 @@ impl TestRequest {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serialize `data` to a URL encoded form and set it as the request payload. The `Content-Type`
|
||||||
|
/// header is set to `application/x-www-form-urlencoded`.
|
||||||
|
pub fn set_form<T: Serialize>(mut self, data: &T) -> Self {
|
||||||
|
let bytes = serde_urlencoded::to_string(data)
|
||||||
|
.expect("Failed to serialize test data as a urlencoded form");
|
||||||
|
self.req.set_payload(bytes);
|
||||||
|
self.req.set(ContentType::form_url_encoded());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Serialize `data` to JSON and set it as the request payload. The `Content-Type` header is
|
/// Serialize `data` to JSON and set it as the request payload. The `Content-Type` header is
|
||||||
/// set to `application/json`.
|
/// set to `application/json`.
|
||||||
pub fn set_json<T: Serialize>(mut self, data: &T) -> Self {
|
pub fn set_json<T: Serialize>(mut self, data: &T) -> Self {
|
||||||
@@ -670,6 +680,31 @@ mod tests {
|
|||||||
assert_eq!(&result.id, "12345");
|
assert_eq!(&result.id, "12345");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_request_response_form() {
|
||||||
|
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||||
|
web::post().to(|person: web::Form<Person>| {
|
||||||
|
HttpResponse::Ok().json(person.into_inner())
|
||||||
|
}),
|
||||||
|
)));
|
||||||
|
|
||||||
|
let payload = Person {
|
||||||
|
id: "12345".to_string(),
|
||||||
|
name: "User name".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let req = TestRequest::post()
|
||||||
|
.uri("/people")
|
||||||
|
.set_form(&payload)
|
||||||
|
.to_request();
|
||||||
|
|
||||||
|
assert_eq!(req.content_type(), "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
let result: Person = read_response_json(&mut app, req);
|
||||||
|
assert_eq!(&result.id, "12345");
|
||||||
|
assert_eq!(&result.name, "User name");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_request_response_json() {
|
fn test_request_response_json() {
|
||||||
let mut app = init_service(App::new().service(web::resource("/people").route(
|
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||||
|
@@ -482,5 +482,4 @@ mod tests {
|
|||||||
use crate::responder::tests::BodyTest;
|
use crate::responder::tests::BodyTest;
|
||||||
assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123");
|
assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Update serde_urlencoded to "0.6.1"
|
||||||
|
|
||||||
|
|
||||||
## [0.2.4] - 2019-07-18
|
## [0.2.4] - 2019-07-18
|
||||||
|
|
||||||
* Update actix-server to 0.6
|
* Update actix-server to 0.6
|
||||||
|
@@ -49,7 +49,7 @@ serde = "1.0"
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sha1 = "0.6"
|
sha1 = "0.6"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
serde_urlencoded = "0.5.3"
|
serde_urlencoded = "0.6.1"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
tokio-tcp = "0.1"
|
tokio-tcp = "0.1"
|
||||||
tokio-timer = "0.2"
|
tokio-timer = "0.2"
|
||||||
|
Reference in New Issue
Block a user