mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-03 09:36:36 +02:00
Compare commits
7 Commits
http-v0.2.
...
multipart-
Author | SHA1 | Date | |
---|---|---|---|
1d45639bed | |||
6a672c9097 | |||
5cb2d500d1 | |||
0212c618c6 | |||
88110ed268 | |||
fba02fdd8c | |||
b2934ad8d2 |
@ -1,6 +1,6 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.9] - 2019-xx-xx
|
||||
## [1.0.9] - 2019-11-14
|
||||
|
||||
### Added
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
* Support `Host` guards when the `Host` header is unset (e.g. HTTP/2 requests) (#1129)
|
||||
|
||||
|
||||
## [1.0.8] - 2019-09-25
|
||||
|
||||
### Added
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-web"
|
||||
version = "1.0.8"
|
||||
version = "1.0.9"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust."
|
||||
readme = "README.md"
|
||||
@ -78,7 +78,7 @@ actix-utils = "0.4.4"
|
||||
actix-router = "0.1.5"
|
||||
actix-rt = "0.2.4"
|
||||
actix-web-codegen = "0.1.2"
|
||||
actix-http = "0.2.9"
|
||||
actix-http = "0.2.11"
|
||||
actix-server = "0.6.1"
|
||||
actix-server-config = "0.1.2"
|
||||
actix-testing = "0.1.0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-files"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Static files support for actix web."
|
||||
readme = "README.md"
|
||||
@ -19,7 +19,7 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-web = { version = "1.0.8", default-features = false }
|
||||
actix-http = "0.2.9"
|
||||
actix-http = "0.2.11"
|
||||
actix-service = "0.4.1"
|
||||
bitflags = "1"
|
||||
bytes = "0.4"
|
||||
|
@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [0.1.5] - 2019-12-07
|
||||
|
||||
* Multipart handling now handles NotReady during read of boundary #1189
|
||||
|
||||
## [0.1.4] - 2019-09-12
|
||||
|
||||
* Multipart handling now parses requests which do not end in CRLF #1038
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-multipart"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Multipart support for actix web framework."
|
||||
readme = "README.md"
|
||||
|
@ -604,7 +604,7 @@ impl InnerField {
|
||||
}
|
||||
|
||||
match payload.readline()? {
|
||||
None => Async::Ready(None),
|
||||
None => Async::NotReady,
|
||||
Some(line) => {
|
||||
if line.as_ref() != b"\r\n" {
|
||||
log::warn!("multipart field did not read all the data or it is malformed");
|
||||
@ -860,6 +860,42 @@ mod tests {
|
||||
(tx, rx.map_err(|_| panic!()).and_then(|res| res))
|
||||
}
|
||||
|
||||
// Stream that returns from a Bytes, one char at a time and NotReady every other poll()
|
||||
struct SlowStream {
|
||||
bytes: Bytes,
|
||||
pos: usize,
|
||||
ready: bool,
|
||||
}
|
||||
|
||||
impl SlowStream {
|
||||
fn new(bytes: Bytes) -> SlowStream {
|
||||
return SlowStream {
|
||||
bytes: bytes,
|
||||
pos: 0,
|
||||
ready: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for SlowStream {
|
||||
type Item = Bytes;
|
||||
type Error = PayloadError;
|
||||
|
||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||
if !self.ready {
|
||||
self.ready = true;
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
if self.pos == self.bytes.len() {
|
||||
return Ok(Async::Ready(None));
|
||||
}
|
||||
let res = Ok(Async::Ready(Some(self.bytes.slice(self.pos, self.pos + 1))));
|
||||
self.pos += 1;
|
||||
self.ready = false;
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
fn create_simple_request_with_header() -> (Bytes, HeaderMap) {
|
||||
let bytes = Bytes::from(
|
||||
"testasdadsad\r\n\
|
||||
@ -965,16 +1001,38 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
// Retries on NotReady
|
||||
fn loop_poll<T>(stream: &mut T) -> Poll<Option<T::Item>, T::Error>
|
||||
where T: Stream {
|
||||
loop {
|
||||
let r = stream.poll();
|
||||
match r {
|
||||
Ok(Async::NotReady) => continue,
|
||||
_ => return r,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loops polling, collecting all bytes until end-of-field
|
||||
fn get_whole_field(field: &mut Field) -> BytesMut {
|
||||
let mut b = BytesMut::new();
|
||||
loop {
|
||||
match loop_poll(field) {
|
||||
Ok(Async::Ready(Some(chunk))) => b.extend_from_slice(&chunk),
|
||||
Ok(Async::Ready(None)) => return b,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stream() {
|
||||
run_on(|| {
|
||||
let (sender, payload) = create_stream();
|
||||
let (bytes, headers) = create_simple_request_with_header();
|
||||
|
||||
sender.unbounded_send(Ok(bytes)).unwrap();
|
||||
let payload = SlowStream::new(bytes);
|
||||
|
||||
let mut multipart = Multipart::new(&headers, payload);
|
||||
match multipart.poll().unwrap() {
|
||||
match loop_poll(&mut multipart).unwrap() {
|
||||
Async::Ready(Some(mut field)) => {
|
||||
let cd = field.content_disposition().unwrap();
|
||||
assert_eq!(cd.disposition, DispositionType::FormData);
|
||||
@ -983,39 +1041,20 @@ mod tests {
|
||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||
|
||||
match field.poll().unwrap() {
|
||||
Async::Ready(Some(chunk)) => assert_eq!(chunk, "test"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
match field.poll().unwrap() {
|
||||
Async::Ready(None) => (),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert_eq!(get_whole_field(&mut field), "test");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
match multipart.poll().unwrap() {
|
||||
match loop_poll(&mut multipart).unwrap() {
|
||||
Async::Ready(Some(mut field)) => {
|
||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||
|
||||
match field.poll() {
|
||||
Ok(Async::Ready(Some(chunk))) => assert_eq!(chunk, "data"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
match field.poll() {
|
||||
Ok(Async::Ready(None)) => (),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert_eq!(get_whole_field(&mut field), "data");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
match multipart.poll().unwrap() {
|
||||
Async::Ready(None) => (),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.3] - 2019-11-14
|
||||
|
||||
* Update actix-web and actix-http dependencies
|
||||
|
||||
## [1.0.2] - 2019-07-20
|
||||
|
||||
* Add `ws::start_with_addr()`, returning the address of the created actor, along
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-web-actors"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix actors support for actix web framework."
|
||||
readme = "README.md"
|
||||
@ -19,8 +19,8 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix = "0.8.3"
|
||||
actix-web = "1.0.3"
|
||||
actix-http = "0.2.5"
|
||||
actix-web = "1.0.9"
|
||||
actix-http = "0.2.11"
|
||||
actix-codec = "0.1.2"
|
||||
bytes = "0.4"
|
||||
futures = "0.1.25"
|
||||
|
@ -1,9 +1,10 @@
|
||||
# Changes
|
||||
|
||||
## [0.2.8] - 2019-10-24
|
||||
## [0.2.8] - 2019-11-06
|
||||
|
||||
* Add support for setting query from Serialize type for client request.
|
||||
|
||||
|
||||
## [0.2.7] - 2019-09-25
|
||||
|
||||
### Added
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "awc"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix http client."
|
||||
readme = "README.md"
|
||||
@ -44,7 +44,7 @@ flate2-rust = ["actix-http/flate2-rust"]
|
||||
[dependencies]
|
||||
actix-codec = "0.1.2"
|
||||
actix-service = "0.4.1"
|
||||
actix-http = "0.2.10"
|
||||
actix-http = "0.2.11"
|
||||
base64 = "0.10.1"
|
||||
bytes = "0.4"
|
||||
derive_more = "0.15.0"
|
||||
@ -62,8 +62,8 @@ rustls = { version = "0.15.2", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "0.2.2"
|
||||
actix-web = { version = "1.0.0", features=["ssl"] }
|
||||
actix-http = { version = "0.2.10", features=["ssl"] }
|
||||
actix-web = { version = "1.0.8", features=["ssl"] }
|
||||
actix-http = { version = "0.2.11", features=["ssl"] }
|
||||
actix-http-test = { version = "0.2.0", features=["ssl"] }
|
||||
actix-utils = "0.4.1"
|
||||
actix-server = { version = "0.6.0", features=["ssl", "rust-tls"] }
|
||||
|
@ -162,6 +162,12 @@ impl ConnectionInfo {
|
||||
/// - Forwarded
|
||||
/// - X-Forwarded-For
|
||||
/// - peer name of opened socket
|
||||
///
|
||||
/// # Security
|
||||
/// Do not use this function for security purposes, unless you can ensure the Forwarded and
|
||||
/// X-Forwarded-For headers cannot be spoofed by the client. If you want the client's socket
|
||||
/// address explicitly, use
|
||||
/// [`HttpRequest::peer_addr()`](../web/struct.HttpRequest.html#method.peer_addr) instead.
|
||||
#[inline]
|
||||
pub fn remote(&self) -> Option<&str> {
|
||||
if let Some(ref r) = self.remote {
|
||||
|
Reference in New Issue
Block a user