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
144/// Implementation of `Transport` trait for the plain TCP socket.
145///
146/// The socket is the reference transport: it already carries a socket
147/// identity, so its addresses are reported directly.
148impl Transport for TcpStream {
149    /// Reports the address of the remote end of the socket.
150    ///
151    /// # Returns
152    ///
153    /// - `Result<SocketAddr, io::Error>` - The peer address of the socket.
154    fn peer_addr(&self) -> Result<SocketAddr, io::Error> {
155        TcpStream::peer_addr(self)
156    }
157
158    /// Reports the address of the local end of the socket.
159    ///
160    /// # Returns
161    ///
162    /// - `Result<SocketAddr, io::Error>` - The local address of the socket.
163    fn local_addr(&self) -> Result<SocketAddr, io::Error> {
164        TcpStream::local_addr(self)
165    }
166}
167
168/// Implements [`Drop`] for [`PooledReader`].
169impl Drop for PooledReader<'_> {
170    /// Releases the buffer back to the pool for reuse by later requests.
171    fn drop(&mut self) {
172        let buffer: Vec<u8> = mem::take(self.get_mut_buffer());
173        return_read_buffer(buffer);
174    }
175}
176
177/// Implements non-blocking buffered reads for `PooledReader`.
178///
179/// Buffered bytes are served first; once drained, reads are delegated
180/// directly to the underlying stream.
181impl AsyncRead for PooledReader<'_> {
182    /// Polls to read data into the provided buffer.
183    ///
184    /// # Arguments
185    ///
186    /// - `Pin<&mut Self>` - The pinned reader.
187    /// - `&mut Context<'_>` - The task context.
188    /// - `&mut ReadBuf<'_>` - The destination buffer.
189    ///
190    /// # Returns
191    ///
192    /// - `Poll<io::Result<()>>` - Ready when data was read or an error occurred.
193    fn poll_read(
194        self: Pin<&mut Self>,
195        cx: &mut Context<'_>,
196        buf: &mut ReadBuf<'_>,
197    ) -> Poll<io::Result<()>> {
198        let this: &mut Self = self.get_mut();
199        if this.get_start() < this.get_end() {
200            let available: usize = this.get_end() - this.get_start();
201            let amount: usize = available.min(buf.remaining());
202            let end: usize = this.get_start() + amount;
203            buf.put_slice(&this.get_buffer()[this.get_start()..end]);
204            this.set_start(end);
205            return Poll::Ready(Ok(()));
206        }
207        return_read_buffer(mem::take(this.get_mut_buffer()));
208        Pin::new(&mut **this.get_mut_stream()).poll_read(cx, buf)
209    }
210}
211
212/// Implements buffered-read support for `PooledReader`.
213///
214/// The internal buffer is refilled from the stream only when fully
215/// consumed, so a single socket read serves multiple line parses.
216impl AsyncBufRead for PooledReader<'_> {
217    /// Polls to fill the internal buffer and returns the available data.
218    ///
219    /// # Arguments
220    ///
221    /// - `Pin<&mut Self>` - The pinned reader.
222    /// - `&mut Context<'_>` - The task context.
223    ///
224    /// # Returns
225    ///
226    /// - `Poll<io::Result<&[u8]>>` - Ready with the unconsumed bytes, or an error.
227    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
228        let this: &mut Self = self.get_mut();
229        let PooledReader {
230            stream,
231            buffer,
232            capacity,
233            start,
234            end,
235        } = this;
236        if *start >= *end {
237            *start = 0;
238            *end = 0;
239            if buffer.is_empty() {
240                *buffer = take_read_buffer(*capacity);
241            }
242            let mut read_buf: ReadBuf<'_> = ReadBuf::new(buffer);
243            match Pin::new(&mut **stream).poll_read(cx, &mut read_buf) {
244                Poll::Ready(Ok(())) => {
245                    *end = read_buf.filled().len();
246                }
247                Poll::Ready(Err(error)) => return Poll::Ready(Err(error)),
248                Poll::Pending => {
249                    return_read_buffer(mem::take(buffer));
250                    return Poll::Pending;
251                }
252            }
253        }
254        Poll::Ready(Ok(&buffer[*start..*end]))
255    }
256
257    /// Marks the given number of bytes as consumed.
258    ///
259    /// # Arguments
260    ///
261    /// - `Pin<&mut Self>` - The pinned reader.
262    /// - `usize` - The number of bytes to consume.
263    fn consume(self: Pin<&mut Self>, amount: usize) {
264        let this: &mut Self = self.get_mut();
265        let new_start: usize = (this.get_start() + amount).min(this.get_end());
266        this.set_start(new_start);
267    }
268}
269
270/// Inherent implementation of [`Stream`].
271impl Stream {
272    /// Boxes a transport into a `Stream` for the request pipeline.
273    ///
274    /// This is the single construction path: a plain TCP socket, a TLS session
275    /// and a per-request duplex stream all enter here, so nothing above the
276    /// transport line has to know which one it is serving. The transport is
277    /// type erased immediately, which keeps `Stream` a fixed size regardless of
278    /// the concrete protocol adapter behind it.
279    ///
280    /// # Arguments
281    ///
282    /// - `T` - The transport type to serve the request cycle over.
283    /// - `RequestConfig` - The parsing limits and read timeout for the cycle.
284    /// - `bool` - Whether the connection starts already closed.
285    ///
286    /// # Returns
287    ///
288    /// - `Self` - A stream serving bytes through the boxed transport.
289    pub fn from_transport<T>(transport: T, request_config: RequestConfig, closed: bool) -> Self
290    where
291        T: Transport + 'static,
292    {
293        Self {
294            stream: Box::new(transport),
295            request_config,
296            closed,
297            leftover: Vec::new(),
298            leftover_start: 0,
299            leftover_end: 0,
300            line_buffer: String::with_capacity(REQUEST_LINE_BUFFER_CAPACITY),
301            header_line_buffer: String::with_capacity(HEADER_LINE_BUFFER_CAPACITY),
302            websocket_state: None,
303        }
304    }
305
306    /// Boxes a TCP socket into a `Stream` for the request pipeline.
307    ///
308    /// Kept as the socket-facing constructor so the accept loop keeps its
309    /// existing call shape; it delegates to `from_transport`, so there is one
310    /// construction path rather than two.
311    ///
312    /// # Arguments
313    ///
314    /// - `TcpStream` - The accepted socket to serve the request cycle over.
315    /// - `RequestConfig` - The parsing limits and read timeout for the cycle.
316    /// - `bool` - Whether the connection starts already closed.
317    ///
318    /// # Returns
319    ///
320    /// - `Self` - A stream serving bytes through the boxed socket.
321    pub fn new(stream: TcpStream, request_config: RequestConfig, closed: bool) -> Self {
322        Self::from_transport(stream, request_config, closed)
323    }
324
325    /// Reports the address of the remote end of the transport.
326    ///
327    /// Delegates to the transport itself, so a transport without a socket
328    /// identity answers with an error rather than a fabricated address.
329    ///
330    /// # Returns
331    ///
332    /// - `Result<SocketAddr, io::Error>` - The peer address reported by the transport.
333    #[inline(always)]
334    pub fn get_peer_addr(&self) -> Result<SocketAddr, io::Error> {
335        self.get_stream().peer_addr()
336    }
337
338    /// Reports the address of the local end of the transport.
339    ///
340    /// Delegates to the transport itself, so a transport without a socket
341    /// identity answers with an error rather than a fabricated address.
342    ///
343    /// # Returns
344    ///
345    /// - `Result<SocketAddr, io::Error>` - The local address reported by the transport.
346    #[inline(always)]
347    pub fn get_local_addr(&self) -> Result<SocketAddr, io::Error> {
348        self.get_stream().local_addr()
349    }
350
351    /// Checks if the connection should be kept alive.
352    ///
353    /// This method evaluates whether the connection should remain open based on
354    /// the closed state and the keep_alive parameter.
355    ///
356    /// # Arguments
357    ///
358    /// - `bool` - Whether keep-alive is enabled for the request.
359    ///
360    /// # Returns
361    ///
362    /// - `bool` - True if the connection should be kept alive, otherwise false.
363    #[inline(always)]
364    pub fn is_keep_alive(&self, keep_alive: bool) -> bool {
365        !self.get_closed() && keep_alive
366    }
367
368    /// Parses the HTTP request content from the stream into the given request.
369    ///
370    /// The request is reset first, then filled in place so its existing
371    /// allocations are reused across keep-alive requests.
372    ///
373    /// # Arguments
374    ///
375    /// - `&mut Request` - The request object to fill.
376    ///
377    /// # Returns
378    ///
379    /// - `Result<(), RequestError>` - Ok on success, or an error if parsing fails.
380    async fn fill_http_from_stream(&mut self, request: &mut Request) -> Result<(), RequestError> {
381        request.reset();
382        let config: RequestConfig = *self.get_request_config();
383        let buffer_size: usize = config.get_buffer_size();
384        let max_path_size: usize = config.get_max_path_size();
385        // Move read-ahead storage and its valid window into the reader instead
386        // of allocating and copying the remaining pipeline for every request.
387        let start: usize = self.get_leftover_start();
388        let end: usize = self.get_leftover_end();
389        let buffer: Vec<u8> = mem::take(self.get_mut_leftover());
390        self.set_leftover_start(0);
391        self.set_leftover_end(0);
392        // Split the borrow of the stream: the reader takes the transport, the
393        // line buffers are separate fields, so both can be held at once.
394        let Stream {
395            stream,
396            line_buffer,
397            header_line_buffer,
398            ..
399        } = self;
400        let mut reader: PooledReader<'_> = PooledReader::new(stream, buffer, buffer_size);
401        reader.set_start(start);
402        reader.set_end(end);
403        line_buffer.clear();
404        AsyncBufReadExt::read_line(&mut reader, line_buffer).await?;
405        let (method, path, version): (RequestMethod, &str, RequestVersion) =
406            Request::get_http_first_line(line_buffer)?;
407        Request::check_http_path_size(path, max_path_size)?;
408        let hash_index: Option<usize> = path.find(HASH);
409        let query_index: Option<usize> = path.find(QUERY);
410        let query: &str = Request::get_http_query(path, query_index, hash_index);
411        Request::fill_http_querys(query, request.get_mut_querys());
412        let path_slice: &str = Request::get_http_path(path, query_index, hash_index);
413        request.get_mut_path().push_str(path_slice);
414        request.set_version(version);
415        let content_size: usize = request
416            .get_http_headers(&mut reader, &config, header_line_buffer)
417            .await?;
418        request.set_method(method);
419        Request::fill_http_body(&mut reader, request.get_mut_body(), content_size).await?;
420        // Preserve bytes read ahead for the next pipelined request: they have
421        // already left the socket and cannot be read again.
422        let reader_start: usize = reader.get_start();
423        let reader_end: usize = reader.get_end();
424        let pending: Vec<u8> = if reader_start < reader_end {
425            mem::take(reader.get_mut_buffer())
426        } else {
427            Vec::new()
428        };
429        drop(reader);
430        let pending_start: usize = if pending.is_empty() { 0 } else { reader_start };
431        let pending_end: usize = if pending.is_empty() { 0 } else { reader_end };
432        self.set_leftover(pending);
433        self.set_leftover_start(pending_start);
434        self.set_leftover_end(pending_end);
435        Ok(())
436    }
437
438    /// Parses an HTTP request from a TCP stream into the given request.
439    ///
440    /// The request is reset and filled in place, reusing its allocations.
441    /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
442    ///
443    /// # Arguments
444    ///
445    /// - `&mut Request` - The request object to reset and fill.
446    ///
447    /// # Returns
448    ///
449    /// - `Result<(), RequestError>` - Ok on success, or an error if parsing fails.
450    pub async fn try_fill_http_request(
451        &mut self,
452        request: &mut Request,
453    ) -> Result<(), RequestError> {
454        if self.get_closed() {
455            return Err(RequestError::ServerClosedConnection(HttpStatus::BadRequest));
456        }
457        let timeout_ms: u64 = self.get_request_config().get_read_timeout_ms();
458        if timeout_ms == DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS {
459            return self.fill_http_from_stream(request).await;
460        }
461        let duration: Duration = Duration::from_millis(timeout_ms);
462        let mut reading: Pin<&mut _> = pin!(self.fill_http_from_stream(request));
463        // A request whose bytes have already arrived is read on the first
464        // poll, so the ordinary case never arms a timer at all. Arming one
465        // costs a timer registration and a cancellation per request, and that
466        // churn is the most expensive thing a request path can do once the
467        // concurrency is high enough for the timer driver to become a
468        // bottleneck. The timer is armed only when the read really has to
469        // wait, which is exactly when the timeout can still fire.
470        if let Some(result) = poll_once(reading.as_mut()).await {
471            return result;
472        }
473        timeout(duration, reading).await?
474    }
475
476    /// Parses an HTTP request from a TCP stream.
477    ///
478    /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
479    /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
480    ///
481    /// # Returns
482    ///
483    /// - `Result<Request, RequestError>` - The parsed request or an error.
484    pub async fn try_get_http_request(&mut self) -> Result<Request, RequestError> {
485        let mut request: Request = Request::default();
486        self.try_fill_http_request(&mut request).await?;
487        Ok(request)
488    }
489
490    /// Parses a WebSocket request from a TCP stream.
491    ///
492    /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
493    /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
494    ///
495    /// # Returns
496    ///
497    /// - `Result<RequestBody, RequestError>` - The parsed WebSocket request or an error.
498    pub async fn try_get_websocket_request(&mut self) -> Result<RequestBody, RequestError> {
499        if self.get_closed() {
500            return self.reset_websocket_state_on_error(Err(RequestError::ServerClosedConnection(
501                HttpStatus::BadRequest,
502            )));
503        }
504        let config: RequestConfig = *self.get_request_config();
505        let read_timeout_ms: u64 = config.get_read_timeout_ms();
506        if self.get_mut_websocket_state().is_none() {
507            let mut buffer: Vec<u8> = mem::take(self.get_mut_leftover());
508            buffer.truncate(self.get_leftover_end());
509            buffer.drain(..self.get_leftover_start());
510            self.set_leftover_start(0);
511            self.set_leftover_end(0);
512            self.set_websocket_state(Some(Box::new(WebSocketReadState {
513                buffer,
514                ..WebSocketReadState::default()
515            })));
516        }
517        let duration_opt: Option<Duration> =
518            if read_timeout_ms == DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS {
519                None
520            } else {
521                let adjusted_timeout_ms: u64 = (read_timeout_ms >> 1) + (read_timeout_ms & 1);
522                Some(Duration::from_millis(adjusted_timeout_ms))
523            };
524        loop {
525            let parsed: Result<Option<RequestBody>, RequestError> =
526                self.try_parse_websocket_request();
527            if let Some(body) = self.reset_websocket_state_on_error(parsed)? {
528                return Ok(body);
529            }
530            let read: Result<Option<usize>, RequestError> =
531                self.get_websocket_from_stream(duration_opt).await;
532            if matches!(self.reset_websocket_state_on_error(read)?, Some(0)) {
533                return self.reset_websocket_state_on_error(Err(
534                    RequestError::IncompleteWebSocketFrame(HttpStatus::BadRequest),
535                ));
536            }
537        }
538    }
539
540    /// Discards cached parsing state only after an operation completes with an error.
541    ///
542    /// # Arguments
543    ///
544    /// - `Result<T, RequestError>` - The completed parsing or reading operation.
545    ///
546    /// # Returns
547    ///
548    /// - `Result<T, RequestError>` - The unchanged result after releasing failed parsing state.
549    #[inline(always)]
550    fn reset_websocket_state_on_error<T>(
551        &mut self,
552        result: Result<T, RequestError>,
553    ) -> Result<T, RequestError> {
554        if result.is_err() {
555            drop(self.get_mut_websocket_state().take());
556        }
557        result
558    }
559
560    /// Parses buffered frames without discarding incomplete or subsequent input.
561    ///
562    /// # Returns
563    ///
564    /// - `Result<Option<RequestBody>, RequestError>` - A complete message, pending input, or a protocol error.
565    fn try_parse_websocket_request(&mut self) -> Result<Option<RequestBody>, RequestError> {
566        let state: &mut WebSocketReadState = self.get_mut_websocket_state().as_deref_mut().ok_or(
567            RequestError::IncompleteWebSocketFrame(HttpStatus::BadRequest),
568        )?;
569        let WebSocketReadState {
570            buffer,
571            full_frame,
572            is_client_response,
573        }: &mut WebSocketReadState = state;
574        while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&buffer[..]) {
575            *is_client_response = true;
576            buffer.drain(..consumed);
577            if buffer.is_empty() {
578                let mut recycled: Vec<u8> = mem::take(buffer);
579                recycled.resize(recycled.capacity().min(MAX_POOLED_READ_BUFFER_SIZE), 0);
580                return_read_buffer(recycled);
581            }
582            match frame.get_opcode() {
583                WebSocketOpcode::Close => {
584                    return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
585                }
586                WebSocketOpcode::Ping | WebSocketOpcode::Pong => continue,
587                WebSocketOpcode::Text | WebSocketOpcode::Binary => {
588                    if frame.get_fin() && full_frame.is_empty() {
589                        let WebSocketFrame { payload_data, .. }: WebSocketFrame = frame;
590                        return Ok(Some(payload_data));
591                    }
592                    if let Some(body) = frame.build_full_frame(full_frame)? {
593                        return Ok(Some(body));
594                    }
595                }
596                _ => {
597                    return Err(RequestError::WebSocketOpcodeUnsupported(
598                        HttpStatus::NotImplemented,
599                    ));
600                }
601            }
602        }
603        Ok(None)
604    }
605
606    /// Polls a WebSocket read using a buffer retained only while data is ready.
607    ///
608    /// # Arguments
609    ///
610    /// - `&mut Context<'_>` - The registered task context.
611    ///
612    /// # Returns
613    ///
614    /// - `Poll<io::Result<usize>>` - The bytes appended to persistent parsing state.
615    fn poll_websocket_read(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
616        let capacity: usize = self.get_request_config().get_buffer_size();
617        let mut temporary: Vec<u8> = take_read_buffer(capacity);
618        let mut read_buffer: ReadBuf<'_> = ReadBuf::new(&mut temporary[..capacity]);
619        match Pin::new(&mut **self.get_mut_stream()).poll_read(cx, &mut read_buffer) {
620            Poll::Ready(Ok(())) => {
621                let len: usize = read_buffer.filled().len();
622                temporary.truncate(len);
623                let state: &mut WebSocketReadState =
624                    match self.get_mut_websocket_state().as_deref_mut() {
625                        Some(state) => state,
626                        None => {
627                            return_read_buffer(temporary);
628                            return Poll::Ready(Err(io::Error::new(
629                                io::ErrorKind::InvalidData,
630                                WEBSOCKET_STATE_ERROR,
631                            )));
632                        }
633                    };
634                if state.get_buffer().is_empty() {
635                    mem::swap(state.get_mut_buffer(), &mut temporary);
636                } else {
637                    state.get_mut_buffer().extend_from_slice(&temporary);
638                }
639                return_read_buffer(temporary);
640                Poll::Ready(Ok(len))
641            }
642            Poll::Ready(Err(error)) => {
643                return_read_buffer(temporary);
644                Poll::Ready(Err(error))
645            }
646            Poll::Pending => {
647                return_read_buffer(temporary);
648                Poll::Pending
649            }
650        }
651    }
652
653    /// Reads data from the stream with optional timeout handling.
654    ///
655    /// # Arguments
656    ///
657    /// - `Option<Duration>` - The timeout interval, or no timeout.
658    ///
659    /// # Returns
660    ///
661    /// - `Result<Option<usize>, RequestError>` - Bytes read, a heartbeat, or an error.
662    pub(crate) async fn get_websocket_from_stream(
663        &mut self,
664        duration_opt: Option<Duration>,
665    ) -> Result<Option<usize>, RequestError> {
666        if let Some(duration) = duration_opt {
667            return match timeout(
668                duration,
669                future::poll_fn(|cx: &mut Context<'_>| self.poll_websocket_read(cx)),
670            )
671            .await
672            {
673                Ok(result) => result.map(Some).map_err(Into::into),
674                Err(error) => {
675                    let state: &mut WebSocketReadState =
676                        self.get_mut_websocket_state().as_deref_mut().ok_or(
677                            RequestError::IncompleteWebSocketFrame(HttpStatus::BadRequest),
678                        )?;
679                    if !state.get_is_client_response() {
680                        return Err(error.into());
681                    }
682                    state.set_is_client_response(false);
683                    self.try_send(&PING_FRAME).await?;
684                    Ok(None)
685                }
686            };
687        }
688        future::poll_fn(|cx: &mut Context<'_>| self.poll_websocket_read(cx))
689            .await
690            .map(Some)
691            .map_err(Into::into)
692    }
693
694    /// Sends data over the stream.
695    ///
696    /// # Arguments
697    ///
698    /// - `D` - The data to send, which must implement `AsRef<[u8]>`.
699    ///
700    /// # Returns
701    ///
702    /// - `Result<(), ResponseError>` - Result indicating success or failure.
703    pub async fn try_send<D>(&mut self, data: D) -> Result<(), ResponseError>
704    where
705        D: AsRef<[u8]>,
706    {
707        if self.get_closed() {
708            return Err(ResponseError::ConnectionClosed);
709        }
710        Ok(self.get_mut_stream().write_all(data.as_ref()).await?)
711    }
712
713    /// Sends data over the stream.
714    ///
715    /// # Arguments
716    ///
717    /// - `D` - The data to send, which must implement `AsRef<[u8]>`.
718    ///
719    /// # Panics
720    ///
721    /// Panics if the write operation fails.
722    pub async fn send<D>(&mut self, data: D)
723    where
724        D: AsRef<[u8]>,
725    {
726        self.try_send(data).await.unwrap();
727    }
728
729    /// Sends multiple data.
730    ///
731    /// # Arguments
732    ///
733    /// - `I` - The data list to send, which must implement `IntoIterator<Item = D>` with
734    ///   `D` requiring the `AsRef<[u8]>` bound.
735    ///
736    /// # Returns
737    ///
738    /// - `Result<(), ResponseError>` - Result indicating success or failure.
739    pub async fn try_send_list<I, D>(&mut self, data_iter: I) -> Result<(), ResponseError>
740    where
741        I: IntoIterator<Item = D>,
742        D: AsRef<[u8]>,
743    {
744        if self.get_closed() {
745            return Err(ResponseError::ConnectionClosed);
746        }
747        let stream: &mut Box<dyn Transport> = self.get_mut_stream();
748        for data in data_iter {
749            stream.write_all(data.as_ref()).await?;
750        }
751        Ok(())
752    }
753
754    /// Sends multiple data.
755    ///
756    /// # Arguments
757    ///
758    /// - `I` - The data list to send, which must implement `IntoIterator<Item = D>` with
759    ///   `D` requiring the `AsRef<[u8]>` bound.
760    ///
761    /// # Panics
762    ///
763    /// Panics if any write operation fails.
764    pub async fn send_list<I, D>(&mut self, data_iter: I)
765    where
766        I: IntoIterator<Item = D>,
767        D: AsRef<[u8]>,
768    {
769        self.try_send_list(data_iter).await.unwrap();
770    }
771
772    /// Flushes all buffered data to the stream.
773    ///
774    /// # Returns
775    ///
776    /// - `Result<(), ResponseError>` - Result indicating success or failure.
777    pub async fn try_flush(&mut self) -> Result<(), ResponseError> {
778        if self.get_closed() {
779            return Err(ResponseError::ConnectionClosed);
780        }
781        Ok(self.get_mut_stream().flush().await?)
782    }
783
784    /// Flushes all buffered data to the stream.
785    ///
786    /// # Panics
787    ///
788    /// Panics if the flush operation fails.
789    pub async fn flush(&mut self) {
790        self.try_flush().await.unwrap();
791    }
792}