use mini_static::Server;
use hyper::Method;
use std::fs;
use tempfile::TempDir;
#[test]
fn directory_without_slash_redirects_to_slash() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/docs");
assert_eq!(response.status().as_u16(), 301);
assert_eq!(
response
.headers()
.get("Location")
.and_then(|v| v.to_str().ok()),
Some("/docs/"),
"redirect location should be /docs/"
);
}
#[test]
fn directory_with_slash_serves_index() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/docs/");
assert_eq!(response.status().as_u16(), 200);
assert!(response.headers().get("Location").is_none());
}
#[test]
fn redirect_has_nosniff_header() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/docs");
assert_eq!(response.status().as_u16(), 301);
assert_eq!(
response
.headers()
.get("X-Content-Type-Options")
.and_then(|v| v.to_str().ok()),
Some("nosniff")
);
}
#[test]
fn nested_directory_redirect() {
let root = TempDir::new().unwrap();
fs::create_dir_all(root.path().join("api/v1/users")).unwrap();
fs::write(root.path().join("api/v1/users/index.html"), b"<html>Users</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/api/v1/users");
assert_eq!(response.status().as_u16(), 301);
assert_eq!(
response
.headers()
.get("Location")
.and_then(|v| v.to_str().ok()),
Some("/api/v1/users/")
);
}
#[test]
fn root_directory_redirect() {
let root = TempDir::new().unwrap();
fs::write(root.path().join("index.html"), b"<html>Home</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "");
let status = response.status().as_u16();
assert!(status == 301 || status == 200);
}
#[test]
fn explicit_index_html_request_no_redirect() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/docs/index.html");
assert_eq!(response.status().as_u16(), 200);
assert!(response.headers().get("Location").is_none());
}
#[test]
fn percent_encoded_explicit_index_html_request_no_redirect() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/docs/index.htm%6c");
assert_eq!(response.status().as_u16(), 200);
assert!(
response.headers().get("Location").is_none(),
"percent-encoded explicit index.html request should not redirect"
);
}
#[test]
fn head_method_directory_redirect() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::HEAD, "/docs");
assert_eq!(response.status().as_u16(), 301);
assert_eq!(
response
.headers()
.get("Location")
.and_then(|v| v.to_str().ok()),
Some("/docs/")
);
}
#[test]
fn redirect_location_preserves_encoding() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("my docs")).unwrap();
fs::write(
root.path().join("my docs/index.html"),
b"<html>Index</html>",
)
.unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/my%20docs");
assert_eq!(response.status().as_u16(), 301);
assert_eq!(
response
.headers()
.get("Location")
.and_then(|v| v.to_str().ok()),
Some("/my%20docs/")
);
}
#[test]
fn directory_without_index_html_returns_404() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("empty")).unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/empty");
assert_eq!(response.status().as_u16(), 404);
}
#[test]
fn redirect_location_format_no_double_slash() {
let root = TempDir::new().unwrap();
fs::create_dir(root.path().join("docs")).unwrap();
fs::write(root.path().join("docs/index.html"), b"<html>Index</html>").unwrap();
let server = Server::new(root.path()).unwrap();
let response = server.handle_request_with_method(&Method::GET, "/docs");
let location = response
.headers()
.get("Location")
.and_then(|v| v.to_str().ok())
.unwrap_or("");
assert_eq!(location, "/docs/");
assert!(!location.contains("//"));
}