| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
use axum::{ |
| 20 |
extract::Path, |
| 21 |
http::{StatusCode, header}, |
| 22 |
response::{IntoResponse, Response}, |
| 23 |
}; |
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
const PAGE_404: &str = include_str!(concat!( |
| 28 |
env!("CARGO_MANIFEST_DIR"), |
| 29 |
"/deploy/error-pages/404.html" |
| 30 |
)); |
| 31 |
const PAGE_500: &str = include_str!(concat!( |
| 32 |
env!("CARGO_MANIFEST_DIR"), |
| 33 |
"/deploy/error-pages/500.html" |
| 34 |
)); |
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
pub(super) async fn error_page(Path(name): Path<String>) -> Response { |
| 45 |
let (status, body) = match name.as_str() { |
| 46 |
"500.html" => (StatusCode::INTERNAL_SERVER_ERROR, PAGE_500), |
| 47 |
_ => (StatusCode::NOT_FOUND, PAGE_404), |
| 48 |
}; |
| 49 |
( |
| 50 |
status, |
| 51 |
[(header::CONTENT_TYPE, "text/html; charset=utf-8")], |
| 52 |
body, |
| 53 |
) |
| 54 |
.into_response() |
| 55 |
} |
| 56 |
|
| 57 |
#[cfg(test)] |
| 58 |
mod tests { |
| 59 |
use super::*; |
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
#[test] |
| 64 |
fn embedded_pages_are_the_real_pages() { |
| 65 |
for page in [PAGE_404, PAGE_500] { |
| 66 |
assert!(page.starts_with("<!DOCTYPE html>"), "not an HTML document"); |
| 67 |
assert!(page.contains("makenot.work"), "missing the wordmark"); |
| 68 |
} |
| 69 |
assert!(PAGE_404.contains("404")); |
| 70 |
assert!(PAGE_500.contains("500")); |
| 71 |
} |
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
#[tokio::test] |
| 76 |
async fn unknown_names_including_502_serve_the_404_page() { |
| 77 |
for name in ["502.html", "tea.html", "../../etc/passwd"] { |
| 78 |
let res = error_page(Path(name.to_string())).await; |
| 79 |
assert_eq!(res.status(), StatusCode::NOT_FOUND, "{name}"); |
| 80 |
} |
| 81 |
} |
| 82 |
|
| 83 |
#[tokio::test] |
| 84 |
async fn status_matches_the_page() { |
| 85 |
let res = error_page(Path("500.html".to_string())).await; |
| 86 |
assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR); |
| 87 |
} |
| 88 |
} |
| 89 |
|