http/response/
mod.rs

1use std::{
2    collections::HashMap,
3    io::{self, BufReader, Read},
4};
5
6use builders::Builder;
7use parse::parse_response;
8
9use crate::HttpStream;
10
11mod parse;
12
13#[derive(Builder)]
14pub struct HttpResponse {
15    #[builder(each = "header")]
16    headers: HashMap<String, String>,
17    #[builder(disabled = true)]
18    #[builder(def = { BufReader::new(HttpStream::dummy()) })]
19    stream: BufReader<HttpStream>,
20    #[builder(def = 200u16)]
21    status: u16,
22    #[builder(optional = true)]
23    body: Option<Vec<u8>>,
24    #[builder(def = 1.0)]
25    version: f32,
26}
27
28impl HttpResponse {
29    pub fn parse(stream: impl Into<HttpStream>) -> crate::Result<Self> {
30        let stream = BufReader::new(stream.into());
31        parse_response(stream)
32    }
33    #[inline]
34    #[must_use]
35    pub fn status(&self) -> u16 {
36        self.status
37    }
38
39    #[inline]
40    #[must_use]
41    pub fn content_length(&self) -> usize {
42        match self.headers.get("Content-Length") {
43            Some(l) => l.parse().unwrap_or(0),
44            None => 0,
45        }
46    }
47    /// Get the value of the given header key, if present
48    #[inline]
49    #[must_use]
50    pub fn header(&self, key: &str) -> Option<&str> {
51        self.headers.get(key).map(String::as_str)
52    }
53
54    #[inline]
55    #[must_use]
56    pub fn version(&self) -> f32 {
57        self.version
58    }
59
60    #[inline]
61    #[must_use]
62    pub fn headers(&self) -> &HashMap<String, String> {
63        &self.headers
64    }
65
66    pub fn body(&mut self) -> Option<&[u8]> {
67        let len = self.content_length();
68        let mut buf: Vec<u8> = Vec::with_capacity(len);
69        if self.stream.read_to_end(&mut buf).is_ok() {
70            self.body = Some(buf);
71        }
72        self.body.as_deref()
73    }
74    pub fn write_to(&mut self, out: &mut dyn io::Write) -> io::Result<usize> {
75        let mut buf = [0_u8; 1024];
76        let mut total = 0;
77        while let Ok(n) = self.stream.read(&mut buf) {
78            out.write_all(&buf[0..n])?;
79            total += n;
80            if n == 0 {
81                break;
82            }
83        }
84        out.flush()?;
85        Ok(total)
86    }
87}