1#![forbid(unsafe_code)]
8#![deny(
9 missing_copy_implementations,
10 rustdoc::missing_crate_level_docs,
11 missing_debug_implementations,
12 missing_docs,
13 nonstandard_style,
14 unused_qualifications
15)]
16
17#[cfg(test)]
18#[doc = include_str!("../README.md")]
19mod readme {}
20
21use trillium::{Conn, Handler, KnownHeaderName::ContentLength, Method, Transport};
22
23#[derive(Default, Clone, Copy, Debug)]
27pub struct Head {
28 _my_private_things: (),
29}
30
31impl Head {
32 pub fn new() -> Self {
34 Self::default()
35 }
36}
37
38#[derive(Clone, Copy, Debug)]
39struct RequestWasHead;
40
41impl Handler for Head {
42 async fn run(&self, mut conn: Conn) -> Conn {
43 if conn.method() == Method::Head {
44 AsMut::<trillium_http::Conn<Box<dyn Transport>>>::as_mut(&mut conn)
45 .set_method(Method::Get);
46 conn.insert_state(RequestWasHead);
47 }
48
49 conn
50 }
51
52 async fn before_send(&self, mut conn: Conn) -> Conn {
53 if conn.state::<RequestWasHead>().is_none() {
54 return conn;
55 }
56 AsMut::<trillium_http::Conn<Box<dyn Transport>>>::as_mut(&mut conn)
57 .set_method(Method::Head);
58 if let Some(len) = conn.take_response_body().and_then(|body| body.len()) {
59 conn.response_headers_mut().insert(ContentLength, len);
60 }
61
62 conn
63 }
64}
65
66pub fn head() -> Head {
68 Head::new()
69}