h2/client.rs
1//! Client implementation of the HTTP/2 protocol.
2//!
3//! # Getting started
4//!
5//! Running an HTTP/2 client requires the caller to establish the underlying
6//! connection as well as get the connection to a state that is ready to begin
7//! the HTTP/2 handshake. See [here](../index.html#handshake) for more
8//! details.
9//!
10//! This could be as basic as using Tokio's [`TcpStream`] to connect to a remote
11//! host, but usually it means using either ALPN or HTTP/1.1 protocol upgrades.
12//!
13//! Once a connection is obtained, it is passed to [`handshake`], which will
14//! begin the [HTTP/2 handshake]. This returns a future that completes once
15//! the handshake process is performed and HTTP/2 streams may be initialized.
16//!
17//! [`handshake`] uses default configuration values. There are a number of
18//! settings that can be changed by using [`Builder`] instead.
19//!
20//! Once the handshake future completes, the caller is provided with a
21//! [`Connection`] instance and a [`SendRequest`] instance. The [`Connection`]
22//! instance is used to drive the connection (see [Managing the connection]).
23//! The [`SendRequest`] instance is used to initialize new streams (see [Making
24//! requests]).
25//!
26//! # Making requests
27//!
28//! Requests are made using the [`SendRequest`] handle provided by the handshake
29//! future. Once a request is submitted, an HTTP/2 stream is initialized and
30//! the request is sent to the server.
31//!
32//! A request body and request trailers are sent using [`SendRequest`] and the
33//! server's response is returned once the [`ResponseFuture`] future completes.
34//! Both the [`SendStream`] and [`ResponseFuture`] instances are returned by
35//! [`SendRequest::send_request`] and are tied to the HTTP/2 stream
36//! initialized by the sent request.
37//!
38//! The [`SendRequest::poll_ready`] function returns `Ready` when a new HTTP/2
39//! stream can be created, i.e. as long as the current number of active streams
40//! is below [`MAX_CONCURRENT_STREAMS`]. If a new stream cannot be created, the
41//! caller will be notified once an existing stream closes, freeing capacity for
42//! the caller. The caller should use [`SendRequest::poll_ready`] to check for
43//! capacity before sending a request to the server.
44//!
45//! [`SendRequest`] enforces the [`MAX_CONCURRENT_STREAMS`] setting. The user
46//! must not send a request if `poll_ready` does not return `Ready`. Attempting
47//! to do so will result in an [`Error`] being returned.
48//!
49//! # Managing the connection
50//!
51//! The [`Connection`] instance is used to manage connection state. The caller
52//! is required to call [`Connection::poll`] in order to advance state.
53//! [`SendRequest::send_request`] and other functions have no effect unless
54//! [`Connection::poll`] is called.
55//!
56//! The [`Connection`] instance should only be dropped once [`Connection::poll`]
57//! returns `Ready`. At this point, the underlying socket has been closed and no
58//! further work needs to be done.
59//!
60//! The easiest way to ensure that the [`Connection`] instance gets polled is to
61//! submit the [`Connection`] instance to an [executor]. The executor will then
62//! manage polling the connection until the connection is complete.
63//! Alternatively, the caller can call `poll` manually.
64//!
65//! # Example
66//!
67//! ```rust, no_run
68//!
69//! use h2::client;
70//!
71//! use http::{Request, Method};
72//! use std::error::Error;
73//! use tokio::net::TcpStream;
74//!
75//! #[tokio::main]
76//! pub async fn main() -> Result<(), Box<dyn Error>> {
77//! // Establish TCP connection to the server.
78//! let tcp = TcpStream::connect("127.0.0.1:5928").await?;
79//! let (h2, connection) = client::handshake(tcp).await?;
80//! tokio::spawn(async move {
81//! connection.await.unwrap();
82//! });
83//!
84//! let mut h2 = h2.ready().await?;
85//! // Prepare the HTTP request to send to the server.
86//! let request = Request::builder()
87//! .method(Method::GET)
88//! .uri("https://www.example.com/")
89//! .body(())
90//! .unwrap();
91//!
92//! // Send the request. The second tuple item allows the caller
93//! // to stream a request body.
94//! let (response, _) = h2.send_request(request, true).unwrap();
95//!
96//! let (head, mut body) = response.await?.into_parts();
97//!
98//! println!("Received response: {:?}", head);
99//!
100//! // The `flow_control` handle allows the caller to manage
101//! // flow control.
102//! //
103//! // Whenever data is received, the caller is responsible for
104//! // releasing capacity back to the server once it has freed
105//! // the data from memory.
106//! let mut flow_control = body.flow_control().clone();
107//!
108//! while let Some(chunk) = body.data().await {
109//! let chunk = chunk?;
110//! println!("RX: {:?}", chunk);
111//!
112//! // Let the server send more data.
113//! let _ = flow_control.release_capacity(chunk.len());
114//! }
115//!
116//! Ok(())
117//! }
118//! ```
119//!
120//! [`TcpStream`]: https://docs.rs/tokio-core/0.1/tokio_core/net/struct.TcpStream.html
121//! [`handshake`]: fn.handshake.html
122//! [executor]: https://docs.rs/futures/0.1/futures/future/trait.Executor.html
123//! [`SendRequest`]: struct.SendRequest.html
124//! [`SendStream`]: ../struct.SendStream.html
125//! [Making requests]: #making-requests
126//! [Managing the connection]: #managing-the-connection
127//! [`Connection`]: struct.Connection.html
128//! [`Connection::poll`]: struct.Connection.html#method.poll
129//! [`SendRequest::send_request`]: struct.SendRequest.html#method.send_request
130//! [`MAX_CONCURRENT_STREAMS`]: http://httpwg.org/specs/rfc7540.html#SettingValues
131//! [`SendRequest`]: struct.SendRequest.html
132//! [`ResponseFuture`]: struct.ResponseFuture.html
133//! [`SendRequest::poll_ready`]: struct.SendRequest.html#method.poll_ready
134//! [HTTP/2 handshake]: http://httpwg.org/specs/rfc7540.html#ConnectionHeader
135//! [`Builder`]: struct.Builder.html
136//! [`Error`]: ../struct.Error.html
137
138use crate::codec::{Codec, SendError, UserError};
139use crate::ext::Protocol;
140use crate::frame::{Headers, Pseudo, Reason, Settings, StreamId};
141use crate::proto::{self, Error};
142use crate::{FlowControl, PingPong, RecvStream, SendStream};
143
144use bytes::{Buf, Bytes};
145use http::{uri, HeaderMap, Method, Request, Response, Version};
146use std::fmt;
147use std::future::Future;
148use std::pin::Pin;
149use std::task::{Context, Poll};
150use std::time::Duration;
151use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
152use tracing::Instrument;
153
154/// Initializes new HTTP/2 streams on a connection by sending a request.
155///
156/// This type does no work itself. Instead, it is a handle to the inner
157/// connection state held by [`Connection`]. If the associated connection
158/// instance is dropped, all `SendRequest` functions will return [`Error`].
159///
160/// [`SendRequest`] instances are able to move to and operate on separate tasks
161/// / threads than their associated [`Connection`] instance. Internally, there
162/// is a buffer used to stage requests before they get written to the
163/// connection. There is no guarantee that requests get written to the
164/// connection in FIFO order as HTTP/2 prioritization logic can play a role.
165///
166/// [`SendRequest`] implements [`Clone`], enabling the creation of many
167/// instances that are backed by a single connection.
168///
169/// See [module] level documentation for more details.
170///
171/// [module]: index.html
172/// [`Connection`]: struct.Connection.html
173/// [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html
174/// [`Error`]: ../struct.Error.html
175pub struct SendRequest<B: Buf> {
176 inner: proto::Streams<B, Peer>,
177 pending: Option<proto::OpaqueStreamRef>,
178}
179
180/// Returns a `SendRequest` instance once it is ready to send at least one
181/// request.
182#[derive(Debug)]
183pub struct ReadySendRequest<B: Buf> {
184 inner: Option<SendRequest<B>>,
185}
186
187/// Manages all state associated with an HTTP/2 client connection.
188///
189/// A `Connection` is backed by an I/O resource (usually a TCP socket) and
190/// implements the HTTP/2 client logic for that connection. It is responsible
191/// for driving the internal state forward, performing the work requested of the
192/// associated handles ([`SendRequest`], [`ResponseFuture`], [`SendStream`],
193/// [`RecvStream`]).
194///
195/// `Connection` values are created by calling [`handshake`]. Once a
196/// `Connection` value is obtained, the caller must repeatedly call [`poll`]
197/// until `Ready` is returned. The easiest way to do this is to submit the
198/// `Connection` instance to an [executor].
199///
200/// [module]: index.html
201/// [`handshake`]: fn.handshake.html
202/// [`SendRequest`]: struct.SendRequest.html
203/// [`ResponseFuture`]: struct.ResponseFuture.html
204/// [`SendStream`]: ../struct.SendStream.html
205/// [`RecvStream`]: ../struct.RecvStream.html
206/// [`poll`]: #method.poll
207/// [executor]: https://docs.rs/futures/0.1/futures/future/trait.Executor.html
208///
209/// # Examples
210///
211/// ```
212/// # use tokio::io::{AsyncRead, AsyncWrite};
213/// # use h2::client;
214/// # use h2::client::*;
215/// #
216/// # async fn doc<T>(my_io: T) -> Result<(), h2::Error>
217/// # where T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
218/// # {
219/// let (send_request, connection) = client::handshake(my_io).await?;
220/// // Submit the connection handle to an executor.
221/// tokio::spawn(async { connection.await.expect("connection failed"); });
222///
223/// // Now, use `send_request` to initialize HTTP/2 streams.
224/// // ...
225/// # Ok(())
226/// # }
227/// #
228/// # pub fn main() {}
229/// ```
230#[must_use = "futures do nothing unless polled"]
231pub struct Connection<T, B: Buf = Bytes> {
232 inner: proto::Connection<T, Peer, B>,
233}
234
235/// A future of an HTTP response.
236#[derive(Debug)]
237#[must_use = "futures do nothing unless polled"]
238pub struct ResponseFuture {
239 inner: proto::OpaqueStreamRef,
240 push_promise_consumed: bool,
241}
242
243/// A future of a pushed HTTP response.
244///
245/// We have to differentiate between pushed and non pushed because of the spec
246/// <https://httpwg.org/specs/rfc7540.html#PUSH_PROMISE>
247/// > PUSH_PROMISE frames MUST only be sent on a peer-initiated stream
248/// > that is in either the "open" or "half-closed (remote)" state.
249#[derive(Debug)]
250#[must_use = "futures do nothing unless polled"]
251pub struct PushedResponseFuture {
252 inner: ResponseFuture,
253}
254
255/// A pushed response and corresponding request headers
256#[derive(Debug)]
257pub struct PushPromise {
258 /// The request headers
259 request: Request<()>,
260
261 /// The pushed response
262 response: PushedResponseFuture,
263}
264
265/// A stream of pushed responses and corresponding promised requests
266#[derive(Debug)]
267#[must_use = "streams do nothing unless polled"]
268pub struct PushPromises {
269 inner: proto::OpaqueStreamRef,
270}
271
272/// Builds client connections with custom configuration values.
273///
274/// Methods can be chained in order to set the configuration values.
275///
276/// The client is constructed by calling [`handshake`] and passing the I/O
277/// handle that will back the HTTP/2 server.
278///
279/// New instances of `Builder` are obtained via [`Builder::new`].
280///
281/// See function level documentation for details on the various client
282/// configuration settings.
283///
284/// [`Builder::new`]: struct.Builder.html#method.new
285/// [`handshake`]: struct.Builder.html#method.handshake
286///
287/// # Examples
288///
289/// ```
290/// # use tokio::io::{AsyncRead, AsyncWrite};
291/// # use h2::client::*;
292/// # use bytes::Bytes;
293/// #
294/// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
295/// -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
296/// # {
297/// // `client_fut` is a future representing the completion of the HTTP/2
298/// // handshake.
299/// let client_fut = Builder::new()
300/// .initial_window_size(1_000_000)
301/// .max_concurrent_streams(1000)
302/// .handshake(my_io);
303/// # client_fut.await
304/// # }
305/// #
306/// # pub fn main() {}
307/// ```
308#[derive(Clone, Debug)]
309pub struct Builder {
310 /// Time to keep locally reset streams around before reaping.
311 reset_stream_duration: Duration,
312
313 /// Initial maximum number of locally initiated (send) streams.
314 /// After receiving a SETTINGS frame from the remote peer,
315 /// the connection will overwrite this value with the
316 /// MAX_CONCURRENT_STREAMS specified in the frame.
317 /// If no value is advertised by the remote peer in the initial SETTINGS
318 /// frame, it will be set to usize::MAX.
319 initial_max_send_streams: usize,
320
321 /// Initial target window size for new connections.
322 initial_target_connection_window_size: Option<u32>,
323
324 /// Maximum amount of bytes to "buffer" for writing per stream.
325 max_send_buffer_size: usize,
326
327 /// Maximum number of locally reset streams to keep at a time.
328 reset_stream_max: usize,
329
330 /// Maximum number of remotely reset streams to allow in the pending
331 /// accept queue.
332 pending_accept_reset_stream_max: usize,
333
334 /// Initial `Settings` frame to send as part of the handshake.
335 settings: Settings,
336
337 /// The stream ID of the first (lowest) stream. Subsequent streams will use
338 /// monotonically increasing stream IDs.
339 stream_id: StreamId,
340
341 /// Maximum number of locally reset streams due to protocol error across
342 /// the lifetime of the connection.
343 ///
344 /// When this gets exceeded, we issue GOAWAYs.
345 local_max_error_reset_streams: Option<usize>,
346
347 /// connection-level budget for DATA framing overhead.
348 ///
349 /// When this gets exhausted, we issue a GOAWAY with `ENHANCE_YOUR_CALM`.
350 data_frame_budget: proto::DataFrameBudget,
351}
352
353#[derive(Debug)]
354pub(crate) struct Peer;
355
356// ===== impl SendRequest =====
357
358impl<B> SendRequest<B>
359where
360 B: Buf,
361{
362 /// Returns `Ready` when the connection can initialize a new HTTP/2
363 /// stream.
364 ///
365 /// This function must return `Ready` before `send_request` is called. When
366 /// `Poll::Pending` is returned, the task will be notified once the readiness
367 /// state changes.
368 ///
369 /// See [module] level docs for more details.
370 ///
371 /// [module]: index.html
372 pub fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), crate::Error>> {
373 ready!(self.inner.poll_pending_open(cx, self.pending.as_ref()))?;
374 self.pending = None;
375 Poll::Ready(Ok(()))
376 }
377
378 /// Consumes `self`, returning a future that returns `self` back once it is
379 /// ready to send a request.
380 ///
381 /// This function should be called before calling `send_request`.
382 ///
383 /// This is a functional combinator for [`poll_ready`]. The returned future
384 /// will call `SendStream::poll_ready` until `Ready`, then returns `self` to
385 /// the caller.
386 ///
387 /// # Examples
388 ///
389 /// ```rust
390 /// # use h2::client::*;
391 /// # use http::*;
392 /// # async fn doc(send_request: SendRequest<&'static [u8]>)
393 /// # {
394 /// // First, wait until the `send_request` handle is ready to send a new
395 /// // request
396 /// let mut send_request = send_request.ready().await.unwrap();
397 /// // Use `send_request` here.
398 /// # }
399 /// # pub fn main() {}
400 /// ```
401 ///
402 /// See [module] level docs for more details.
403 ///
404 /// [`poll_ready`]: #method.poll_ready
405 /// [module]: index.html
406 pub fn ready(self) -> ReadySendRequest<B> {
407 ReadySendRequest { inner: Some(self) }
408 }
409
410 /// Sends a HTTP/2 request to the server.
411 ///
412 /// `send_request` initializes a new HTTP/2 stream on the associated
413 /// connection, then sends the given request using this new stream. Only the
414 /// request head is sent.
415 ///
416 /// On success, a [`ResponseFuture`] instance and [`SendStream`] instance
417 /// are returned. The [`ResponseFuture`] instance is used to get the
418 /// server's response and the [`SendStream`] instance is used to send a
419 /// request body or trailers to the server over the same HTTP/2 stream.
420 ///
421 /// To send a request body or trailers, set `end_of_stream` to `false`.
422 /// Then, use the returned [`SendStream`] instance to stream request body
423 /// chunks or send trailers. If `end_of_stream` is **not** set to `false`
424 /// then attempting to call [`SendStream::send_data`] or
425 /// [`SendStream::send_trailers`] will result in an error.
426 ///
427 /// If no request body or trailers are to be sent, set `end_of_stream` to
428 /// `true` and drop the returned [`SendStream`] instance.
429 ///
430 /// # A note on HTTP versions
431 ///
432 /// The provided `Request` will be encoded differently depending on the
433 /// value of its version field. If the version is set to 2.0, then the
434 /// request is encoded as per the specification recommends.
435 ///
436 /// If the version is set to a lower value, then the request is encoded to
437 /// preserve the characteristics of HTTP 1.1 and lower. Specifically, host
438 /// headers are permitted and the `:authority` pseudo header is not
439 /// included.
440 ///
441 /// The caller should always set the request's version field to 2.0 unless
442 /// specifically transmitting an HTTP 1.1 request over 2.0.
443 ///
444 /// # Examples
445 ///
446 /// Sending a request with no body
447 ///
448 /// ```rust
449 /// # use h2::client::*;
450 /// # use http::*;
451 /// # async fn doc(send_request: SendRequest<&'static [u8]>)
452 /// # {
453 /// // First, wait until the `send_request` handle is ready to send a new
454 /// // request
455 /// let mut send_request = send_request.ready().await.unwrap();
456 /// // Prepare the HTTP request to send to the server.
457 /// let request = Request::get("https://www.example.com/")
458 /// .body(())
459 /// .unwrap();
460 ///
461 /// // Send the request to the server. Since we are not sending a
462 /// // body or trailers, we can drop the `SendStream` instance.
463 /// let (response, _) = send_request.send_request(request, true).unwrap();
464 /// let response = response.await.unwrap();
465 /// // Process the response
466 /// # }
467 /// # pub fn main() {}
468 /// ```
469 ///
470 /// Sending a request with a body and trailers
471 ///
472 /// ```rust
473 /// # use h2::client::*;
474 /// # use http::*;
475 /// # async fn doc(send_request: SendRequest<&'static [u8]>)
476 /// # {
477 /// // First, wait until the `send_request` handle is ready to send a new
478 /// // request
479 /// let mut send_request = send_request.ready().await.unwrap();
480 ///
481 /// // Prepare the HTTP request to send to the server.
482 /// let request = Request::get("https://www.example.com/")
483 /// .body(())
484 /// .unwrap();
485 ///
486 /// // Send the request to the server. If we are not sending a
487 /// // body or trailers, we can drop the `SendStream` instance.
488 /// let (response, mut send_stream) = send_request
489 /// .send_request(request, false).unwrap();
490 ///
491 /// // At this point, one option would be to wait for send capacity.
492 /// // Doing so would allow us to not hold data in memory that
493 /// // cannot be sent. However, this is not a requirement, so this
494 /// // example will skip that step. See `SendStream` documentation
495 /// // for more details.
496 /// send_stream.send_data(b"hello", false).unwrap();
497 /// send_stream.send_data(b"world", false).unwrap();
498 ///
499 /// // Send the trailers.
500 /// let mut trailers = HeaderMap::new();
501 /// trailers.insert(
502 /// header::HeaderName::from_bytes(b"my-trailer").unwrap(),
503 /// header::HeaderValue::from_bytes(b"hello").unwrap());
504 ///
505 /// send_stream.send_trailers(trailers).unwrap();
506 ///
507 /// let response = response.await.unwrap();
508 /// // Process the response
509 /// # }
510 /// # pub fn main() {}
511 /// ```
512 ///
513 /// [`ResponseFuture`]: struct.ResponseFuture.html
514 /// [`SendStream`]: ../struct.SendStream.html
515 /// [`SendStream::send_data`]: ../struct.SendStream.html#method.send_data
516 /// [`SendStream::send_trailers`]: ../struct.SendStream.html#method.send_trailers
517 pub fn send_request(
518 &mut self,
519 request: Request<()>,
520 end_of_stream: bool,
521 ) -> Result<(ResponseFuture, SendStream<B>), crate::Error> {
522 self.inner
523 .send_request(request, end_of_stream, self.pending.as_ref())
524 .map_err(Into::into)
525 .map(|(stream, is_full)| {
526 if stream.is_pending_open() && is_full {
527 // Only prevent sending another request when the request queue
528 // is not full.
529 self.pending = Some(stream.clone_to_opaque());
530 }
531
532 let response = ResponseFuture {
533 inner: stream.clone_to_opaque(),
534 push_promise_consumed: false,
535 };
536
537 let stream = SendStream::new(stream);
538
539 (response, stream)
540 })
541 }
542
543 /// Returns whether the [extended CONNECT protocol][1] is enabled or not.
544 ///
545 /// This setting is configured by the server peer by sending the
546 /// [`SETTINGS_ENABLE_CONNECT_PROTOCOL` parameter][2] in a `SETTINGS` frame.
547 /// This method returns the currently acknowledged value received from the
548 /// remote.
549 ///
550 /// [1]: https://datatracker.ietf.org/doc/html/rfc8441#section-4
551 /// [2]: https://datatracker.ietf.org/doc/html/rfc8441#section-3
552 pub fn is_extended_connect_protocol_enabled(&self) -> bool {
553 self.inner.is_extended_connect_protocol_enabled()
554 }
555
556 /// Returns the current max send streams
557 pub fn current_max_send_streams(&self) -> usize {
558 self.inner.current_max_send_streams()
559 }
560
561 /// Returns the current max recv streams
562 pub fn current_max_recv_streams(&self) -> usize {
563 self.inner.current_max_recv_streams()
564 }
565}
566
567impl<B> fmt::Debug for SendRequest<B>
568where
569 B: Buf,
570{
571 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
572 fmt.debug_struct("SendRequest").finish()
573 }
574}
575
576impl<B> Clone for SendRequest<B>
577where
578 B: Buf,
579{
580 fn clone(&self) -> Self {
581 SendRequest {
582 inner: self.inner.clone(),
583 pending: None,
584 }
585 }
586}
587
588#[cfg(feature = "unstable")]
589impl<B> SendRequest<B>
590where
591 B: Buf,
592{
593 /// Returns the number of active streams.
594 ///
595 /// An active stream is a stream that has not yet transitioned to a closed
596 /// state.
597 pub fn num_active_streams(&self) -> usize {
598 self.inner.num_active_streams()
599 }
600
601 /// Returns the number of streams that are held in memory.
602 ///
603 /// A wired stream is a stream that is either active or is closed but must
604 /// stay in memory for some reason. For example, there are still outstanding
605 /// userspace handles pointing to the slot.
606 pub fn num_wired_streams(&self) -> usize {
607 self.inner.num_wired_streams()
608 }
609}
610
611// ===== impl ReadySendRequest =====
612
613impl<B> Future for ReadySendRequest<B>
614where
615 B: Buf,
616{
617 type Output = Result<SendRequest<B>, crate::Error>;
618
619 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
620 match &mut self.inner {
621 Some(send_request) => {
622 ready!(send_request.poll_ready(cx))?;
623 }
624 None => panic!("called `poll` after future completed"),
625 }
626
627 Poll::Ready(Ok(self.inner.take().unwrap()))
628 }
629}
630
631// ===== impl Builder =====
632
633impl Builder {
634 /// Returns a new client builder instance initialized with default
635 /// configuration values.
636 ///
637 /// Configuration methods can be chained on the return value.
638 ///
639 /// # Examples
640 ///
641 /// ```
642 /// # use tokio::io::{AsyncRead, AsyncWrite};
643 /// # use h2::client::*;
644 /// # use bytes::Bytes;
645 /// #
646 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
647 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
648 /// # {
649 /// // `client_fut` is a future representing the completion of the HTTP/2
650 /// // handshake.
651 /// let client_fut = Builder::new()
652 /// .initial_window_size(1_000_000)
653 /// .max_concurrent_streams(1000)
654 /// .handshake(my_io);
655 /// # client_fut.await
656 /// # }
657 /// #
658 /// # pub fn main() {}
659 /// ```
660 pub fn new() -> Builder {
661 Builder {
662 max_send_buffer_size: proto::DEFAULT_MAX_SEND_BUFFER_SIZE,
663 reset_stream_duration: Duration::from_secs(proto::DEFAULT_RESET_STREAM_SECS),
664 reset_stream_max: proto::DEFAULT_RESET_STREAM_MAX,
665 pending_accept_reset_stream_max: proto::DEFAULT_REMOTE_RESET_STREAM_MAX,
666 initial_target_connection_window_size: None,
667 initial_max_send_streams: usize::MAX,
668 settings: Default::default(),
669 stream_id: 1.into(),
670 local_max_error_reset_streams: Some(proto::DEFAULT_LOCAL_RESET_COUNT_MAX),
671 data_frame_budget: proto::DataFrameBudget::Auto,
672 }
673 }
674
675 /// Indicates the initial window size (in octets) for stream-level
676 /// flow control for received data.
677 ///
678 /// The initial window of a stream is used as part of flow control. For more
679 /// details, see [`FlowControl`].
680 ///
681 /// The default value is 65,535.
682 ///
683 /// [`FlowControl`]: ../struct.FlowControl.html
684 ///
685 /// # Examples
686 ///
687 /// ```
688 /// # use tokio::io::{AsyncRead, AsyncWrite};
689 /// # use h2::client::*;
690 /// # use bytes::Bytes;
691 /// #
692 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
693 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
694 /// # {
695 /// // `client_fut` is a future representing the completion of the HTTP/2
696 /// // handshake.
697 /// let client_fut = Builder::new()
698 /// .initial_window_size(1_000_000)
699 /// .handshake(my_io);
700 /// # client_fut.await
701 /// # }
702 /// #
703 /// # pub fn main() {}
704 /// ```
705 pub fn initial_window_size(&mut self, size: u32) -> &mut Self {
706 self.settings.set_initial_window_size(Some(size));
707 self
708 }
709
710 /// Indicates the initial window size (in octets) for connection-level flow control
711 /// for received data.
712 ///
713 /// The initial window of a connection is used as part of flow control. For more details,
714 /// see [`FlowControl`].
715 ///
716 /// The default value is 65,535.
717 ///
718 /// [`FlowControl`]: ../struct.FlowControl.html
719 ///
720 /// # Examples
721 ///
722 /// ```
723 /// # use tokio::io::{AsyncRead, AsyncWrite};
724 /// # use h2::client::*;
725 /// # use bytes::Bytes;
726 /// #
727 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
728 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
729 /// # {
730 /// // `client_fut` is a future representing the completion of the HTTP/2
731 /// // handshake.
732 /// let client_fut = Builder::new()
733 /// .initial_connection_window_size(1_000_000)
734 /// .handshake(my_io);
735 /// # client_fut.await
736 /// # }
737 /// #
738 /// # pub fn main() {}
739 /// ```
740 pub fn initial_connection_window_size(&mut self, size: u32) -> &mut Self {
741 self.initial_target_connection_window_size = Some(size);
742 self
743 }
744
745 /// Indicates the size (in octets) of the largest HTTP/2 frame payload that the
746 /// configured client is able to accept.
747 ///
748 /// The sender may send data frames that are **smaller** than this value,
749 /// but any data larger than `max` will be broken up into multiple `DATA`
750 /// frames.
751 ///
752 /// The value **must** be between 16,384 and 16,777,215. The default value is 16,384.
753 ///
754 /// # Examples
755 ///
756 /// ```
757 /// # use tokio::io::{AsyncRead, AsyncWrite};
758 /// # use h2::client::*;
759 /// # use bytes::Bytes;
760 /// #
761 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
762 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
763 /// # {
764 /// // `client_fut` is a future representing the completion of the HTTP/2
765 /// // handshake.
766 /// let client_fut = Builder::new()
767 /// .max_frame_size(1_000_000)
768 /// .handshake(my_io);
769 /// # client_fut.await
770 /// # }
771 /// #
772 /// # pub fn main() {}
773 /// ```
774 ///
775 /// # Panics
776 ///
777 /// This function panics if `max` is not within the legal range specified
778 /// above.
779 pub fn max_frame_size(&mut self, max: u32) -> &mut Self {
780 self.settings.set_max_frame_size(Some(max));
781 self
782 }
783
784 /// Sets the max size of received header frames.
785 ///
786 /// This advisory setting informs a peer of the maximum size of header list
787 /// that the sender is prepared to accept, in octets. The value is based on
788 /// the uncompressed size of header fields, including the length of the name
789 /// and value in octets plus an overhead of 32 octets for each header field.
790 ///
791 /// This setting is also used to limit the maximum amount of data that is
792 /// buffered to decode HEADERS frames.
793 ///
794 /// # Examples
795 ///
796 /// ```
797 /// # use tokio::io::{AsyncRead, AsyncWrite};
798 /// # use h2::client::*;
799 /// # use bytes::Bytes;
800 /// #
801 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
802 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
803 /// # {
804 /// // `client_fut` is a future representing the completion of the HTTP/2
805 /// // handshake.
806 /// let client_fut = Builder::new()
807 /// .max_header_list_size(16 * 1024)
808 /// .handshake(my_io);
809 /// # client_fut.await
810 /// # }
811 /// #
812 /// # pub fn main() {}
813 /// ```
814 pub fn max_header_list_size(&mut self, max: u32) -> &mut Self {
815 self.settings.set_max_header_list_size(Some(max));
816 self
817 }
818
819 /// Sets the maximum number of concurrent streams.
820 ///
821 /// The maximum concurrent streams setting only controls the maximum number
822 /// of streams that can be initiated by the remote peer. In other words,
823 /// when this setting is set to 100, this does not limit the number of
824 /// concurrent streams that can be created by the caller.
825 ///
826 /// It is recommended that this value be no smaller than 100, so as to not
827 /// unnecessarily limit parallelism. However, any value is legal, including
828 /// 0. If `max` is set to 0, then the remote will not be permitted to
829 /// initiate streams.
830 ///
831 /// Note that streams in the reserved state, i.e., push promises that have
832 /// been reserved but the stream has not started, do not count against this
833 /// setting.
834 ///
835 /// Also note that if the remote *does* exceed the value set here, it is not
836 /// a protocol level error. Instead, the `h2` library will immediately reset
837 /// the stream.
838 ///
839 /// See [Section 5.1.2] in the HTTP/2 spec for more details.
840 ///
841 /// [Section 5.1.2]: https://http2.github.io/http2-spec/#rfc.section.5.1.2
842 ///
843 /// # Examples
844 ///
845 /// ```
846 /// # use tokio::io::{AsyncRead, AsyncWrite};
847 /// # use h2::client::*;
848 /// # use bytes::Bytes;
849 /// #
850 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
851 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
852 /// # {
853 /// // `client_fut` is a future representing the completion of the HTTP/2
854 /// // handshake.
855 /// let client_fut = Builder::new()
856 /// .max_concurrent_streams(1000)
857 /// .handshake(my_io);
858 /// # client_fut.await
859 /// # }
860 /// #
861 /// # pub fn main() {}
862 /// ```
863 pub fn max_concurrent_streams(&mut self, max: u32) -> &mut Self {
864 self.settings.set_max_concurrent_streams(Some(max));
865 self
866 }
867
868 /// Sets the initial maximum of locally initiated (send) streams.
869 ///
870 /// The initial settings will be overwritten by the remote peer when
871 /// the SETTINGS frame is received. The new value will be set to the
872 /// `max_concurrent_streams()` from the frame. If no value is advertised in
873 /// the initial SETTINGS frame from the remote peer as part of
874 /// [HTTP/2 Connection Preface], `usize::MAX` will be set.
875 ///
876 /// This setting prevents the caller from exceeding this number of
877 /// streams that are counted towards the concurrency limit.
878 ///
879 /// Sending streams past the limit returned by the peer will be treated
880 /// as a stream error of type PROTOCOL_ERROR or REFUSED_STREAM.
881 ///
882 /// See [Section 5.1.2] in the HTTP/2 spec for more details.
883 ///
884 /// The default value is `usize::MAX`.
885 ///
886 /// [HTTP/2 Connection Preface]: https://httpwg.org/specs/rfc9113.html#preface
887 /// [Section 5.1.2]: https://httpwg.org/specs/rfc9113.html#rfc.section.5.1.2
888 ///
889 /// # Examples
890 ///
891 /// ```
892 /// # use tokio::io::{AsyncRead, AsyncWrite};
893 /// # use h2::client::*;
894 /// # use bytes::Bytes;
895 /// #
896 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
897 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
898 /// # {
899 /// // `client_fut` is a future representing the completion of the HTTP/2
900 /// // handshake.
901 /// let client_fut = Builder::new()
902 /// .initial_max_send_streams(1000)
903 /// .handshake(my_io);
904 /// # client_fut.await
905 /// # }
906 /// #
907 /// # pub fn main() {}
908 /// ```
909 pub fn initial_max_send_streams(&mut self, initial: usize) -> &mut Self {
910 self.initial_max_send_streams = initial;
911 self
912 }
913
914 /// Sets the maximum number of concurrent locally reset streams.
915 ///
916 /// When a stream is explicitly reset, the HTTP/2 specification requires
917 /// that any further frames received for that stream must be ignored for
918 /// "some time".
919 ///
920 /// In order to satisfy the specification, internal state must be maintained
921 /// to implement the behavior. This state grows linearly with the number of
922 /// streams that are locally reset.
923 ///
924 /// The `max_concurrent_reset_streams` setting configures sets an upper
925 /// bound on the amount of state that is maintained. When this max value is
926 /// reached, the oldest reset stream is purged from memory.
927 ///
928 /// Once the stream has been fully purged from memory, any additional frames
929 /// received for that stream will result in a connection level protocol
930 /// error, forcing the connection to terminate.
931 ///
932 /// The default value is currently 50.
933 ///
934 /// # Examples
935 ///
936 /// ```
937 /// # use tokio::io::{AsyncRead, AsyncWrite};
938 /// # use h2::client::*;
939 /// # use bytes::Bytes;
940 /// #
941 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
942 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
943 /// # {
944 /// // `client_fut` is a future representing the completion of the HTTP/2
945 /// // handshake.
946 /// let client_fut = Builder::new()
947 /// .max_concurrent_reset_streams(1000)
948 /// .handshake(my_io);
949 /// # client_fut.await
950 /// # }
951 /// #
952 /// # pub fn main() {}
953 /// ```
954 pub fn max_concurrent_reset_streams(&mut self, max: usize) -> &mut Self {
955 self.reset_stream_max = max;
956 self
957 }
958
959 /// Sets the duration to remember locally reset streams.
960 ///
961 /// When a stream is explicitly reset, the HTTP/2 specification requires
962 /// that any further frames received for that stream must be ignored for
963 /// "some time".
964 ///
965 /// In order to satisfy the specification, internal state must be maintained
966 /// to implement the behavior. This state grows linearly with the number of
967 /// streams that are locally reset.
968 ///
969 /// The `reset_stream_duration` setting configures the max amount of time
970 /// this state will be maintained in memory. Once the duration elapses, the
971 /// stream state is purged from memory.
972 ///
973 /// Once the stream has been fully purged from memory, any additional frames
974 /// received for that stream will result in a connection level protocol
975 /// error, forcing the connection to terminate.
976 ///
977 /// The default value is currently 1 second.
978 ///
979 /// # Examples
980 ///
981 /// ```
982 /// # use tokio::io::{AsyncRead, AsyncWrite};
983 /// # use h2::client::*;
984 /// # use std::time::Duration;
985 /// # use bytes::Bytes;
986 /// #
987 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
988 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
989 /// # {
990 /// // `client_fut` is a future representing the completion of the HTTP/2
991 /// // handshake.
992 /// let client_fut = Builder::new()
993 /// .reset_stream_duration(Duration::from_secs(10))
994 /// .handshake(my_io);
995 /// # client_fut.await
996 /// # }
997 /// #
998 /// # pub fn main() {}
999 /// ```
1000 pub fn reset_stream_duration(&mut self, dur: Duration) -> &mut Self {
1001 self.reset_stream_duration = dur;
1002 self
1003 }
1004
1005 /// Sets the maximum number of local resets due to protocol errors made by the remote end.
1006 ///
1007 /// Invalid frames and many other protocol errors will lead to resets being generated for those streams.
1008 /// Too many of these often indicate a malicious client, and there are attacks which can abuse this to DOS servers.
1009 /// This limit protects against these DOS attacks by limiting the amount of resets we can be forced to generate.
1010 ///
1011 /// When the number of local resets exceeds this threshold, the client will close the connection.
1012 ///
1013 /// If you really want to disable this, supply [`Option::None`] here.
1014 /// Disabling this is not recommended and may expose you to DOS attacks.
1015 ///
1016 /// The default value is currently 1024, but could change.
1017 pub fn max_local_error_reset_streams(&mut self, max: Option<usize>) -> &mut Self {
1018 self.local_max_error_reset_streams = max;
1019 self
1020 }
1021
1022 /// Sets the maximum number of pending-accept remotely-reset streams.
1023 ///
1024 /// Streams that have been received by the peer, but not accepted by the
1025 /// user, can also receive a RST_STREAM. This is a legitimate pattern: one
1026 /// could send a request and then shortly after, realize it is not needed,
1027 /// sending a CANCEL.
1028 ///
1029 /// However, since those streams are now "closed", they don't count towards
1030 /// the max concurrent streams. So, they will sit in the accept queue,
1031 /// using memory.
1032 ///
1033 /// When the number of remotely-reset streams sitting in the pending-accept
1034 /// queue reaches this maximum value, a connection error with the code of
1035 /// `ENHANCE_YOUR_CALM` will be sent to the peer, and returned by the
1036 /// `Future`.
1037 ///
1038 /// The default value is currently 20, but could change.
1039 ///
1040 /// # Examples
1041 ///
1042 /// ```
1043 /// # use tokio::io::{AsyncRead, AsyncWrite};
1044 /// # use h2::client::*;
1045 /// # use bytes::Bytes;
1046 /// #
1047 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1048 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
1049 /// # {
1050 /// // `client_fut` is a future representing the completion of the HTTP/2
1051 /// // handshake.
1052 /// let client_fut = Builder::new()
1053 /// .max_pending_accept_reset_streams(100)
1054 /// .handshake(my_io);
1055 /// # client_fut.await
1056 /// # }
1057 /// #
1058 /// # pub fn main() {}
1059 /// ```
1060 pub fn max_pending_accept_reset_streams(&mut self, max: usize) -> &mut Self {
1061 self.pending_accept_reset_stream_max = max;
1062 self
1063 }
1064
1065 /// Sets the maximum send buffer size per stream.
1066 ///
1067 /// Once a stream has buffered up to (or over) the maximum, the stream's
1068 /// flow control will not "poll" additional capacity. Once bytes for the
1069 /// stream have been written to the connection, the send buffer capacity
1070 /// will be freed up again.
1071 ///
1072 /// The default is currently ~400KB, but may change.
1073 ///
1074 /// # Panics
1075 ///
1076 /// This function panics if `max` is larger than `u32::MAX`.
1077 pub fn max_send_buffer_size(&mut self, max: usize) -> &mut Self {
1078 assert!(max <= u32::MAX as usize);
1079 self.max_send_buffer_size = max;
1080 self
1081 }
1082
1083 /// Enables or disables server push promises.
1084 ///
1085 /// This value is included in the initial SETTINGS handshake.
1086 /// Setting this value to value to
1087 /// false in the initial SETTINGS handshake guarantees that the remote server
1088 /// will never send a push promise.
1089 ///
1090 /// This setting can be changed during the life of a single HTTP/2
1091 /// connection by sending another settings frame updating the value.
1092 ///
1093 /// Default value: `true`.
1094 ///
1095 /// # Examples
1096 ///
1097 /// ```
1098 /// # use tokio::io::{AsyncRead, AsyncWrite};
1099 /// # use h2::client::*;
1100 /// # use std::time::Duration;
1101 /// # use bytes::Bytes;
1102 /// #
1103 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1104 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
1105 /// # {
1106 /// // `client_fut` is a future representing the completion of the HTTP/2
1107 /// // handshake.
1108 /// let client_fut = Builder::new()
1109 /// .enable_push(false)
1110 /// .handshake(my_io);
1111 /// # client_fut.await
1112 /// # }
1113 /// #
1114 /// # pub fn main() {}
1115 /// ```
1116 pub fn enable_push(&mut self, enabled: bool) -> &mut Self {
1117 self.settings.set_enable_push(enabled);
1118 self
1119 }
1120
1121 /// Sets the header table size.
1122 ///
1123 /// This setting informs the peer of the maximum size of the header compression
1124 /// table used to encode header blocks, in octets. The encoder may select any value
1125 /// equal to or less than the header table size specified by the sender.
1126 ///
1127 /// The default value is 4,096.
1128 ///
1129 /// # Examples
1130 ///
1131 /// ```
1132 /// # use tokio::io::{AsyncRead, AsyncWrite};
1133 /// # use h2::client::*;
1134 /// # use bytes::Bytes;
1135 /// #
1136 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1137 /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
1138 /// # {
1139 /// // `client_fut` is a future representing the completion of the HTTP/2
1140 /// // handshake.
1141 /// let client_fut = Builder::new()
1142 /// .header_table_size(1_000_000)
1143 /// .handshake(my_io);
1144 /// # client_fut.await
1145 /// # }
1146 /// #
1147 /// # pub fn main() {}
1148 /// ```
1149 pub fn header_table_size(&mut self, size: u32) -> &mut Self {
1150 self.settings.set_header_table_size(Some(size));
1151 self
1152 }
1153
1154 /// Sets a connection-level budget for limiting memory overhead from
1155 /// received small DATA frames.
1156 ///
1157 /// HTTP/2 flow control accounts for DATA payload bytes, but not the
1158 /// additional memory required to buffer each DATA frame. An excessive
1159 /// number of small frames may therefore consume disproportionate memory.
1160 ///
1161 /// Small DATA frames consume this budget. The budget is restored when
1162 /// buffered frames are consumed by the application, while sufficiently
1163 /// large frames may also restore budget. Empty DATA frames are limited
1164 /// separately and do not consume this budget.
1165 ///
1166 /// When this budget is exhausted, the connection is closed with
1167 /// `ENHANCE_YOUR_CALM`.
1168 ///
1169 /// By default, the budget is half the initial connection window, with a
1170 /// minimum of 25,600 bytes. Increasing the connection window therefore
1171 /// also increases the permitted framing overhead.
1172 pub fn data_frame_budget(&mut self, budget: usize) -> &mut Self {
1173 self.data_frame_budget = proto::DataFrameBudget::Configured(budget);
1174 self
1175 }
1176
1177 /// Sets the first stream ID to something other than 1.
1178 #[cfg(feature = "unstable")]
1179 pub fn initial_stream_id(&mut self, stream_id: u32) -> &mut Self {
1180 self.stream_id = stream_id.into();
1181 assert!(
1182 self.stream_id.is_client_initiated(),
1183 "stream id must be odd"
1184 );
1185 self
1186 }
1187
1188 /// Creates a new configured HTTP/2 client backed by `io`.
1189 ///
1190 /// It is expected that `io` already be in an appropriate state to commence
1191 /// the [HTTP/2 handshake]. The handshake is completed once both the connection
1192 /// preface and the initial settings frame is sent by the client.
1193 ///
1194 /// The handshake future does not wait for the initial settings frame from the
1195 /// server.
1196 ///
1197 /// Returns a future which resolves to the [`Connection`] / [`SendRequest`]
1198 /// tuple once the HTTP/2 handshake has been completed.
1199 ///
1200 /// This function also allows the caller to configure the send payload data
1201 /// type. See [Outbound data type] for more details.
1202 ///
1203 /// [HTTP/2 handshake]: http://httpwg.org/specs/rfc7540.html#ConnectionHeader
1204 /// [`Connection`]: struct.Connection.html
1205 /// [`SendRequest`]: struct.SendRequest.html
1206 /// [Outbound data type]: ../index.html#outbound-data-type.
1207 ///
1208 /// # Examples
1209 ///
1210 /// Basic usage:
1211 ///
1212 /// ```
1213 /// # use tokio::io::{AsyncRead, AsyncWrite};
1214 /// # use h2::client::*;
1215 /// # use bytes::Bytes;
1216 /// #
1217 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1218 /// -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
1219 /// # {
1220 /// // `client_fut` is a future representing the completion of the HTTP/2
1221 /// // handshake.
1222 /// let client_fut = Builder::new()
1223 /// .handshake(my_io);
1224 /// # client_fut.await
1225 /// # }
1226 /// #
1227 /// # pub fn main() {}
1228 /// ```
1229 ///
1230 /// Configures the send-payload data type. In this case, the outbound data
1231 /// type will be `&'static [u8]`.
1232 ///
1233 /// ```
1234 /// # use tokio::io::{AsyncRead, AsyncWrite};
1235 /// # use h2::client::*;
1236 /// #
1237 /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1238 /// # -> Result<((SendRequest<&'static [u8]>, Connection<T, &'static [u8]>)), h2::Error>
1239 /// # {
1240 /// // `client_fut` is a future representing the completion of the HTTP/2
1241 /// // handshake.
1242 /// let client_fut = Builder::new()
1243 /// .handshake::<_, &'static [u8]>(my_io);
1244 /// # client_fut.await
1245 /// # }
1246 /// #
1247 /// # pub fn main() {}
1248 /// ```
1249 pub fn handshake<T, B>(
1250 &self,
1251 io: T,
1252 ) -> impl Future<Output = Result<(SendRequest<B>, Connection<T, B>), crate::Error>>
1253 where
1254 T: AsyncRead + AsyncWrite + Unpin,
1255 B: Buf,
1256 {
1257 Connection::handshake2(io, self.clone())
1258 }
1259}
1260
1261impl Default for Builder {
1262 fn default() -> Builder {
1263 Builder::new()
1264 }
1265}
1266
1267/// Creates a new configured HTTP/2 client with default configuration
1268/// values backed by `io`.
1269///
1270/// It is expected that `io` already be in an appropriate state to commence
1271/// the [HTTP/2 handshake]. See [Handshake] for more details.
1272///
1273/// Returns a future which resolves to the [`Connection`] / [`SendRequest`]
1274/// tuple once the HTTP/2 handshake has been completed. The returned
1275/// [`Connection`] instance will be using default configuration values. Use
1276/// [`Builder`] to customize the configuration values used by a [`Connection`]
1277/// instance.
1278///
1279/// [HTTP/2 handshake]: http://httpwg.org/specs/rfc7540.html#ConnectionHeader
1280/// [Handshake]: ../index.html#handshake
1281/// [`Connection`]: struct.Connection.html
1282/// [`SendRequest`]: struct.SendRequest.html
1283///
1284/// # Examples
1285///
1286/// ```
1287/// # use tokio::io::{AsyncRead, AsyncWrite};
1288/// # use h2::client;
1289/// # use h2::client::*;
1290/// #
1291/// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T) -> Result<(), h2::Error>
1292/// # {
1293/// let (send_request, connection) = client::handshake(my_io).await?;
1294/// // The HTTP/2 handshake has completed, now start polling
1295/// // `connection` and use `send_request` to send requests to the
1296/// // server.
1297/// # Ok(())
1298/// # }
1299/// #
1300/// # pub fn main() {}
1301/// ```
1302pub async fn handshake<T>(io: T) -> Result<(SendRequest<Bytes>, Connection<T, Bytes>), crate::Error>
1303where
1304 T: AsyncRead + AsyncWrite + Unpin,
1305{
1306 let builder = Builder::new();
1307 builder
1308 .handshake(io)
1309 .instrument(tracing::trace_span!("client_handshake"))
1310 .await
1311}
1312
1313// ===== impl Connection =====
1314
1315async fn bind_connection<T>(io: &mut T) -> Result<(), crate::Error>
1316where
1317 T: AsyncRead + AsyncWrite + Unpin,
1318{
1319 tracing::debug!("binding client connection");
1320
1321 let msg: &'static [u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
1322 io.write_all(msg).await.map_err(crate::Error::from_io)?;
1323
1324 tracing::debug!("client connection bound");
1325
1326 Ok(())
1327}
1328
1329impl<T, B> Connection<T, B>
1330where
1331 T: AsyncRead + AsyncWrite + Unpin,
1332 B: Buf,
1333{
1334 async fn handshake2(
1335 mut io: T,
1336 builder: Builder,
1337 ) -> Result<(SendRequest<B>, Connection<T, B>), crate::Error> {
1338 bind_connection(&mut io).await?;
1339
1340 // Create the codec
1341 let mut codec = Codec::new(io);
1342
1343 if let Some(max) = builder.settings.max_frame_size() {
1344 codec.set_max_recv_frame_size(max as usize);
1345 }
1346
1347 if let Some(max) = builder.settings.max_header_list_size() {
1348 codec.set_max_recv_header_list_size(max as usize);
1349 }
1350
1351 // Send initial settings frame
1352 codec
1353 .buffer(builder.settings.clone().into())
1354 .expect("invalid SETTINGS frame");
1355
1356 let inner = proto::Connection::new(
1357 codec,
1358 proto::Config {
1359 next_stream_id: builder.stream_id,
1360 initial_max_send_streams: builder.initial_max_send_streams,
1361 max_send_buffer_size: builder.max_send_buffer_size,
1362 reset_stream_duration: builder.reset_stream_duration,
1363 reset_stream_max: builder.reset_stream_max,
1364 remote_reset_stream_max: builder.pending_accept_reset_stream_max,
1365 local_error_reset_streams_max: builder.local_max_error_reset_streams,
1366 settings: builder.settings,
1367 data_frame_budget: builder
1368 .data_frame_budget
1369 .resolve(builder.initial_target_connection_window_size),
1370 },
1371 );
1372 let send_request = SendRequest {
1373 inner: inner.streams().clone(),
1374 pending: None,
1375 };
1376
1377 let mut connection = Connection { inner };
1378 if let Some(sz) = builder.initial_target_connection_window_size {
1379 connection.set_target_window_size(sz);
1380 }
1381
1382 Ok((send_request, connection))
1383 }
1384
1385 /// Sets the target window size for the whole connection.
1386 ///
1387 /// If `size` is greater than the current value, then a `WINDOW_UPDATE`
1388 /// frame will be immediately sent to the remote, increasing the connection
1389 /// level window by `size - current_value`.
1390 ///
1391 /// If `size` is less than the current value, nothing will happen
1392 /// immediately. However, as window capacity is released by
1393 /// [`FlowControl`] instances, no `WINDOW_UPDATE` frames will be sent
1394 /// out until the number of "in flight" bytes drops below `size`.
1395 ///
1396 /// The default value is 65,535.
1397 ///
1398 /// See [`FlowControl`] documentation for more details.
1399 ///
1400 /// [`FlowControl`]: ../struct.FlowControl.html
1401 /// [library level]: ../index.html#flow-control
1402 pub fn set_target_window_size(&mut self, size: u32) {
1403 assert!(size <= proto::MAX_WINDOW_SIZE);
1404 self.inner.set_target_window_size(size);
1405 }
1406
1407 /// Set a new `INITIAL_WINDOW_SIZE` setting (in octets) for stream-level
1408 /// flow control for received data.
1409 ///
1410 /// The `SETTINGS` will be sent to the remote, and only applied once the
1411 /// remote acknowledges the change.
1412 ///
1413 /// This can be used to increase or decrease the window size for existing
1414 /// streams.
1415 ///
1416 /// # Errors
1417 ///
1418 /// Returns an error if a previous call is still pending acknowledgement
1419 /// from the remote endpoint.
1420 pub fn set_initial_window_size(&mut self, size: u32) -> Result<(), crate::Error> {
1421 assert!(size <= proto::MAX_WINDOW_SIZE);
1422 self.inner.set_initial_window_size(size)?;
1423 Ok(())
1424 }
1425
1426 /// Takes a `PingPong` instance from the connection.
1427 ///
1428 /// # Note
1429 ///
1430 /// This may only be called once. Calling multiple times will return `None`.
1431 pub fn ping_pong(&mut self) -> Option<PingPong> {
1432 self.inner.take_user_pings().map(PingPong::new)
1433 }
1434
1435 /// Returns the maximum number of concurrent streams that may be initiated
1436 /// by this client.
1437 ///
1438 /// This limit is configured by the server peer by sending the
1439 /// [`SETTINGS_MAX_CONCURRENT_STREAMS` parameter][1] in a `SETTINGS` frame.
1440 /// This method returns the currently acknowledged value received from the
1441 /// remote.
1442 ///
1443 /// [1]: https://tools.ietf.org/html/rfc7540#section-5.1.2
1444 pub fn max_concurrent_send_streams(&self) -> usize {
1445 self.inner.max_send_streams()
1446 }
1447 /// Returns the maximum number of concurrent streams that may be initiated
1448 /// by the server on this connection.
1449 ///
1450 /// This returns the value of the [`SETTINGS_MAX_CONCURRENT_STREAMS`
1451 /// parameter][1] sent in a `SETTINGS` frame that has been
1452 /// acknowledged by the remote peer. The value to be sent is configured by
1453 /// the [`Builder::max_concurrent_streams`][2] method before handshaking
1454 /// with the remote peer.
1455 ///
1456 /// [1]: https://tools.ietf.org/html/rfc7540#section-5.1.2
1457 /// [2]: ../struct.Builder.html#method.max_concurrent_streams
1458 pub fn max_concurrent_recv_streams(&self) -> usize {
1459 self.inner.max_recv_streams()
1460 }
1461}
1462
1463impl<T, B> Future for Connection<T, B>
1464where
1465 T: AsyncRead + AsyncWrite + Unpin,
1466 B: Buf,
1467{
1468 type Output = Result<(), crate::Error>;
1469
1470 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1471 self.inner.maybe_close_connection_if_no_streams();
1472 let had_streams_or_refs = self.inner.has_streams_or_other_references();
1473 let result = self.inner.poll(cx).map_err(Into::into);
1474 // if we had streams/refs, and don't anymore, wake up one more time to
1475 // ensure proper shutdown
1476 if result.is_pending()
1477 && had_streams_or_refs
1478 && !self.inner.has_streams_or_other_references()
1479 {
1480 tracing::trace!("last stream closed during poll, wake again");
1481 cx.waker().wake_by_ref();
1482 }
1483 result
1484 }
1485}
1486
1487impl<T, B> fmt::Debug for Connection<T, B>
1488where
1489 T: AsyncRead + AsyncWrite,
1490 T: fmt::Debug,
1491 B: fmt::Debug + Buf,
1492{
1493 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1494 fmt::Debug::fmt(&self.inner, fmt)
1495 }
1496}
1497
1498// ===== impl ResponseFuture =====
1499
1500impl Future for ResponseFuture {
1501 type Output = Result<Response<RecvStream>, crate::Error>;
1502
1503 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1504 let (parts, _) = ready!(self.inner.poll_response(cx))?.into_parts();
1505 let body = RecvStream::new(FlowControl::new(self.inner.clone()));
1506
1507 Poll::Ready(Ok(Response::from_parts(parts, body)))
1508 }
1509}
1510
1511impl ResponseFuture {
1512 /// Returns the stream ID of the response stream.
1513 ///
1514 /// # Panics
1515 ///
1516 /// If the lock on the stream store has been poisoned.
1517 pub fn stream_id(&self) -> crate::StreamId {
1518 crate::StreamId::from_internal(self.inner.stream_id())
1519 }
1520
1521 /// Polls for informational responses (1xx status codes).
1522 ///
1523 /// This method should be called before polling the main response future
1524 /// to check for any informational responses that have been received.
1525 ///
1526 /// Returns `Poll::Ready(Some(response))` if an informational response is available,
1527 /// `Poll::Ready(None)` if no more informational responses are expected,
1528 /// or `Poll::Pending` if no informational response is currently available.
1529 pub fn poll_informational(
1530 &mut self,
1531 cx: &mut Context<'_>,
1532 ) -> Poll<Option<Result<Response<()>, crate::Error>>> {
1533 self.inner.poll_informational(cx).map_err(Into::into)
1534 }
1535
1536 /// Returns a stream of PushPromises
1537 ///
1538 /// # Panics
1539 ///
1540 /// If this method has been called before
1541 /// or the stream was itself was pushed
1542 pub fn push_promises(&mut self) -> PushPromises {
1543 if self.push_promise_consumed {
1544 panic!("Reference to push promises stream taken!");
1545 }
1546 self.push_promise_consumed = true;
1547 PushPromises {
1548 inner: self.inner.clone(),
1549 }
1550 }
1551}
1552
1553// ===== impl PushPromises =====
1554
1555impl PushPromises {
1556 /// Get the next `PushPromise`.
1557 pub async fn push_promise(&mut self) -> Option<Result<PushPromise, crate::Error>> {
1558 crate::poll_fn(move |cx| self.poll_push_promise(cx)).await
1559 }
1560
1561 #[doc(hidden)]
1562 pub fn poll_push_promise(
1563 &mut self,
1564 cx: &mut Context<'_>,
1565 ) -> Poll<Option<Result<PushPromise, crate::Error>>> {
1566 match self.inner.poll_pushed(cx) {
1567 Poll::Ready(Some(Ok((request, response)))) => {
1568 let response = PushedResponseFuture {
1569 inner: ResponseFuture {
1570 inner: response,
1571 push_promise_consumed: false,
1572 },
1573 };
1574 Poll::Ready(Some(Ok(PushPromise { request, response })))
1575 }
1576 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e.into()))),
1577 Poll::Ready(None) => Poll::Ready(None),
1578 Poll::Pending => Poll::Pending,
1579 }
1580 }
1581}
1582
1583#[cfg(feature = "stream")]
1584impl futures_core::Stream for PushPromises {
1585 type Item = Result<PushPromise, crate::Error>;
1586
1587 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1588 self.poll_push_promise(cx)
1589 }
1590}
1591
1592// ===== impl PushPromise =====
1593
1594impl PushPromise {
1595 /// Returns a reference to the push promise's request headers.
1596 pub fn request(&self) -> &Request<()> {
1597 &self.request
1598 }
1599
1600 /// Returns a mutable reference to the push promise's request headers.
1601 pub fn request_mut(&mut self) -> &mut Request<()> {
1602 &mut self.request
1603 }
1604
1605 /// Consumes `self`, returning the push promise's request headers and
1606 /// response future.
1607 pub fn into_parts(self) -> (Request<()>, PushedResponseFuture) {
1608 (self.request, self.response)
1609 }
1610}
1611
1612// ===== impl PushedResponseFuture =====
1613
1614impl Future for PushedResponseFuture {
1615 type Output = Result<Response<RecvStream>, crate::Error>;
1616
1617 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1618 Pin::new(&mut self.inner).poll(cx)
1619 }
1620}
1621
1622impl PushedResponseFuture {
1623 /// Returns the stream ID of the response stream.
1624 ///
1625 /// # Panics
1626 ///
1627 /// If the lock on the stream store has been poisoned.
1628 pub fn stream_id(&self) -> crate::StreamId {
1629 self.inner.stream_id()
1630 }
1631}
1632
1633// ===== impl Peer =====
1634
1635impl Peer {
1636 pub fn convert_send_message(
1637 id: StreamId,
1638 request: Request<()>,
1639 protocol: Option<Protocol>,
1640 end_of_stream: bool,
1641 ) -> Result<Headers, SendError> {
1642 use http::request::Parts;
1643
1644 let (
1645 Parts {
1646 method,
1647 uri,
1648 headers,
1649 version,
1650 ..
1651 },
1652 _,
1653 ) = request.into_parts();
1654
1655 let is_connect = method == Method::CONNECT;
1656
1657 // Build the set pseudo header set. All requests will include `method`
1658 // and `path`.
1659 let mut pseudo = Pseudo::request(method, uri, protocol);
1660
1661 if pseudo.scheme.is_none() {
1662 // If the scheme is not set, then there are a two options.
1663 //
1664 // 1) Authority is not set. In this case, a request was issued with
1665 // a relative URI. This is permitted **only** when forwarding
1666 // HTTP 1.x requests. If the HTTP version is set to 2.0, then
1667 // this is an error.
1668 //
1669 // 2) Authority is set, then the HTTP method *must* be CONNECT.
1670 //
1671 // It is not possible to have a scheme but not an authority set (the
1672 // `http` crate does not allow it).
1673 //
1674 if pseudo.authority.is_none() {
1675 if version == Version::HTTP_2 {
1676 return Err(UserError::MissingUriSchemeAndAuthority.into());
1677 } else {
1678 // This is acceptable as per the above comment. However,
1679 // HTTP/2 requires that a scheme is set. Since we are
1680 // forwarding an HTTP 1.1 request, the scheme is set to
1681 // "http".
1682 pseudo.set_scheme(uri::Scheme::HTTP);
1683 }
1684 } else if !is_connect {
1685 // TODO: Error
1686 }
1687 }
1688
1689 // Create the HEADERS frame
1690 let mut frame = Headers::new(id, pseudo, headers);
1691
1692 if end_of_stream {
1693 frame.set_end_stream()
1694 }
1695
1696 Ok(frame)
1697 }
1698}
1699
1700impl proto::Peer for Peer {
1701 type Poll = Response<()>;
1702
1703 const NAME: &'static str = "Client";
1704
1705 fn r#dyn() -> proto::DynPeer {
1706 proto::DynPeer::Client
1707 }
1708
1709 /*
1710 fn is_server() -> bool {
1711 false
1712 }
1713 */
1714
1715 fn convert_poll_message(
1716 pseudo: Pseudo,
1717 fields: HeaderMap,
1718 stream_id: StreamId,
1719 ) -> Result<Self::Poll, Error> {
1720 let mut b = Response::builder();
1721
1722 b = b.version(Version::HTTP_2);
1723
1724 if let Some(status) = pseudo.status {
1725 b = b.status(status);
1726 }
1727
1728 let mut response = match b.body(()) {
1729 Ok(response) => response,
1730 Err(_) => {
1731 // TODO: Should there be more specialized handling for different
1732 // kinds of errors
1733 return Err(Error::library_reset(stream_id, Reason::PROTOCOL_ERROR));
1734 }
1735 };
1736
1737 *response.headers_mut() = fields;
1738
1739 Ok(response)
1740 }
1741}