trillium_http/
synthetic.rs1use crate::{
2 Conn, Headers, HttpConfig, HttpContext, KnownHeaderName, Method, ProtocolSession, TypeSet,
3 Version, 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 let request_body_state = ReceivedBodyState::new_h1(Some(transport.len() as u64), false);
139
140 Self {
141 context: Arc::default(),
142 transport,
143 request_headers,
144 spare_request_headers: None,
145 response_headers: Headers::new(),
146 path: Cow::Owned(path.into()),
147 method,
148 status: None,
149 version: Version::Http1_1,
150 state: TypeSet::new(),
151 response_body: None,
152 buffer: Vec::with_capacity(HttpConfig::DEFAULT.request_buffer_initial_len).into(),
153 request_body_state,
154 secure: false,
155 after_send: AfterSend::default(),
156 start_time: Instant::now(),
157 peer_ip: None,
158 authority: None,
159 scheme: None,
160 protocol: None,
161 protocol_session: ProtocolSession::Http1,
162 request_trailers: None,
163 upgrade: false,
164 peer_gone: None,
165 }
166 }
167
168 #[doc(hidden)]
170 pub fn set_context(&mut self, context: Arc<HttpContext>) {
171 self.context = context;
172 }
173
174 #[doc(hidden)]
176 #[must_use]
177 pub fn with_context(mut self, context: Arc<HttpContext>) -> Self {
178 self.set_context(context);
179 self
180 }
181
182 #[doc(hidden)]
184 pub fn close(&mut self) {
185 self.transport.close();
186 }
187
188 #[doc(hidden)]
190 pub fn replace_body(&mut self, body: impl Into<Synthetic>) {
191 let transport = body.into();
192 self.request_headers_mut()
193 .insert(KnownHeaderName::ContentLength, transport.len().to_string());
194 self.request_body_state = ReceivedBodyState::new_h1(Some(transport.len() as u64), false);
195 self.transport = transport;
196 }
197}