Skip to main content

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}