http_type/stream/impl.rs
1use super::*;
2
3/// Implementation of `From` trait for converting `usize` address into `&Stream`.
4impl From<usize> for &'static Stream {
5 /// Converts a memory address into a reference to `Stream`.
6 ///
7 /// # Arguments
8 ///
9 /// - `usize` - The memory address of the `Stream` instance.
10 ///
11 /// # Returns
12 ///
13 /// - `&'static Stream` - A reference to the `Stream` at the given address.
14 ///
15 /// # Safety
16 ///
17 /// - The address is guaranteed to be a valid `Stream` instance
18 /// that was previously converted from a reference and is managed by the runtime.
19 #[inline(always)]
20 fn from(address: usize) -> &'static Stream {
21 unsafe { &*(address as *const Stream) }
22 }
23}
24
25/// Implementation of `From` trait for converting `usize` address into `&mut Stream`.
26impl<'a> From<usize> for &'a mut Stream {
27 /// Converts a memory address into a mutable reference to `Stream`.
28 ///
29 /// # Arguments
30 ///
31 /// - `usize` - The memory address of the `Stream` instance.
32 ///
33 /// # Returns
34 ///
35 /// - `&'a mut Stream` - A mutable reference to the `Stream` at the given address.
36 ///
37 /// # Safety
38 ///
39 /// - The address is guaranteed to be a valid `Stream` instance
40 /// that was previously converted from a reference and is managed by the runtime.
41 #[inline(always)]
42 fn from(address: usize) -> &'a mut Stream {
43 unsafe { &mut *(address as *mut Stream) }
44 }
45}
46
47/// Implementation of `From` trait for converting `&Stream` into `usize` address.
48impl From<&Stream> for usize {
49 /// Converts a reference to `Stream` into its memory address.
50 ///
51 /// # Arguments
52 ///
53 /// - `&Stream` - The reference to the `Stream` instance.
54 ///
55 /// # Returns
56 ///
57 /// - `usize` - The memory address of the `Stream` instance.
58 #[inline(always)]
59 fn from(stream: &Stream) -> Self {
60 stream as *const Stream as usize
61 }
62}
63
64/// Implementation of `From` trait for converting `&mut Stream` into `usize` address.
65impl From<&mut Stream> for usize {
66 /// Converts a mutable reference to `Stream` into its memory address.
67 ///
68 /// # Arguments
69 ///
70 /// - `&mut Stream` - The mutable reference to the `Stream` instance.
71 ///
72 /// # Returns
73 ///
74 /// - `usize` - The memory address of the `Stream` instance.
75 #[inline(always)]
76 fn from(stream: &mut Stream) -> Self {
77 stream as *mut Stream as usize
78 }
79}
80
81/// Implementation of `AsRef` trait for `Stream`.
82impl AsRef<Stream> for Stream {
83 /// Converts `&Stream` to `&Stream` via memory address conversion.
84 ///
85 /// # Returns
86 ///
87 /// - `&Self` - A reference to the `Stream` instance.
88 #[inline(always)]
89 fn as_ref(&self) -> &Self {
90 let address: usize = self.into();
91 address.into()
92 }
93}
94
95/// Implementation of `AsMut` trait for `Stream`.
96impl AsMut<Stream> for Stream {
97 /// Converts `&mut Stream` to `&mut Stream` via memory address conversion.
98 ///
99 /// # Returns
100 ///
101 /// - `&mut Self` - A mutable reference to the `Stream` instance.
102 #[inline(always)]
103 fn as_mut(&mut self) -> &mut Self {
104 let address: usize = self.into();
105 address.into()
106 }
107}
108
109/// Implementation of `Lifetime` trait for `Stream`.
110impl Lifetime for Stream {
111 /// Converts a reference to the stream into a `'static` reference.
112 ///
113 /// # Returns
114 ///
115 /// - `&'static Self` - A reference to the stream with a `'static` lifetime.
116 ///
117 /// # Safety
118 ///
119 /// - The address is guaranteed to be a valid `Self` instance
120 /// that was previously converted from a reference and is managed by the runtime.
121 #[inline(always)]
122 unsafe fn leak(&self) -> &'static Self {
123 let address: usize = self.into();
124 address.into()
125 }
126
127 /// Converts a reference to the stream into a `'static` mutable reference.
128 ///
129 /// # Returns
130 ///
131 /// - `&'static mut Self` - A mutable reference to the stream with a `'static` lifetime.
132 ///
133 /// # Safety
134 ///
135 /// - The address is guaranteed to be a valid `Self` instance
136 /// that was previously converted from a reference and is managed by the runtime.
137 #[inline(always)]
138 unsafe fn leak_mut(&self) -> &'static mut Self {
139 let address: usize = self.into();
140 address.into()
141 }
142}
143
144impl Drop for PooledReader<'_> {
145 /// Releases the buffer back to the pool for reuse by later requests.
146 fn drop(&mut self) {
147 let buffer: Vec<u8> = mem::take(self.get_mut_buffer());
148 return_read_buffer(buffer);
149 }
150}
151
152/// Implements non-blocking buffered reads for `PooledReader`.
153///
154/// Buffered bytes are served first; once drained, reads are delegated
155/// directly to the underlying stream.
156impl AsyncRead for PooledReader<'_> {
157 /// Polls to read data into the provided buffer.
158 ///
159 /// # Arguments
160 ///
161 /// - `Pin<&mut Self>` - The pinned reader.
162 /// - `&mut Context<'_>` - The task context.
163 /// - `&mut ReadBuf<'_>` - The destination buffer.
164 ///
165 /// # Returns
166 ///
167 /// - `Poll<io::Result<()>>` - Ready when data was read or an error occurred.
168 fn poll_read(
169 self: Pin<&mut Self>,
170 cx: &mut Context<'_>,
171 buf: &mut ReadBuf<'_>,
172 ) -> Poll<io::Result<()>> {
173 let this: &mut Self = self.get_mut();
174 if *this.get_start() < *this.get_end() {
175 let available: usize = *this.get_end() - *this.get_start();
176 let amount: usize = available.min(buf.remaining());
177 let end: usize = *this.get_start() + amount;
178 buf.put_slice(&this.get_buffer()[*this.get_start()..end]);
179 this.set_start(end);
180 return Poll::Ready(Ok(()));
181 }
182 Pin::new(&mut **this.get_mut_stream()).poll_read(cx, buf)
183 }
184}
185
186/// Implements buffered-read support for `PooledReader`.
187///
188/// The internal buffer is refilled from the stream only when fully
189/// consumed, so a single socket read serves multiple line parses.
190impl AsyncBufRead for PooledReader<'_> {
191 /// Polls to fill the internal buffer and returns the available data.
192 ///
193 /// # Arguments
194 ///
195 /// - `Pin<&mut Self>` - The pinned reader.
196 /// - `&mut Context<'_>` - The task context.
197 ///
198 /// # Returns
199 ///
200 /// - `Poll<io::Result<&[u8]>>` - Ready with the unconsumed bytes, or an error.
201 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
202 let this: &mut Self = self.get_mut();
203 let PooledReader {
204 stream,
205 buffer,
206 start,
207 end,
208 } = this;
209 if *start >= *end {
210 *start = 0;
211 *end = 0;
212 let mut read_buf: ReadBuf<'_> = ReadBuf::new(buffer);
213 match Pin::new(&mut **stream).poll_read(cx, &mut read_buf) {
214 Poll::Ready(Ok(())) => {
215 *end = read_buf.filled().len();
216 }
217 Poll::Ready(Err(error)) => return Poll::Ready(Err(error)),
218 Poll::Pending => return Poll::Pending,
219 }
220 }
221 Poll::Ready(Ok(&buffer[*start..*end]))
222 }
223
224 /// Marks the given number of bytes as consumed.
225 ///
226 /// # Arguments
227 ///
228 /// - `Pin<&mut Self>` - The pinned reader.
229 /// - `usize` - The number of bytes to consume.
230 fn consume(self: Pin<&mut Self>, amount: usize) {
231 let this: &mut Self = self.get_mut();
232 let new_start: usize = (*this.get_start() + amount).min(*this.get_end());
233 this.set_start(new_start);
234 }
235}
236
237impl Stream {
238 /// Checks if the connection should be kept alive.
239 ///
240 /// This method evaluates whether the connection should remain open based on
241 /// the closed state and the keep_alive parameter.
242 ///
243 /// # Arguments
244 ///
245 /// - `bool` - Whether keep-alive is enabled for the request.
246 ///
247 /// # Returns
248 ///
249 /// - `bool` - True if the connection should be kept alive, otherwise false.
250 #[inline(always)]
251 pub fn is_keep_alive(&self, keep_alive: bool) -> bool {
252 !self.get_closed() && keep_alive
253 }
254
255 /// Parses the HTTP request content from the stream into the given request.
256 ///
257 /// The request is reset first, then filled in place so its existing
258 /// allocations are reused across keep-alive requests.
259 ///
260 /// # Arguments
261 ///
262 /// - `&mut Request` - The request object to fill.
263 ///
264 /// # Returns
265 ///
266 /// - `Result<(), RequestError>` - Ok on success, or an error if parsing fails.
267 async fn fill_http_from_stream(&mut self, request: &mut Request) -> Result<(), RequestError> {
268 request.reset();
269 let config: RequestConfig = *self.get_request_config();
270 let buffer_size: usize = config.get_buffer_size();
271 let max_path_size: usize = config.get_max_path_size();
272 // Take any bytes the previous request read ahead, BEFORE borrowing the
273 // socket: those bytes already left the socket and cannot be re-read, so
274 // dropping them would silently discard a pipelined request.
275 let seeded: Vec<u8> = {
276 let start: usize = self.get_leftover_start();
277 let end: usize = self.get_leftover_end();
278 let mut pending: Vec<u8> = Vec::new();
279 if start < end {
280 let leftover: Vec<u8> = mem::take(self.get_mut_leftover());
281 let take: usize = (end - start).min(leftover.len());
282 pending.extend_from_slice(&leftover[start..start + take]);
283 }
284 self.set_leftover(Vec::new());
285 self.set_leftover_start(0);
286 self.set_leftover_end(0);
287 pending
288 };
289 let buffer: Vec<u8> = take_read_buffer(buffer_size);
290 let mut reader: PooledReader<'_> = PooledReader::new(self.get_mut_stream(), buffer);
291 if !seeded.is_empty() {
292 let target: &mut Vec<u8> = reader.get_mut_buffer();
293 let copy_len: usize = seeded.len().min(target.len());
294 target[..copy_len].copy_from_slice(&seeded[..copy_len]);
295 reader.set_end(copy_len);
296 }
297 let mut line: String = String::with_capacity(REQUEST_LINE_BUFFER_CAPACITY);
298 AsyncBufReadExt::read_line(&mut reader, &mut line).await?;
299 let (method, path, version): (RequestMethod, &str, RequestVersion) =
300 Request::get_http_first_line(&line)?;
301 Request::check_http_path_size(path, max_path_size)?;
302 let hash_index: Option<usize> = path.find(HASH);
303 let query_index: Option<usize> = path.find(QUERY);
304 let query: &str = Request::get_http_query(path, query_index, hash_index);
305 Request::fill_http_querys(query, request.get_mut_querys());
306 let path_slice: &str = Request::get_http_path(path, query_index, hash_index);
307 request.get_mut_path().push_str(path_slice);
308 let content_size: usize = request.get_http_headers(&mut reader, &config).await?;
309 request.set_method(method);
310 request.set_version(version);
311 Request::fill_http_body(&mut reader, request.get_mut_body(), content_size).await?;
312 // Preserve bytes read ahead for the next pipelined request: they have
313 // already left the socket and cannot be read again.
314 let reader_start: usize = *reader.get_start();
315 let reader_end: usize = *reader.get_end();
316 let pending: Vec<u8> = if reader_start < reader_end {
317 reader.get_buffer()[reader_start..reader_end].to_vec()
318 } else {
319 Vec::new()
320 };
321 drop(reader);
322 let pending_len: usize = pending.len();
323 self.set_leftover(pending);
324 self.set_leftover_start(0);
325 self.set_leftover_end(pending_len);
326 Ok(())
327 }
328
329 /// Parses an HTTP request from a TCP stream into the given request.
330 ///
331 /// The request is reset and filled in place, reusing its allocations.
332 /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
333 ///
334 /// # Arguments
335 ///
336 /// - `&mut Request` - The request object to reset and fill.
337 ///
338 /// # Returns
339 ///
340 /// - `Result<(), RequestError>` - Ok on success, or an error if parsing fails.
341 pub async fn try_fill_http_request(
342 &mut self,
343 request: &mut Request,
344 ) -> Result<(), RequestError> {
345 if self.get_closed() {
346 return Err(RequestError::ServerClosedConnection(HttpStatus::BadRequest));
347 }
348 let timeout_ms: u64 = self.get_request_config().get_read_timeout_ms();
349 if timeout_ms == DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS {
350 return self.fill_http_from_stream(request).await;
351 }
352 let duration: Duration = Duration::from_millis(timeout_ms);
353 timeout(duration, self.fill_http_from_stream(request)).await?
354 }
355
356 /// Parses an HTTP request from a TCP stream.
357 ///
358 /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
359 /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
360 ///
361 /// # Returns
362 ///
363 /// - `Result<Request, RequestError>` - The parsed request or an error.
364 pub async fn try_get_http_request(&mut self) -> Result<Request, RequestError> {
365 let mut request: Request = Request::default();
366 self.try_fill_http_request(&mut request).await?;
367 Ok(request)
368 }
369
370 /// Parses a WebSocket request from a TCP stream.
371 ///
372 /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
373 /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
374 ///
375 /// # Returns
376 ///
377 /// - `Result<RequestBody, RequestError>` - The parsed WebSocket request or an error.
378 pub async fn try_get_websocket_request(&mut self) -> Result<RequestBody, RequestError> {
379 if self.get_closed() {
380 return Err(RequestError::ServerClosedConnection(HttpStatus::BadRequest));
381 }
382 let config: RequestConfig = *self.get_request_config();
383 let buffer_size: usize = config.get_buffer_size();
384 let read_timeout_ms: u64 = config.get_read_timeout_ms();
385 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
386 let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
387 let mut full_frame: Vec<u8> = Vec::new();
388 let mut is_client_response: bool = false;
389 let duration_opt: Option<Duration> =
390 if read_timeout_ms == DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS {
391 None
392 } else {
393 let adjusted_timeout_ms: u64 = (read_timeout_ms >> 1) + (read_timeout_ms & 1);
394 Some(Duration::from_millis(adjusted_timeout_ms))
395 };
396 loop {
397 let len: usize = match self
398 .get_websocket_from_stream(&mut temp_buffer, duration_opt, &mut is_client_response)
399 .await
400 {
401 Ok(Some(len)) => len,
402 Ok(None) => continue,
403 Err(error) => return Err(error),
404 };
405 if len == 0 {
406 return Err(RequestError::IncompleteWebSocketFrame(
407 HttpStatus::BadRequest,
408 ));
409 }
410 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
411 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
412 is_client_response = true;
413 dynamic_buffer.drain(0..consumed);
414 match frame.get_opcode() {
415 WebSocketOpcode::Close => {
416 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
417 }
418 WebSocketOpcode::Ping | WebSocketOpcode::Pong => continue,
419 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
420 match frame.build_full_frame(&mut full_frame) {
421 Ok(Some(result)) => return Ok(result),
422 Ok(None) => continue,
423 Err(error) => return Err(error),
424 }
425 }
426 _ => {
427 return Err(RequestError::WebSocketOpcodeUnsupported(
428 HttpStatus::NotImplemented,
429 ));
430 }
431 }
432 }
433 }
434 }
435
436 /// Reads data from the stream with optional timeout handling.
437 ///
438 /// # Arguments
439 ///
440 /// - `&mut [u8]` - The buffer to read data into.
441 /// - `Option<Duration>` - The optional timeout duration. If Some, timeout is applied; if None, no timeout.
442 /// - `&mut bool` - Mutable reference to track if we got a client response.
443 ///
444 /// # Returns
445 ///
446 /// - `Result<Option<usize>, RequestError>` - The number of bytes read, None for timeout/ping, or an error.
447 pub(crate) async fn get_websocket_from_stream(
448 &mut self,
449 buffer: &mut [u8],
450 duration_opt: Option<Duration>,
451 is_client_response: &mut bool,
452 ) -> Result<Option<usize>, RequestError> {
453 let stream: &mut TcpStream = self.get_mut_stream();
454 if let Some(duration) = duration_opt {
455 return match timeout(duration, stream.read(buffer)).await {
456 Ok(result) => match result {
457 Ok(len) => Ok(Some(len)),
458 Err(error) => Err(error.into()),
459 },
460 Err(error) => {
461 if !*is_client_response {
462 return Err(error.into());
463 }
464 *is_client_response = false;
465 self.try_send(&PING_FRAME).await?;
466 Ok(None)
467 }
468 };
469 }
470 match stream.read(buffer).await {
471 Ok(len) => Ok(Some(len)),
472 Err(error) => Err(error.into()),
473 }
474 }
475
476 /// Sends data over the stream.
477 ///
478 /// # Arguments
479 ///
480 /// - `D` - The data to send, which must implement `AsRef<[u8]>`.
481 ///
482 /// # Returns
483 ///
484 /// - `Result<(), ResponseError>` - Result indicating success or failure.
485 pub async fn try_send<D>(&mut self, data: D) -> Result<(), ResponseError>
486 where
487 D: AsRef<[u8]>,
488 {
489 if self.get_closed() {
490 return Err(ResponseError::ConnectionClosed);
491 }
492 Ok(self.get_mut_stream().write_all(data.as_ref()).await?)
493 }
494
495 /// Sends data over the stream.
496 ///
497 /// # Arguments
498 ///
499 /// - `D` - The data to send, which must implement `AsRef<[u8]>`.
500 ///
501 /// # Panics
502 ///
503 /// Panics if the write operation fails.
504 pub async fn send<D>(&mut self, data: D)
505 where
506 D: AsRef<[u8]>,
507 {
508 self.try_send(data).await.unwrap();
509 }
510
511 /// Sends multiple data.
512 ///
513 /// # Arguments
514 ///
515 /// - `I` - The data list to send, which must implement `IntoIterator<Item = D>` with
516 /// `D` requiring the `AsRef<[u8]>` bound.
517 ///
518 /// # Returns
519 ///
520 /// - `Result<(), ResponseError>` - Result indicating success or failure.
521 pub async fn try_send_list<I, D>(&mut self, data_iter: I) -> Result<(), ResponseError>
522 where
523 I: IntoIterator<Item = D>,
524 D: AsRef<[u8]>,
525 {
526 if self.get_closed() {
527 return Err(ResponseError::ConnectionClosed);
528 }
529 let stream: &mut TcpStream = self.get_mut_stream();
530 for data in data_iter {
531 stream.write_all(data.as_ref()).await?;
532 }
533 Ok(())
534 }
535
536 /// Sends multiple data.
537 ///
538 /// # Arguments
539 ///
540 /// - `I` - The data list to send, which must implement `IntoIterator<Item = D>` with
541 /// `D` requiring the `AsRef<[u8]>` bound.
542 ///
543 /// # Panics
544 ///
545 /// Panics if any write operation fails.
546 pub async fn send_list<I, D>(&mut self, data_iter: I)
547 where
548 I: IntoIterator<Item = D>,
549 D: AsRef<[u8]>,
550 {
551 self.try_send_list(data_iter).await.unwrap();
552 }
553
554 /// Flushes all buffered data to the stream.
555 ///
556 /// # Returns
557 ///
558 /// - `Result<(), ResponseError>` - Result indicating success or failure.
559 pub async fn try_flush(&mut self) -> Result<(), ResponseError> {
560 if self.get_closed() {
561 return Err(ResponseError::ConnectionClosed);
562 }
563 Ok(self.get_mut_stream().flush().await?)
564 }
565
566 /// Flushes all buffered data to the stream.
567 ///
568 /// # Panics
569 ///
570 /// Panics if the flush operation fails.
571 pub async fn flush(&mut self) {
572 self.try_flush().await.unwrap();
573 }
574}