1use bytes::Buf;
4
5use crate::{
6 error::{
7 connection_error_creators::CloseStream, internal_error::InternalConnectionError, Code,
8 StreamError,
9 },
10 quic::{self},
11 shared_state::{ConnectionState, SharedState},
12};
13
14use super::connection::RequestEnd;
15use std::sync::Arc;
16
17use std::{
18 option::Option,
19 result::Result,
20 task::{Context, Poll},
21};
22
23use bytes::BytesMut;
24use futures_util::future;
25use http::{response, HeaderMap, Response};
26
27use quic::StreamId;
28
29use crate::{
30 proto::{frame::Frame, headers::Header},
31 qpack,
32 quic::SendStream as _,
33 stream::{self},
34};
35
36#[cfg(feature = "tracing")]
37use tracing::{error, instrument};
38
39pub struct RequestStream<S, B> {
45 pub(super) inner: crate::connection::RequestStream<S, B>,
46 pub(super) request_end: Arc<RequestEnd>,
47}
48
49impl<S, B> AsMut<crate::connection::RequestStream<S, B>> for RequestStream<S, B> {
50 fn as_mut(&mut self) -> &mut crate::connection::RequestStream<S, B> {
51 &mut self.inner
52 }
53}
54
55impl<S, B> ConnectionState for RequestStream<S, B> {
56 fn shared_state(&self) -> &SharedState {
57 &self.inner.conn_state
58 }
59}
60
61impl<S, B> CloseStream for RequestStream<S, B> {}
62
63impl<S, B> RequestStream<S, B>
64where
65 S: quic::RecvStream,
66 B: Buf,
67{
68 #[cfg_attr(feature = "tracing", instrument(skip_all, level = "trace"))]
70 pub async fn recv_data(&mut self) -> Result<Option<impl Buf>, StreamError> {
71 future::poll_fn(|cx| self.poll_recv_data(cx)).await
72 }
73
74 #[cfg_attr(feature = "tracing", instrument(skip_all, level = "trace"))]
76 pub fn poll_recv_data(
77 &mut self,
78 cx: &mut Context<'_>,
79 ) -> Poll<Result<Option<impl Buf>, StreamError>> {
80 self.inner.poll_recv_data(cx)
81 }
82
83 #[cfg_attr(feature = "tracing", instrument(skip_all, level = "trace"))]
85 pub async fn recv_trailers(&mut self) -> Result<Option<HeaderMap>, StreamError> {
86 future::poll_fn(|cx| self.poll_recv_trailers(cx)).await
87 }
88
89 #[cfg_attr(feature = "tracing", instrument(skip_all, level = "trace"))]
91 pub fn poll_recv_trailers(
92 &mut self,
93 cx: &mut Context<'_>,
94 ) -> Poll<Result<Option<HeaderMap>, StreamError>> {
95 self.inner.poll_recv_trailers(cx)
96 }
97
98 #[cfg_attr(feature = "tracing", instrument(skip_all, level = "trace"))]
100 pub fn stop_sending(&mut self, error_code: Code) {
101 self.inner.stream.stop_sending(error_code)
102 }
103
104 pub fn id(&self) -> StreamId {
106 self.inner.stream.id()
107 }
108}
109
110impl<S, B> RequestStream<S, B>
111where
112 S: quic::SendStream<B>,
113 B: Buf,
114{
115 pub async fn send_response(&mut self, resp: Response<()>) -> Result<(), StreamError> {
120 let (parts, _) = resp.into_parts();
121 let response::Parts {
122 status, headers, ..
123 } = parts;
124 let headers = Header::response(status, headers);
125
126 let mut block = BytesMut::new();
127 let mem_size = qpack::encode_stateless(&mut block, headers).map_err(|_e| {
128 self.handle_connection_error_on_stream(InternalConnectionError {
129 code: Code::H3_INTERNAL_ERROR,
130 message: "Failed to encode headers".to_string(),
131 })
132 })?;
133
134 let max_mem_size = self.inner.settings().max_field_section_size;
135
136 if mem_size > max_mem_size {
146 return Err(StreamError::HeaderTooBig {
147 actual_size: mem_size,
148 max_size: max_mem_size,
149 });
150 }
151
152 stream::write(&mut self.inner.stream, Frame::Headers(block.freeze()))
153 .await
154 .map_err(|e| self.handle_quic_stream_error(e))?;
155
156 Ok(())
157 }
158
159 pub async fn send_data(&mut self, buf: B) -> Result<(), StreamError> {
161 self.inner.send_data(buf).await
162 }
163
164 pub fn stop_stream(&mut self, error_code: Code) {
168 self.inner.stop_stream(error_code);
169 }
170
171 pub async fn send_trailers(&mut self, trailers: HeaderMap) -> Result<(), StreamError> {
175 self.inner.send_trailers(trailers).await
176 }
177
178 pub async fn finish(&mut self) -> Result<(), StreamError> {
182 self.inner.finish().await
183 }
184
185 pub fn send_id(&self) -> StreamId {
195 self.inner.stream.send_id()
196 }
197}
198
199impl<S, B> RequestStream<S, B>
200where
201 S: quic::BidiStream<B>,
202 B: Buf,
203{
204 pub fn split(
207 self,
208 ) -> (
209 RequestStream<S::SendStream, B>,
210 RequestStream<S::RecvStream, B>,
211 ) {
212 let (send, recv) = self.inner.split();
213 (
214 RequestStream {
215 inner: send,
216 request_end: self.request_end.clone(),
217 },
218 RequestStream {
219 inner: recv,
220 request_end: self.request_end,
221 },
222 )
223 }
224}
225
226impl Drop for RequestEnd {
227 fn drop(&mut self) {
228 if let Err(_error) = self.request_end.send(self.stream_id) {
229 #[cfg(feature = "tracing")]
230 error!(
231 "failed to notify connection of request end: {} {}",
232 self.stream_id, _error
233 );
234 }
235 }
236}