1use std::{
4 cell::{Ref, RefCell, RefMut},
5 io::{self, Read, Write},
6 pin::Pin,
7 rc::Rc,
8 str::FromStr,
9 task::{Context, Poll},
10};
11
12use actix_codec::{AsyncRead, AsyncWrite, ReadBuf};
13use bytes::{Bytes, BytesMut};
14use http::{Method, Uri, Version};
15
16use crate::{
17 header::{HeaderMap, TryIntoHeaderPair},
18 payload::Payload,
19 Request,
20};
21
22pub struct TestRequest(Option<Inner>);
24
25struct Inner {
26 version: Version,
27 method: Method,
28 uri: Uri,
29 headers: HeaderMap,
30 payload: Option<Payload>,
31}
32
33impl Default for TestRequest {
34 fn default() -> TestRequest {
35 TestRequest(Some(Inner {
36 method: Method::GET,
37 uri: Uri::from_str("/").unwrap(),
38 version: Version::HTTP_11,
39 headers: HeaderMap::new(),
40 payload: None,
41 }))
42 }
43}
44
45impl TestRequest {
46 pub fn with_uri(path: &str) -> TestRequest {
48 TestRequest::default().uri(path).take()
49 }
50
51 pub fn version(&mut self, ver: Version) -> &mut Self {
53 parts(&mut self.0).version = ver;
54 self
55 }
56
57 pub fn method(&mut self, meth: Method) -> &mut Self {
59 parts(&mut self.0).method = meth;
60 self
61 }
62
63 pub fn uri(&mut self, path: &str) -> &mut Self {
68 parts(&mut self.0).uri = Uri::from_str(path).unwrap();
69 self
70 }
71
72 pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
74 match header.try_into_pair() {
75 Ok((key, value)) => {
76 parts(&mut self.0).headers.insert(key, value);
77 }
78 Err(err) => {
79 panic!("Error inserting test header: {}.", err.into());
80 }
81 }
82
83 self
84 }
85
86 pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
88 match header.try_into_pair() {
89 Ok((key, value)) => {
90 parts(&mut self.0).headers.append(key, value);
91 }
92 Err(err) => {
93 panic!("Error inserting test header: {}.", err.into());
94 }
95 }
96
97 self
98 }
99
100 pub fn set_payload(&mut self, data: impl Into<Bytes>) -> &mut Self {
102 let mut payload = crate::h1::Payload::empty();
103 payload.unread_data(data.into());
104 parts(&mut self.0).payload = Some(payload.into());
105 self
106 }
107
108 pub fn take(&mut self) -> TestRequest {
109 TestRequest(self.0.take())
110 }
111
112 pub fn finish(&mut self) -> Request {
114 let inner = self.0.take().expect("cannot reuse test request builder");
115
116 let mut req = if let Some(pl) = inner.payload {
117 Request::with_payload(pl)
118 } else {
119 Request::with_payload(crate::h1::Payload::empty().into())
120 };
121
122 let head = req.head_mut();
123 head.uri = inner.uri;
124 head.method = inner.method;
125 head.version = inner.version;
126 head.headers = inner.headers;
127
128 req
129 }
130}
131
132#[inline]
133fn parts(parts: &mut Option<Inner>) -> &mut Inner {
134 parts.as_mut().expect("cannot reuse test request builder")
135}
136
137#[derive(Debug)]
139pub struct TestBuffer {
140 pub read_buf: Rc<RefCell<BytesMut>>,
141 pub write_buf: Rc<RefCell<BytesMut>>,
142 pub err: Option<Rc<io::Error>>,
143}
144
145impl TestBuffer {
146 pub fn new<T>(data: T) -> Self
148 where
149 T: Into<BytesMut>,
150 {
151 Self {
152 read_buf: Rc::new(RefCell::new(data.into())),
153 write_buf: Rc::new(RefCell::new(BytesMut::new())),
154 err: None,
155 }
156 }
157
158 #[allow(dead_code)]
160 pub(crate) fn clone(&self) -> Self {
161 Self {
162 read_buf: Rc::clone(&self.read_buf),
163 write_buf: Rc::clone(&self.write_buf),
164 err: self.err.clone(),
165 }
166 }
167
168 pub fn empty() -> Self {
170 Self::new("")
171 }
172
173 #[allow(dead_code)]
174 pub(crate) fn read_buf_slice(&self) -> Ref<'_, [u8]> {
175 Ref::map(self.read_buf.borrow(), |b| b.as_ref())
176 }
177
178 #[allow(dead_code)]
179 pub(crate) fn read_buf_slice_mut(&self) -> RefMut<'_, [u8]> {
180 RefMut::map(self.read_buf.borrow_mut(), |b| b.as_mut())
181 }
182
183 #[allow(dead_code)]
184 pub(crate) fn write_buf_slice(&self) -> Ref<'_, [u8]> {
185 Ref::map(self.write_buf.borrow(), |b| b.as_ref())
186 }
187
188 #[allow(dead_code)]
189 pub(crate) fn write_buf_slice_mut(&self) -> RefMut<'_, [u8]> {
190 RefMut::map(self.write_buf.borrow_mut(), |b| b.as_mut())
191 }
192
193 #[allow(dead_code)]
194 pub(crate) fn take_write_buf(&self) -> Bytes {
195 self.write_buf.borrow_mut().split().freeze()
196 }
197
198 pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T) {
200 self.read_buf.borrow_mut().extend_from_slice(data.as_ref())
201 }
202}
203
204impl io::Read for TestBuffer {
205 fn read(&mut self, dst: &mut [u8]) -> Result<usize, io::Error> {
206 if self.read_buf.borrow().is_empty() {
207 if self.err.is_some() {
208 Err(Rc::try_unwrap(self.err.take().unwrap()).unwrap())
209 } else {
210 Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
211 }
212 } else {
213 let size = std::cmp::min(self.read_buf.borrow().len(), dst.len());
214 let b = self.read_buf.borrow_mut().split_to(size);
215 dst[..size].copy_from_slice(&b);
216 Ok(size)
217 }
218 }
219}
220
221impl io::Write for TestBuffer {
222 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
223 self.write_buf.borrow_mut().extend(buf);
224 Ok(buf.len())
225 }
226
227 fn flush(&mut self) -> io::Result<()> {
228 Ok(())
229 }
230}
231
232impl AsyncRead for TestBuffer {
233 fn poll_read(
234 self: Pin<&mut Self>,
235 _: &mut Context<'_>,
236 buf: &mut ReadBuf<'_>,
237 ) -> Poll<io::Result<()>> {
238 let dst = buf.initialize_unfilled();
239 let res = self.get_mut().read(dst).map(|n| buf.advance(n));
240 Poll::Ready(res)
241 }
242}
243
244impl AsyncWrite for TestBuffer {
245 fn poll_write(
246 self: Pin<&mut Self>,
247 _: &mut Context<'_>,
248 buf: &[u8],
249 ) -> Poll<io::Result<usize>> {
250 Poll::Ready(self.get_mut().write(buf))
251 }
252
253 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
254 Poll::Ready(Ok(()))
255 }
256
257 fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
258 Poll::Ready(Ok(()))
259 }
260}
261
262#[derive(Clone)]
264pub struct TestSeqBuffer(Rc<RefCell<TestSeqInner>>);
265
266impl TestSeqBuffer {
267 pub fn new<T>(data: T) -> Self
269 where
270 T: Into<BytesMut>,
271 {
272 Self(Rc::new(RefCell::new(TestSeqInner {
273 read_buf: data.into(),
274 write_buf: BytesMut::new(),
275 err: None,
276 })))
277 }
278
279 pub fn empty() -> Self {
281 Self::new(BytesMut::new())
282 }
283
284 pub fn read_buf(&self) -> Ref<'_, BytesMut> {
285 Ref::map(self.0.borrow(), |inner| &inner.read_buf)
286 }
287
288 pub fn write_buf(&self) -> Ref<'_, BytesMut> {
289 Ref::map(self.0.borrow(), |inner| &inner.write_buf)
290 }
291
292 pub fn err(&self) -> Ref<'_, Option<io::Error>> {
293 Ref::map(self.0.borrow(), |inner| &inner.err)
294 }
295
296 pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T) {
298 self.0
299 .borrow_mut()
300 .read_buf
301 .extend_from_slice(data.as_ref())
302 }
303}
304
305pub struct TestSeqInner {
306 read_buf: BytesMut,
307 write_buf: BytesMut,
308 err: Option<io::Error>,
309}
310
311impl io::Read for TestSeqBuffer {
312 fn read(&mut self, dst: &mut [u8]) -> Result<usize, io::Error> {
313 if self.0.borrow().read_buf.is_empty() {
314 if self.0.borrow().err.is_some() {
315 Err(self.0.borrow_mut().err.take().unwrap())
316 } else {
317 Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
318 }
319 } else {
320 let size = std::cmp::min(self.0.borrow().read_buf.len(), dst.len());
321 let b = self.0.borrow_mut().read_buf.split_to(size);
322 dst[..size].copy_from_slice(&b);
323 Ok(size)
324 }
325 }
326}
327
328impl io::Write for TestSeqBuffer {
329 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
330 self.0.borrow_mut().write_buf.extend(buf);
331 Ok(buf.len())
332 }
333
334 fn flush(&mut self) -> io::Result<()> {
335 Ok(())
336 }
337}
338
339impl AsyncRead for TestSeqBuffer {
340 fn poll_read(
341 self: Pin<&mut Self>,
342 _: &mut Context<'_>,
343 buf: &mut ReadBuf<'_>,
344 ) -> Poll<io::Result<()>> {
345 let dst = buf.initialize_unfilled();
346 let r = self.get_mut().read(dst);
347 match r {
348 Ok(n) => {
349 buf.advance(n);
350 Poll::Ready(Ok(()))
351 }
352 Err(err) if err.kind() == io::ErrorKind::WouldBlock => Poll::Pending,
353 Err(err) => Poll::Ready(Err(err)),
354 }
355 }
356}
357
358impl AsyncWrite for TestSeqBuffer {
359 fn poll_write(
360 self: Pin<&mut Self>,
361 _: &mut Context<'_>,
362 buf: &[u8],
363 ) -> Poll<io::Result<usize>> {
364 Poll::Ready(self.get_mut().write(buf))
365 }
366
367 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
368 Poll::Ready(Ok(()))
369 }
370
371 fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
372 Poll::Ready(Ok(()))
373 }
374}