async_http_codec/internal/
dec_helpers.rs1use crate::{RequestHead, ResponseHead};
2use http::header::HeaderName;
3use http::{HeaderMap, HeaderValue, Method, Request, Response, StatusCode, Uri, Version};
4use httparse::Header;
5use std::error::Error;
6use std::io;
7use std::io::ErrorKind::InvalidData;
8
9#[allow(deprecated)]
10pub fn request_head_parse(buffer: &[u8], max_headers: usize) -> io::Result<RequestHead<'static>> {
11 let mut headers = vec![httparse::EMPTY_HEADER; max_headers];
12 let mut parsed_request = httparse::Request::new(&mut headers);
13 if parsed_request
14 .parse(buffer)
15 .map_err(|err| io::Error::new(InvalidData, err.description()))?
16 .is_partial()
17 {
18 return Err(io::Error::new(InvalidData, "malformed HTTP head"));
19 }
20 if parsed_request.version != Some(1) {
21 return Err(io::Error::new(InvalidData, "unsupported HTTP version"));
22 }
23 let method = Method::from_bytes(parsed_request.method.unwrap_or("").as_bytes())
24 .map_err(|err| io::Error::new(InvalidData, err.description()))?;
25 let uri = parsed_request
26 .path
27 .unwrap_or("")
28 .parse::<Uri>()
29 .map_err(|_| io::Error::new(InvalidData, "invalid uri"))?;
30 let mut request = Request::new(());
31 *request.method_mut() = method;
32 *request.uri_mut() = uri;
33 *request.version_mut() = Version::HTTP_11;
34 let headers = request.headers_mut();
35 copy_parsed_headers(headers, parsed_request.headers)?;
36 Ok(RequestHead::from(request))
37}
38
39#[allow(deprecated)]
40pub fn response_head_parse(buffer: &[u8], max_headers: usize) -> io::Result<ResponseHead<'static>> {
41 let mut headers = vec![httparse::EMPTY_HEADER; max_headers];
42 let mut parsed_response = httparse::Response::new(&mut headers);
43 if parsed_response
44 .parse(buffer)
45 .map_err(|err| io::Error::new(InvalidData, err.description()))?
46 .is_partial()
47 {
48 return Err(io::Error::new(InvalidData, "malformed HTTP head"));
49 }
50 if parsed_response.version != Some(1) {
51 return Err(io::Error::new(InvalidData, "unsupported HTTP version"));
52 }
53 let mut response = Response::new(());
54 *response.version_mut() = Version::HTTP_11;
55 *response.status_mut() = StatusCode::from_u16(parsed_response.code.unwrap())
56 .map_err(|_| io::Error::new(InvalidData, "invalid status code"))?;
57 let headers = response.headers_mut();
58 copy_parsed_headers(headers, parsed_response.headers)?;
59 Ok(ResponseHead::from(response))
60}
61
62pub(crate) fn copy_parsed_headers(trg: &mut HeaderMap, parsed: &[Header]) -> io::Result<()> {
63 trg.reserve(parsed.len());
64 for header in parsed {
65 trg.append(
66 HeaderName::from_bytes(header.name.as_bytes())
67 .map_err(|_| io::Error::new(InvalidData, "invalid header name"))?,
68 HeaderValue::from_bytes(header.value)
69 .map_err(|_| io::Error::new(InvalidData, "invalid header value"))?,
70 );
71 }
72 Ok(())
73}