1use crate::header::{HeaderValues, RequestHeader, Uri, HOST};
2
3use std::net::SocketAddr;
4
5use hyper::http::uri::{Authority, Scheme};
6
7#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
8pub enum HeaderError {
9 #[error("No host header found")]
10 NoHost,
11
12 #[error("Host header is invalid")]
13 HostInvalid,
14
15 #[error("Invalid uri")]
16 Uri,
17}
18
19type Result<T> = std::result::Result<T, HeaderError>;
20
21pub fn convert_hyper_parts_to_fire_header(
22 parts: hyper::http::request::Parts,
23 address: SocketAddr,
24) -> Result<RequestHeader> {
25 let values = HeaderValues::from_inner(parts.headers);
26 let uri = fill_uri(parts.uri, &values)?;
27
28 Ok(RequestHeader {
29 address,
30 method: parts.method,
31 uri,
32 values,
33 })
34}
35
36pub fn convert_hyper_req_to_fire_header<B>(
37 req: &hyper::Request<B>,
38 address: SocketAddr,
39) -> Result<RequestHeader> {
40 let values = HeaderValues::from_inner(req.headers().clone());
41 let uri = fill_uri(req.uri().clone(), &values)?;
42
43 Ok(RequestHeader {
44 address,
45 method: req.method().clone(),
46 uri,
47 values,
48 })
49}
50
51fn fill_uri(uri: Uri, headers: &HeaderValues) -> Result<Uri> {
52 let mut parts = uri.into_parts();
53 parts.scheme = Some(Scheme::HTTP);
56
57 let host = headers.get(HOST).ok_or(HeaderError::NoHost)?;
59
60 parts.authority = Some(
61 Authority::try_from(host.as_bytes())
62 .map_err(|_| HeaderError::HostInvalid)?,
63 );
64
65 Uri::from_parts(parts).map_err(|_| HeaderError::Uri)
66}