From 6db625f55b17725a4ba8d6c336e384bcb5e68b01 Mon Sep 17 00:00:00 2001 From: Miles Granger Date: Sat, 25 May 2019 10:52:23 +0200 Subject: [PATCH 01/34] Update actix-web dep to 1.0.0-rc (#864) --- actix-files/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 6b065758d..de79946a4 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -18,7 +18,7 @@ name = "actix_files" path = "src/lib.rs" [dependencies] -actix-web = "1.0.0-beta.5" +actix-web = "1.0.0-rc" actix-service = "0.4.0" bitflags = "1" bytes = "0.4" From 35eb378585087a9db5e1eaa6206b0864e7a42883 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 25 May 2019 02:02:28 -0700 Subject: [PATCH 02/34] prepare actix-files release --- actix-files/CHANGES.md | 2 +- actix-files/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index e8457f42f..021f8dc63 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -1,6 +1,6 @@ # Changes -## [0.1.0] - 2019-05-xx +## [0.1.0] - 2019-05-25 * NamedFile last-modified check always fails due to nano-seconds in file modified date #820 diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index de79946a4..9ffbf0e7a 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-files" -version = "0.1.0-beta.4" +version = "0.1.0" authors = ["Nikolay Kim "] description = "Static files support for actix web." readme = "README.md" @@ -31,4 +31,4 @@ percent-encoding = "1.0" v_htmlescape = "0.4" [dev-dependencies] -actix-web = { version = "1.0.0-beta.5", features=["ssl"] } +actix-web = { version = "1.0.0-rc", features=["ssl"] } From 3f196f469d115af8053ae4ca99f3001eae5eeb81 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 25 May 2019 02:13:04 -0700 Subject: [PATCH 03/34] update version --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0bf6e7c9b..815aeb5a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "1.0.0-rc" +version = "1.0.0" authors = ["Nikolay Kim "] description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust." readme = "README.md" @@ -102,7 +102,7 @@ rustls = { version = "0.15", optional = true } [dev-dependencies] actix-http = { version = "0.2.0", features=["ssl", "brotli", "flate2-zlib"] } actix-http-test = { version = "0.2.0", features=["ssl"] } -actix-files = { version = "0.1.0-beta.4" } +actix-files = { version = "0.1.0" } rand = "0.6" env_logger = "0.6" serde_derive = "1.0" From 7f12b754e9aabc0cbfd02eaee9512bc19ed20bb4 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 25 May 2019 03:07:40 -0700 Subject: [PATCH 04/34] Handle socket read disconnect --- actix-http/CHANGES.md | 7 +++++++ actix-http/Cargo.toml | 4 ++-- actix-http/src/h1/dispatcher.rs | 8 +++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 61c211b26..b3d8604c0 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,5 +1,12 @@ # Changes +## [0.2.1] - 2019-05-2 + +### Fixed + +* Handle socket read disconnect + + ## [0.2.0] - 2019-05-12 ### Changed diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index fabf7fe92..b4bfabec5 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "0.2.0" +version = "0.2.1" authors = ["Nikolay Kim "] description = "Actix http primitives" readme = "README.md" @@ -47,7 +47,7 @@ secure-cookies = ["ring"] actix-service = "0.4.0" actix-codec = "0.1.2" actix-connect = "0.2.0" -actix-utils = "0.4.0" +actix-utils = "0.4.1" actix-server-config = "0.1.1" actix-threadpool = "0.1.0" diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index ec717ae07..131811a9e 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -583,6 +583,9 @@ where self.ka_timer = Some(Delay::new(interval)); } else { self.flags.insert(Flags::READ_DISCONNECT); + if let Some(mut payload) = self.payload.take() { + payload.set_error(PayloadError::Incomplete(None)); + } return Ok(()); } } else { @@ -694,7 +697,10 @@ where if let Some(true) = read_available(&mut inner.io, &mut inner.read_buf)? { - inner.flags.insert(Flags::READ_DISCONNECT) + inner.flags.insert(Flags::READ_DISCONNECT); + if let Some(mut payload) = inner.payload.take() { + payload.feed_eof(); + } } } From aa626a1e7281c22aebadbc296e2f8510eb1965dd Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 25 May 2019 03:16:46 -0700 Subject: [PATCH 05/34] handle disconnects --- actix-multipart/CHANGES.md | 6 +++- actix-multipart/Cargo.toml | 2 +- actix-multipart/src/server.rs | 64 ++++++++++++++++++++++------------- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 3a959890a..cf32859e3 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -1,12 +1,16 @@ # Changes +## [0.1.1] - 2019-05-25 + +* Fix disconnect handling #834 + ## [0.1.0] - 2019-05-18 * Release ## [0.1.0-beta.4] - 2019-05-12 -* Handle cancellation of uploads #834 #736 +* Handle cancellation of uploads #736 * Upgrade to actix-web 1.0.0-beta.4 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index ca1ff9c91..fe63d5361 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.1.0" +version = "0.1.1" authors = ["Nikolay Kim "] description = "Multipart support for actix web framework." readme = "README.md" diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 7d746ea2f..8245d241e 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -128,7 +128,7 @@ impl InnerMultipart { fn read_headers( payload: &mut PayloadBuffer, ) -> Result, MultipartError> { - match payload.read_until(b"\r\n\r\n") { + match payload.read_until(b"\r\n\r\n")? { None => { if payload.eof { Err(MultipartError::Incomplete) @@ -167,7 +167,7 @@ impl InnerMultipart { boundary: &str, ) -> Result, MultipartError> { // TODO: need to read epilogue - match payload.readline() { + match payload.readline()? { None => { if payload.eof { Ok(Some(true)) @@ -200,7 +200,7 @@ impl InnerMultipart { ) -> Result, MultipartError> { let mut eof = false; loop { - match payload.readline() { + match payload.readline()? { Some(chunk) => { if chunk.is_empty() { return Err(MultipartError::Boundary); @@ -481,7 +481,7 @@ impl InnerField { if *size == 0 { Ok(Async::Ready(None)) } else { - match payload.read_max(*size) { + match payload.read_max(*size)? { Some(mut chunk) => { let len = cmp::min(chunk.len() as u64, *size); *size -= len; @@ -512,7 +512,11 @@ impl InnerField { let len = payload.buf.len(); if len == 0 { - return Ok(Async::NotReady); + return if payload.eof { + Err(MultipartError::Incomplete) + } else { + Ok(Async::NotReady) + }; } // check boundary @@ -597,7 +601,7 @@ impl InnerField { } } - match payload.readline() { + match payload.readline()? { None => Async::Ready(None), Some(line) => { if line.as_ref() != b"\r\n" { @@ -749,23 +753,31 @@ impl PayloadBuffer { } } - fn read_max(&mut self, size: u64) -> Option { + fn read_max(&mut self, size: u64) -> Result, MultipartError> { if !self.buf.is_empty() { let size = std::cmp::min(self.buf.len() as u64, size) as usize; - Some(self.buf.split_to(size).freeze()) + Ok(Some(self.buf.split_to(size).freeze())) + } else if self.eof { + Err(MultipartError::Incomplete) } else { - None + Ok(None) } } /// Read until specified ending - pub fn read_until(&mut self, line: &[u8]) -> Option { - twoway::find_bytes(&self.buf, line) - .map(|idx| self.buf.split_to(idx + line.len()).freeze()) + pub fn read_until(&mut self, line: &[u8]) -> Result, MultipartError> { + let res = twoway::find_bytes(&self.buf, line) + .map(|idx| self.buf.split_to(idx + line.len()).freeze()); + + if res.is_none() && self.eof { + Err(MultipartError::Incomplete) + } else { + Ok(res) + } } /// Read bytes until new line delimiter - pub fn readline(&mut self) -> Option { + pub fn readline(&mut self) -> Result, MultipartError> { self.read_until(b"\n") } @@ -991,7 +1003,7 @@ mod tests { assert_eq!(payload.buf.len(), 0); payload.poll_stream().unwrap(); - assert_eq!(None, payload.read_max(1)); + assert_eq!(None, payload.read_max(1).unwrap()); }) } @@ -1001,14 +1013,14 @@ mod tests { let (mut sender, payload) = Payload::create(false); let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_max(4)); + assert_eq!(None, payload.read_max(4).unwrap()); sender.feed_data(Bytes::from("data")); sender.feed_eof(); payload.poll_stream().unwrap(); - assert_eq!(Some(Bytes::from("data")), payload.read_max(4)); + assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap()); assert_eq!(payload.buf.len(), 0); - assert_eq!(None, payload.read_max(1)); + assert!(payload.read_max(1).is_err()); assert!(payload.eof); }) } @@ -1018,7 +1030,7 @@ mod tests { run_on(|| { let (mut sender, payload) = Payload::create(false); let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_max(1)); + assert_eq!(None, payload.read_max(1).unwrap()); sender.set_error(PayloadError::Incomplete(None)); payload.poll_stream().err().unwrap(); }) @@ -1035,10 +1047,10 @@ mod tests { payload.poll_stream().unwrap(); assert_eq!(payload.buf.len(), 10); - assert_eq!(Some(Bytes::from("line1")), payload.read_max(5)); + assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap()); assert_eq!(payload.buf.len(), 5); - assert_eq!(Some(Bytes::from("line2")), payload.read_max(5)); + assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap()); assert_eq!(payload.buf.len(), 0); }) } @@ -1069,16 +1081,22 @@ mod tests { let (mut sender, payload) = Payload::create(false); let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_until(b"ne")); + assert_eq!(None, payload.read_until(b"ne").unwrap()); sender.feed_data(Bytes::from("line1")); sender.feed_data(Bytes::from("line2")); payload.poll_stream().unwrap(); - assert_eq!(Some(Bytes::from("line")), payload.read_until(b"ne")); + assert_eq!( + Some(Bytes::from("line")), + payload.read_until(b"ne").unwrap() + ); assert_eq!(payload.buf.len(), 6); - assert_eq!(Some(Bytes::from("1line2")), payload.read_until(b"2")); + assert_eq!( + Some(Bytes::from("1line2")), + payload.read_until(b"2").unwrap() + ); assert_eq!(payload.buf.len(), 0); }) } From 1eb89b83751b14267d935aae0d82af565c2bc9d1 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 25 May 2019 03:16:53 -0700 Subject: [PATCH 06/34] remove debug prints --- actix-http/CHANGES.md | 2 +- src/app_service.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index b3d8604c0..041596c31 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,6 +1,6 @@ # Changes -## [0.2.1] - 2019-05-2 +## [0.2.1] - 2019-05-25 ### Fixed diff --git a/src/app_service.rs b/src/app_service.rs index 88e97de1e..5a9731bf2 100644 --- a/src/app_service.rs +++ b/src/app_service.rs @@ -239,7 +239,6 @@ where { fn drop(&mut self) { self.pool.clear(); - println!("DROP: APP-INIT-ENTRY"); } } @@ -436,7 +435,6 @@ mod tests { impl Drop for DropData { fn drop(&mut self) { self.0.store(true, Ordering::Relaxed); - println!("Dropping!"); } } From a614be7cb5c603523b0b509e2a30cde27bc58392 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Wed, 29 May 2019 18:37:42 +0200 Subject: [PATCH 07/34] Don't DISCONNECT from stream when reader is empty (#870) * Don't DISCONNECT from stream when reader is empty * Fix chunked transfer: poll_request before closing stream + Test --- actix-http/src/h1/dispatcher.rs | 22 +++++++------- actix-http/tests/test_server.rs | 51 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index 131811a9e..b7b9db2d7 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -693,18 +693,20 @@ where } } else { // read socket into a buf - if !inner.flags.contains(Flags::READ_DISCONNECT) { - if let Some(true) = - read_available(&mut inner.io, &mut inner.read_buf)? - { - inner.flags.insert(Flags::READ_DISCONNECT); - if let Some(mut payload) = inner.payload.take() { - payload.feed_eof(); - } - } - } + let should_disconnect = if !inner.flags.contains(Flags::READ_DISCONNECT) { + read_available(&mut inner.io, &mut inner.read_buf)? + } else { + None + }; inner.poll_request()?; + if let Some(true) = should_disconnect { + inner.flags.insert(Flags::READ_DISCONNECT); + if let Some(mut payload) = inner.payload.take() { + payload.feed_eof(); + } + }; + loop { if inner.write_buf.remaining_mut() < LW_BUFFER_SIZE { inner.write_buf.reserve(HW_BUFFER_SIZE); diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index d0c5e3526..a299f58d7 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -9,6 +9,7 @@ use actix_service::{new_service_cfg, service_fn, NewService}; use bytes::{Bytes, BytesMut}; use futures::future::{self, ok, Future}; use futures::stream::{once, Stream}; +use regex::Regex; use tokio_timer::sleep; use actix_http::body::Body; @@ -215,6 +216,56 @@ fn test_expect_continue_h1() { assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n")); } +#[test] +fn test_chunked_payload() { + let chunk_sizes = vec![ 32768, 32, 32768 ]; + let total_size: usize = chunk_sizes.iter().sum(); + + let srv = TestServer::new(|| { + HttpService::build() + .h1(|mut request: Request| { + request.take_payload() + .map_err(|e| panic!(format!("Error reading payload: {}", e))) + .fold(0usize, |acc, chunk| { + future::ok::<_, ()>(acc + chunk.len()) + }) + .map(|req_size| { + Response::Ok().body(format!("size={}", req_size)) + }) + }) + }); + + let returned_size = { + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"); + + for chunk_size in chunk_sizes.iter() { + let mut bytes = Vec::new(); + let random_bytes: Vec = (0..*chunk_size).map(|_| rand::random::()).collect(); + + bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes()); + bytes.extend(&random_bytes[..]); + bytes.extend(b"\r\n"); + let _ = stream.write_all(&bytes); + } + + let _ = stream.write_all(b"0\r\n\r\n"); + stream.shutdown(net::Shutdown::Write).unwrap(); + + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + + let re = Regex::new(r"size=(\d+)").unwrap(); + let size: usize = match re.captures(&data) { + Some(caps) => caps.get(1).unwrap().as_str().parse().unwrap(), + None => panic!(format!("Failed to find size in HTTP Response: {}", data)), + }; + size + }; + + assert_eq!(returned_size, total_size); +} + #[test] fn test_slow_request() { let srv = TestServer::new(|| { From fe781345d5eb0c491039a4250a8a4862898a19b0 Mon Sep 17 00:00:00 2001 From: octave99 <36263355+octave99@users.noreply.github.com> Date: Wed, 29 May 2019 16:47:04 +0000 Subject: [PATCH 08/34] Add Migration steps for Custom Error (#869) Adds migration steps for custom error in 1.0 --- MIGRATION.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 73669ddb8..1736ee65d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -238,6 +238,17 @@ * Actors support have been moved to `actix-web-actors` crate +* Custom Error + + Instead of error_response method alone, ResponseError now provides two methods: error_response and render_response respectively. Where, error_response creates the error response and render_response returns the error response to the caller. + + Simplest migration from 0.7 to 1.0 shall include below method to the custom implementation of ResponseError: + + ```rust + fn render_response(&self) -> HttpResponse { + self.error_response() + } + ``` ## 0.7.15 From 21418c7414d007372615dcadd14bf17d93d5858a Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 29 May 2019 16:15:12 -0700 Subject: [PATCH 09/34] prep actix-http release --- actix-http/CHANGES.md | 7 +++++++ actix-http/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 041596c31..edc075b92 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,5 +1,12 @@ # Changes +## [0.2.2] - 2019-05-29 + +### Fixed + +* Parse incoming stream before closing stream on disconnect #868 + + ## [0.2.1] - 2019-05-25 ### Fixed diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index b4bfabec5..187d84da1 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "0.2.1" +version = "0.2.2" authors = ["Nikolay Kim "] description = "Actix http primitives" readme = "README.md" From c2d7db7e069568df0bb9c0fbf69d30e7dd875683 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 29 May 2019 16:22:57 -0700 Subject: [PATCH 10/34] prepare actix-web-actors release --- Cargo.toml | 4 ++-- actix-http/Cargo.toml | 2 +- actix-web-actors/CHANGES.md | 4 ++++ actix-web-actors/Cargo.toml | 8 ++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 815aeb5a4..829277654 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ actix-utils = "0.4.1" actix-router = "0.1.5" actix-rt = "0.2.2" actix-web-codegen = "0.1.0" -actix-http = "0.2.0" +actix-http = "0.2.2" actix-server = "0.5.1" actix-server-config = "0.1.1" actix-threadpool = "0.1.0" @@ -100,7 +100,7 @@ openssl = { version="0.10", optional = true } rustls = { version = "0.15", optional = true } [dev-dependencies] -actix-http = { version = "0.2.0", features=["ssl", "brotli", "flate2-zlib"] } +actix-http = { version = "0.2.2", features=["ssl", "brotli", "flate2-zlib"] } actix-http-test = { version = "0.2.0", features=["ssl"] } actix-files = { version = "0.1.0" } rand = "0.6" diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 187d84da1..6a020eae3 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -81,7 +81,7 @@ time = "0.1.42" tokio-tcp = "0.1.3" tokio-timer = "0.2.8" tokio-current-thread = "0.1" -trust-dns-resolver = { version="0.11.0", default-features = false } +trust-dns-resolver = { version="0.11.1", default-features = false } # for secure cookie ring = { version = "0.14.6", optional = true } diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index 34592aafc..89b4be818 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [1.0.0] - 2019-05-29 + +* Update actix-http and actix-web + ## [0.1.0-alpha.3] - 2019-04-02 * Update actix-http and actix-web diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml index 0341641a3..565b53a57 100644 --- a/actix-web-actors/Cargo.toml +++ b/actix-web-actors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-actors" -version = "1.0.0-beta.4" +version = "1.0.0" authors = ["Nikolay Kim "] description = "Actix actors support for actix web framework." readme = "README.md" @@ -18,9 +18,9 @@ name = "actix_web_actors" path = "src/lib.rs" [dependencies] -actix = "0.8.2" -actix-web = "1.0.0-beta.5" -actix-http = "0.2.0" +actix = "0.8.3" +actix-web = "1.0.0-rc" +actix-http = "0.2.2" actix-codec = "0.1.2" bytes = "0.4" futures = "0.1.25" From f1764bba435e525df5cc06ea0c3972c7317e7078 Mon Sep 17 00:00:00 2001 From: Mohab Usama Date: Fri, 31 May 2019 10:09:21 +0200 Subject: [PATCH 11/34] Fix Logger time format (use rfc3339) (#867) * Fix Logger time format (use rfc3339) * Update change log --- CHANGES.md | 2 ++ src/middleware/logger.rs | 32 +++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5974ee69a..0dc7be27c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,8 @@ ### Fixed +* Fix Logger request time format, and use rfc3339. #867 + * Clear http requests pool on app service drop #860 diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index 5d0b615e1..d47e45023 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -53,7 +53,7 @@ use crate::HttpResponse; /// /// `%a` Remote IP-address (IP-address of proxy if using reverse proxy) /// -/// `%t` Time when the request was started to process +/// `%t` Time when the request was started to process (in rfc3339 format) /// /// `%r` First line of request /// @@ -417,10 +417,7 @@ impl FormatText { } FormatText::UrlPath => *self = FormatText::Str(format!("{}", req.path())), FormatText::RequestTime => { - *self = FormatText::Str(format!( - "{:?}", - now.strftime("[%d/%b/%Y:%H:%M:%S %z]").unwrap() - )) + *self = FormatText::Str(format!("{}", now.rfc3339())) } FormatText::RequestHeader(ref name) => { let s = if let Some(val) = req.headers().get(name) { @@ -547,4 +544,29 @@ mod tests { assert!(s.contains("200 1024")); assert!(s.contains("ACTIX-WEB")); } + + #[test] + fn test_request_time_format() { + let mut format = Format::new("%t"); + let req = TestRequest::default().to_srv_request(); + + let now = time::now(); + for unit in &mut format.0 { + unit.render_request(now, &req); + } + + let resp = HttpResponse::build(StatusCode::OK).force_close().finish(); + for unit in &mut format.0 { + unit.render_response(&resp); + } + + let render = |fmt: &mut Formatter| { + for unit in &format.0 { + unit.render(fmt, 1024, now)?; + } + Ok(()) + }; + let s = format!("{}", FormatDisplay(&render)); + assert!(s.contains(&format!("{}", now.rfc3339()))); + } } From 7753b9da6dcb21ed7e7a56022869208447680319 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Sat, 1 Jun 2019 10:13:45 +0200 Subject: [PATCH 12/34] web-codegen: Add extra-traits to syn features (#879) ```rust error[E0277]: `syn::attr::NestedMeta` doesn't implement `std::fmt::Debug` --> src/route.rs:149:57 | 149 | attr => panic!("Unknown attribute{:?}", attr), | ^^^^ `syn::attr::NestedMeta` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `std::fmt::Debug` is not implemented for `syn::attr::NestedMeta` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&syn::attr::NestedMeta` = note: required by `std::fmt::Debug::fmt` ``` --- actix-web-codegen/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 5ca9f416d..8b9f8d1bd 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] quote = "0.6" -syn = { version = "0.15", features = ["full", "parsing"] } +syn = { version = "0.15", features = ["full", "parsing", "extra-traits"] } [dev-dependencies] actix-web = { version = "1.0.0-beta.5" } From 29a0fe76d5d6b4ba778fe92f15e51be7e8edd117 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 1 Jun 2019 17:21:22 +0600 Subject: [PATCH 13/34] prepare actix-web-codegen release --- actix-web-codegen/CHANGES.md | 4 ++++ actix-web-codegen/Cargo.toml | 10 +++++----- actix-web-codegen/LICENSE-APACHE | 1 + actix-web-codegen/LICENSE-MIT | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) create mode 120000 actix-web-codegen/LICENSE-APACHE create mode 120000 actix-web-codegen/LICENSE-MIT diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 4f2d1c865..ac1861118 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.1] - 2019-06-01 + +* Add syn "extra-traits" feature + ## [0.1.0] - 2019-05-18 * Release diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 8b9f8d1bd..5557441c4 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-codegen" -version = "0.1.0" +version = "0.1.1" description = "Actix web proc macros" readme = "README.md" authors = ["Nikolay Kim "] @@ -12,11 +12,11 @@ workspace = ".." proc-macro = true [dependencies] -quote = "0.6" -syn = { version = "0.15", features = ["full", "parsing", "extra-traits"] } +quote = "0.6.12" +syn = { version = "0.15.34", features = ["full", "parsing", "extra-traits"] } [dev-dependencies] -actix-web = { version = "1.0.0-beta.5" } -actix-http = { version = "0.2.0", features=["ssl"] } +actix-web = { version = "1.0.0-rc" } +actix-http = { version = "0.2.2", features=["ssl"] } actix-http-test = { version = "0.2.0", features=["ssl"] } futures = { version = "0.1" } diff --git a/actix-web-codegen/LICENSE-APACHE b/actix-web-codegen/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/actix-web-codegen/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/actix-web-codegen/LICENSE-MIT b/actix-web-codegen/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/actix-web-codegen/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file From a1b40f431481e0f41a73f4808c33241708abeb9f Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 1 Jun 2019 17:25:29 +0600 Subject: [PATCH 14/34] add license files --- Cargo.toml | 2 +- actix-files/LICENSE-APACHE | 1 + actix-files/LICENSE-MIT | 1 + actix-multipart/LICENSE-APACHE | 1 + actix-multipart/LICENSE-MIT | 1 + actix-session/LICENSE-APACHE | 1 + actix-session/LICENSE-MIT | 1 + actix-web-actors/LICENSE-APACHE | 1 + actix-web-actors/LICENSE-MIT | 1 + awc/LICENSE-APACHE | 1 + awc/LICENSE-MIT | 1 + test-server/LICENSE-APACHE | 1 + test-server/LICENSE-MIT | 1 + 13 files changed, 13 insertions(+), 1 deletion(-) create mode 120000 actix-files/LICENSE-APACHE create mode 120000 actix-files/LICENSE-MIT create mode 120000 actix-multipart/LICENSE-APACHE create mode 120000 actix-multipart/LICENSE-MIT create mode 120000 actix-session/LICENSE-APACHE create mode 120000 actix-session/LICENSE-MIT create mode 120000 actix-web-actors/LICENSE-APACHE create mode 120000 actix-web-actors/LICENSE-MIT create mode 120000 awc/LICENSE-APACHE create mode 120000 awc/LICENSE-MIT create mode 120000 test-server/LICENSE-APACHE create mode 120000 test-server/LICENSE-MIT diff --git a/Cargo.toml b/Cargo.toml index 829277654..e8fdb1362 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,7 +72,7 @@ actix-service = "0.4.0" actix-utils = "0.4.1" actix-router = "0.1.5" actix-rt = "0.2.2" -actix-web-codegen = "0.1.0" +actix-web-codegen = "0.1.1" actix-http = "0.2.2" actix-server = "0.5.1" actix-server-config = "0.1.1" diff --git a/actix-files/LICENSE-APACHE b/actix-files/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/actix-files/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/actix-files/LICENSE-MIT b/actix-files/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/actix-files/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/actix-multipart/LICENSE-APACHE b/actix-multipart/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/actix-multipart/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/actix-multipart/LICENSE-MIT b/actix-multipart/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/actix-multipart/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/actix-session/LICENSE-APACHE b/actix-session/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/actix-session/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/actix-session/LICENSE-MIT b/actix-session/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/actix-session/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/actix-web-actors/LICENSE-APACHE b/actix-web-actors/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/actix-web-actors/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/actix-web-actors/LICENSE-MIT b/actix-web-actors/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/actix-web-actors/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/awc/LICENSE-APACHE b/awc/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/awc/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/awc/LICENSE-MIT b/awc/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/awc/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/test-server/LICENSE-APACHE b/test-server/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/test-server/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/test-server/LICENSE-MIT b/test-server/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/test-server/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file From 666756bfbe1a6ed5e17cee567320f603af7b3cf9 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 1 Jun 2019 17:57:25 +0600 Subject: [PATCH 15/34] body helpers --- actix-http/CHANGES.md | 10 +++++++++ actix-http/src/body.rs | 25 +++++++++++++++++++--- actix-http/src/response.rs | 19 +++++++++++++++++ actix-http/tests/test_server.rs | 37 +++++++++++++++------------------ 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index edc075b92..e677c3fa6 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,5 +1,15 @@ # Changes +### Added + +* Debug impl for ResponseBuilder + +* From SizedStream and BodyStream for Body + +### Changed + +* SizedStream accepts u64 + ## [0.2.2] - 2019-05-29 ### Fixed diff --git a/actix-http/src/body.rs b/actix-http/src/body.rs index 0652dd274..e728cdb98 100644 --- a/actix-http/src/body.rs +++ b/actix-http/src/body.rs @@ -234,6 +234,25 @@ impl From for Body { } } +impl From> for Body +where + S: Stream + 'static, +{ + fn from(s: SizedStream) -> Body { + Body::from_message(s) + } +} + +impl From> for Body +where + S: Stream + 'static, + E: Into + 'static, +{ + fn from(s: BodyStream) -> Body { + Body::from_message(s) + } +} + impl MessageBody for Bytes { fn size(&self) -> BodySize { BodySize::Sized(self.len()) @@ -366,7 +385,7 @@ where /// Type represent streaming body. This body implementation should be used /// if total size of stream is known. Data get sent as is without using transfer encoding. pub struct SizedStream { - size: usize, + size: u64, stream: S, } @@ -374,7 +393,7 @@ impl SizedStream where S: Stream, { - pub fn new(size: usize, stream: S) -> Self { + pub fn new(size: u64, stream: S) -> Self { SizedStream { size, stream } } } @@ -384,7 +403,7 @@ where S: Stream, { fn size(&self) -> BodySize { - BodySize::Sized(self.size) + BodySize::Sized64(self.size) } fn poll_next(&mut self) -> Poll, Error> { diff --git a/actix-http/src/response.rs b/actix-http/src/response.rs index fd51e54c7..ce986a472 100644 --- a/actix-http/src/response.rs +++ b/actix-http/src/response.rs @@ -764,6 +764,25 @@ impl IntoFuture for ResponseBuilder { } } +impl fmt::Debug for ResponseBuilder { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let head = self.head.as_ref().unwrap(); + + let res = writeln!( + f, + "\nResponseBuilder {:?} {}{}", + head.version, + head.status, + head.reason.unwrap_or(""), + ); + let _ = writeln!(f, " headers:"); + for (key, val) in head.headers.iter() { + let _ = writeln!(f, " {:?}: {:?}", key, val); + } + res + } +} + /// Helper converters impl, E: Into> From> for Response { fn from(res: Result) -> Self { diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index a299f58d7..4a679f4b9 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -12,7 +12,6 @@ use futures::stream::{once, Stream}; use regex::Regex; use tokio_timer::sleep; -use actix_http::body::Body; use actix_http::error::PayloadError; use actix_http::{ body, error, http, http::header, Error, HttpService, KeepAlive, Request, Response, @@ -218,30 +217,28 @@ fn test_expect_continue_h1() { #[test] fn test_chunked_payload() { - let chunk_sizes = vec![ 32768, 32, 32768 ]; + let chunk_sizes = vec![32768, 32, 32768]; let total_size: usize = chunk_sizes.iter().sum(); let srv = TestServer::new(|| { - HttpService::build() - .h1(|mut request: Request| { - request.take_payload() - .map_err(|e| panic!(format!("Error reading payload: {}", e))) - .fold(0usize, |acc, chunk| { - future::ok::<_, ()>(acc + chunk.len()) - }) - .map(|req_size| { - Response::Ok().body(format!("size={}", req_size)) - }) - }) + HttpService::build().h1(|mut request: Request| { + request + .take_payload() + .map_err(|e| panic!(format!("Error reading payload: {}", e))) + .fold(0usize, |acc, chunk| future::ok::<_, ()>(acc + chunk.len())) + .map(|req_size| Response::Ok().body(format!("size={}", req_size))) + }) }); let returned_size = { let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"); + let _ = stream + .write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"); for chunk_size in chunk_sizes.iter() { let mut bytes = Vec::new(); - let random_bytes: Vec = (0..*chunk_size).map(|_| rand::random::()).collect(); + let random_bytes: Vec = + (0..*chunk_size).map(|_| rand::random::()).collect(); bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes()); bytes.extend(&random_bytes[..]); @@ -826,8 +823,7 @@ fn test_h1_body_length() { HttpService::build().h1(|_| { let body = once(Ok(Bytes::from_static(STR.as_ref()))); ok::<_, ()>( - Response::Ok() - .body(Body::from_message(body::SizedStream::new(STR.len(), body))), + Response::Ok().body(body::SizedStream::new(STR.len() as u64, body)), ) }) }); @@ -852,9 +848,10 @@ fn test_h2_body_length() { HttpService::build() .h2(|_| { let body = once(Ok(Bytes::from_static(STR.as_ref()))); - ok::<_, ()>(Response::Ok().body(Body::from_message( - body::SizedStream::new(STR.len(), body), - ))) + ok::<_, ()>( + Response::Ok() + .body(body::SizedStream::new(STR.len() as u64, body)), + ) }) .map_err(|_| ()), ) From 15cdc680f6f1b1ba6454974838f6022e7e20b3e3 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 1 Jun 2019 17:57:40 +0600 Subject: [PATCH 16/34] Static files are incorrectly served as both chunked and with length #812 --- actix-files/CHANGES.md | 4 ++++ actix-files/Cargo.toml | 1 + actix-files/src/named.rs | 3 ++- src/lib.rs | 4 ++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index 021f8dc63..c77494575 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.1] - 2019-06-01 + +* Static files are incorrectly served as both chunked and with length #812 + ## [0.1.0] - 2019-05-25 * NamedFile last-modified check always fails due to nano-seconds diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 9ffbf0e7a..fa48fff08 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -19,6 +19,7 @@ path = "src/lib.rs" [dependencies] actix-web = "1.0.0-rc" +actix-http = "0.2.2" actix-service = "0.4.0" bitflags = "1" bytes = "0.4" diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index 2298e35af..29e9eee41 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -11,6 +11,7 @@ use bitflags::bitflags; use mime; use mime_guess::guess_mime_type; +use actix_http::body::SizedStream; use actix_web::http::header::{ self, ContentDisposition, DispositionParam, DispositionType, }; @@ -434,7 +435,7 @@ impl Responder for NamedFile { if offset != 0 || length != self.md.len() { return Ok(resp.status(StatusCode::PARTIAL_CONTENT).streaming(reader)); }; - Ok(resp.streaming(reader)) + Ok(resp.body(SizedStream::new(length, reader))) } } } diff --git a/src/lib.rs b/src/lib.rs index f84dbd5be..0e4a421ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,7 +111,7 @@ pub use actix_web_codegen::*; // re-export for convenience pub use actix_http::Response as HttpResponse; -pub use actix_http::{cookie, http, Error, HttpMessage, ResponseError, Result}; +pub use actix_http::{body, cookie, http, Error, HttpMessage, ResponseError, Result}; pub use crate::app::App; pub use crate::extract::FromRequest; @@ -143,7 +143,7 @@ pub mod dev { pub use crate::types::json::JsonBody; pub use crate::types::readlines::Readlines; - pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody}; + pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody, SizedStream}; pub use actix_http::encoding::Decoder as Decompress; pub use actix_http::ResponseBuilder as HttpResponseBuilder; pub use actix_http::{ From 24180f9014e8e041e2e4d711c4f92a16be1751bf Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sun, 2 Jun 2019 12:58:37 +0600 Subject: [PATCH 17/34] Fix boundary parsing #876 --- actix-multipart/CHANGES.md | 4 ++++ actix-multipart/Cargo.toml | 4 ++-- actix-multipart/src/server.rs | 4 +--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index cf32859e3..751bc1269 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.2] - 2019-06-02 + +* Fix boundary parsing #876 + ## [0.1.1] - 2019-05-25 * Fix disconnect handling #834 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index fe63d5361..9bb1179d8 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.1.1" +version = "0.1.2" authors = ["Nikolay Kim "] description = "Multipart support for actix web framework." readme = "README.md" @@ -31,4 +31,4 @@ twoway = "0.2" [dev-dependencies] actix-rt = "0.2.2" -actix-http = "0.2.0" \ No newline at end of file +actix-http = "0.2.2" \ No newline at end of file diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 8245d241e..e1a5543d4 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -537,8 +537,6 @@ impl InnerField { if &payload.buf[b_len..b_size] == boundary.as_bytes() { // found boundary return Ok(Async::Ready(None)); - } else { - pos = b_size; } } } @@ -576,7 +574,7 @@ impl InnerField { } } } else { - return Ok(Async::Ready(Some(payload.buf.take().freeze()))); + Ok(Async::Ready(Some(payload.buf.take().freeze()))) }; } } From b1cfbdcf7a4f391ec93aabdd2f81fd24b87517bb Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sun, 2 Jun 2019 13:05:22 +0600 Subject: [PATCH 18/34] prepare actix-http release --- actix-http/CHANGES.md | 5 ++++- actix-http/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index e677c3fa6..d0c75da76 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,5 +1,7 @@ # Changes +## [0.2.3] - 2019-06-02 + ### Added * Debug impl for ResponseBuilder @@ -8,7 +10,8 @@ ### Changed -* SizedStream accepts u64 +* SizedStream uses u64 + ## [0.2.2] - 2019-05-29 diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 6a020eae3..1847a5ba2 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "0.2.2" +version = "0.2.3" authors = ["Nikolay Kim "] description = "Actix http primitives" readme = "README.md" From 6d2e190c8e6f5f8304cfc08e4fbc7d07567b7dfa Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sun, 2 Jun 2019 13:09:21 +0600 Subject: [PATCH 19/34] prepare actix-files release --- actix-files/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index fa48fff08..9d6b0f480 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-files" -version = "0.1.0" +version = "0.1.1" authors = ["Nikolay Kim "] description = "Static files support for actix web." readme = "README.md" @@ -19,7 +19,7 @@ path = "src/lib.rs" [dependencies] actix-web = "1.0.0-rc" -actix-http = "0.2.2" +actix-http = "0.2.3" actix-service = "0.4.0" bitflags = "1" bytes = "0.4" From a780ea10e9f225b4620b2e7e8d72c553c1e45554 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 3 Jun 2019 06:30:30 +0200 Subject: [PATCH 20/34] Guard cookie mod by cookie-session feature (#883) Signed-off-by: Igor Gnatenko --- actix-session/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/actix-session/src/lib.rs b/actix-session/src/lib.rs index 0e7831442..fb316f394 100644 --- a/actix-session/src/lib.rs +++ b/actix-session/src/lib.rs @@ -52,7 +52,9 @@ use serde::de::DeserializeOwned; use serde::Serialize; use serde_json; +#[cfg(feature = "cookie-session")] mod cookie; +#[cfg(feature = "cookie-session")] pub use crate::cookie::CookieSession; /// The high-level interface you use to modify session data. From 4a179d1ae12d39b409a48d45b5de6b6f10db8474 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Mon, 3 Jun 2019 10:52:43 +0600 Subject: [PATCH 21/34] prepare actix-session release --- actix-session/CHANGES.md | 4 ++++ actix-session/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/actix-session/CHANGES.md b/actix-session/CHANGES.md index 10727ae35..10aea8700 100644 --- a/actix-session/CHANGES.md +++ b/actix-session/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.1] - 2019-06-03 + +* Fix optional cookie session support + ## [0.1.0] - 2019-05-18 * Use actix-web 1.0.0-rc diff --git a/actix-session/Cargo.toml b/actix-session/Cargo.toml index b0ef1e2b4..1101ceffc 100644 --- a/actix-session/Cargo.toml +++ b/actix-session/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-session" -version = "0.1.0" +version = "0.1.1" authors = ["Nikolay Kim "] description = "Session for actix web framework." readme = "README.md" From 1fce4876f38b9f2ab276bac2c4be7a0762ce8ac2 Mon Sep 17 00:00:00 2001 From: Denys Vitali Date: Mon, 3 Jun 2019 19:12:37 +0200 Subject: [PATCH 22/34] Scope configuration (#880) * WIP: Scope configuarion * Extensions: Fix into_iter() * Scope: Fix tests * Add ScopeConfig to web Committing from mobile, if this doesn't look good it's because I haven't tested it... * Scope Config: Use ServiceConfig instead * Scope: Switch to ServiceConfig in doc * ScopeConfig: Remove unnecessary changes, handle the case when data is empty * ScopeConfig: Remove changes from actix-http --- src/config.rs | 2 +- src/scope.rs | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index bc33da9df..8de43f36c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -188,7 +188,7 @@ impl ServiceConfig { } } - /// Set application data. Applicatin data could be accessed + /// Set application data. Application data could be accessed /// by using `Data` extractor where `T` is data type. /// /// This is same as `App::data()` method. diff --git a/src/scope.rs b/src/scope.rs index 84f34dae6..e9b60c6e3 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -21,6 +21,7 @@ use crate::route::Route; use crate::service::{ ServiceFactory, ServiceFactoryWrapper, ServiceRequest, ServiceResponse, }; +use crate::config::ServiceConfig; type Guards = Vec>; type HttpService = BoxedService; @@ -83,6 +84,56 @@ impl Scope { factory_ref: fref, } } + + + /// Run external configuration as part of the scope building + /// process + /// + /// This function is useful for moving parts of configuration to a + /// different module or even library. For example, + /// some of the resource's configuration could be moved to different module. + /// + /// ```rust + /// # extern crate actix_web; + /// use actix_web::{web, middleware, App, HttpResponse}; + /// + /// // this function could be located in different module + /// fn config(cfg: &mut web::ServiceConfig) { + /// cfg.service(web::resource("/test") + /// .route(web::get().to(|| HttpResponse::Ok())) + /// .route(web::head().to(|| HttpResponse::MethodNotAllowed())) + /// ); + /// } + /// + /// fn main() { + /// let app = App::new() + /// .wrap(middleware::Logger::default()) + /// .service( + /// web::scope("/api") + /// .configure(config) + /// ) + /// .route("/index.html", web::get().to(|| HttpResponse::Ok())); + /// } + /// ``` + pub fn configure(mut self, f: F) -> Self + where + F: FnOnce(&mut ServiceConfig), + { + let mut cfg = ServiceConfig::new(); + f(&mut cfg); + self.services.extend(cfg.services); + + if !cfg.data.is_empty() { + let mut data = self.data.unwrap_or(Extensions::new()); + + for value in cfg.data.iter() { + value.create(&mut data); + } + + self.data = Some(data); + } + self + } } impl Scope @@ -1022,4 +1073,40 @@ mod tests { let resp = call_service(&mut srv, req); assert_eq!(resp.status(), StatusCode::OK); } + + #[test] + fn test_scope_config() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .configure(|s|{ + s.route("/path1", web::get().to(||HttpResponse::Ok())); + }) + ), + ); + + let req = TestRequest::with_uri("/app/path1").to_request(); + let resp = block_on(srv.call(req)).unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + } + + #[test] + fn test_scope_config_2() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .configure(|s|{ + s.service( + web::scope("/v1") + .configure(|s|{ + s.route("/", web::get().to(||HttpResponse::Ok())); + })); + }) + ), + ); + + let req = TestRequest::with_uri("/app/v1/").to_request(); + let resp = block_on(srv.call(req)).unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + } } From 0e138e111f439ee447a57ef5f1a19203520691d3 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Mon, 3 Jun 2019 23:41:32 +0600 Subject: [PATCH 23/34] add external resource support on scope level --- CHANGES.md | 4 +- Cargo.toml | 2 +- src/rmap.rs | 4 +- src/scope.rs | 170 +++++++++++++++++++++++++++++---------------------- 4 files changed, 105 insertions(+), 75 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0dc7be27c..b5078d531 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,9 +1,11 @@ # Changes -## [1.0.0] - 2019-05-xx +## [1.0.0] - 2019-06-xx ### Add +* Add `Scope::configure()` method. + * Add `ServiceRequest::set_payload()` method. * Add `test::TestRequest::set_json()` convenience method to automatically diff --git a/Cargo.toml b/Cargo.toml index e8fdb1362..e689fab0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,7 @@ rustls = { version = "0.15", optional = true } [dev-dependencies] actix-http = { version = "0.2.2", features=["ssl", "brotli", "flate2-zlib"] } actix-http-test = { version = "0.2.0", features=["ssl"] } -actix-files = { version = "0.1.0" } +actix-files = { version = "0.1.1" } rand = "0.6" env_logger = "0.6" serde_derive = "1.0" diff --git a/src/rmap.rs b/src/rmap.rs index 35fe8ee32..6a543b75c 100644 --- a/src/rmap.rs +++ b/src/rmap.rs @@ -122,7 +122,9 @@ impl ResourceMap { I: AsRef, { if let Some(pattern) = self.named.get(name) { - self.fill_root(path, elements)?; + if pattern.pattern().starts_with("/") { + self.fill_root(path, elements)?; + } if pattern.resource_path(path, elements) { Ok(Some(())) } else { diff --git a/src/scope.rs b/src/scope.rs index e9b60c6e3..ad97fcb62 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -11,6 +11,7 @@ use actix_service::{ use futures::future::{ok, Either, Future, FutureResult}; use futures::{Async, IntoFuture, Poll}; +use crate::config::ServiceConfig; use crate::data::Data; use crate::dev::{AppService, HttpServiceFactory}; use crate::error::Error; @@ -21,7 +22,6 @@ use crate::route::Route; use crate::service::{ ServiceFactory, ServiceFactoryWrapper, ServiceRequest, ServiceResponse, }; -use crate::config::ServiceConfig; type Guards = Vec>; type HttpService = BoxedService; @@ -67,6 +67,7 @@ pub struct Scope { services: Vec>, guards: Vec>, default: Rc>>>, + external: Vec, factory_ref: Rc>>, } @@ -81,59 +82,10 @@ impl Scope { guards: Vec::new(), services: Vec::new(), default: Rc::new(RefCell::new(None)), + external: Vec::new(), factory_ref: fref, } } - - - /// Run external configuration as part of the scope building - /// process - /// - /// This function is useful for moving parts of configuration to a - /// different module or even library. For example, - /// some of the resource's configuration could be moved to different module. - /// - /// ```rust - /// # extern crate actix_web; - /// use actix_web::{web, middleware, App, HttpResponse}; - /// - /// // this function could be located in different module - /// fn config(cfg: &mut web::ServiceConfig) { - /// cfg.service(web::resource("/test") - /// .route(web::get().to(|| HttpResponse::Ok())) - /// .route(web::head().to(|| HttpResponse::MethodNotAllowed())) - /// ); - /// } - /// - /// fn main() { - /// let app = App::new() - /// .wrap(middleware::Logger::default()) - /// .service( - /// web::scope("/api") - /// .configure(config) - /// ) - /// .route("/index.html", web::get().to(|| HttpResponse::Ok())); - /// } - /// ``` - pub fn configure(mut self, f: F) -> Self - where - F: FnOnce(&mut ServiceConfig), - { - let mut cfg = ServiceConfig::new(); - f(&mut cfg); - self.services.extend(cfg.services); - - if !cfg.data.is_empty() { - let mut data = self.data.unwrap_or(Extensions::new()); - - for value in cfg.data.iter() { - value.create(&mut data); - } - - self.data = Some(data); - } - self - } } impl Scope @@ -204,6 +156,56 @@ where self } + /// Run external configuration as part of the scope building + /// process + /// + /// This function is useful for moving parts of configuration to a + /// different module or even library. For example, + /// some of the resource's configuration could be moved to different module. + /// + /// ```rust + /// # extern crate actix_web; + /// use actix_web::{web, middleware, App, HttpResponse}; + /// + /// // this function could be located in different module + /// fn config(cfg: &mut web::ServiceConfig) { + /// cfg.service(web::resource("/test") + /// .route(web::get().to(|| HttpResponse::Ok())) + /// .route(web::head().to(|| HttpResponse::MethodNotAllowed())) + /// ); + /// } + /// + /// fn main() { + /// let app = App::new() + /// .wrap(middleware::Logger::default()) + /// .service( + /// web::scope("/api") + /// .configure(config) + /// ) + /// .route("/index.html", web::get().to(|| HttpResponse::Ok())); + /// } + /// ``` + pub fn configure(mut self, f: F) -> Self + where + F: FnOnce(&mut ServiceConfig), + { + let mut cfg = ServiceConfig::new(); + f(&mut cfg); + self.services.extend(cfg.services); + self.external.extend(cfg.external); + + if !cfg.data.is_empty() { + let mut data = self.data.unwrap_or_else(|| Extensions::new()); + + for value in cfg.data.iter() { + value.create(&mut data); + } + + self.data = Some(data); + } + self + } + /// Register http service. /// /// This is similar to `App's` service registration. @@ -332,6 +334,7 @@ where guards: self.guards, services: self.services, default: self.default, + external: self.external, factory_ref: self.factory_ref, } } @@ -410,6 +413,11 @@ where let mut rmap = ResourceMap::new(ResourceDef::root_prefix(&self.rdef)); + // external resources + for mut rdef in std::mem::replace(&mut self.external, Vec::new()) { + rmap.add(&mut rdef, None); + } + // custom app data storage if let Some(ref mut ext) = self.data { config.set_service_data(ext); @@ -645,7 +653,7 @@ mod tests { use crate::dev::{Body, ResponseBody}; use crate::http::{header, HeaderValue, Method, StatusCode}; use crate::service::{ServiceRequest, ServiceResponse}; - use crate::test::{block_on, call_service, init_service, TestRequest}; + use crate::test::{block_on, call_service, init_service, read_body, TestRequest}; use crate::{guard, web, App, Error, HttpRequest, HttpResponse}; #[test] @@ -1076,14 +1084,10 @@ mod tests { #[test] fn test_scope_config() { - let mut srv = init_service( - App::new().service( - web::scope("/app") - .configure(|s|{ - s.route("/path1", web::get().to(||HttpResponse::Ok())); - }) - ), - ); + let mut srv = + init_service(App::new().service(web::scope("/app").configure(|s| { + s.route("/path1", web::get().to(|| HttpResponse::Ok())); + }))); let req = TestRequest::with_uri("/app/path1").to_request(); let resp = block_on(srv.call(req)).unwrap(); @@ -1092,21 +1096,43 @@ mod tests { #[test] fn test_scope_config_2() { - let mut srv = init_service( - App::new().service( - web::scope("/app") - .configure(|s|{ - s.service( - web::scope("/v1") - .configure(|s|{ - s.route("/", web::get().to(||HttpResponse::Ok())); - })); - }) - ), - ); + let mut srv = + init_service(App::new().service(web::scope("/app").configure(|s| { + s.service(web::scope("/v1").configure(|s| { + s.route("/", web::get().to(|| HttpResponse::Ok())); + })); + }))); let req = TestRequest::with_uri("/app/v1/").to_request(); let resp = block_on(srv.call(req)).unwrap(); assert_eq!(resp.status(), StatusCode::OK); } + + #[test] + fn test_url_for_external() { + let mut srv = + init_service(App::new().service(web::scope("/app").configure(|s| { + s.service(web::scope("/v1").configure(|s| { + s.external_resource( + "youtube", + "https://youtube.com/watch/{video_id}", + ); + s.route( + "/", + web::get().to(|req: HttpRequest| { + HttpResponse::Ok().body(format!( + "{}", + req.url_for("youtube", &["xxxxxx"]).unwrap().as_str() + )) + }), + ); + })); + }))); + + let req = TestRequest::with_uri("/app/v1/").to_request(); + let resp = block_on(srv.call(req)).unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + let body = read_body(resp); + assert_eq!(body, &b"https://youtube.com/watch/xxxxxx"[..]); + } } From cf217d35a895a2ed98c4f5fcb8ddd9fd58596c5a Mon Sep 17 00:00:00 2001 From: Glade Miller Date: Tue, 4 Jun 2019 10:30:43 -0600 Subject: [PATCH 24/34] Added HEAD, CONNECT, OPTIONS and TRACE to the codegen (#886) * Added HEAD, CONNECT, OPTIONS and TRACE to the codegen * Add new macros to use statement * Add patch to supported codegen http methods * Update CHANGES.md Added head, options, trace, connect and patch codegen changes to CHANGES.md --- CHANGES.md | 2 + actix-web-codegen/src/lib.rs | 65 +++++++++++++++++++++++++++ actix-web-codegen/src/route.rs | 10 +++++ actix-web-codegen/tests/test_macro.rs | 52 ++++++++++++++++++++- 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index b5078d531..1ed434b74 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ * Add `test::TestRequest::set_json()` convenience method to automatically serialize data and set header in test requests. + +* Add codegen now supports head, options, trace, connect and patch http methods ### Changes diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index 70cde90e4..99abbb6a3 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -11,6 +11,11 @@ //! - [post](attr.post.html) //! - [put](attr.put.html) //! - [delete](attr.delete.html) +//! - [head](attr.head.html) +//! - [connect](attr.connect.html) +//! - [options](attr.options.html) +//! - [trace](attr.trace.html) +//! - [patch](attr.patch.html) //! //! ### Attributes: //! @@ -92,3 +97,63 @@ pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream { let gen = route::Args::new(&args, input, route::GuardType::Delete); gen.generate() } + +/// Creates route handler with `HEAD` method guard. +/// +/// Syntax: `#[head("path"[, attributes])]` +/// +/// Attributes are the same as in [head](attr.head.html) +#[proc_macro_attribute] +pub fn head(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as syn::AttributeArgs); + let gen = route::Args::new(&args, input, route::GuardType::Head); + gen.generate() +} + +/// Creates route handler with `CONNECT` method guard. +/// +/// Syntax: `#[connect("path"[, attributes])]` +/// +/// Attributes are the same as in [connect](attr.connect.html) +#[proc_macro_attribute] +pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as syn::AttributeArgs); + let gen = route::Args::new(&args, input, route::GuardType::Connect); + gen.generate() +} + +/// Creates route handler with `OPTIONS` method guard. +/// +/// Syntax: `#[options("path"[, attributes])]` +/// +/// Attributes are the same as in [options](attr.options.html) +#[proc_macro_attribute] +pub fn options(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as syn::AttributeArgs); + let gen = route::Args::new(&args, input, route::GuardType::Options); + gen.generate() +} + +/// Creates route handler with `TRACE` method guard. +/// +/// Syntax: `#[trace("path"[, attributes])]` +/// +/// Attributes are the same as in [trace](attr.trace.html) +#[proc_macro_attribute] +pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as syn::AttributeArgs); + let gen = route::Args::new(&args, input, route::GuardType::Trace); + gen.generate() +} + +/// Creates route handler with `PATCH` method guard. +/// +/// Syntax: `#[patch("path"[, attributes])]` +/// +/// Attributes are the same as in [patch](attr.patch.html) +#[proc_macro_attribute] +pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as syn::AttributeArgs); + let gen = route::Args::new(&args, input, route::GuardType::Patch); + gen.generate() +} \ No newline at end of file diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 1a5f79298..3b890c1cb 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -25,6 +25,11 @@ pub enum GuardType { Post, Put, Delete, + Head, + Connect, + Options, + Trace, + Patch } impl fmt::Display for GuardType { @@ -34,6 +39,11 @@ impl fmt::Display for GuardType { &GuardType::Post => write!(f, "Post"), &GuardType::Put => write!(f, "Put"), &GuardType::Delete => write!(f, "Delete"), + &GuardType::Head => write!(f, "Head"), + &GuardType::Connect => write!(f, "Connect"), + &GuardType::Options => write!(f, "Options"), + &GuardType::Trace => write!(f, "Trace"), + &GuardType::Patch => write!(f, "Patch"), } } } diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs index cd899d48d..718728879 100644 --- a/actix-web-codegen/tests/test_macro.rs +++ b/actix-web-codegen/tests/test_macro.rs @@ -1,7 +1,7 @@ use actix_http::HttpService; use actix_http_test::TestServer; use actix_web::{http, web::Path, App, HttpResponse, Responder}; -use actix_web_codegen::{delete, get, post, put}; +use actix_web_codegen::{delete, get, post, put, patch, head, connect, options, trace}; use futures::{future, Future}; #[get("/test")] @@ -14,11 +14,36 @@ fn put_test() -> impl Responder { HttpResponse::Created() } +#[patch("/test")] +fn patch_test() -> impl Responder { + HttpResponse::Ok() +} + #[post("/test")] fn post_test() -> impl Responder { HttpResponse::NoContent() } +#[head("/test")] +fn head_test() -> impl Responder { + HttpResponse::Ok() +} + +#[connect("/test")] +fn connect_test() -> impl Responder { + HttpResponse::Ok() +} + +#[options("/test")] +fn options_test() -> impl Responder { + HttpResponse::Ok() +} + +#[trace("/test")] +fn trace_test() -> impl Responder { + HttpResponse::Ok() +} + #[get("/test")] fn auto_async() -> impl Future { future::ok(HttpResponse::Ok().finish()) @@ -75,6 +100,11 @@ fn test_body() { App::new() .service(post_test) .service(put_test) + .service(head_test) + .service(connect_test) + .service(options_test) + .service(trace_test) + .service(patch_test) .service(test), ) }); @@ -82,6 +112,26 @@ fn test_body() { let response = srv.block_on(request.send()).unwrap(); assert!(response.status().is_success()); + let request = srv.request(http::Method::HEAD, srv.url("/test")); + let response = srv.block_on(request.send()).unwrap(); + assert!(response.status().is_success()); + + let request = srv.request(http::Method::CONNECT, srv.url("/test")); + let response = srv.block_on(request.send()).unwrap(); + assert!(response.status().is_success()); + + let request = srv.request(http::Method::OPTIONS, srv.url("/test")); + let response = srv.block_on(request.send()).unwrap(); + assert!(response.status().is_success()); + + let request = srv.request(http::Method::TRACE, srv.url("/test")); + let response = srv.block_on(request.send()).unwrap(); + assert!(response.status().is_success()); + + let request = srv.request(http::Method::PATCH, srv.url("/test")); + let response = srv.block_on(request.send()).unwrap(); + assert!(response.status().is_success()); + let request = srv.request(http::Method::PUT, srv.url("/test")); let response = srv.block_on(request.send()).unwrap(); assert!(response.status().is_success()); From a771540b16d9441a3a69f7e39fb61d26fc1698ae Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Tue, 4 Jun 2019 22:33:43 +0600 Subject: [PATCH 25/34] prepare actix-web-codegen release --- CHANGES.md | 4 ++-- actix-web-codegen/CHANGES.md | 4 ++++ actix-web-codegen/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1ed434b74..09c398772 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,8 +10,8 @@ * Add `test::TestRequest::set_json()` convenience method to automatically serialize data and set header in test requests. - -* Add codegen now supports head, options, trace, connect and patch http methods + +* Add macros for head, options, trace, connect and patch http methods ### Changes diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index ac1861118..7cc0c164f 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.2] - 2019-06-04 + +* Add macros for head, options, trace, connect and patch http methods + ## [0.1.1] - 2019-06-01 * Add syn "extra-traits" feature diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 5557441c4..23e9a432f 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-codegen" -version = "0.1.1" +version = "0.1.2" description = "Actix web proc macros" readme = "README.md" authors = ["Nikolay Kim "] From 38f04b75a798434eb64ec0df27595fcfac4a43a7 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Tue, 4 Jun 2019 22:36:10 +0600 Subject: [PATCH 26/34] update deps --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e689fab0e..f1890765c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,8 +72,8 @@ actix-service = "0.4.0" actix-utils = "0.4.1" actix-router = "0.1.5" actix-rt = "0.2.2" -actix-web-codegen = "0.1.1" -actix-http = "0.2.2" +actix-web-codegen = "0.1.2" +actix-http = "0.2.3" actix-server = "0.5.1" actix-server-config = "0.1.1" actix-threadpool = "0.1.0" @@ -100,7 +100,7 @@ openssl = { version="0.10", optional = true } rustls = { version = "0.15", optional = true } [dev-dependencies] -actix-http = { version = "0.2.2", features=["ssl", "brotli", "flate2-zlib"] } +actix-http = { version = "0.2.3", features=["ssl", "brotli", "flate2-zlib"] } actix-http-test = { version = "0.2.0", features=["ssl"] } actix-files = { version = "0.1.1" } rand = "0.6" From a342b1289dfa163bd09da4c30c79154c05c9e74d Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 5 Jun 2019 08:13:43 +0600 Subject: [PATCH 27/34] prep awc release --- Cargo.toml | 2 +- awc/CHANGES.md | 6 ++++++ awc/Cargo.toml | 12 ++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f1890765c..cd0e94589 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ actix-web-codegen = "0.1.2" actix-http = "0.2.3" actix-server = "0.5.1" actix-server-config = "0.1.1" -actix-threadpool = "0.1.0" +actix-threadpool = "0.1.1" awc = { version = "0.2.0", optional = true } bytes = "0.4" diff --git a/awc/CHANGES.md b/awc/CHANGES.md index f36b0bb3a..b5f64dd37 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -1,5 +1,11 @@ # Changes +## [0.2.1] - 2019-06-05 + +### Added + +* Add license files + ## [0.2.0] - 2019-05-12 ### Added diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 2112185c8..cad52033e 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awc" -version = "0.2.0" +version = "0.2.1" authors = ["Nikolay Kim "] description = "Actix http client." readme = "README.md" @@ -41,7 +41,7 @@ flate2-rust = ["actix-http/flate2-rust"] [dependencies] actix-codec = "0.1.2" actix-service = "0.4.0" -actix-http = "0.2.0" +actix-http = "0.2.3" base64 = "0.10.1" bytes = "0.4" derive_more = "0.14" @@ -58,11 +58,11 @@ openssl = { version="0.10", optional = true } [dev-dependencies] actix-rt = "0.2.2" -actix-web = { version = "1.0.0-beta.4", features=["ssl"] } -actix-http = { version = "0.2.0", features=["ssl"] } +actix-web = { version = "1.0.0-rc", features=["ssl"] } +actix-http = { version = "0.2.3", features=["ssl"] } actix-http-test = { version = "0.2.0", features=["ssl"] } -actix-utils = "0.4.0" -actix-server = { version = "0.5.0", features=["ssl"] } +actix-utils = "0.4.1" +actix-server = { version = "0.5.1", features=["ssl"] } brotli2 = { version="0.3.2" } flate2 = { version="1.0.2" } env_logger = "0.6" From ae64475d988b7831464dfb9cbfc8d5957e990f1f Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 5 Jun 2019 08:27:25 +0600 Subject: [PATCH 28/34] test-server release --- CHANGES.md | 2 +- test-server/CHANGES.md | 4 ++++ test-server/Cargo.toml | 14 +++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 09c398772..07991142e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # Changes -## [1.0.0] - 2019-06-xx +## [1.0.0] - 2019-06-05 ### Add diff --git a/test-server/CHANGES.md b/test-server/CHANGES.md index 8704a64c2..a31937909 100644 --- a/test-server/CHANGES.md +++ b/test-server/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.2.1] - 2019-06-05 + +* Add license files + ## [0.2.0] - 2019-05-12 * Update awc and actix-http deps diff --git a/test-server/Cargo.toml b/test-server/Cargo.toml index 8567b745e..37e2b0444 100644 --- a/test-server/Cargo.toml +++ b/test-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http-test" -version = "0.2.0" +version = "0.2.1" authors = ["Nikolay Kim "] description = "Actix http test server" readme = "README.md" @@ -32,10 +32,10 @@ ssl = ["openssl", "actix-server/ssl", "awc/ssl"] [dependencies] actix-codec = "0.1.2" actix-rt = "0.2.2" -actix-service = "0.4.0" -actix-server = "0.5.0" -actix-utils = "0.4.0" -awc = "0.2.0" +actix-service = "0.4.1" +actix-server = "0.5.1" +actix-utils = "0.4.1" +awc = "0.2.1" base64 = "0.10" bytes = "0.4" @@ -55,5 +55,5 @@ tokio-timer = "0.2" openssl = { version="0.10", optional = true } [dev-dependencies] -actix-web = "1.0.0-beta.4" -actix-http = "0.2.0" +actix-web = "1.0.0-rc" +actix-http = "0.2.3" From a548b69679ebec4be9bb280e9e1fd88707d6790d Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 5 Jun 2019 08:43:13 +0600 Subject: [PATCH 29/34] fmt --- actix-http/src/h1/dispatcher.rs | 11 ++++++----- actix-web-codegen/src/lib.rs | 2 +- actix-web-codegen/src/route.rs | 2 +- actix-web-codegen/tests/test_macro.rs | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index b7b9db2d7..220984f8d 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -693,11 +693,12 @@ where } } else { // read socket into a buf - let should_disconnect = if !inner.flags.contains(Flags::READ_DISCONNECT) { - read_available(&mut inner.io, &mut inner.read_buf)? - } else { - None - }; + let should_disconnect = + if !inner.flags.contains(Flags::READ_DISCONNECT) { + read_available(&mut inner.io, &mut inner.read_buf)? + } else { + None + }; inner.poll_request()?; if let Some(true) = should_disconnect { diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index 99abbb6a3..b3ae7dd9b 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -156,4 +156,4 @@ pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); let gen = route::Args::new(&args, input, route::GuardType::Patch); gen.generate() -} \ No newline at end of file +} diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 3b890c1cb..268adecb0 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -29,7 +29,7 @@ pub enum GuardType { Connect, Options, Trace, - Patch + Patch, } impl fmt::Display for GuardType { diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs index 718728879..f02b82f00 100644 --- a/actix-web-codegen/tests/test_macro.rs +++ b/actix-web-codegen/tests/test_macro.rs @@ -1,7 +1,7 @@ use actix_http::HttpService; use actix_http_test::TestServer; use actix_web::{http, web::Path, App, HttpResponse, Responder}; -use actix_web_codegen::{delete, get, post, put, patch, head, connect, options, trace}; +use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, trace}; use futures::{future, Future}; #[get("/test")] From d9a62c4bbf9091a39aa5df05ae08a6a0a8e149ae Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 5 Jun 2019 08:43:39 +0600 Subject: [PATCH 30/34] add App::register_data() --- src/app.rs | 7 +++++++ src/data.rs | 23 ++++++++++++++++++++++- test-server/Cargo.toml | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 1568d5fca..4f8b283e1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -100,6 +100,13 @@ where self } + /// Set application data. Application data could be accessed + /// by using `Data` extractor where `T` is data type. + pub fn register_data(mut self, data: Data) -> Self { + self.data.push(Box::new(data)); + self + } + /// Run external configuration as part of the application building /// process /// diff --git a/src/data.rs b/src/data.rs index 1328c4ef6..9fd8b67fc 100644 --- a/src/data.rs +++ b/src/data.rs @@ -54,7 +54,7 @@ pub(crate) trait DataFactory { /// /// let app = App::new() /// // Store `MyData` in application storage. -/// .data(data.clone()) +/// .register_data(data.clone()) /// .service( /// web::resource("/index.html").route( /// web::get().to(index))); @@ -130,6 +130,7 @@ impl DataFactory for Data { mod tests { use actix_service::Service; + use super::*; use crate::http::StatusCode; use crate::test::{block_on, init_service, TestRequest}; use crate::{web, App, HttpResponse}; @@ -154,6 +155,26 @@ mod tests { assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); } + #[test] + fn test_register_data_extractor() { + let mut srv = + init_service(App::new().register_data(Data::new(10usize)).service( + web::resource("/").to(|_: web::Data| HttpResponse::Ok()), + )); + + let req = TestRequest::default().to_request(); + let resp = block_on(srv.call(req)).unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let mut srv = + init_service(App::new().register_data(Data::new(10u32)).service( + web::resource("/").to(|_: web::Data| HttpResponse::Ok()), + )); + let req = TestRequest::default().to_request(); + let resp = block_on(srv.call(req)).unwrap(); + assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); + } + #[test] fn test_route_data_extractor() { let mut srv = diff --git a/test-server/Cargo.toml b/test-server/Cargo.toml index 37e2b0444..a8f4425ba 100644 --- a/test-server/Cargo.toml +++ b/test-server/Cargo.toml @@ -32,7 +32,7 @@ ssl = ["openssl", "actix-server/ssl", "awc/ssl"] [dependencies] actix-codec = "0.1.2" actix-rt = "0.2.2" -actix-service = "0.4.1" +actix-service = "0.4.0" actix-server = "0.5.1" actix-utils = "0.4.1" awc = "0.2.1" From e399e01a22b8a848ecbbc21c362878cd59a4342e Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 5 Jun 2019 09:02:44 +0600 Subject: [PATCH 31/34] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc8f78b86..cae737b68 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Actix web is a simple, pragmatic and extremely fast web framework for Rust. * Multipart streams * Static assets * SSL support with OpenSSL or Rustls -* Middlewares ([Logger, Session, CORS, CSRF, etc](https://actix.rs/docs/middleware/)) +* Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/)) * Includes an asynchronous [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html) * Supports [Actix actor framework](https://github.com/actix/actix) @@ -22,7 +22,7 @@ Actix web is a simple, pragmatic and extremely fast web framework for Rust. * [API Documentation (0.7)](https://docs.rs/actix-web/0.7.19/actix_web/) * [Chat on gitter](https://gitter.im/actix/actix) * Cargo package: [actix-web](https://crates.io/crates/actix-web) -* Minimum supported Rust version: 1.32 or later +* Minimum supported Rust version: 1.34 or later ## Example From 53e2f8090f3afbb5ae21ff6c89f8e9cb33668c93 Mon Sep 17 00:00:00 2001 From: Stefano Probst Date: Thu, 6 Jun 2019 07:14:56 +0200 Subject: [PATCH 32/34] Mark default enabled package features in the docs (#890) --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0e4a421ed..f0bf01bc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,15 +66,15 @@ //! //! ## Package feature //! -//! * `client` - enables http client +//! * `client` - enables http client (default enabled) //! * `ssl` - enables ssl support via `openssl` crate, supports `http/2` //! * `rust-tls` - enables ssl support via `rustls` crate, supports `http/2` //! * `secure-cookies` - enables secure cookies support, includes `ring` crate as -//! dependency +//! dependency (default enabled) //! * `brotli` - enables `brotli` compression support, requires `c` -//! compiler +//! compiler (default enabled) //! * `flate2-zlib` - enables `gzip`, `deflate` compression support, requires -//! `c` compiler +//! `c` compiler (default enabled) //! * `flate2-rust` - experimental rust based implementation for //! `gzip`, `deflate` compression. //! From bfbac4f875f656dc83c3227d4fb85a4e5887751a Mon Sep 17 00:00:00 2001 From: simlay Date: Thu, 6 Jun 2019 20:34:30 -0700 Subject: [PATCH 33/34] Upgraded actix-web dependency and set default-features to false (#900) --- actix-files/CHANGES.md | 4 ++++ actix-files/Cargo.toml | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index c77494575..862a59442 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.2] - 2019-06-06 + +* Fix ring dependency from actix-web default features for #741. + ## [0.1.1] - 2019-06-01 * Static files are incorrectly served as both chunked and with length #812 diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 9d6b0f480..b1428a22b 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-files" -version = "0.1.1" +version = "0.1.2" authors = ["Nikolay Kim "] description = "Static files support for actix web." readme = "README.md" @@ -18,7 +18,7 @@ name = "actix_files" path = "src/lib.rs" [dependencies] -actix-web = "1.0.0-rc" +actix-web = { version = "1.0.0", default-features = false } actix-http = "0.2.3" actix-service = "0.4.0" bitflags = "1" @@ -32,4 +32,4 @@ percent-encoding = "1.0" v_htmlescape = "0.4" [dev-dependencies] -actix-web = { version = "1.0.0-rc", features=["ssl"] } +actix-web = { version = "1.0.0", features=["ssl"] } From c4b7980b4f4e31a4f881c4ff812873661c4a812c Mon Sep 17 00:00:00 2001 From: simlay Date: Thu, 6 Jun 2019 20:34:56 -0700 Subject: [PATCH 34/34] Upgraded actix-web dependency and set default-features to false (#895) --- actix-multipart/CHANGES.md | 4 ++++ actix-multipart/Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 751bc1269..b0d8f285e 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.1.3] - 2019-06-06 + +* Fix ring dependency from actix-web default features for #741. + ## [0.1.2] - 2019-06-02 * Fix boundary parsing #876 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 9bb1179d8..d377be1f4 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.1.2" +version = "0.1.3" authors = ["Nikolay Kim "] description = "Multipart support for actix web framework." readme = "README.md" @@ -18,7 +18,7 @@ name = "actix_multipart" path = "src/lib.rs" [dependencies] -actix-web = "1.0.0-rc" +actix-web = { version = "1.0.0", default-features = false } actix-service = "0.4.0" bytes = "0.4" derive_more = "0.14"