feather_runtime/http/
request.rs1use std::io;
2use std::net::SocketAddr;
3pub type Error = Box<dyn std::error::Error>;
6use bytes::Bytes;
7use http::{Extensions, HeaderMap, Method, Uri, Version};
8use std::str::FromStr;
9use std::{borrow::Cow, collections::HashMap, fmt};
10use urlencoding::decode;
11#[derive(Debug)]
14pub struct Request {
15 pub method: Method,
18 pub uri: Uri,
20 pub version: Version,
22 pub headers: HeaderMap,
24 pub body: Bytes,
26 pub extensions: Extensions,
28 addr: SocketAddr,
30 params: HashMap<String, String>,
32}
33
34impl Request {
35 pub fn parse(headers_raw: &[u8], body: Bytes, incoming_addr: SocketAddr) -> Result<Request, Error> {
37 let mut headers = [httparse::EMPTY_HEADER; 64];
38 let mut request = httparse::Request::new(&mut headers);
39
40 request.parse(headers_raw).map_err(|e| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to parse request: {}", e))) })?;
41
42 let method_str = request.method.ok_or_else(|| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, "Missing HTTP method")) })?;
44
45 let method = Method::from_str(method_str).map_err(|_| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Invalid HTTP method: {}", method_str))) })?;
47 let path = request.path.ok_or_else(|| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, "Failed to parse URI")) })?;
48 let uri: Uri = path.parse().map_err(|e| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to parse URI: {}", e))) })?;
49
50 let version = match request.version {
51 Some(0) => Version::HTTP_10,
52 Some(1) => Version::HTTP_11,
53 _ => Version::HTTP_11,
54 };
55 let mut header_map = HeaderMap::new();
56 for header in request.headers.iter() {
57 let name = http::header::HeaderName::from_bytes(header.name.as_bytes()).map_err(|e| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to parse header name: {}", e))) })?;
58 let value = http::header::HeaderValue::from_bytes(header.value).map_err(|e| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to parse header value: {}", e))) })?;
59
60 header_map.insert(name, value);
61 }
62
63 let extensions = Extensions::new();
64 Ok(Request {
65 method,
66 uri,
67 version,
68 headers: header_map,
69 body,
70 addr: incoming_addr,
71 extensions,
72 params: HashMap::new(),
73 })
74 }
75
76 #[cfg(feature = "json")]
79 pub fn json(&self) -> Result<serde_json::Value, Error> {
80 serde_json::from_slice(&self.body).map_err(|e| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to parse JSON body: {}", e))) })
81 }
82 pub fn query(&self) -> Result<HashMap<String, String>, Error> {
85 if let Some(query) = self.uri.query() {
86 serde_urlencoded::from_str(query).map_err(|e| -> Error { Box::new(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to Parse Query parameters {}", e))) })
87 } else {
88 Ok(HashMap::new())
89 }
90 }
91
92 pub fn set_params(&mut self, params: HashMap<String, String>) {
93 self.params = params;
94 }
95
96 pub fn param(&self, key: &str) -> Option<&str> {
97 self.params.get(key).map(|v| &**v)
98 }
99
100 pub fn path(&self) -> Cow<'_, str> {
102 decode(self.uri.path()).unwrap()
103 }
104 pub fn remote_addr(&self) -> SocketAddr {
105 self.addr
106 }
107}
108
109impl fmt::Display for Request {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 write!(f, "{} {}", self.method, self.uri.path())
112 }
113}