diff --git a/Cargo.lock b/Cargo.lock index 5b85ac564..ad23083ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -733,7 +733,7 @@ dependencies = [ [[package]] name = "futures" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1310,7 +1310,7 @@ dependencies = [ "ethcore-rpc 1.5.0", "ethcore-signer 1.5.0", "ethcore-util 1.5.0", - "futures 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1347,6 +1347,17 @@ dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot" version = "0.3.5" @@ -1609,7 +1620,7 @@ dependencies = [ "ethcore-bigint 0.1.2", "ethcore-rpc 1.5.0", "ethcore-util 1.5.0", - "futures 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc-client 1.4.0", "rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2121,7 +2132,7 @@ dependencies = [ "checksum ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0c53453517f620847be51943db329276ae52f2e210cfc659e81182864be2f" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" -"checksum futures 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd89497091f8c5d3a65c6b4baf6d2f0731937a7c9217d2f89141b21437a9d96" +"checksum futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bad0a2ac64b227fdc10c254051ae5af542cf19c9328704fd4092f7914196897" "checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" @@ -2182,6 +2193,7 @@ dependencies = [ "checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7" "checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab" "checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "" +"checksum parking_lot 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "968f685642555d2f7e202c48b8b11de80569e9bfea817f7f12d7c61aac62d4e6" "checksum parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc5847584161f273e69edc63c1a86254a22f570a0b5dd87aa6f9773f6f7d125" "checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068" "checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026" diff --git a/signer/src/tests/mod.rs b/signer/src/tests/mod.rs index 767f84a62..ab46a0e6f 100644 --- a/signer/src/tests/mod.rs +++ b/signer/src/tests/mod.rs @@ -17,7 +17,6 @@ use std::ops::{Deref, DerefMut}; use std::sync::Arc; -#[cfg(test)] use devtools::http_client; use devtools::RandomTempPath; @@ -61,189 +60,202 @@ pub fn serve() -> (Server, usize, GuardedAuthCodes) { }) } -#[test] -fn should_reject_invalid_host() { - // given - let server = serve().0; - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: test:8180\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - assert_eq!(response.status, "HTTP/1.1 403 FORBIDDEN".to_owned()); - assert!(response.body.contains("URL Blocked")); - http_client::assert_security_headers_present(&response.headers, None); +/// Test a single request to running server +pub fn request(server: Server, request: &str) -> http_client::Response { + http_client::request(server.addr(), request) } -#[test] -fn should_allow_home_parity_host() { - // given - let server = serve().0; +#[cfg(test)] +mod testing { + use std::time; + use util::Hashable; + use devtools::http_client; + use super::{serve, request}; - // when - let response = request(server, - "\ - GET http://home.parity/ HTTP/1.1\r\n\ - Host: home.parity\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); + #[test] + fn should_reject_invalid_host() { + // given + let server = serve().0; - // then - assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); - http_client::assert_security_headers_present(&response.headers, None); -} - -#[test] -fn should_serve_styles_even_on_disallowed_domain() { - // given - let server = serve().0; - - // when - let response = request(server, - "\ - GET /styles.css HTTP/1.1\r\n\ - Host: test:8180\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); - http_client::assert_security_headers_present(&response.headers, None); -} - -#[test] -fn should_return_200_ok_for_connect_requests() { - // given - let server = serve().0; - - // when - let response = request(server, - "\ - CONNECT home.parity:8080 HTTP/1.1\r\n\ - Host: home.parity\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); -} - -#[test] -fn should_block_if_authorization_is_incorrect() { - // given - let (server, port, _) = serve(); - - // when - let response = request(server, - &format!("\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:{}\r\n\ - Connection: Upgrade\r\n\ - Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ - Sec-WebSocket-Protocol: wrong\r\n\ - Sec-WebSocket-Version: 13\r\n\ - \r\n\ - {{}} - ", port) - ); - - // then - assert_eq!(response.status, "HTTP/1.1 403 FORBIDDEN".to_owned()); - http_client::assert_security_headers_present(&response.headers, None); -} - -#[test] -fn should_allow_if_authorization_is_correct() { - // given - let (server, port, mut authcodes) = serve(); - let code = authcodes.generate_new().unwrap().replace("-", ""); - authcodes.to_file(&authcodes.path).unwrap(); - let timestamp = time::UNIX_EPOCH.elapsed().unwrap().as_secs(); - - // when - let response = request(server, - &format!("\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:{}\r\n\ - Connection: Close\r\n\ - Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ - Sec-WebSocket-Protocol: {:?}_{}\r\n\ - Sec-WebSocket-Version: 13\r\n\ - \r\n\ - {{}} - ", - port, - format!("{}:{}", code, timestamp).sha3(), - timestamp, - ) - ); - - // then - assert_eq!(response.status, "HTTP/1.1 101 Switching Protocols".to_owned()); -} - -#[test] -fn should_allow_initial_connection_but_only_once() { - // given - let (server, port, authcodes) = serve(); - let code = "initial"; - let timestamp = time::UNIX_EPOCH.elapsed().unwrap().as_secs(); - assert!(authcodes.is_empty()); - - // when - let response1 = http_client::request(server.addr(), - &format!("\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:{}\r\n\ - Connection: Close\r\n\ - Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ - Sec-WebSocket-Protocol:{:?}_{}\r\n\ - Sec-WebSocket-Version: 13\r\n\ - \r\n\ - {{}} - ", - port, - format!("{}:{}", code, timestamp).sha3(), - timestamp, - ) - ); - let response2 = http_client::request(server.addr(), - &format!("\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:{}\r\n\ - Connection: Close\r\n\ - Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ - Sec-WebSocket-Protocol:{:?}_{}\r\n\ - Sec-WebSocket-Version: 13\r\n\ - \r\n\ - {{}} - ", - port, - format!("{}:{}", code, timestamp).sha3(), - timestamp, - ) - ); - - - // then - assert_eq!(response1.status, "HTTP/1.1 101 Switching Protocols".to_owned()); - assert_eq!(response2.status, "HTTP/1.1 403 FORBIDDEN".to_owned()); - http_client::assert_security_headers_present(&response2.headers, None); + // when + let response = request(server, + "\ + GET / HTTP/1.1\r\n\ + Host: test:8180\r\n\ + Connection: close\r\n\ + \r\n\ + {} + " + ); + + // then + assert_eq!(response.status, "HTTP/1.1 403 FORBIDDEN".to_owned()); + assert!(response.body.contains("URL Blocked")); + http_client::assert_security_headers_present(&response.headers, None); + } + + #[test] + fn should_allow_home_parity_host() { + // given + let server = serve().0; + + // when + let response = request(server, + "\ + GET http://home.parity/ HTTP/1.1\r\n\ + Host: home.parity\r\n\ + Connection: close\r\n\ + \r\n\ + {} + " + ); + + // then + assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); + http_client::assert_security_headers_present(&response.headers, None); + } + + #[test] + fn should_serve_styles_even_on_disallowed_domain() { + // given + let server = serve().0; + + // when + let response = request(server, + "\ + GET /styles.css HTTP/1.1\r\n\ + Host: test:8180\r\n\ + Connection: close\r\n\ + \r\n\ + {} + " + ); + + // then + assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); + http_client::assert_security_headers_present(&response.headers, None); + } + + #[test] + fn should_return_200_ok_for_connect_requests() { + // given + let server = serve().0; + + // when + let response = request(server, + "\ + CONNECT home.parity:8080 HTTP/1.1\r\n\ + Host: home.parity\r\n\ + Connection: close\r\n\ + \r\n\ + {} + " + ); + + // then + assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); + } + + #[test] + fn should_block_if_authorization_is_incorrect() { + // given + let (server, port, _) = serve(); + + // when + let response = request(server, + &format!("\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:{}\r\n\ + Connection: Upgrade\r\n\ + Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ + Sec-WebSocket-Protocol: wrong\r\n\ + Sec-WebSocket-Version: 13\r\n\ + \r\n\ + {{}} + ", port) + ); + + // then + assert_eq!(response.status, "HTTP/1.1 403 FORBIDDEN".to_owned()); + http_client::assert_security_headers_present(&response.headers, None); + } + + #[test] + fn should_allow_if_authorization_is_correct() { + // given + let (server, port, mut authcodes) = serve(); + let code = authcodes.generate_new().unwrap().replace("-", ""); + authcodes.to_file(&authcodes.path).unwrap(); + let timestamp = time::UNIX_EPOCH.elapsed().unwrap().as_secs(); + + // when + let response = request(server, + &format!("\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:{}\r\n\ + Connection: Close\r\n\ + Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ + Sec-WebSocket-Protocol: {:?}_{}\r\n\ + Sec-WebSocket-Version: 13\r\n\ + \r\n\ + {{}} + ", + port, + format!("{}:{}", code, timestamp).sha3(), + timestamp, + ) + ); + + // then + assert_eq!(response.status, "HTTP/1.1 101 Switching Protocols".to_owned()); + } + + #[test] + fn should_allow_initial_connection_but_only_once() { + // given + let (server, port, authcodes) = serve(); + let code = "initial"; + let timestamp = time::UNIX_EPOCH.elapsed().unwrap().as_secs(); + assert!(authcodes.is_empty()); + + // when + let response1 = http_client::request(server.addr(), + &format!("\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:{}\r\n\ + Connection: Close\r\n\ + Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ + Sec-WebSocket-Protocol:{:?}_{}\r\n\ + Sec-WebSocket-Version: 13\r\n\ + \r\n\ + {{}} + ", + port, + format!("{}:{}", code, timestamp).sha3(), + timestamp, + ) + ); + let response2 = http_client::request(server.addr(), + &format!("\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:{}\r\n\ + Connection: Close\r\n\ + Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\ + Sec-WebSocket-Protocol:{:?}_{}\r\n\ + Sec-WebSocket-Version: 13\r\n\ + \r\n\ + {{}} + ", + port, + format!("{}:{}", code, timestamp).sha3(), + timestamp, + ) + ); + + + // then + assert_eq!(response1.status, "HTTP/1.1 101 Switching Protocols".to_owned()); + assert_eq!(response2.status, "HTTP/1.1 403 FORBIDDEN".to_owned()); + http_client::assert_security_headers_present(&response2.headers, None); + } }