use http_fs::{ServeEntry, StaticFiles}; use std::path::Path; #[test] fn serve_files() { let static_files = StaticFiles::default(); let path = Path::new("Cargo.tml"); let result = static_files.serve(&path); match result { ServeEntry::NotFound => (), _ => panic!("Unexpected result for serve. Should ServeEntry::NotFound") } //Serve file with no headers for GET. let path = Path::new("Cargo.toml"); match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let file_len = format!("{}", meta.len()); let file_etag = format!("{}", etag::EntityTag::from_file_meta(&meta)); let file_last_modified = httpdate::fmt_http_date(meta.modified().expect("Get Last-Modified")); let headers = http::header::HeaderMap::new(); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::GET, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::OK); let etag = out_headers.get(http::header::ETAG).expect("To have ETag in out_headers"); let last_modified = out_headers.get(http::header::LAST_MODIFIED).expect("To have Last-Modified in out_headers"); let content_type = out_headers.get(http::header::CONTENT_TYPE).expect("To have Content-Type in out_headers"); let content_disposition = out_headers.get(http::header::CONTENT_DISPOSITION).expect("To have Content-Disposition in out_headers"); let content_len = out_headers.get(http::header::CONTENT_LENGTH).expect("To have Content-Length in out_headers"); assert_eq!(etag.to_str().unwrap(), file_etag); assert_eq!(last_modified.to_str().unwrap(), file_last_modified); assert_eq!(content_len.to_str().unwrap(), file_len); assert_eq!(content_type.to_str().unwrap(), "text/x-toml"); assert_eq!(content_disposition.to_str().unwrap(), "inline"); assert!(!body.is_finished()); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } //Serve file with no headers for HEAD. match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let file_len = format!("{}", meta.len()); let file_etag = format!("{}", etag::EntityTag::from_file_meta(&meta)); let file_last_modified = httpdate::fmt_http_date(meta.modified().expect("Get Last-Modified")); let headers = http::header::HeaderMap::new(); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::HEAD, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::OK); let etag = out_headers.get(http::header::ETAG).expect("To have ETag in out_headers"); let last_modified = out_headers.get(http::header::LAST_MODIFIED).expect("To have Last-Modified in out_headers"); let content_type = out_headers.get(http::header::CONTENT_TYPE).expect("To have Content-Type in out_headers"); let content_disposition = out_headers.get(http::header::CONTENT_DISPOSITION).expect("To have Content-Disposition in out_headers"); let content_len = out_headers.get(http::header::CONTENT_LENGTH).expect("To have Content-Length in out_headers"); assert_eq!(etag.to_str().unwrap(), file_etag); assert_eq!(last_modified.to_str().unwrap(), file_last_modified); assert_eq!(content_len.to_str().unwrap(), file_len); assert_eq!(content_type.to_str().unwrap(), "text/x-toml"); assert_eq!(content_disposition.to_str().unwrap(), "inline"); assert!(body.is_finished()); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } //Serve cached file by ETAG match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let file_etag = etag::EntityTag::from_file_meta(&meta); let mut headers = http::header::HeaderMap::new(); headers.insert(http::header::IF_NONE_MATCH, http_fs::utils::display_to_header(&file_etag)); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::GET, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::NOT_MODIFIED); assert!(body.is_finished()); let etag = out_headers.get(http::header::ETAG).expect("To have ETag in out_headers"); assert_eq!(etag.to_str().unwrap(), format!("{}", file_etag)); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let mut headers = http::header::HeaderMap::new(); headers.insert(http::header::IF_MATCH, http_fs::utils::display_to_header(&"wrong etag")); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::GET, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::PRECONDITION_FAILED); assert!(body.is_finished()); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } //Serve cached file by Last-Modified match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let file_last_modified = httpdate::fmt_http_date(meta.modified().expect("Get Last-Modified")); let mut headers = http::header::HeaderMap::new(); headers.insert(http::header::IF_MODIFIED_SINCE, http_fs::utils::display_to_header(&file_last_modified)); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::GET, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::NOT_MODIFIED); assert!(body.is_finished()); let etag = out_headers.get(http::header::LAST_MODIFIED).expect("To have Last-Modified in out_headers"); assert_eq!(etag.to_str().unwrap(), format!("{}", file_last_modified)); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let file_last_modified = httpdate::fmt_http_date(meta.modified().expect("Get Last-Modified")); let mut headers = http::header::HeaderMap::new(); headers.insert(http::header::IF_MODIFIED_SINCE, http_fs::utils::display_to_header(&file_last_modified)); //We ignore IF_MODIFIED_SINCE when IF_NONE_MATCH is present headers.insert(http::header::IF_NONE_MATCH, http::header::HeaderValue::from_static("dummy")); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::GET, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::OK); assert!(!body.is_finished()); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } match static_files.serve(&path) { ServeEntry::File(file, meta, _) => { let file_last_modified = httpdate::fmt_http_date(meta.modified().expect("Get Last-Modified")); let unmodified_since = meta.modified().expect("Get Last-Modified") - std::time::Duration::from_secs(60); let mut headers = http::header::HeaderMap::new(); headers.insert(http::header::IF_UNMODIFIED_SINCE, http_fs::utils::display_to_header(&httpdate::fmt_http_date(unmodified_since))); let mut out_headers = http::header::HeaderMap::new(); let (code, body) = static_files.serve_file(&path, file, meta, http::Method::GET, &headers, &mut out_headers); assert_eq!(code, http::StatusCode::PRECONDITION_FAILED); assert!(body.is_finished()); let etag = out_headers.get(http::header::LAST_MODIFIED).expect("To have Last-Modified in out_headers"); assert_eq!(etag.to_str().unwrap(), format!("{}", file_last_modified)); }, _ => panic!("Unexpected result for serve. Should ServeEntry::File") } }