1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-08-19 20:35:36 +02:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Douman
1fbb52ad3b 0.7.18 Bump 2019-01-10 17:05:18 +03:00
Julian Tescher
e5cdd22720 Fix test server listener thread leak (#655) 2019-01-08 10:42:22 -08:00
Douman
4f2e970732 Tidy up CHANGES.md 2019-01-08 10:49:03 +03:00
Douman
4d45313f9d Decode special characters when handling static files 2019-01-08 10:46:58 +03:00
Juan Aguilar
55a2a59906 Improve change askama_escape in favor of v_htmlescape (#651) 2019-01-03 22:34:18 +03:00
Ji Qu
61883042c2 Add with-cookie init-method for TestRequest (#647) 2019-01-02 13:24:08 +03:00
6 changed files with 85 additions and 12 deletions

View File

@@ -1,5 +1,19 @@
# Changes
## [0.7.18] - 2019-01-10
### Added
* Add `with_cookie` for `TestRequest` to allow users to customize request cookie. #647
* Add `cookie` method for `TestRequest` to allow users to add cookie dynamically.
### Fixed
* StaticFiles decode special characters in request's path
* Fix test server listener leak #654
## [0.7.17] - 2018-12-25
### Added

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-web"
version = "0.7.17"
version = "0.7.18"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust."
readme = "README.md"
@@ -64,7 +64,7 @@ cell = ["actix-net/cell"]
actix = "0.7.9"
actix-net = "0.2.6"
askama_escape = "0.1.0"
v_htmlescape = "0.3.2"
base64 = "0.10"
bitflags = "1.0"
failure = "^0.1.2"

View File

@@ -11,7 +11,7 @@ use std::{cmp, io};
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
use askama_escape::{escape as escape_html_entity};
use v_htmlescape::HTMLEscape;
use bytes::Bytes;
use futures::{Async, Future, Poll, Stream};
use futures_cpupool::{CpuFuture, CpuPool};
@@ -569,6 +569,11 @@ macro_rules! encode_file_url {
};
}
#[inline]
fn escape_html_entity(s: &str) -> HTMLEscape {
HTMLEscape::from(s)
}
// " -- &quot; & -- &amp; ' -- &#x27; < -- &lt; > -- &gt; / -- &#x2f;
macro_rules! encode_file_name {
($entry:ident) => {
@@ -756,7 +761,7 @@ impl<S: 'static, C: StaticFileConfig> StaticFiles<S, C> {
&self,
req: &HttpRequest<S>,
) -> Result<AsyncResult<HttpResponse>, Error> {
let tail: String = req.match_info().query("tail")?;
let tail: String = req.match_info().get_decoded("tail").unwrap_or_else(|| "".to_string());
let relpath = PathBuf::from_param(tail.trim_left_matches('/'))?;
// full filepath
@@ -1298,6 +1303,27 @@ mod tests {
assert_eq!(bytes, data);
}
#[test]
fn test_static_files_with_spaces() {
let mut srv = test::TestServer::with_factory(|| {
App::new().handler(
"/",
StaticFiles::new(".").unwrap().index_file("Cargo.toml"),
)
});
let request = srv
.get()
.uri(srv.url("/tests/test%20space.binary"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::OK);
let bytes = srv.execute(response.body()).unwrap();
let data = Bytes::from(fs::read("tests/test space.binary").unwrap());
assert_eq!(bytes, data);
}
#[derive(Default)]
pub struct OnlyMethodHeadConfig;
impl StaticFileConfig for OnlyMethodHeadConfig {

View File

@@ -100,7 +100,6 @@ extern crate failure;
extern crate lazy_static;
#[macro_use]
extern crate futures;
extern crate askama_escape;
extern crate cookie;
extern crate futures_cpupool;
extern crate http as modhttp;
@@ -137,6 +136,7 @@ extern crate serde_urlencoded;
extern crate percent_encoding;
extern crate serde_json;
extern crate smallvec;
extern crate v_htmlescape;
extern crate actix_net;
#[macro_use]

View File

@@ -5,7 +5,9 @@ use std::sync::mpsc;
use std::{net, thread};
use actix::{Actor, Addr, System};
use actix::actors::signal;
use actix_net::server::Server;
use cookie::Cookie;
use futures::Future;
use http::header::HeaderName;
@@ -66,6 +68,7 @@ pub struct TestServer {
ssl: bool,
conn: Addr<ClientConnector>,
rt: Runtime,
backend: Addr<Server>,
}
impl TestServer {
@@ -112,24 +115,25 @@ impl TestServer {
let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
let local_addr = tcp.local_addr().unwrap();
let _ = HttpServer::new(factory)
let srv = HttpServer::new(factory)
.disable_signals()
.listen(tcp)
.keep_alive(5)
.start();
tx.send((System::current(), local_addr, TestServer::get_conn()))
tx.send((System::current(), local_addr, TestServer::get_conn(), srv))
.unwrap();
sys.run();
});
let (system, addr, conn) = rx.recv().unwrap();
let (system, addr, conn, backend) = rx.recv().unwrap();
System::set_current(system);
TestServer {
addr,
conn,
ssl: false,
rt: Runtime::new().unwrap(),
backend,
}
}
@@ -197,6 +201,7 @@ impl TestServer {
/// Stop http server
fn stop(&mut self) {
let _ = self.backend.send(signal::Signal(signal::SignalType::Term)).wait();
System::current().stop();
}
@@ -333,8 +338,7 @@ where
.keep_alive(5)
.disable_signals();
tx.send((System::current(), addr, TestServer::get_conn()))
.unwrap();
#[cfg(any(feature = "alpn", feature = "ssl"))]
{
@@ -356,18 +360,22 @@ where
let tcp = net::TcpListener::bind(addr).unwrap();
srv = srv.listen(tcp);
}
srv.start();
let backend = srv.start();
tx.send((System::current(), addr, TestServer::get_conn(), backend))
.unwrap();
sys.run();
});
let (system, addr, conn) = rx.recv().unwrap();
let (system, addr, conn, backend) = rx.recv().unwrap();
System::set_current(system);
TestServer {
addr,
conn,
ssl: has_ssl,
rt: Runtime::new().unwrap(),
backend,
}
}
}
@@ -507,6 +515,11 @@ impl TestRequest<()> {
{
TestRequest::default().header(key, value)
}
/// Create TestRequest and set request cookie
pub fn with_cookie(cookie: Cookie<'static>) -> TestRequest<()> {
TestRequest::default().cookie(cookie)
}
}
impl<S: 'static> TestRequest<S> {
@@ -543,6 +556,25 @@ impl<S: 'static> TestRequest<S> {
self
}
/// set cookie of this request
pub fn cookie(mut self, cookie: Cookie<'static>) -> Self {
if self.cookies.is_none() {
let mut should_insert = true;
let old_cookies = self.cookies.as_mut().unwrap();
for old_cookie in old_cookies.iter() {
if old_cookie == &cookie {
should_insert = false
};
};
if should_insert {
old_cookies.push(cookie);
};
} else {
self.cookies = Some(vec![cookie]);
};
self
}
/// Set a header
pub fn set<H: Header>(mut self, hdr: H) -> Self {
if let Ok(value) = hdr.try_into() {

1
tests/test space.binary Normal file
View File

@@ -0,0 +1 @@
<EFBFBD>TǑɂV<EFBFBD>2<EFBFBD>vI<EFBFBD><EFBFBD><EFBFBD>\<5C><52><CB99><EFBFBD>e<EFBFBD><04>vD<76>:藽<>RV<03>Yp<59><70>;<3B><>G<><47>p!2<7F>C<EFBFBD>.<2E> <0C><><EFBFBD><EFBFBD>pA !<21>ߦ<EFBFBD>x j+Uc<55><63><EFBFBD>X<13>c%<17>;<3B>"y<10><>AI