1use std::error::Error as StdError;
2use std::future::Future;
3use std::io::{Cursor, IoSlice};
4use std::pin::Pin;
5use std::task::{Context, Poll};
6
7use bytes::Buf;
8use futures_core::ready;
9use h2::SendStream;
10use http::header::{HeaderName, CONNECTION, TRANSFER_ENCODING, UPGRADE};
11use http::HeaderMap;
12use pin_project_lite::pin_project;
13
14use crate::body::Body;
15
16pub(crate) mod ping;
17pub(crate) mod upgrade;
18
19cfg_client! {
20 pub(crate) mod client;
21 pub(crate) use self::client::ClientTask;
22}
23
24cfg_server! {
25 pub(crate) mod server;
26 pub(crate) use self::server::Server;
27}
28
29pub(crate) const SPEC_WINDOW_SIZE: u32 = 65_535;
31
32static CONNECTION_HEADERS: [HeaderName; 4] = [
37 HeaderName::from_static("keep-alive"),
38 HeaderName::from_static("proxy-connection"),
39 TRANSFER_ENCODING,
40 UPGRADE,
41];
42
43enum MessageKind {
44 #[cfg(feature = "client")]
45 Request,
46 #[cfg(feature = "server")]
47 Response,
48}
49
50fn strip_connection_headers(headers: &mut HeaderMap, kind: MessageKind) {
51 for header in &CONNECTION_HEADERS {
52 if headers.remove(header).is_some() {
53 warn!("Connection header illegal in HTTP/2: {}", header.as_str());
54 }
55 }
56
57 #[cfg(not(feature = "client"))]
58 let _ = kind;
59 #[cfg(feature = "client")]
60 if matches!(kind, MessageKind::Request) {
61 if headers
62 .get(http::header::TE)
63 .map_or(false, |te_header| te_header != "trailers")
64 {
65 warn!("TE headers not set to \"trailers\" are illegal in HTTP/2 requests");
66 headers.remove(http::header::TE);
67 }
68 } else if headers.remove(http::header::TE).is_some() {
69 warn!("TE headers illegal in HTTP/2 responses");
70 }
71
72 if let Some(header) = headers.remove(CONNECTION) {
73 warn!(
74 "Connection header illegal in HTTP/2: {}",
75 CONNECTION.as_str()
76 );
77 if let Ok(header_contents) = header.to_str() {
84 for name in header_contents.split(',') {
85 let name = name.trim();
86 headers.remove(name);
87 }
88 }
89 }
90}
91
92pin_project! {
95 pub(crate) struct PipeToSendStream<S>
96 where
97 S: Body,
98 {
99 body_tx: SendStream<SendBuf<S::Data>>,
100 data_done: bool,
101 buffered_data: Option<Peeked<S::Data>>,
106 #[pin]
107 stream: S,
108 }
109}
110
111struct Peeked<D> {
112 data: D,
113 is_eos: bool,
114}
115
116impl<S> PipeToSendStream<S>
117where
118 S: Body,
119{
120 fn new(stream: S, tx: SendStream<SendBuf<S::Data>>) -> PipeToSendStream<S> {
121 PipeToSendStream {
122 body_tx: tx,
123 data_done: false,
124 buffered_data: None,
125 stream,
126 }
127 }
128
129 #[cfg(feature = "client")]
130 fn send_reset(self: Pin<&mut Self>, reason: h2::Reason) {
131 self.project().body_tx.send_reset(reason);
132 }
133}
134
135impl<S> Future for PipeToSendStream<S>
136where
137 S: Body,
138 S::Error: Into<Box<dyn StdError + Send + Sync>>,
139{
140 type Output = crate::Result<()>;
141
142 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
143 let mut me = self.project();
144 loop {
145 if let Poll::Ready(reason) = me
149 .body_tx
150 .poll_reset(cx)
151 .map_err(crate::Error::new_body_write)?
152 {
153 debug!("stream received RST_STREAM: {:?}", reason);
154 return Poll::Ready(Err(crate::Error::new_body_write(::h2::Error::from(reason))));
155 }
156
157 if me.buffered_data.is_some() {
161 while me.body_tx.capacity() == 0 {
162 match ready!(me.body_tx.poll_capacity(cx)) {
163 Some(Ok(0)) => {}
164 Some(Ok(_)) => break,
165 Some(Err(e)) => return Poll::Ready(Err(crate::Error::new_body_write(e))),
166 None => {
167 return Poll::Ready(Err(crate::Error::new_body_write(
171 "send stream capacity unexpectedly closed",
172 )));
173 }
174 }
175 }
176
177 let peeked = me.buffered_data.take().expect("checked is_some above");
178 let buf = SendBuf::Buf(peeked.data);
179 me.body_tx
180 .send_data(buf, peeked.is_eos)
181 .map_err(crate::Error::new_body_write)?;
182
183 if peeked.is_eos {
184 return Poll::Ready(Ok(()));
185 }
186 continue;
187 }
188
189 match ready!(me.stream.as_mut().poll_frame(cx)) {
196 Some(Ok(frame)) => {
197 if frame.is_data() {
198 let chunk = frame.into_data().unwrap_or_else(|_| unreachable!());
199 let is_eos = me.stream.is_end_stream();
200 let len = chunk.remaining();
201 trace!("send body chunk: {} bytes, eos={}", len, is_eos);
202
203 if len == 0 {
204 let buf = SendBuf::Buf(chunk);
209 me.body_tx
210 .send_data(buf, is_eos)
211 .map_err(crate::Error::new_body_write)?;
212
213 if is_eos {
214 return Poll::Ready(Ok(()));
215 }
216 continue;
217 }
218
219 me.body_tx.reserve_capacity(len);
225 *me.buffered_data = Some(Peeked {
226 data: chunk,
227 is_eos,
228 });
229 } else if frame.is_trailers() {
230 me.body_tx.reserve_capacity(0);
232 me.body_tx
233 .send_trailers(frame.into_trailers().unwrap_or_else(|_| unreachable!()))
234 .map_err(crate::Error::new_body_write)?;
235 return Poll::Ready(Ok(()));
236 } else {
237 trace!("discarding unknown frame");
238 }
240 }
241 Some(Err(e)) => return Poll::Ready(Err(me.body_tx.on_user_err(e))),
242 None => {
243 return Poll::Ready(me.body_tx.send_eos_frame());
247 }
248 }
249 }
250 }
251}
252
253trait SendStreamExt {
254 fn on_user_err<E>(&mut self, err: E) -> crate::Error
255 where
256 E: Into<Box<dyn std::error::Error + Send + Sync>>;
257 fn send_eos_frame(&mut self) -> crate::Result<()>;
258}
259
260impl<B: Buf> SendStreamExt for SendStream<SendBuf<B>> {
261 fn on_user_err<E>(&mut self, err: E) -> crate::Error
262 where
263 E: Into<Box<dyn std::error::Error + Send + Sync>>,
264 {
265 let err = crate::Error::new_user_body(err);
266 debug!("send body user stream error: {}", err);
267 self.send_reset(err.h2_reason());
268 err
269 }
270
271 fn send_eos_frame(&mut self) -> crate::Result<()> {
272 trace!("send body eos");
273 self.send_data(SendBuf::None, true)
274 .map_err(crate::Error::new_body_write)
275 }
276}
277
278#[repr(usize)]
279enum SendBuf<B> {
280 Buf(B),
281 Cursor(Cursor<Box<[u8]>>),
282 None,
283}
284
285impl<B: Buf> Buf for SendBuf<B> {
286 #[inline]
287 fn remaining(&self) -> usize {
288 match *self {
289 Self::Buf(ref b) => b.remaining(),
290 Self::Cursor(ref c) => Buf::remaining(c),
291 Self::None => 0,
292 }
293 }
294
295 #[inline]
296 fn chunk(&self) -> &[u8] {
297 match *self {
298 Self::Buf(ref b) => b.chunk(),
299 Self::Cursor(ref c) => c.chunk(),
300 Self::None => &[],
301 }
302 }
303
304 #[inline]
305 fn advance(&mut self, cnt: usize) {
306 match *self {
307 Self::Buf(ref mut b) => b.advance(cnt),
308 Self::Cursor(ref mut c) => c.advance(cnt),
309 Self::None => {}
310 }
311 }
312
313 fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
314 match *self {
315 Self::Buf(ref b) => b.chunks_vectored(dst),
316 Self::Cursor(ref c) => c.chunks_vectored(dst),
317 Self::None => 0,
318 }
319 }
320}