1#![forbid(unsafe_code)]
10#![deny(
11 missing_copy_implementations,
12 rustdoc::missing_crate_level_docs,
13 missing_debug_implementations,
14 missing_docs,
15 nonstandard_style,
16 unused_qualifications
17)]
18
19use trillium::{async_trait, conn_unwrap, Conn, Handler, KnownHeaderName::ContentLength, Method};
20
21#[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
41#[async_trait]
42impl Handler for Head {
43 async fn run(&self, mut conn: Conn) -> Conn {
44 if conn.method() == Method::Head {
45 conn.inner_mut().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 conn_unwrap!(conn.state::<RequestWasHead>(), conn);
54 conn.inner_mut().set_method(Method::Head);
55 let len = conn_unwrap!(
56 conn.inner_mut()
57 .take_response_body()
58 .and_then(|body| body.len()),
59 conn
60 );
61 conn.with_response_header(ContentLength, len.to_string())
62 }
63}
64
65pub fn head() -> Head {
67 Head::new()
68}