trillium_http/
synthetic.rs1use crate::{
2 Conn, Headers, HttpConfig, HttpContext, KnownHeaderName, Method, TypeSet, Version,
3 after_send::AfterSend, received_body::ReceivedBodyState,
4};
5use futures_lite::io::{AsyncRead, AsyncWrite, Cursor, Result};
6use std::{
7 borrow::Cow,
8 pin::Pin,
9 sync::Arc,
10 task::{Context, Poll},
11 time::Instant,
12};
13
14#[doc(hidden)]
18#[derive(Debug)]
19pub struct Synthetic {
20 data: Cursor<Vec<u8>>,
21 closed: bool,
22}
23
24impl AsyncRead for Synthetic {
25 fn poll_read(
26 mut self: Pin<&mut Self>,
27 cx: &mut Context<'_>,
28 buf: &mut [u8],
29 ) -> Poll<Result<usize>> {
30 let Synthetic { data, closed } = &mut *self;
31 if *closed {
32 Poll::Ready(Ok(0))
33 } else {
34 match Pin::new(data).poll_read(cx, buf) {
35 Poll::Ready(Ok(0)) => Poll::Pending,
36 other => other,
37 }
38 }
39 }
40}
41
42impl Synthetic {
43 #[doc(hidden)]
45 pub fn len(&self) -> usize {
46 self.data.get_ref().len()
47 }
48
49 #[doc(hidden)]
51 pub fn is_empty(&self) -> bool {
52 self.data.get_ref().is_empty()
53 }
54
55 #[doc(hidden)]
57 pub fn close(&mut self) {
58 self.closed = true;
59 }
60}
61
62impl AsyncWrite for Synthetic {
63 fn poll_write(self: Pin<&mut Self>, _cx: &mut Context<'_>, _buf: &[u8]) -> Poll<Result<usize>> {
64 Poll::Ready(Ok(0))
65 }
66
67 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>> {
68 Poll::Ready(Ok(()))
69 }
70
71 fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>> {
72 Poll::Ready(Ok(()))
73 }
74}
75
76impl From<Cursor<Vec<u8>>> for Synthetic {
77 fn from(data: Cursor<Vec<u8>>) -> Self {
78 Self {
79 data,
80 closed: false,
81 }
82 }
83}
84
85impl From<Vec<u8>> for Synthetic {
86 fn from(v: Vec<u8>) -> Self {
87 Cursor::new(v).into()
88 }
89}
90
91impl From<&[u8]> for Synthetic {
92 fn from(v: &[u8]) -> Self {
93 v.to_owned().into()
94 }
95}
96
97impl From<String> for Synthetic {
98 fn from(v: String) -> Self {
99 v.into_bytes().into()
100 }
101}
102
103impl From<&str> for Synthetic {
104 fn from(v: &str) -> Self {
105 v.as_bytes().into()
106 }
107}
108
109impl From<()> for Synthetic {
110 fn from((): ()) -> Self {
111 Vec::new().into()
112 }
113}
114
115impl From<Option<Vec<u8>>> for Synthetic {
116 fn from(v: Option<Vec<u8>>) -> Self {
117 v.unwrap_or_default().into()
118 }
119}
120
121impl Conn<Synthetic> {
122 #[doc(hidden)]
130 pub fn new_synthetic(
131 method: Method,
132 path: impl Into<String>,
133 body: impl Into<Synthetic>,
134 ) -> Self {
135 let transport = body.into();
136 let mut request_headers = Headers::new();
137 request_headers.insert(KnownHeaderName::ContentLength, transport.len().to_string());
138
139 Self {
140 context: Arc::default(),
141 transport,
142 request_headers,
143 response_headers: Headers::new(),
144 path: Cow::Owned(path.into()),
145 method,
146 status: None,
147 version: Version::Http1_1,
148 state: TypeSet::new(),
149 response_body: None,
150 buffer: Vec::with_capacity(HttpConfig::DEFAULT.request_buffer_initial_len).into(),
151 request_body_state: ReceivedBodyState::Start,
152 secure: false,
153 after_send: AfterSend::default(),
154 start_time: Instant::now(),
155 peer_ip: None,
156 authority: None,
157 scheme: None,
158 h3_connection: None,
159 protocol: None,
160 request_trailers: None,
161 }
162 }
163
164 #[doc(hidden)]
166 pub fn set_context(&mut self, context: Arc<HttpContext>) {
167 self.context = context;
168 }
169
170 #[doc(hidden)]
172 #[must_use]
173 pub fn with_context(mut self, context: Arc<HttpContext>) -> Self {
174 self.set_context(context);
175 self
176 }
177
178 #[doc(hidden)]
180 pub fn close(&mut self) {
181 self.transport.close();
182 }
183
184 #[doc(hidden)]
186 pub fn replace_body(&mut self, body: impl Into<Synthetic>) {
187 let transport = body.into();
188 self.request_headers_mut()
189 .insert(KnownHeaderName::ContentLength, transport.len().to_string());
190 self.transport = transport;
191 self.request_body_state = ReceivedBodyState::default();
192 }
193}