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 let content_size: usize = request
415 .get_http_headers(&mut reader, &config, header_line_buffer)
416 .await?;
417 request.set_method(method);
418 request.set_version(version);
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
567 .get_mut_websocket_state()
568 .as_mut()
569 .expect(WEBSOCKET_STATE_EXPECT);
570 let WebSocketReadState {
571 buffer,
572 full_frame,
573 is_client_response,
574 }: &mut WebSocketReadState = state;
575 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&buffer[..]) {
576 *is_client_response = true;
577 buffer.drain(..consumed);
578 if buffer.is_empty() {
579 let mut recycled: Vec<u8> = mem::take(buffer);
580 recycled.resize(recycled.capacity().min(MAX_POOLED_READ_BUFFER_SIZE), 0);
581 return_read_buffer(recycled);
582 }
583 match frame.get_opcode() {
584 WebSocketOpcode::Close => {
585 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
586 }
587 WebSocketOpcode::Ping | WebSocketOpcode::Pong => continue,
588 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
589 if frame.get_fin() && full_frame.is_empty() {
590 let WebSocketFrame { payload_data, .. }: WebSocketFrame = frame;
591 return Ok(Some(payload_data));
592 }
593 if let Some(body) = frame.build_full_frame(full_frame)? {
594 return Ok(Some(body));
595 }
596 }
597 _ => {
598 return Err(RequestError::WebSocketOpcodeUnsupported(
599 HttpStatus::NotImplemented,
600 ));
601 }
602 }
603 }
604 Ok(None)
605 }
606
607 /// Polls a WebSocket read using a buffer retained only while data is ready.
608 ///
609 /// # Arguments
610 ///
611 /// - `&mut Context<'_>` - The registered task context.
612 ///
613 /// # Returns
614 ///
615 /// - `Poll<io::Result<usize>>` - The bytes appended to persistent parsing state.
616 fn poll_websocket_read(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
617 let capacity: usize = self.get_request_config().get_buffer_size();
618 let mut temporary: Vec<u8> = take_read_buffer(capacity);
619 let mut read_buffer: ReadBuf<'_> = ReadBuf::new(&mut temporary[..capacity]);
620 match Pin::new(&mut **self.get_mut_stream()).poll_read(cx, &mut read_buffer) {
621 Poll::Ready(Ok(())) => {
622 let len: usize = read_buffer.filled().len();
623 temporary.truncate(len);
624 let state: &mut WebSocketReadState = self
625 .get_mut_websocket_state()
626 .as_mut()
627 .expect(WEBSOCKET_STATE_EXPECT);
628 if state.get_buffer().is_empty() {
629 mem::swap(state.get_mut_buffer(), &mut temporary);
630 } else {
631 state.get_mut_buffer().extend_from_slice(&temporary);
632 }
633 return_read_buffer(temporary);
634 Poll::Ready(Ok(len))
635 }
636 Poll::Ready(Err(error)) => {
637 return_read_buffer(temporary);
638 Poll::Ready(Err(error))
639 }
640 Poll::Pending => {
641 return_read_buffer(temporary);
642 Poll::Pending
643 }
644 }
645 }
646
647 /// Reads data from the stream with optional timeout handling.
648 ///
649 /// # Arguments
650 ///
651 /// - `Option<Duration>` - The timeout interval, or no timeout.
652 ///
653 /// # Returns
654 ///
655 /// - `Result<Option<usize>, RequestError>` - Bytes read, a heartbeat, or an error.
656 pub(crate) async fn get_websocket_from_stream(
657 &mut self,
658 duration_opt: Option<Duration>,
659 ) -> Result<Option<usize>, RequestError> {
660 if let Some(duration) = duration_opt {
661 return match timeout(
662 duration,
663 future::poll_fn(|cx: &mut Context<'_>| self.poll_websocket_read(cx)),
664 )
665 .await
666 {
667 Ok(result) => result.map(Some).map_err(Into::into),
668 Err(error) => {
669 let state: &mut WebSocketReadState = self
670 .get_mut_websocket_state()
671 .as_mut()
672 .expect(WEBSOCKET_STATE_EXPECT);
673 if !state.get_is_client_response() {
674 return Err(error.into());
675 }
676 state.set_is_client_response(false);
677 self.try_send(&PING_FRAME).await?;
678 Ok(None)
679 }
680 };
681 }
682 future::poll_fn(|cx: &mut Context<'_>| self.poll_websocket_read(cx))
683 .await
684 .map(Some)
685 .map_err(Into::into)
686 }
687
688 /// Sends data over the stream.
689 ///
690 /// # Arguments
691 ///
692 /// - `D` - The data to send, which must implement `AsRef<[u8]>`.
693 ///
694 /// # Returns
695 ///
696 /// - `Result<(), ResponseError>` - Result indicating success or failure.
697 pub async fn try_send<D>(&mut self, data: D) -> Result<(), ResponseError>
698 where
699 D: AsRef<[u8]>,
700 {
701 if self.get_closed() {
702 return Err(ResponseError::ConnectionClosed);
703 }
704 Ok(self.get_mut_stream().write_all(data.as_ref()).await?)
705 }
706
707 /// Sends data over the stream.
708 ///
709 /// # Arguments
710 ///
711 /// - `D` - The data to send, which must implement `AsRef<[u8]>`.
712 ///
713 /// # Panics
714 ///
715 /// Panics if the write operation fails.
716 pub async fn send<D>(&mut self, data: D)
717 where
718 D: AsRef<[u8]>,
719 {
720 self.try_send(data).await.unwrap();
721 }
722
723 /// Sends multiple data.
724 ///
725 /// # Arguments
726 ///
727 /// - `I` - The data list to send, which must implement `IntoIterator<Item = D>` with
728 /// `D` requiring the `AsRef<[u8]>` bound.
729 ///
730 /// # Returns
731 ///
732 /// - `Result<(), ResponseError>` - Result indicating success or failure.
733 pub async fn try_send_list<I, D>(&mut self, data_iter: I) -> Result<(), ResponseError>
734 where
735 I: IntoIterator<Item = D>,
736 D: AsRef<[u8]>,
737 {
738 if self.get_closed() {
739 return Err(ResponseError::ConnectionClosed);
740 }
741 let stream: &mut Box<dyn Transport> = self.get_mut_stream();
742 for data in data_iter {
743 stream.write_all(data.as_ref()).await?;
744 }
745 Ok(())
746 }
747
748 /// Sends multiple data.
749 ///
750 /// # Arguments
751 ///
752 /// - `I` - The data list to send, which must implement `IntoIterator<Item = D>` with
753 /// `D` requiring the `AsRef<[u8]>` bound.
754 ///
755 /// # Panics
756 ///
757 /// Panics if any write operation fails.
758 pub async fn send_list<I, D>(&mut self, data_iter: I)
759 where
760 I: IntoIterator<Item = D>,
761 D: AsRef<[u8]>,
762 {
763 self.try_send_list(data_iter).await.unwrap();
764 }
765
766 /// Flushes all buffered data to the stream.
767 ///
768 /// # Returns
769 ///
770 /// - `Result<(), ResponseError>` - Result indicating success or failure.
771 pub async fn try_flush(&mut self) -> Result<(), ResponseError> {
772 if self.get_closed() {
773 return Err(ResponseError::ConnectionClosed);
774 }
775 Ok(self.get_mut_stream().flush().await?)
776 }
777
778 /// Flushes all buffered data to the stream.
779 ///
780 /// # Panics
781 ///
782 /// Panics if the flush operation fails.
783 pub async fn flush(&mut self) {
784 self.try_flush().await.unwrap();
785 }
786}