From ff4ec6e0af2c3759b48bbcba0782c0c3139ab115 Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Tue, 21 Apr 2020 14:17:10 +0200 Subject: [PATCH] feat: staticfile test cases --- Cargo.lock | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +++ src/main.rs | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 02ed881..f486684 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,6 +295,19 @@ dependencies = [ ] [[package]] +name = "iron-test" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1944bcf30f8b3f51ebf01e715517dd9755e9480934778d6de70179a41d283c1" +dependencies = [ + "hyper", + "iron", + "log 0.3.9", + "url", + "uuid", +] + +[[package]] name = "iron_staticfile_middleware" version = "0.3.0" source = "git+https://github.com/joseluisq/iron-staticfile-middleware.git#d3107bbf9718dffa00d3fb3ec703eeea74f89b97" @@ -613,6 +626,29 @@ dependencies = [ [[package]] name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +dependencies = [ + "libc", + "rand 0.4.6", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" @@ -874,14 +910,17 @@ dependencies = [ "chrono", "env_logger", "flate2", + "hyper", "hyper-native-tls", "iron", + "iron-test", "iron_staticfile_middleware", "log 0.4.8", "nix", "openssl", "signal", "structopt", + "tempdir", ] [[package]] @@ -937,6 +976,16 @@ dependencies = [ ] [[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + +[[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1074,6 +1123,15 @@ dependencies = [ ] [[package]] +name = "uuid" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" +dependencies = [ + "rand 0.3.23", +] + +[[package]] name = "vcpkg" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 1f660e4..9d88191 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,9 @@ signal = "0.7" [dev-dependencies] openssl = { version = "0.10", features = ["vendored"] } +hyper = "0.10" +iron-test = "0.6" +tempdir = "0.3" [profile.release] lto = true diff --git a/src/main.rs b/src/main.rs index ec5f806..61eea09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,3 +63,180 @@ fn main() { } } } + +#[cfg(test)] +mod test { + extern crate hyper; + extern crate iron_test; + extern crate tempdir; + + use super::*; + + use std::fs::{DirBuilder, File}; + use std::io::Write; + use std::path::{Path, PathBuf}; + + use self::hyper::header::Headers; + use self::iron_test::{request, response}; + use self::tempdir::TempDir; + use iron::headers::ContentLength; + use iron::status; + + struct TestFilesystemSetup(TempDir); + + impl TestFilesystemSetup { + fn new() -> Self { + TestFilesystemSetup(TempDir::new("test").expect("Could not create test directory")) + } + + fn path(&self) -> &Path { + self.0.path() + } + + fn dir(&self, name: &str) -> PathBuf { + let p = self.path().join(name); + DirBuilder::new() + .recursive(true) + .create(&p) + .expect("Could not create directory"); + p + } + + fn file(&self, name: &str, body: Vec) -> PathBuf { + let p = self.path().join(name); + + let mut file = File::create(&p).expect("Could not create file"); + file.write_all(&body).expect("Could not write to file"); + + p + } + } + + #[test] + fn staticfile_allow_request_methods() { + let opts = Options::from_args(); + + let files = StaticFiles::new(StaticFilesOptions { + root_dir: opts.root, + assets_dir: opts.assets, + page_50x_path: opts.page50x, + page_404_path: opts.page404, + }); + + let response = request::head("http://127.0.0.1/", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::Ok)); + + let response = request::get("http://127.0.0.1/", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::Ok)); + } + + #[test] + fn staticfile_empty_body_on_head_request() { + let opts = Options::from_args(); + + let files = StaticFiles::new(StaticFilesOptions { + root_dir: opts.root, + assets_dir: opts.assets, + page_50x_path: opts.page50x, + page_404_path: opts.page404, + }); + + let res = request::head("http://127.0.0.1/", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(res.status, Some(status::Ok)); + + let result_body = response::extract_body_to_bytes(res); + assert_eq!(result_body, vec!()); + } + + #[test] + fn staticfile_valid_content_length_on_head_request() { + let root = TestFilesystemSetup::new(); + root.dir("root"); + root.file("index.html", b"

hello

".to_vec()); + + let assets = TestFilesystemSetup::new(); + assets.dir("assets"); + + let opts = Options::from_args(); + + let files = StaticFiles::new(StaticFilesOptions { + root_dir: root.path().to_str().unwrap().to_string(), + assets_dir: assets.path().to_str().unwrap().to_string(), + page_50x_path: opts.page50x, + page_404_path: opts.page404, + }); + + let res = request::head("http://127.0.0.1/", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(res.status, Some(status::Ok)); + + let content_length = res.headers.get::().unwrap(); + + assert_eq!(content_length.0, 27); + } + + #[test] + fn staticfile_zero_content_length_on_404_head_request() { + let opts = Options::from_args(); + + let files = StaticFiles::new(StaticFilesOptions { + root_dir: opts.root, + assets_dir: opts.assets, + page_50x_path: opts.page50x, + page_404_path: opts.page404, + }); + + let res = request::head("http://127.0.0.1/unknown", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(res.status, Some(status::NotFound)); + + let content_length = res.headers.get::().unwrap(); + + assert_eq!(content_length.0, 0); + } + + #[test] + fn staticfile_disallow_request_methods() { + let opts = Options::from_args(); + + let files = StaticFiles::new(StaticFilesOptions { + root_dir: opts.root, + assets_dir: opts.assets, + page_50x_path: opts.page50x, + page_404_path: opts.page404, + }); + + let response = request::post("http://127.0.0.1/", Headers::new(), "", &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::MethodNotAllowed)); + + let response = request::delete("http://127.0.0.1/", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::MethodNotAllowed)); + + let response = request::put("http://127.0.0.1/", Headers::new(), "", &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::MethodNotAllowed)); + + let response = request::patch("http://127.0.0.1/", Headers::new(), "", &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::MethodNotAllowed)); + + let response = request::options("http://127.0.0.1/", Headers::new(), &files.handle()) + .expect("Response was a http error"); + + assert_eq!(response.status, Some(status::MethodNotAllowed)); + } +} -- libgit2 1.7.2