use crate::error::Error;
use crate::http::{html, text, Request, Response, MAX_REQUEST_BODY_BYTES};
use crate::middleware::Next;
use crate::router::{Params, Router};
const HOME_HTML: &str = include_str!("../assets/home.html");
pub fn homepage() -> Response {
html(HOME_HTML)
}
pub fn docs_placeholder() -> Response {
text("RustIO docs — coming soon.")
}
pub async fn body_limit(req: Request, next: Next) -> Result<Response, Error> {
if let Some(header) = req.headers().get(hyper::header::CONTENT_LENGTH) {
if let Ok(s) = header.to_str() {
if let Ok(n) = s.parse::<u64>() {
if n as u128 > MAX_REQUEST_BODY_BYTES as u128 {
return Err(Error::PayloadTooLarge);
}
}
}
}
next.run(req).await
}
pub fn with_defaults(mut router: Router) -> Router {
if !router.has_route(&hyper::Method::GET, "/") {
router = router.get("/", |_req: Request, _p: Params| async {
Ok::<Response, Error>(homepage())
});
}
if !router.has_route(&hyper::Method::GET, "/docs") {
router = router.get("/docs", |_req: Request, _p: Params| async {
Ok::<Response, Error>(docs_placeholder())
});
}
router.wrap(body_limit)
}
#[cfg(test)]
mod tests {
use super::*;
fn check_content_length(value: &str) -> Result<(), ()> {
let n: u64 = value.parse().map_err(|_| ())?;
if n as u128 > MAX_REQUEST_BODY_BYTES as u128 {
Err(())
} else {
Ok(())
}
}
#[test]
fn content_length_at_limit_is_accepted() {
let at_limit = MAX_REQUEST_BODY_BYTES.to_string();
assert!(check_content_length(&at_limit).is_ok());
}
#[test]
fn content_length_over_limit_is_rejected() {
let over = (MAX_REQUEST_BODY_BYTES + 1).to_string();
assert!(check_content_length(&over).is_err());
}
#[test]
fn content_length_way_over_limit_is_rejected() {
let huge = format!("{}", u64::MAX);
assert!(check_content_length(&huge).is_err());
}
}