hyper/server/conn/http1.rs
1//! HTTP/1 Server Connections.
2
3use std::error::Error as StdError;
4use std::fmt;
5use std::future::Future;
6use std::pin::Pin;
7use std::sync::Arc;
8use std::task::{Context, Poll};
9use std::time::Duration;
10
11use crate::rt::{Read, Write};
12use crate::upgrade::Upgraded;
13use bytes::Bytes;
14use futures_core::ready;
15use httparse::ParserConfig;
16
17use crate::body::{Body, Incoming as IncomingBody};
18use crate::proto;
19use crate::service::HttpService;
20use crate::{
21 common::time::{Dur, Time},
22 rt::Timer,
23};
24
25type Http1Dispatcher<T, B, S> = proto::h1::Dispatcher<
26 proto::h1::dispatch::Server<S, IncomingBody>,
27 B,
28 T,
29 proto::ServerTransaction,
30>;
31
32pin_project_lite::pin_project! {
33 /// A [`Future`](core::future::Future) representing an HTTP/1 connection, bound to a
34 /// [`Service`](crate::service::Service), returned from
35 /// [`Builder::serve_connection`](struct.Builder.html#method.serve_connection).
36 ///
37 /// To drive HTTP on this connection this future **must be polled**, typically with
38 /// `.await`. If it isn't polled, no progress will be made on this connection.
39 #[must_use = "futures do nothing unless polled"]
40 pub struct Connection<T, S>
41 where
42 S: HttpService<IncomingBody>,
43 {
44 conn: Http1Dispatcher<T, S::ResBody, S>,
45 }
46}
47
48/// A configuration builder for HTTP/1 server connections.
49///
50/// **Note**: The default values of options are *not considered stable*. They
51/// are subject to change at any time.
52///
53/// # Example
54///
55/// ```
56/// # use std::time::Duration;
57/// # use hyper::server::conn::http1::Builder;
58/// # fn main() {
59/// let mut http = Builder::new();
60/// // Set options one at a time
61/// http.half_close(false);
62///
63/// // Or, chain multiple options
64/// http.keep_alive(false).title_case_headers(true).max_buf_size(8192);
65///
66/// # }
67/// ```
68///
69/// Use [`Builder::serve_connection`](struct.Builder.html#method.serve_connection)
70/// to bind the built connection to a service.
71#[derive(Clone, Debug)]
72pub struct Builder {
73 h1_parser_config: ParserConfig,
74 timer: Time,
75 h1_half_close: bool,
76 h1_keep_alive: bool,
77 h1_title_case_headers: bool,
78 h1_preserve_header_case: bool,
79 h1_max_headers: Option<usize>,
80 h1_max_header_size: Option<usize>,
81 h1_header_read_timeout: Dur,
82 h1_writev: Option<bool>,
83 max_buf_size: Option<usize>,
84 pipeline_flush: bool,
85 date_header: bool,
86}
87
88/// Deconstructed parts of a `Connection`.
89///
90/// This allows taking apart a `Connection` at a later time, in order to
91/// reclaim the IO object, and additional related pieces.
92#[derive(Debug)]
93#[non_exhaustive]
94pub struct Parts<T, S> {
95 /// The original IO object used in the handshake.
96 pub io: T,
97 /// A buffer of bytes that have been read but not processed as HTTP.
98 ///
99 /// If the client sent additional bytes after its last request, and
100 /// this connection "ended" with an upgrade, the read buffer will contain
101 /// those bytes.
102 ///
103 /// You will want to check for any existing bytes if you plan to continue
104 /// communicating on the IO object.
105 pub read_buf: Bytes,
106 /// The `Service` used to serve this connection.
107 pub service: S,
108}
109
110// ===== impl Connection =====
111
112impl<I, S> fmt::Debug for Connection<I, S>
113where
114 S: HttpService<IncomingBody>,
115{
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.debug_struct("Connection").finish()
118 }
119}
120
121impl<I, B, S> Connection<I, S>
122where
123 S: HttpService<IncomingBody, ResBody = B>,
124 S::Error: Into<Box<dyn StdError + Send + Sync>>,
125 I: Read + Write + Unpin,
126 B: Body + 'static,
127 B::Error: Into<Box<dyn StdError + Send + Sync>>,
128{
129 /// Start a graceful shutdown process for this connection.
130 ///
131 /// This `Connection` should continue to be polled until shutdown
132 /// can finish.
133 ///
134 /// # Note
135 ///
136 /// This should only be called while the `Connection` future is still
137 /// pending. If called after `Connection::poll` has resolved, this does
138 /// nothing.
139 pub fn graceful_shutdown(mut self: Pin<&mut Self>) {
140 self.conn.disable_keep_alive();
141 }
142
143 /// Return the inner IO object, and additional information.
144 ///
145 /// If the IO object has been "rewound" the io will not contain those bytes rewound.
146 /// This should only be called after `poll_without_shutdown` signals
147 /// that the connection is "done". Otherwise, it may not have finished
148 /// flushing all necessary HTTP bytes.
149 ///
150 /// # Panics
151 /// This method will panic if this connection is using an h2 protocol.
152 pub fn into_parts(self) -> Parts<I, S> {
153 let (io, read_buf, dispatch) = self.conn.into_inner();
154 Parts {
155 io,
156 read_buf,
157 service: dispatch.into_service(),
158 }
159 }
160
161 /// Poll the connection for completion, but without calling `shutdown`
162 /// on the underlying IO.
163 ///
164 /// This is useful to allow running a connection while doing an HTTP
165 /// upgrade. Once the upgrade is completed, the connection would be "done",
166 /// but it is not desired to actually shutdown the IO object. Instead you
167 /// would take it back using `into_parts`.
168 pub fn poll_without_shutdown(&mut self, cx: &mut Context<'_>) -> Poll<crate::Result<()>>
169 where
170 S: Unpin,
171 S::Future: Unpin,
172 {
173 self.conn.poll_without_shutdown(cx)
174 }
175
176 /// Prevent shutdown of the underlying IO object at the end of service the request,
177 /// instead run `into_parts`. This is a convenience wrapper over `poll_without_shutdown`.
178 ///
179 /// # Error
180 ///
181 /// This errors if the underlying connection protocol is not HTTP/1.
182 #[allow(clippy::missing_panics_doc)]
183 pub fn without_shutdown(self) -> impl Future<Output = crate::Result<Parts<I, S>>> {
184 let mut zelf = Some(self);
185 crate::common::future::poll_fn(move |cx| {
186 ready!(zelf
187 .as_mut()
188 .expect("server connection polled after completion")
189 .conn
190 .poll_without_shutdown(cx))?;
191 Poll::Ready(Ok(zelf
192 .take()
193 .expect("server connection missing before completion")
194 .into_parts()))
195 })
196 }
197
198 /// Enable this connection to support higher-level HTTP upgrades.
199 ///
200 /// See [the `upgrade` module](crate::upgrade) for more.
201 pub fn with_upgrades(self) -> UpgradeableConnection<I, S>
202 where
203 I: Send,
204 {
205 UpgradeableConnection { inner: Some(self) }
206 }
207}
208
209impl<I, B, S> Future for Connection<I, S>
210where
211 S: HttpService<IncomingBody, ResBody = B>,
212 S::Error: Into<Box<dyn StdError + Send + Sync>>,
213 I: Read + Write + Unpin,
214 B: Body + 'static,
215 B::Error: Into<Box<dyn StdError + Send + Sync>>,
216{
217 type Output = crate::Result<()>;
218
219 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
220 match ready!(Pin::new(&mut self.conn).poll(cx)) {
221 Ok(done) => {
222 match done {
223 proto::Dispatched::Shutdown => {}
224 proto::Dispatched::Upgrade(pending) => {
225 // With no `Send` bound on `I`, we can't try to do
226 // upgrades here. In case a user was trying to use
227 // `Body::on_upgrade` with this API, send a special
228 // error letting them know about that.
229 pending.manual();
230 }
231 }
232 Poll::Ready(Ok(()))
233 }
234 Err(e) => Poll::Ready(Err(e)),
235 }
236 }
237}
238
239// ===== impl Builder =====
240
241impl Builder {
242 /// Create a new connection builder.
243 pub fn new() -> Self {
244 Self {
245 h1_parser_config: ParserConfig::default(),
246 timer: Time::Empty,
247 h1_half_close: false,
248 h1_keep_alive: true,
249 h1_title_case_headers: false,
250 h1_preserve_header_case: false,
251 h1_max_headers: None,
252 h1_max_header_size: None,
253 h1_header_read_timeout: Dur::Default(Some(Duration::from_secs(30))),
254 h1_writev: None,
255 max_buf_size: None,
256 pipeline_flush: false,
257 date_header: true,
258 }
259 }
260 /// Set whether HTTP/1 connections should support half-closures.
261 ///
262 /// Clients can chose to shutdown their write-side while waiting
263 /// for the server to respond. Setting this to `true` will
264 /// prevent closing the connection immediately if `read`
265 /// detects an EOF in the middle of a request.
266 ///
267 /// Default is `false`.
268 pub fn half_close(&mut self, val: bool) -> &mut Self {
269 self.h1_half_close = val;
270 self
271 }
272
273 /// Enables or disables HTTP/1 keep-alive.
274 ///
275 /// Default is `true`.
276 pub fn keep_alive(&mut self, val: bool) -> &mut Self {
277 self.h1_keep_alive = val;
278 self
279 }
280
281 /// Set whether HTTP/1 connections will write header names as title case at
282 /// the socket level.
283 ///
284 /// Default is `false`.
285 pub fn title_case_headers(&mut self, enabled: bool) -> &mut Self {
286 self.h1_title_case_headers = enabled;
287 self
288 }
289
290 /// Set whether multiple spaces are allowed as delimiters in request lines.
291 ///
292 /// Default is `false`.
293 pub fn allow_multiple_spaces_in_request_line_delimiters(&mut self, enabled: bool) -> &mut Self {
294 self.h1_parser_config
295 .allow_multiple_spaces_in_request_line_delimiters(enabled);
296 self
297 }
298
299 /// Set whether HTTP/1 connections will silently ignored malformed header lines.
300 ///
301 /// If this is enabled and a header line does not start with a valid header
302 /// name, or does not include a colon at all, the line will be silently ignored
303 /// and no error will be reported.
304 ///
305 /// Default is `false`.
306 pub fn ignore_invalid_headers(&mut self, enabled: bool) -> &mut Builder {
307 self.h1_parser_config
308 .ignore_invalid_headers_in_requests(enabled);
309 self
310 }
311
312 /// Set whether to support preserving original header cases.
313 ///
314 /// Currently, this will record the original cases received, and store them
315 /// in a private extension on the `Request`. It will also look for and use
316 /// such an extension in any provided `Response`.
317 ///
318 /// Since the relevant extension is still private, there is no way to
319 /// interact with the original cases. The only effect this can have now is
320 /// to forward the cases in a proxy-like fashion.
321 ///
322 /// Default is `false`.
323 pub fn preserve_header_case(&mut self, enabled: bool) -> &mut Self {
324 self.h1_preserve_header_case = enabled;
325 self
326 }
327
328 /// Set the maximum number of headers.
329 ///
330 /// When a request is received, the parser will reserve a buffer to store headers for optimal
331 /// performance.
332 ///
333 /// If server receives more headers than the buffer size, it responds to the client with
334 /// "431 Request Header Fields Too Large".
335 ///
336 /// Note that headers is allocated on the stack by default, which has higher performance. After
337 /// setting this value, headers will be allocated in heap memory, that is, heap memory
338 /// allocation will occur for each request, and there will be a performance drop of about 5%.
339 ///
340 /// Default is 100.
341 pub fn max_headers(&mut self, val: usize) -> &mut Self {
342 self.h1_max_headers = Some(val);
343 self
344 }
345
346 /// Set the maximum size of request headers (including the start line) in bytes.
347 ///
348 /// If the client sends headers exceeding this limit, the server responds to the
349 /// client with "431 Request Header Fields Too Large" and closes the connection.
350 ///
351 /// If not configured, then the [`max_buf_size`](Builder::max_buf_size) will naturally be reached and applied.
352 ///
353 /// This value is also used as the maximum size limit for chunked trailers.
354 ///
355 /// Default is `None`.
356 pub fn max_header_size(&mut self, val: usize) -> &mut Self {
357 self.h1_max_header_size = Some(val);
358 self
359 }
360
361 /// Set a timeout for reading client request headers. If a client does not
362 /// transmit the entire header within this time, the connection is closed.
363 ///
364 /// Requires a [`Timer`] set by [`Builder::timer`] to take effect. Panics if `header_read_timeout` is configured
365 /// without a [`Timer`].
366 ///
367 /// Pass `None` to disable.
368 ///
369 /// Default is 30 seconds.
370 pub fn header_read_timeout(&mut self, read_timeout: impl Into<Option<Duration>>) -> &mut Self {
371 self.h1_header_read_timeout = Dur::Configured(read_timeout.into());
372 self
373 }
374
375 /// Set whether HTTP/1 connections should try to use vectored writes,
376 /// or always flatten into a single buffer.
377 ///
378 /// Note that setting this to false may mean more copies of body data,
379 /// but may also improve performance when an IO transport doesn't
380 /// support vectored writes well, such as most TLS implementations.
381 ///
382 /// Setting this to true will force hyper to use queued strategy,
383 /// which may eliminate unnecessary cloning on some TLS backends.
384 ///
385 /// Default is `auto`. In this mode hyper will try to guess which
386 /// mode to use.
387 pub fn writev(&mut self, val: bool) -> &mut Self {
388 self.h1_writev = Some(val);
389 self
390 }
391
392 /// Set the maximum buffer size for the connection.
393 ///
394 /// Default is ~400kb.
395 ///
396 /// # Panics
397 ///
398 /// The minimum value allowed is 8192. This method panics if the passed `max` is less than the minimum.
399 pub fn max_buf_size(&mut self, max: usize) -> &mut Self {
400 assert!(
401 max >= proto::h1::MINIMUM_MAX_BUFFER_SIZE,
402 "the max_buf_size cannot be smaller than the minimum that h1 specifies."
403 );
404 self.max_buf_size = Some(max);
405 self
406 }
407
408 /// Set whether the `date` header should be included in HTTP responses.
409 ///
410 /// Note that including the `date` header is recommended by RFC 7231.
411 ///
412 /// Default is `true`.
413 pub fn auto_date_header(&mut self, enabled: bool) -> &mut Self {
414 self.date_header = enabled;
415 self
416 }
417
418 /// Aggregates flushes to better support pipelined responses.
419 ///
420 /// Experimental, may have bugs.
421 ///
422 /// Default is `false`.
423 pub fn pipeline_flush(&mut self, enabled: bool) -> &mut Self {
424 self.pipeline_flush = enabled;
425 self
426 }
427
428 /// Set the timer used in background tasks.
429 pub fn timer<M>(&mut self, timer: M) -> &mut Self
430 where
431 M: Timer + Send + Sync + 'static,
432 {
433 self.timer = Time::Timer(Arc::new(timer));
434 self
435 }
436
437 /// Bind a connection together with a [`Service`](crate::service::Service).
438 ///
439 /// This returns a Future that must be polled in order for HTTP to be
440 /// driven on the connection.
441 ///
442 /// # Panics
443 ///
444 /// If a timeout option has been configured, but a `timer` has not been
445 /// provided, calling `serve_connection` will panic.
446 ///
447 /// # Example
448 ///
449 /// ```
450 /// # use hyper::{body::Incoming, Request, Response};
451 /// # use hyper::service::Service;
452 /// # use hyper::server::conn::http1::Builder;
453 /// # use hyper::rt::{Read, Write};
454 /// # async fn run<I, S>(some_io: I, some_service: S)
455 /// # where
456 /// # I: Read + Write + Unpin + Send + 'static,
457 /// # S: Service<hyper::Request<Incoming>, Response=hyper::Response<Incoming>> + Send + 'static,
458 /// # S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
459 /// # S::Future: Send,
460 /// # {
461 /// let http = Builder::new();
462 /// let conn = http.serve_connection(some_io, some_service);
463 ///
464 /// if let Err(e) = conn.await {
465 /// eprintln!("server connection error: {}", e);
466 /// }
467 /// # }
468 /// # fn main() {}
469 /// ```
470 pub fn serve_connection<I, S>(&self, io: I, service: S) -> Connection<I, S>
471 where
472 S: HttpService<IncomingBody>,
473 S::Error: Into<Box<dyn StdError + Send + Sync>>,
474 S::ResBody: 'static,
475 <S::ResBody as Body>::Error: Into<Box<dyn StdError + Send + Sync>>,
476 I: Read + Write + Unpin,
477 {
478 let mut conn = proto::Conn::new(io);
479 conn.set_h1_parser_config(self.h1_parser_config.clone());
480 conn.set_timer(self.timer.clone());
481 if !self.h1_keep_alive {
482 conn.disable_keep_alive();
483 }
484 if self.h1_half_close {
485 conn.set_allow_half_close();
486 }
487 if self.h1_title_case_headers {
488 conn.set_title_case_headers();
489 }
490 if self.h1_preserve_header_case {
491 conn.set_preserve_header_case();
492 }
493 if let Some(max_headers) = self.h1_max_headers {
494 conn.set_http1_max_headers(max_headers);
495 }
496 if let Some(max_header_size) = self.h1_max_header_size {
497 conn.set_http1_max_header_size(max_header_size);
498 }
499 if let Some(dur) = self
500 .timer
501 .check(self.h1_header_read_timeout, "header_read_timeout")
502 {
503 conn.set_http1_header_read_timeout(dur);
504 }
505 if let Some(writev) = self.h1_writev {
506 if writev {
507 conn.set_write_strategy_queue();
508 } else {
509 conn.set_write_strategy_flatten();
510 }
511 }
512 conn.set_flush_pipeline(self.pipeline_flush);
513 if let Some(max) = self.max_buf_size {
514 conn.set_max_buf_size(max);
515 }
516 if !self.date_header {
517 conn.disable_date_header();
518 }
519 let sd = proto::h1::dispatch::Server::new(service);
520 let proto = proto::h1::Dispatcher::new(sd, conn);
521 Connection { conn: proto }
522 }
523}
524
525/// A future binding a connection with a Service with Upgrade support.
526#[must_use = "futures do nothing unless polled"]
527#[allow(missing_debug_implementations)]
528pub struct UpgradeableConnection<T, S>
529where
530 S: HttpService<IncomingBody>,
531{
532 pub(super) inner: Option<Connection<T, S>>,
533}
534
535impl<I, B, S> UpgradeableConnection<I, S>
536where
537 S: HttpService<IncomingBody, ResBody = B>,
538 S::Error: Into<Box<dyn StdError + Send + Sync>>,
539 I: Read + Write + Unpin,
540 B: Body + 'static,
541 B::Error: Into<Box<dyn StdError + Send + Sync>>,
542{
543 /// Start a graceful shutdown process for this connection.
544 ///
545 /// This `Connection` should continue to be polled until shutdown
546 /// can finish.
547 pub fn graceful_shutdown(mut self: Pin<&mut Self>) {
548 // Connection (`inner`) is `None` if it was upgraded (and `poll` is `Ready`).
549 // In that case, we don't need to call `graceful_shutdown`.
550 if let Some(conn) = self.inner.as_mut() {
551 Pin::new(conn).graceful_shutdown();
552 }
553 }
554
555 /// Return the inner IO object, and additional information provided the connection
556 /// has not yet been upgraded.
557 pub fn into_parts(self) -> Option<Parts<I, S>> {
558 self.inner.map(|conn| conn.into_parts())
559 }
560}
561
562impl<I, B, S> Future for UpgradeableConnection<I, S>
563where
564 S: HttpService<IncomingBody, ResBody = B>,
565 S::Error: Into<Box<dyn StdError + Send + Sync>>,
566 I: Read + Write + Unpin + Send + 'static,
567 B: Body + 'static,
568 B::Error: Into<Box<dyn StdError + Send + Sync>>,
569{
570 type Output = crate::Result<()>;
571
572 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
573 if let Some(conn) = self.inner.as_mut() {
574 match ready!(Pin::new(&mut conn.conn).poll(cx)) {
575 Ok(proto::Dispatched::Shutdown) => Poll::Ready(Ok(())),
576 Ok(proto::Dispatched::Upgrade(pending)) => {
577 let (io, buf, _) = self
578 .inner
579 .take()
580 .expect("upgradeable server connection missing after upgrade")
581 .conn
582 .into_inner();
583 pending.fulfill(Upgraded::new(io, buf));
584 Poll::Ready(Ok(()))
585 }
586 Err(e) => Poll::Ready(Err(e)),
587 }
588 } else {
589 // inner is `None`, meaning the connection was upgraded, thus it's `Poll::Ready(Ok(()))`
590 Poll::Ready(Ok(()))
591 }
592 }
593}