1use std::{
2 cmp::min,
3 io::{self, Read, Write},
4 net::TcpStream,
5 time::Duration,
6};
7
8#[derive(Debug)]
9struct StringStream(Vec<u8>, usize);
10
11impl Read for StringStream {
12 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
13 let n = self.peek(buf)?;
14 self.1 += n;
15 Ok(n)
16 }
17
18 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
19 const CHUNK_SIZE: usize = 1024;
20 let mut chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
21 let n = self.1;
22 while self.read(&mut chunk)? > 0 {
23 buf.write_all(&chunk)?;
24 }
25 Ok(self.1 - n)
26 }
27}
28
29impl StringStream {
30 fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
31 if buf.is_empty() || self.1 >= self.0.len() {
32 return Ok(0);
33 }
34 let src = &self.0[self.1..];
35 let n = min(buf.len(), src.len());
36 buf[..n].copy_from_slice(src);
37 Ok(n)
38 }
39}
40
41#[derive(Debug)]
42enum HttpStreamInner {
43 Tcp(TcpStream),
44 String(StringStream, Vec<u8>),
45 Dummy,
46}
47
48#[derive(Debug)]
81pub struct HttpStream {
82 inner: HttpStreamInner,
83}
84
85impl HttpStream {
86 pub fn set_read_timeout(&self, d: Option<Duration>) -> io::Result<()> {
87 match &self.inner {
88 HttpStreamInner::Tcp(tcp_stream) => tcp_stream.set_read_timeout(d),
89 HttpStreamInner::Dummy | HttpStreamInner::String(..) => Ok(()),
90 }
91 }
92 pub fn peek(&self, buf: &mut [u8]) -> std::io::Result<usize> {
93 match &self.inner {
94 HttpStreamInner::Tcp(tcp_stream) => tcp_stream.peek(buf),
95 HttpStreamInner::Dummy => Ok(0),
96 HttpStreamInner::String(read, _) => read.peek(buf),
97 }
98 }
99 pub fn is_ready(&self) -> std::io::Result<bool> {
100 let mut buf = [0_u8; 1];
101 let n = match &self.inner {
102 HttpStreamInner::Tcp(tcp_stream) => tcp_stream.peek(&mut buf)?,
103 HttpStreamInner::String(string_stream, _) => string_stream.peek(&mut buf)?,
104 HttpStreamInner::Dummy => 0,
105 };
106 Ok(n > 0)
107 }
108}
109
110impl Read for HttpStream {
111 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
112 match &mut self.inner {
113 HttpStreamInner::Tcp(tcp_stream) => tcp_stream.read(buf),
114 HttpStreamInner::Dummy => Ok(0),
115 HttpStreamInner::String(buf_reader, _) => buf_reader.read(buf),
116 }
117 }
118}
119
120impl Write for HttpStream {
121 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
122 match &mut self.inner {
123 HttpStreamInner::Tcp(tcp_stream) => tcp_stream.write(buf),
124 HttpStreamInner::Dummy => Ok(0),
125 HttpStreamInner::String(_, w) => w.write(buf),
126 }
127 }
128
129 fn flush(&mut self) -> std::io::Result<()> {
130 match &mut self.inner {
131 HttpStreamInner::Tcp(tcp_stream) => tcp_stream.flush(),
132 HttpStreamInner::Dummy | HttpStreamInner::String(..) => Ok(()),
133 }
134 }
135}
136
137impl From<TcpStream> for HttpStream {
138 fn from(value: TcpStream) -> Self {
139 Self {
140 inner: HttpStreamInner::Tcp(value),
141 }
142 }
143}
144
145impl From<String> for HttpStream {
146 fn from(value: String) -> Self {
147 let src_vec = value.into_bytes();
148 let stream = StringStream(src_vec, 0);
149 Self {
150 inner: HttpStreamInner::String(stream, Vec::new()),
151 }
152 }
153}
154
155impl<'a> From<&'a str> for HttpStream {
156 fn from(value: &'a str) -> Self {
157 Self::from(value.to_string())
158 }
159}
160
161impl HttpStream {
162 #[must_use]
163 pub fn dummy() -> Self {
164 Self {
165 inner: HttpStreamInner::Dummy,
166 }
167 }
168}