http1_spec/
request_head_renderer.rs

1use std::io::{Error as IoError, ErrorKind as IoErrorKind};
2
3use http::{request::Parts, Request, Version};
4
5use crate::{
6    head_renderer::HeadRenderer, COLON, CRLF, HTTP_VERSION_10, HTTP_VERSION_11, HTTP_VERSION_2,
7    HTTP_VERSION_3, SP,
8};
9
10#[derive(Default)]
11pub struct RequestHeadRenderer {}
12
13impl HeadRenderer<Request<()>> for RequestHeadRenderer {
14    fn new() -> Self {
15        Self::default()
16    }
17
18    fn render(&self, head: Request<()>, buf: &mut Vec<u8>) -> Result<(), IoError> {
19        let (parts, _) = head.into_parts();
20        HeadRenderer::<Parts>::render(self, parts, buf)
21    }
22}
23
24impl HeadRenderer<Parts> for RequestHeadRenderer {
25    fn new() -> Self {
26        Self::default()
27    }
28
29    fn render(&self, parts: Parts, buf: &mut Vec<u8>) -> Result<(), IoError> {
30        let version_bytes = match parts.version {
31            Version::HTTP_10 => HTTP_VERSION_10,
32            Version::HTTP_11 => HTTP_VERSION_11,
33            Version::HTTP_2 => HTTP_VERSION_2,
34            Version::HTTP_3 => HTTP_VERSION_3,
35            _ => return Err(IoError::new(IoErrorKind::InvalidInput, "unimplemented")),
36        };
37
38        buf.extend_from_slice(parts.method.as_str().as_bytes());
39        buf.extend_from_slice(&[SP]);
40        buf.extend_from_slice(parts.uri.to_string().as_bytes());
41        buf.extend_from_slice(&[SP]);
42        buf.extend_from_slice(version_bytes);
43        buf.extend_from_slice(CRLF);
44
45        for (k, v) in &parts.headers {
46            buf.extend_from_slice(k.to_string().as_bytes());
47            buf.extend_from_slice(&[COLON]);
48            buf.extend_from_slice(v.as_bytes());
49            buf.extend_from_slice(CRLF);
50        }
51
52        buf.extend_from_slice(CRLF);
53
54        Ok(())
55    }
56}