This commit is contained in:
nora 2023-03-07 15:19:06 +01:00
parent 0b89e245d9
commit e1ebd97c91
73 changed files with 3822 additions and 3822 deletions

View file

@ -3,16 +3,16 @@ use bytes::Buf;
use super::HttpBody;
use crate::common::buf::BufList;
/// Aggregate the data buffers from a body asynchronously.
///
/// The returned `impl Buf` groups the `Buf`s from the `HttpBody` without
/// copying them. This is ideal if you don't require a contiguous buffer.
///
/// # Note
///
/// Care needs to be taken if the remote is untrusted. The function doesn't implement any length
/// checks and an malicious peer might make it consume arbitrary amounts of memory. Checking the
/// `Content-Length` is a possibility, but it is not strictly mandated to be present.
pub async fn aggregate<T>(body: T) -> Result<impl Buf, T::Error>
where
T: HttpBody,

View file

@ -18,18 +18,18 @@ use crate::common::{task, watch, Pin, Poll};
use crate::proto::h2::ping;
type BodySender = mpsc::Sender<Result<Bytes, crate::Error>>;
type TrailersSender = oneshot::Sender<HeaderMap>;
/// A stream of `Bytes`, used when receiving bodies.
///
/// A good default [`HttpBody`](crate::body::HttpBody) to use in many
/// applications.
///
/// Note: To read the full body, use [`body::to_bytes`](crate::body::to_bytes)
/// or [`body::aggregate`](crate::body::aggregate).
#[must_use = "streams do nothing unless polled"]
pub struct Body {
kind: Kind,
/// Keep the extra bits in an `Option<Box<Extra>>`, so that
/// Body stays small in the common case (no extras needed).
extra: Option<Box<Extra>>,
}
enum Kind {
@ -58,43 +58,43 @@ enum Kind {
),
}
struct Extra {
/// Allow the client to pass a future to delay the `Body` from returning
/// EOF. This allows the `Client` to try to put the idle connection
/// back into the pool before the body is "finished".
///
/// The reason for this is so that creating a new request after finishing
/// streaming the body of a response could sometimes result in creating
/// a brand new connection, since the pool didn't know about the idle
/// connection yet.
delayed_eof: Option<DelayEof>,
}
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
type DelayEofUntil = oneshot::Receiver<Never>;
enum DelayEof {
/// Initial state, stream hasn't seen EOF yet.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "client")]
NotEof(DelayEofUntil),
/// Transitions to this state once we've seen `poll` try to
/// return EOF (`None`). This future is then polled, and
/// when it completes, the Body finally returns EOF (`None`).
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "client")]
Eof(DelayEofUntil),
}
/// A sender half created through [`Body::channel()`].
///
/// Useful when wanting to stream chunks from another thread.
///
/// ## Body Closing
///
/// Note that the request body will always be closed normally when the sender is dropped (meaning
/// that the empty terminating chunk will be sent to the remote). If you desire to close the
/// connection with an incomplete response (e.g. in the case of an error during asynchronous
/// processing), call the [`Sender::abort()`] method to abort the body in an abnormal fashion.
///
/// [`Body::channel()`]: struct.Body.html#method.channel
/// [`Sender::abort()`]: struct.Sender.html#method.abort
#[must_use = "Sender does nothing unless sent on"]
pub struct Sender {
want_rx: watch::Receiver,
@ -102,41 +102,41 @@ pub struct Sender {
trailers_tx: Option<TrailersSender>,
}
impl Body {
/// Create an empty `Body` stream.
///
/// # Example
///
/// ```
/// use hyper::{Body, Request};
///
/// // create a `GET /` request
/// let get = Request::new(Body::empty());
/// ```
#[inline]
pub fn empty() -> Body {
loop {}
}
/// Wrap a futures `Stream` in a box inside `Body`.
///
/// # Example
///
/// ```
/// # use hyper::Body;
/// let chunks: Vec<Result<_, std::io::Error>> = vec![
/// Ok("hello"),
/// Ok(" "),
/// Ok("world"),
/// ];
///
/// let stream = futures_util::stream::iter(chunks);
///
/// let body = Body::wrap_stream(stream);
/// ```
///
/// # Optional
///
/// This function requires enabling the `stream` feature in your
/// `Cargo.toml`.
#[cfg(feature = "stream")]
#[cfg_attr(docsrs, doc(cfg(feature = "stream")))]
pub fn wrap_stream<S, O, E>(stream: S) -> Body
@ -153,7 +153,7 @@ impl Body {
}
}
impl Default for Body {
/// Returns `Body::empty()`.
#[inline]
fn default() -> Body {
loop {}
@ -188,10 +188,10 @@ impl fmt::Debug for Body {
loop {}
}
}
/// # Optional
///
/// This function requires enabling the `stream` feature in your
/// `Cargo.toml`.
#[cfg(feature = "stream")]
impl Stream for Body {
type Item = crate::Result<Bytes>;
@ -202,10 +202,10 @@ impl Stream for Body {
loop {}
}
}
/// # Optional
///
/// This function requires enabling the `stream` feature in your
/// `Cargo.toml`.
#[cfg(feature = "stream")]
impl From<Box<dyn Stream<Item = Result<Bytes, Box<dyn StdError + Send + Sync>>> + Send>>
for Body {

View file

@ -15,20 +15,20 @@ impl DecodedLength {
pub(crate) fn new(len: u64) -> Self {
loop {}
}
/// Takes the length as a content-length without other checks.
///
/// Should only be called if previously confirmed this isn't
/// CLOSE_DELIMITED or CHUNKED.
#[inline]
#[cfg(feature = "http1")]
pub(crate) fn danger_len(self) -> u64 {
loop {}
}
/// Converts to an Option<u64> representing a Known or Unknown length.
pub(crate) fn into_opt(self) -> Option<u64> {
loop {}
}
/// Checks the `u64` is within the maximum allowed for content-length.
#[cfg(any(feature = "http1", feature = "http2"))]
pub(crate) fn checked_new(len: u64) -> Result<Self, crate::error::Parse> {
loop {}
@ -36,11 +36,11 @@ impl DecodedLength {
pub(crate) fn sub_if(&mut self, amt: u64) {
loop {}
}
/// Returns whether this represents an exact length.
///
/// This includes 0, which of course is an exact known length.
///
/// It would return false if "chunked" or otherwise size-unknown.
#[cfg(feature = "http2")]
pub(crate) fn is_exact(&self) -> bool {
loop {}

View file

@ -1,47 +1,47 @@
use bytes::{Bytes};
use super::HttpBody;
/// Concatenate the buffers from a body into a single `Bytes` asynchronously.
///
/// This may require copying the data into a single buffer. If you don't need
/// a contiguous buffer, prefer the [`aggregate`](crate::body::aggregate())
/// function.
///
/// # Note
///
/// Care needs to be taken if the remote is untrusted. The function doesn't implement any length
/// checks and an malicious peer might make it consume arbitrary amounts of memory. Checking the
/// `Content-Length` is a possibility, but it is not strictly mandated to be present.
///
/// # Example
///
/// ```
/// # #[cfg(all(feature = "client", feature = "tcp", any(feature = "http1", feature = "http2")))]
/// # async fn doc() -> hyper::Result<()> {
/// use hyper::{body::HttpBody};
///
/// # let request = hyper::Request::builder()
/// # .method(hyper::Method::POST)
/// # .uri("http://httpbin.org/post")
/// # .header("content-type", "application/json")
/// # .body(hyper::Body::from(r#"{"library":"hyper"}"#)).unwrap();
/// # let client = hyper::Client::new();
/// let response = client.request(request).await?;
///
/// const MAX_ALLOWED_RESPONSE_SIZE: u64 = 1024;
///
/// let response_content_length = match response.body().size_hint().upper() {
/// Some(v) => v,
/// None => MAX_ALLOWED_RESPONSE_SIZE + 1 // Just to protect ourselves from a malicious response
/// };
///
/// if response_content_length < MAX_ALLOWED_RESPONSE_SIZE {
/// let body_bytes = hyper::body::to_bytes(response.into_body()).await?;
/// println!("body: {:?}", body_bytes);
/// }
///
/// # Ok(())
/// # }
/// ```
pub async fn to_bytes<T>(body: T) -> Result<Bytes, T::Error>
where
T: HttpBody,

View file

@ -21,10 +21,10 @@ use crate::common::{
Lazy, Pin, Poll,
};
use crate::rt::Executor;
/// A Client to make outgoing HTTP requests.
///
/// `Client` is cheap to clone and cloning is the recommended way to share a `Client`. The
/// underlying connection pool will be reused.
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
pub struct Client<C, B = Body> {
config: Config,
@ -38,9 +38,9 @@ struct Config {
set_host: bool,
ver: Ver,
}
/// A `Future` that will resolve to an HTTP Response.
///
/// This is returned by `Client::request` (and `Client::get`).
#[must_use = "futures do nothing unless polled"]
pub struct ResponseFuture {
inner: SyncWrapper<
@ -49,13 +49,13 @@ pub struct ResponseFuture {
}
#[cfg(feature = "tcp")]
impl Client<HttpConnector, Body> {
/// Create a new Client with the default [config](Builder).
///
/// # Note
///
/// The default connector does **not** handle TLS. Speaking to `https`
/// destinations will require [configuring a connector that implements
/// TLS](https://hyper.rs/guides/client/configuration).
#[cfg_attr(docsrs, doc(cfg(feature = "tcp")))]
#[inline]
pub(crate) fn new() -> Client<HttpConnector, Body> {
@ -69,25 +69,25 @@ impl Default for Client<HttpConnector, Body> {
}
}
impl Client<(), Body> {
/// Create a builder to configure a new `Client`.
///
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # fn run () {
/// use std::time::Duration;
/// use hyper::Client;
///
/// let client = Client::builder()
/// .pool_idle_timeout(Duration::from_secs(30))
/// .http2_only(true)
/// .build_http();
/// # let infer: Client<_, hyper::Body> = client;
/// # drop(infer);
/// # }
/// # fn main() {}
/// ```
#[inline]
pub(crate) fn builder() -> Builder {
loop {}
@ -100,54 +100,54 @@ where
B::Data: Send,
B::Error: Into<Box<dyn StdError + Send + Sync>>,
{
/// Send a `GET` request to the supplied `Uri`.
///
/// # Note
///
/// This requires that the `HttpBody` type have a `Default` implementation.
/// It *should* return an "empty" version of itself, such that
/// `HttpBody::is_end_stream` is `true`.
///
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # fn run () {
/// use hyper::{Client, Uri};
///
/// let client = Client::new();
///
/// let future = client.get(Uri::from_static("http://httpbin.org/ip"));
/// # }
/// # fn main() {}
/// ```
pub(crate) fn get(&self, uri: Uri) -> ResponseFuture
where
B: Default,
{
loop {}
}
/// Send a constructed `Request` using this `Client`.
///
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # fn run () {
/// use hyper::{Body, Method, Client, Request};
///
/// let client = Client::new();
///
/// let req = Request::builder()
/// .method(Method::POST)
/// .uri("http://httpbin.org/post")
/// .body(Body::from("Hallo!"))
/// .expect("request builder");
///
/// let future = client.request(req);
/// # }
/// # fn main() {}
/// ```
pub(crate) fn request(&self, mut req: Request<B>) -> ResponseFuture {
loop {}
}
@ -419,7 +419,7 @@ enum ClientConnectError {
Normal(crate::Error),
H2CheckoutIsClosed(crate::Error),
}
/// A marker to identify what version a pooled connection is.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(super) enum Ver {
Auto,
@ -449,25 +449,25 @@ fn get_non_default_port(uri: &Uri) -> Option<Port<&str>> {
fn is_schema_secure(uri: &Uri) -> bool {
loop {}
}
/// A builder to configure a new [`Client`](Client).
///
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # fn run () {
/// use std::time::Duration;
/// use hyper::Client;
///
/// let client = Client::builder()
/// .pool_idle_timeout(Duration::from_secs(30))
/// .http2_only(true)
/// .build_http();
/// # let infer: Client<_, hyper::Body> = client;
/// # drop(infer);
/// # }
/// # fn main() {}
/// ```
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
#[derive(Clone)]
pub struct Builder {
@ -496,11 +496,11 @@ impl Builder {
{
loop {}
}
/// Set an optional timeout for idle sockets being kept-alive.
///
/// Pass `None` to disable timeout.
///
/// Default is 90 seconds.
pub(crate) fn pool_idle_timeout<D>(&mut self, val: D) -> &mut Self
where
D: Into<Option<Duration>>,
@ -512,198 +512,198 @@ impl Builder {
pub(crate) fn max_idle_per_host(&mut self, max_idle: usize) -> &mut Self {
loop {}
}
/// Sets the maximum idle connection per host allowed in the pool.
///
/// Default is `usize::MAX` (no limit).
pub(crate) fn pool_max_idle_per_host(&mut self, max_idle: usize) -> &mut Self {
loop {}
}
/// Sets the exact size of the read buffer to *always* use.
///
/// Note that setting this option unsets the `http1_max_buf_size` option.
///
/// Default is an adaptive read buffer.
pub(crate) fn http1_read_buf_exact_size(&mut self, sz: usize) -> &mut Self {
loop {}
}
/// Set the maximum buffer size for the connection.
///
/// Default is ~400kb.
///
/// Note that setting this option unsets the `http1_read_exact_buf_size` option.
///
/// # Panics
///
/// The minimum value allowed is 8192. This method panics if the passed `max` is less than the minimum.
#[cfg(feature = "http1")]
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))]
pub(crate) fn http1_max_buf_size(&mut self, max: usize) -> &mut Self {
loop {}
}
/// Set whether HTTP/1 connections will accept spaces between header names
/// and the colon that follow them in responses.
///
/// Newline codepoints (`\r` and `\n`) will be transformed to spaces when
/// parsing.
///
/// You probably don't need this, here is what [RFC 7230 Section 3.2.4.] has
/// to say about it:
///
/// > No whitespace is allowed between the header field-name and colon. In
/// > the past, differences in the handling of such whitespace have led to
/// > security vulnerabilities in request routing and response handling. A
/// > server MUST reject any received request message that contains
/// > whitespace between a header field-name and colon with a response code
/// > of 400 (Bad Request). A proxy MUST remove any such whitespace from a
/// > response message before forwarding the message downstream.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
///
/// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4
pub(crate) fn http1_allow_spaces_after_header_name_in_responses(
&mut self,
val: bool,
) -> &mut Self {
loop {}
}
/// Set whether HTTP/1 connections will accept obsolete line folding for
/// header values.
///
/// You probably don't need this, here is what [RFC 7230 Section 3.2.4.] has
/// to say about it:
///
/// > A server that receives an obs-fold in a request message that is not
/// > within a message/http container MUST either reject the message by
/// > sending a 400 (Bad Request), preferably with a representation
/// > explaining that obsolete line folding is unacceptable, or replace
/// > each received obs-fold with one or more SP octets prior to
/// > interpreting the field value or forwarding the message downstream.
///
/// > A proxy or gateway that receives an obs-fold in a response message
/// > that is not within a message/http container MUST either discard the
/// > message and replace it with a 502 (Bad Gateway) response, preferably
/// > with a representation explaining that unacceptable line folding was
/// > received, or replace each received obs-fold with one or more SP
/// > octets prior to interpreting the field value or forwarding the
/// > message downstream.
///
/// > A user agent that receives an obs-fold in a response message that is
/// > not within a message/http container MUST replace each received
/// > obs-fold with one or more SP octets prior to interpreting the field
/// > value.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
///
/// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4
pub(crate) fn http1_allow_obsolete_multiline_headers_in_responses(
&mut self,
val: bool,
) -> &mut Self {
loop {}
}
/// Sets whether invalid header lines should be silently ignored in HTTP/1 responses.
///
/// This mimicks the behaviour of major browsers. You probably don't want this.
/// You should only want this if you are implementing a proxy whose main
/// purpose is to sit in front of browsers whose users access arbitrary content
/// which may be malformed, and they expect everything that works without
/// the proxy to keep working with the proxy.
///
/// This option will prevent Hyper's client from returning an error encountered
/// when parsing a header, except if the error was caused by the character NUL
/// (ASCII code 0), as Chrome specifically always reject those.
///
/// The ignorable errors are:
/// * empty header names;
/// * characters that are not allowed in header names, except for `\0` and `\r`;
/// * when `allow_spaces_after_header_name_in_responses` is not enabled,
/// spaces and tabs between the header name and the colon;
/// * missing colon between header name and colon;
/// * characters that are not allowed in header values except for `\0` and `\r`.
///
/// If an ignorable error is encountered, the parser tries to find the next
/// line in the input to resume parsing the rest of the headers. An error
/// will be emitted nonetheless if it finds `\0` or a lone `\r` while
/// looking for the next line.
pub(crate) fn http1_ignore_invalid_headers_in_responses(
&mut self,
val: bool,
) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections should try to use vectored writes,
/// or always flatten into a single buffer.
///
/// Note that setting this to false may mean more copies of body data,
/// but may also improve performance when an IO transport doesn't
/// support vectored writes well, such as most TLS implementations.
///
/// Setting this to true will force hyper to use queued strategy
/// which may eliminate unnecessary cloning on some TLS backends
///
/// Default is `auto`. In this mode hyper will try to guess which
/// mode to use
pub(crate) fn http1_writev(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections will write header names as title case at
/// the socket level.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
pub(crate) fn http1_title_case_headers(&mut self, val: bool) -> &mut Self {
loop {}
}
/// Set whether to support preserving original header cases.
///
/// Currently, this will record the original cases received, and store them
/// in a private extension on the `Response`. It will also look for and use
/// such an extension in any provided `Request`.
///
/// Since the relevant extension is still private, there is no way to
/// interact with the original cases. The only effect this can have now is
/// to forward the cases in a proxy-like fashion.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
pub(crate) fn http1_preserve_header_case(&mut self, val: bool) -> &mut Self {
loop {}
}
/// Set whether HTTP/0.9 responses should be tolerated.
///
/// Default is false.
pub(crate) fn http09_responses(&mut self, val: bool) -> &mut Self {
loop {}
}
/// Set whether the connection **must** use HTTP/2.
///
/// The destination must either allow HTTP2 Prior Knowledge, or the
/// `Connect` should be configured to do use ALPN to upgrade to `h2`
/// as part of the connection process. This will not make the `Client`
/// utilize ALPN by itself.
///
/// Note that setting this to true prevents HTTP/1 from being allowed.
///
/// Default is false.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_only(&mut self, val: bool) -> &mut Self {
loop {}
}
/// Sets the [`SETTINGS_INITIAL_WINDOW_SIZE`][spec] option for HTTP2
/// stream-level flow control.
///
/// Passing `None` will do nothing.
///
/// If not set, hyper will use a default.
///
/// [spec]: https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_initial_stream_window_size(
@ -712,11 +712,11 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets the max connection-level flow control for HTTP2
///
/// Passing `None` will do nothing.
///
/// If not set, hyper will use a default.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_initial_connection_window_size(
@ -725,21 +725,21 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets whether to use an adaptive flow control.
///
/// Enabling this will override the limits set in
/// `http2_initial_stream_window_size` and
/// `http2_initial_connection_window_size`.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_adaptive_window(&mut self, enabled: bool) -> &mut Self {
loop {}
}
/// Sets the maximum frame size to use for HTTP2.
///
/// Passing `None` will do nothing.
///
/// If not set, hyper will use a default.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_max_frame_size(
@ -748,16 +748,16 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets an interval for HTTP2 Ping frames should be sent to keep a
/// connection alive.
///
/// Pass `None` to disable HTTP2 keep-alive.
///
/// Default is currently disabled.
///
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
@ -767,48 +767,48 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets a timeout for receiving an acknowledgement of the keep-alive ping.
///
/// If the ping is not acknowledged within the timeout, the connection will
/// be closed. Does nothing if `http2_keep_alive_interval` is disabled.
///
/// Default is 20 seconds.
///
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_keep_alive_timeout(&mut self, timeout: Duration) -> &mut Self {
loop {}
}
/// Sets whether HTTP2 keep-alive should apply while the connection is idle.
///
/// If disabled, keep-alive pings are only sent while there are open
/// request/responses streams. If enabled, pings are also sent when no
/// streams are active. Does nothing if `http2_keep_alive_interval` is
/// disabled.
///
/// Default is `false`.
///
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_keep_alive_while_idle(&mut self, enabled: bool) -> &mut Self {
loop {}
}
/// Sets the maximum number of HTTP2 concurrent locally reset streams.
///
/// See the documentation of [`h2::client::Builder::max_concurrent_reset_streams`] for more
/// details.
///
/// The default value is determined by the `h2` crate.
///
/// [`h2::client::Builder::max_concurrent_reset_streams`]: https://docs.rs/h2/client/struct.Builder.html#method.max_concurrent_reset_streams
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_max_concurrent_reset_streams(
@ -817,51 +817,51 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Set the maximum write buffer size for each HTTP/2 stream.
///
/// Default is currently 1MB, but may change.
///
/// # Panics
///
/// The value must be no larger than `u32::MAX`.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_max_send_buf_size(&mut self, max: usize) -> &mut Self {
loop {}
}
/// Set whether to retry requests that get disrupted before ever starting
/// to write.
///
/// This means a request that is queued, and gets given an idle, reused
/// connection, and then encounters an error immediately as the idle
/// connection was found to be unusable.
///
/// When this is set to `false`, the related `ResponseFuture` would instead
/// resolve to an `Error::Cancel`.
///
/// Default is `true`.
#[inline]
pub(crate) fn retry_canceled_requests(&mut self, val: bool) -> &mut Self {
loop {}
}
/// Set whether to automatically add the `Host` header to requests.
///
/// If true, and a request does not include a `Host` header, one will be
/// added automatically, derived from the authority of the `Uri`.
///
/// Default is `true`.
#[inline]
pub(crate) fn set_host(&mut self, val: bool) -> &mut Self {
loop {}
}
/// Provide an executor to execute background `Connection` tasks.
pub(crate) fn executor<E>(&mut self, exec: E) -> &mut Self
where
E: Executor<BoxSendFuture> + Send + Sync + 'static,
{
loop {}
}
/// Builder a client with this configuration and the default `HttpConnector`.
#[cfg(feature = "tcp")]
pub(crate) fn build_http<B>(&self) -> Client<HttpConnector, B>
where
@ -870,7 +870,7 @@ impl Builder {
{
loop {}
}
/// Combine the configuration of this builder with a connector to create a `Client`.
pub(crate) fn build<C, B>(&self, connector: C) -> Client<C, B>
where
C: Connect + Clone,

View file

@ -96,10 +96,10 @@ pin_project! {
#[project = ProtoClientProj] enum ProtoClient < T, B > where B : HttpBody, { H1 {
#[pin] h1 : Http1Dispatcher < T, B >, }, H2 { #[pin] h2 : Http2ClientTask < B >, }, }
}
/// Returns a handshake future over some IO.
///
/// This is a shortcut for `Builder::new().handshake(io)`.
/// See [`client::conn`](crate::client::conn) for more.
pub(crate) async fn handshake<T>(
io: T,
) -> crate::Result<(SendRequest<crate::Body>, Connection<T, crate::Body>)>
@ -108,14 +108,14 @@ where
{
loop {}
}
/// The sender side of an established connection.
pub struct SendRequest<B> {
dispatch: dispatch::Sender<Request<B>, Response<Body>>,
}
/// A future that processes all HTTP state for the IO object.
///
/// In most cases, this should just be spawned into an executor, so that it
/// can process incoming and outgoing messages, notice hangups, and the like.
#[must_use = "futures do nothing unless polled"]
pub struct Connection<T, B>
where
@ -124,9 +124,9 @@ where
{
inner: Option<ProtoClient<T, B>>,
}
/// A builder to configure an HTTP connection.
///
/// After setting options, the builder is used to create a handshake future.
#[derive(Clone, Debug)]
pub struct Builder {
pub(super) exec: Exec,
@ -152,9 +152,9 @@ enum Proto {
#[cfg(feature = "http2")]
Http2,
}
/// A future returned by `SendRequest::send_request`.
///
/// Yields a `Response` if successful.
#[must_use = "futures do nothing unless polled"]
pub struct ResponseFuture {
inner: ResponseFutureState,
@ -163,22 +163,22 @@ enum ResponseFutureState {
Waiting(dispatch::Promise<Response<Body>>),
Error(Option<crate::Error>),
}
/// Deconstructed parts of a `Connection`.
///
/// This allows taking apart a `Connection` at a later time, in order to
/// reclaim the IO object, and additional related pieces.
#[derive(Debug)]
pub struct Parts<T> {
/// The original IO object used in the handshake.
pub(crate) io: T,
/// A buffer of bytes that have been read but not processed as HTTP.
///
/// For instance, if the `Connection` is used for an HTTP upgrade request,
/// it is possible the server sent back the first bytes of the new protocol
/// along with the response upgrade.
///
/// You will want to check for any existing bytes if you plan to continue
/// communicating on the IO object.
pub(crate) read_buf: Bytes,
_inner: (),
}
@ -188,9 +188,9 @@ pub(super) struct Http2SendRequest<B> {
dispatch: dispatch::UnboundedSender<Request<B>, Response<Body>>,
}
impl<B> SendRequest<B> {
/// Polls to determine whether this sender can be used yet for a request.
///
/// If the associated connection is closed, this returns an Error.
pub(crate) fn poll_ready(
&mut self,
cx: &mut task::Context<'_>,
@ -215,47 +215,47 @@ impl<B> SendRequest<B>
where
B: HttpBody + 'static,
{
/// Sends a `Request` on the associated connection.
///
/// Returns a future that if successful, yields the `Response`.
///
/// # Note
///
/// There are some key differences in what automatic things the `Client`
/// does for you that will not be done here:
///
/// - `Client` requires absolute-form `Uri`s, since the scheme and
/// authority are needed to connect. They aren't required here.
/// - Since the `Client` requires absolute-form `Uri`s, it can add
/// the `Host` header based on it. You must add a `Host` header yourself
/// before calling this method.
/// - Since absolute-form `Uri`s are not required, if received, they will
/// be serialized as-is.
///
/// # Example
///
/// ```
/// # use http::header::HOST;
/// # use hyper::client::conn::SendRequest;
/// # use hyper::Body;
/// use hyper::Request;
///
/// # async fn doc(mut tx: SendRequest<Body>) -> hyper::Result<()> {
/// // build a Request
/// let req = Request::builder()
/// .uri("/foo/bar")
/// .header(HOST, "hyper.rs")
/// .body(Body::empty())
/// .unwrap();
///
/// // send it and await a Response
/// let res = tx.send_request(req).await?;
/// // assert the Response
/// assert!(res.status().is_success());
/// # Ok(())
/// # }
/// # fn main() {}
/// ```
pub(crate) fn send_request(&mut self, req: Request<B>) -> ResponseFuture {
loop {}
}
@ -372,31 +372,31 @@ where
B::Data: Send,
B::Error: Into<Box<dyn StdError + Send + Sync>>,
{
/// Return the inner IO object, and additional information.
///
/// Only works for HTTP/1 connections. HTTP/2 connections will panic.
pub(crate) fn into_parts(self) -> Parts<T> {
loop {}
}
/// Poll the connection for completion, but without calling `shutdown`
/// on the underlying IO.
///
/// This is useful to allow running a connection while doing an HTTP
/// upgrade. Once the upgrade is completed, the connection would be "done",
/// but it is not desired to actually shutdown the IO object. Instead you
/// would take it back using `into_parts`.
///
/// Use [`poll_fn`](https://docs.rs/futures/0.1.25/futures/future/fn.poll_fn.html)
/// and [`try_ready!`](https://docs.rs/futures/0.1.25/futures/macro.try_ready.html)
/// to work with this function; or use the `without_shutdown` wrapper.
pub(crate) fn poll_without_shutdown(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<crate::Result<()>> {
loop {}
}
/// Prevent shutdown of the underlying IO object at the end of service the request,
/// instead run `into_parts`. This is a convenience wrapper over `poll_without_shutdown`.
pub(crate) fn without_shutdown(
self,
) -> impl Future<Output = crate::Result<Parts<T>>> {
@ -406,15 +406,15 @@ where
Poll::Ready(Ok(conn.take().unwrap().into_parts()))
})
}
/// Returns whether the [extended CONNECT protocol][1] is enabled or not.
///
/// This setting is configured by the server peer by sending the
/// [`SETTINGS_ENABLE_CONNECT_PROTOCOL` parameter][2] in a `SETTINGS` frame.
/// This method returns the currently acknowledged value received from the
/// remote.
///
/// [1]: https://datatracker.ietf.org/doc/html/rfc8441#section-4
/// [2]: https://datatracker.ietf.org/doc/html/rfc8441#section-3
#[cfg(feature = "http2")]
pub(crate) fn http2_is_extended_connect_protocol_enabled(&self) -> bool {
loop {}
@ -442,177 +442,177 @@ where
}
}
impl Builder {
/// Creates a new connection builder.
#[inline]
pub(crate) fn new() -> Builder {
loop {}
}
/// Provide an executor to execute background HTTP2 tasks.
pub(crate) fn executor<E>(&mut self, exec: E) -> &mut Builder
where
E: Executor<BoxSendFuture> + Send + Sync + 'static,
{
loop {}
}
/// Set whether HTTP/0.9 responses should be tolerated.
///
/// Default is false.
pub(crate) fn http09_responses(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections will accept spaces between header names
/// and the colon that follow them in responses.
///
/// You probably don't need this, here is what [RFC 7230 Section 3.2.4.] has
/// to say about it:
///
/// > No whitespace is allowed between the header field-name and colon. In
/// > the past, differences in the handling of such whitespace have led to
/// > security vulnerabilities in request routing and response handling. A
/// > server MUST reject any received request message that contains
/// > whitespace between a header field-name and colon with a response code
/// > of 400 (Bad Request). A proxy MUST remove any such whitespace from a
/// > response message before forwarding the message downstream.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
///
/// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4
pub(crate) fn http1_allow_spaces_after_header_name_in_responses(
&mut self,
enabled: bool,
) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections will accept obsolete line folding for
/// header values.
///
/// Newline codepoints (`\r` and `\n`) will be transformed to spaces when
/// parsing.
///
/// You probably don't need this, here is what [RFC 7230 Section 3.2.4.] has
/// to say about it:
///
/// > A server that receives an obs-fold in a request message that is not
/// > within a message/http container MUST either reject the message by
/// > sending a 400 (Bad Request), preferably with a representation
/// > explaining that obsolete line folding is unacceptable, or replace
/// > each received obs-fold with one or more SP octets prior to
/// > interpreting the field value or forwarding the message downstream.
///
/// > A proxy or gateway that receives an obs-fold in a response message
/// > that is not within a message/http container MUST either discard the
/// > message and replace it with a 502 (Bad Gateway) response, preferably
/// > with a representation explaining that unacceptable line folding was
/// > received, or replace each received obs-fold with one or more SP
/// > octets prior to interpreting the field value or forwarding the
/// > message downstream.
///
/// > A user agent that receives an obs-fold in a response message that is
/// > not within a message/http container MUST replace each received
/// > obs-fold with one or more SP octets prior to interpreting the field
/// > value.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
///
/// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4
pub(crate) fn http1_allow_obsolete_multiline_headers_in_responses(
&mut self,
enabled: bool,
) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections will silently ignored malformed header lines.
///
/// If this is enabled and and a header line does not start with a valid header
/// name, or does not include a colon at all, the line will be silently ignored
/// and no error will be reported.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
pub(crate) fn http1_ignore_invalid_headers_in_responses(
&mut self,
enabled: bool,
) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections should try to use vectored writes,
/// or always flatten into a single buffer.
///
/// Note that setting this to false may mean more copies of body data,
/// but may also improve performance when an IO transport doesn't
/// support vectored writes well, such as most TLS implementations.
///
/// Setting this to true will force hyper to use queued strategy
/// which may eliminate unnecessary cloning on some TLS backends
///
/// Default is `auto`. In this mode hyper will try to guess which
/// mode to use
pub(crate) fn http1_writev(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Set whether HTTP/1 connections will write header names as title case at
/// the socket level.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
pub(crate) fn http1_title_case_headers(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Set whether to support preserving original header cases.
///
/// Currently, this will record the original cases received, and store them
/// in a private extension on the `Response`. It will also look for and use
/// such an extension in any provided `Request`.
///
/// Since the relevant extension is still private, there is no way to
/// interact with the original cases. The only effect this can have now is
/// to forward the cases in a proxy-like fashion.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
pub(crate) fn http1_preserve_header_case(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Set whether to support preserving original header order.
///
/// Currently, this will record the order in which headers are received, and store this
/// ordering in a private extension on the `Response`. It will also look for and use
/// such an extension in any provided `Request`.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
#[cfg(feature = "ffi")]
pub(crate) fn http1_preserve_header_order(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Sets the exact size of the read buffer to *always* use.
///
/// Note that setting this option unsets the `http1_max_buf_size` option.
///
/// Default is an adaptive read buffer.
pub(crate) fn http1_read_buf_exact_size(
&mut self,
sz: Option<usize>,
) -> &mut Builder {
loop {}
}
/// Set the maximum buffer size for the connection.
///
/// Default is ~400kb.
///
/// Note that setting this option unsets the `http1_read_exact_buf_size` option.
///
/// # Panics
///
/// The minimum value allowed is 8192. This method panics if the passed `max` is less than the minimum.
#[cfg(feature = "http1")]
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))]
pub(crate) fn http1_max_buf_size(&mut self, max: usize) -> &mut Self {
@ -622,22 +622,22 @@ impl Builder {
pub(crate) fn http1_headers_raw(&mut self, enabled: bool) -> &mut Self {
loop {}
}
/// Sets whether HTTP2 is required.
///
/// Default is false.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_only(&mut self, enabled: bool) -> &mut Builder {
loop {}
}
/// Sets the [`SETTINGS_INITIAL_WINDOW_SIZE`][spec] option for HTTP2
/// stream-level flow control.
///
/// Passing `None` will do nothing.
///
/// If not set, hyper will use a default.
///
/// [spec]: https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_initial_stream_window_size(
@ -646,11 +646,11 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets the max connection-level flow control for HTTP2
///
/// Passing `None` will do nothing.
///
/// If not set, hyper will use a default.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_initial_connection_window_size(
@ -659,21 +659,21 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets whether to use an adaptive flow control.
///
/// Enabling this will override the limits set in
/// `http2_initial_stream_window_size` and
/// `http2_initial_connection_window_size`.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_adaptive_window(&mut self, enabled: bool) -> &mut Self {
loop {}
}
/// Sets the maximum frame size to use for HTTP2.
///
/// Passing `None` will do nothing.
///
/// If not set, hyper will use a default.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_max_frame_size(
@ -682,16 +682,16 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets an interval for HTTP2 Ping frames should be sent to keep a
/// connection alive.
///
/// Pass `None` to disable HTTP2 keep-alive.
///
/// Default is currently disabled.
///
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
@ -701,48 +701,48 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Sets a timeout for receiving an acknowledgement of the keep-alive ping.
///
/// If the ping is not acknowledged within the timeout, the connection will
/// be closed. Does nothing if `http2_keep_alive_interval` is disabled.
///
/// Default is 20 seconds.
///
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_keep_alive_timeout(&mut self, timeout: Duration) -> &mut Self {
loop {}
}
/// Sets whether HTTP2 keep-alive should apply while the connection is idle.
///
/// If disabled, keep-alive pings are only sent while there are open
/// request/responses streams. If enabled, pings are also sent when no
/// streams are active. Does nothing if `http2_keep_alive_interval` is
/// disabled.
///
/// Default is `false`.
///
/// # Cargo Feature
///
/// Requires the `runtime` cargo feature to be enabled.
#[cfg(feature = "runtime")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_keep_alive_while_idle(&mut self, enabled: bool) -> &mut Self {
loop {}
}
/// Sets the maximum number of HTTP2 concurrent locally reset streams.
///
/// See the documentation of [`h2::client::Builder::max_concurrent_reset_streams`] for more
/// details.
///
/// The default value is determined by the `h2` crate.
///
/// [`h2::client::Builder::max_concurrent_reset_streams`]: https://docs.rs/h2/client/struct.Builder.html#method.max_concurrent_reset_streams
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_max_concurrent_reset_streams(
@ -751,23 +751,23 @@ impl Builder {
) -> &mut Self {
loop {}
}
/// Set the maximum write buffer size for each HTTP/2 stream.
///
/// Default is currently 1MB, but may change.
///
/// # Panics
///
/// The value must be no larger than `u32::MAX`.
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub(crate) fn http2_max_send_buf_size(&mut self, max: usize) -> &mut Self {
loop {}
}
/// Constructs a connection with the configured options and IO.
/// See [`client::conn`](crate::client::conn) for more.
///
/// Note, if [`Connection`] is not `await`-ed, [`SendRequest`] will
/// do nothing.
pub(crate) fn handshake<T, B>(
&self,
io: T,

View file

@ -34,21 +34,21 @@ use tokio::task::JoinHandle;
use tower_service::Service;
pub(super) use self::sealed::Resolve;
/// A domain name to resolve into IP addresses.
#[derive(Clone, Hash, Eq, PartialEq)]
pub struct Name {
host: Box<str>,
}
/// A resolver using blocking `getaddrinfo` calls in a threadpool.
#[derive(Clone)]
pub struct GaiResolver {
_priv: (),
}
/// An iterator of IP addresses returned from `getaddrinfo`.
pub struct GaiAddrs {
inner: SocketAddrs,
}
/// A future to resolve a name returned by `GaiResolver`.
pub struct GaiFuture {
inner: JoinHandle<Result<SocketAddrs, io::Error>>,
}
@ -56,7 +56,7 @@ impl Name {
pub(super) fn new(host: Box<str>) -> Name {
loop {}
}
/// View the hostname as a string slice.
pub(crate) fn as_str(&self) -> &str {
loop {}
}
@ -77,7 +77,7 @@ impl FromStr for Name {
loop {}
}
}
/// Error indicating a given string was not a valid domain name.
#[derive(Debug)]
pub struct InvalidNameError(());
impl fmt::Display for InvalidNameError {
@ -87,7 +87,7 @@ impl fmt::Display for InvalidNameError {
}
impl Error for InvalidNameError {}
impl GaiResolver {
/// Construct a new `GaiResolver`.
pub(crate) fn new() -> Self {
loop {}
}

View file

@ -16,48 +16,48 @@ use tokio::time::Sleep;
use tracing::{warn};
use super::dns::{self, GaiResolver, Resolve};
use super::{Connected, Connection};
/// A connector for the `http` scheme.
///
/// Performs DNS resolution in a thread pool, and then connects over TCP.
///
/// # Note
///
/// Sets the [`HttpInfo`](HttpInfo) value on responses, which includes
/// transport information such as the remote socket address used.
#[cfg_attr(docsrs, doc(cfg(feature = "tcp")))]
#[derive(Clone)]
pub struct HttpConnector<R = GaiResolver> {
config: Arc<Config>,
resolver: R,
}
/// Extra information about the transport when an HttpConnector is used.
///
/// # Example
///
/// ```
/// # async fn doc() -> hyper::Result<()> {
/// use hyper::Uri;
/// use hyper::client::{Client, connect::HttpInfo};
///
/// let client = Client::new();
/// let uri = Uri::from_static("http://example.com");
///
/// let res = client.get(uri).await?;
/// res
/// .extensions()
/// .get::<HttpInfo>()
/// .map(|info| {
/// println!("remote addr = {}", info.remote_addr());
/// });
/// # Ok(())
/// # }
/// ```
///
/// # Note
///
/// If a different connector is used besides [`HttpConnector`](HttpConnector),
/// this value will not exist in the extensions. Consult that specific
/// connector to see what "extra" information it might provide to responses.
#[derive(Clone, Debug)]
pub struct HttpInfo {
remote_addr: SocketAddr,
@ -77,62 +77,62 @@ struct Config {
recv_buffer_size: Option<usize>,
}
impl HttpConnector {
/// Construct a new HttpConnector.
pub(crate) fn new() -> HttpConnector {
loop {}
}
}
impl<R> HttpConnector<R> {
/// Construct a new HttpConnector.
///
/// Takes a [`Resolver`](crate::client::connect::dns#resolvers-are-services) to handle DNS lookups.
pub(crate) fn new_with_resolver(resolver: R) -> HttpConnector<R> {
loop {}
}
/// Option to enforce all `Uri`s have the `http` scheme.
///
/// Enabled by default.
#[inline]
pub(crate) fn enforce_http(&mut self, is_enforced: bool) {
loop {}
}
/// Set that all sockets have `SO_KEEPALIVE` set with the supplied duration.
///
/// If `None`, the option will not be set.
///
/// Default is `None`.
#[inline]
pub(crate) fn set_keepalive(&mut self, dur: Option<Duration>) {
loop {}
}
/// Set that all sockets have `SO_NODELAY` set to the supplied value `nodelay`.
///
/// Default is `false`.
#[inline]
pub(crate) fn set_nodelay(&mut self, nodelay: bool) {
loop {}
}
/// Sets the value of the SO_SNDBUF option on the socket.
#[inline]
pub(crate) fn set_send_buffer_size(&mut self, size: Option<usize>) {
loop {}
}
/// Sets the value of the SO_RCVBUF option on the socket.
#[inline]
pub(crate) fn set_recv_buffer_size(&mut self, size: Option<usize>) {
loop {}
}
/// Set that all sockets are bound to the configured address before connection.
///
/// If `None`, the sockets will not be bound.
///
/// Default is `None`.
#[inline]
pub(crate) fn set_local_address(&mut self, addr: Option<IpAddr>) {
loop {}
}
/// Set that all sockets are bound to the configured IPv4 or IPv6 address (depending on host's
/// preferences) before connection.
#[inline]
pub(crate) fn set_local_addresses(
&mut self,
@ -141,35 +141,35 @@ impl<R> HttpConnector<R> {
) {
loop {}
}
/// Set the connect timeout.
///
/// If a domain resolves to multiple IP addresses, the timeout will be
/// evenly divided across them.
///
/// Default is `None`.
#[inline]
pub(crate) fn set_connect_timeout(&mut self, dur: Option<Duration>) {
loop {}
}
/// Set timeout for [RFC 6555 (Happy Eyeballs)][RFC 6555] algorithm.
///
/// If hostname resolves to both IPv4 and IPv6 addresses and connection
/// cannot be established using preferred address family before timeout
/// elapses, then connector will in parallel attempt connection using other
/// address family.
///
/// If `None`, parallel connection attempts are disabled.
///
/// Default is 300 milliseconds.
///
/// [RFC 6555]: https://tools.ietf.org/html/rfc6555
#[inline]
pub(crate) fn set_happy_eyeballs_timeout(&mut self, dur: Option<Duration>) {
loop {}
}
/// Set that all socket have `SO_REUSEADDR` set to the supplied value `reuse_address`.
///
/// Default is `false`.
#[inline]
pub(crate) fn set_reuse_address(&mut self, reuse_address: bool) -> &mut Self {
loop {}
@ -224,11 +224,11 @@ impl Connection for TcpStream {
}
}
impl HttpInfo {
/// Get the remote address of the transport used.
pub(crate) fn remote_addr(&self) -> SocketAddr {
loop {}
}
/// Get the local address of the transport used.
pub(crate) fn local_addr(&self) -> SocketAddr {
loop {}
}

View file

@ -88,15 +88,15 @@ cfg_feature! {
cfg_feature! {
#![any(feature = "http1", feature = "http2")] pub use self::sealed::Connect;
}
/// Describes a type returned by a connector.
pub trait Connection {
/// Return metadata describing the connection.
fn connected(&self) -> Connected;
}
/// Extra information about the connected transport.
///
/// This can be used to inform recipients about things like if ALPN
/// was used, or if connected to an HTTP proxy.
#[derive(Debug)]
pub struct Connected {
pub(super) alpn: Alpn,
@ -110,51 +110,51 @@ pub(super) enum Alpn {
None,
}
impl Connected {
/// Create new `Connected` type with empty metadata.
pub(crate) fn new() -> Connected {
loop {}
}
/// Set whether the connected transport is to an HTTP proxy.
///
/// This setting will affect if HTTP/1 requests written on the transport
/// will have the request-target in absolute-form or origin-form:
///
/// - When `proxy(false)`:
///
/// ```http
/// GET /guide HTTP/1.1
/// ```
///
/// - When `proxy(true)`:
///
/// ```http
/// GET http://hyper.rs/guide HTTP/1.1
/// ```
///
/// Default is `false`.
pub(crate) fn proxy(mut self, is_proxied: bool) -> Connected {
loop {}
}
/// Determines if the connected transport is to an HTTP proxy.
pub(crate) fn is_proxied(&self) -> bool {
loop {}
}
/// Set extra connection information to be set in the extensions of every `Response`.
pub(crate) fn extra<T: Clone + Send + Sync + 'static>(
mut self,
extra: T,
) -> Connected {
loop {}
}
/// Copies the extra connection information into an `Extensions` map.
pub(crate) fn get_extras(&self, extensions: &mut Extensions) {
loop {}
}
/// Set that the connected transport negotiated HTTP/2 as its next protocol.
pub(crate) fn negotiated_h2(mut self) -> Connected {
loop {}
}
/// Determines if the connected transport negotiated HTTP/2 as its next protocol.
pub(crate) fn is_negotiated_h2(&self) -> bool {
loop {}
}
@ -219,16 +219,16 @@ pub(super) mod sealed {
use tokio::io::{AsyncRead, AsyncWrite};
use super::Connection;
use crate::common::{Future, Unpin};
/// Connect to a destination, returning an IO transport.
///
/// A connector receives a [`Uri`](::http::Uri) and returns a `Future` of the
/// ready connection.
///
/// # Trait Alias
///
/// This is really just an *alias* for the `tower::Service` trait, with
/// additional bounds set for convenience *inside* hyper. You don't actually
/// implement this trait, but `tower::Service<Uri>` instead.
pub trait Connect: Sealed + Sized {
#[doc(hidden)]
type _Svc: ConnectSvc;

View file

@ -11,30 +11,30 @@ pub(crate) type Promise<T> = oneshot::Receiver<Result<T, crate::Error>>;
pub(crate) fn channel<T, U>() -> (Sender<T, U>, Receiver<T, U>) {
loop {}
}
/// A bounded sender of requests and callbacks for when responses are ready.
///
/// While the inner sender is unbounded, the Giver is used to determine
/// if the Receiver is ready for another request.
pub(crate) struct Sender<T, U> {
/// One message is always allowed, even if the Receiver hasn't asked
/// for it yet. This boolean keeps track of whether we've sent one
/// without notice.
buffered_once: bool,
/// The Giver helps watch that the the Receiver side has been polled
/// when the queue is empty. This helps us know when a request and
/// response have been fully processed, and a connection is ready
/// for more.
giver: want::Giver,
/// Actually bounded by the Giver, plus `buffered_once`.
inner: mpsc::UnboundedSender<Envelope<T, U>>,
}
/// An unbounded version.
///
/// Cannot poll the Giver, but can still use it to determine if the Receiver
/// has been dropped. However, this version can be cloned.
#[cfg(feature = "http2")]
pub(crate) struct UnboundedSender<T, U> {
/// Only used for `is_closed`, since mpsc::UnboundedSender cannot be checked.
giver: want::SharedGiver,
inner: mpsc::UnboundedSender<Envelope<T, U>>,
}
@ -158,7 +158,7 @@ mod tests {
loop {}
}
}
/// Helper to check if the future is ready after polling once.
struct PollOnce<'a, F>(&'a mut F);
impl<F, T> Future for PollOnce<'_, F>
where

View file

@ -17,29 +17,29 @@ pub(super) struct Pool<T> {
}
pub(super) trait Poolable: Unpin + Send + Sized + 'static {
fn is_open(&self) -> bool;
/// Reserve this connection.
///
/// Allows for HTTP/2 to return a shared reservation.
fn reserve(self) -> Reservation<Self>;
fn can_share(&self) -> bool;
}
/// When checking out a pooled connection, it might be that the connection
/// only supports a single reservation, or it might be usable for many.
///
/// Specifically, HTTP/1 requires a unique reservation, but HTTP/2 can be
/// used for multiple requests.
#[allow(missing_debug_implementations)]
pub(super) enum Reservation<T> {
/// This connection could be used multiple times, the first one will be
/// reinserted into the `idle` pool, and the second will be given to
/// the `Checkout`.
#[cfg(feature = "http2")]
Shared(T, T),
/// This connection requires unique access. It will be returned after
/// use is complete.
Unique(T),
}
/// Simple type alias in case the key type needs to be adjusted.
pub(super) type Key = (http::uri::Scheme, http::uri::Authority);
struct PoolInner<T> {
connecting: HashSet<Key>,
@ -76,13 +76,13 @@ impl<T> Pool<T> {
}
}
impl<T: Poolable> Pool<T> {
/// Returns a `Checkout` which is a future that resolves if an idle
/// connection becomes available.
pub(super) fn checkout(&self, key: Key) -> Checkout<T> {
loop {}
}
/// Ensure that there is only ever 1 connecting task for HTTP/2
/// connections. This does nothing for HTTP/1.
pub(super) fn connecting(&self, key: &Key, ver: Ver) -> Option<Connecting<T>> {
loop {}
}
@ -102,7 +102,7 @@ impl<T: Poolable> Pool<T> {
loop {}
}
}
/// Pop off this list, looking for a usable connection that hasn't expired.
struct IdlePopper<'a, T> {
key: &'a Key,
list: &'a mut Vec<Idle<T>>,
@ -116,8 +116,8 @@ impl<T: Poolable> PoolInner<T> {
fn put(&mut self, key: Key, value: T, __pool_ref: &Arc<Mutex<PoolInner<T>>>) {
loop {}
}
/// A `Connecting` task is complete. Not necessarily successfully,
/// but the lock is going away, so clean up.
fn connected(&mut self, key: &Key) {
loop {}
}
@ -127,17 +127,17 @@ impl<T: Poolable> PoolInner<T> {
}
}
impl<T> PoolInner<T> {
/// Any `FutureResponse`s that were created will have made a `Checkout`,
/// and possibly inserted into the pool that it is waiting for an idle
/// connection. If a user ever dropped that future, we need to clean out
/// those parked senders.
fn clean_waiters(&mut self, key: &Key) {
loop {}
}
}
#[cfg(feature = "runtime")]
impl<T: Poolable> PoolInner<T> {
/// This should *only* be called by the IdleTask
fn clear_expired(&mut self) {
loop {}
}
@ -147,7 +147,7 @@ impl<T> Clone for Pool<T> {
loop {}
}
}
/// A wrapped poolable value that tries to reinsert to the Pool on Drop.
pub(super) struct Pooled<T: Poolable> {
value: Option<T>,
is_reused: bool,
@ -283,7 +283,7 @@ mod tests {
use std::time::Duration;
use super::{Connecting, Key, Pool, Poolable, Reservation, WeakOpt};
use crate::common::{exec::Exec, task, Future, Pin};
/// Test unique reservations.
#[derive(Debug, PartialEq, Eq)]
struct Uniq<T>(T);
impl<T: Send + 'static + Unpin> Poolable for Uniq<T> {
@ -313,7 +313,7 @@ mod tests {
async fn test_pool_checkout_smoke() {
loop {}
}
/// Helper to check if the future is ready after polling once.
struct PollOnce<'a, F>(&'a mut F);
impl<F, T, U> Future for PollOnce<'_, F>
where

View file

@ -10,11 +10,11 @@ use crate::{
body::HttpBody, common::{task, Pin, Poll},
service::{MakeConnection, Service},
};
/// Creates a connection via `SendRequest`.
///
/// This accepts a `hyper::client::conn::Builder` and provides
/// a `MakeService` implementation to create connections from some
/// target `T`.
#[derive(Debug)]
pub(crate) struct Connect<C, B, T> {
inner: C,
@ -22,8 +22,8 @@ pub(crate) struct Connect<C, B, T> {
_pd: PhantomData<fn(T, B)>,
}
impl<C, B, T> Connect<C, B, T> {
/// Create a new `Connect` with some inner connector `C` and a connection
/// builder.
pub(crate) fn new(inner: C, builder: Builder) -> Self {
loop {}
}

View file

@ -3,7 +3,7 @@ use std::{io};
use bytes::{Bytes};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use crate::common::{task, Pin, Poll};
/// Combine a buffer with an IO, rewinding reads to use the buffer.
#[derive(Debug)]
pub(crate) struct Rewind<T> {
pre: Option<Bytes>,

View file

@ -1,97 +1,97 @@
/// A mutual exclusion primitive that relies on static type information only
///
/// In some cases synchronization can be proven statically: whenever you hold an exclusive `&mut`
/// reference, the Rust type system ensures that no other part of the program can hold another
/// reference to the data. Therefore it is safe to access it even if the current thread obtained
/// this reference via a channel. Whenever this is the case, the overhead of allocating and locking
/// a [`Mutex`] can be avoided by using this static version.
///
/// One example where this is often applicable is [`Future`], which requires an exclusive reference
/// for its [`poll`] method: While a given `Future` implementation may not be safe to access by
/// multiple threads concurrently, the executor can only run the `Future` on one thread at any
/// given time, making it [`Sync`] in practice as long as the implementation is `Send`. You can
/// therefore use the sync wrapper to prove that your data structure is `Sync` even though it
/// contains such a `Future`.
///
/// # Example
///
/// ```ignore
/// use hyper::common::sync_wrapper::SyncWrapper;
/// use std::future::Future;
///
/// struct MyThing {
/// future: SyncWrapper<Box<dyn Future<Output = String> + Send>>,
/// }
///
/// impl MyThing {
/// // all accesses to `self.future` now require an exclusive reference or ownership
/// }
///
/// fn assert_sync<T: Sync>() {}
///
/// assert_sync::<MyThing>();
/// ```
///
/// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
/// [`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html
/// [`poll`]: https://doc.rust-lang.org/std/future/trait.Future.html#method.poll
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
#[repr(transparent)]
pub(crate) struct SyncWrapper<T>(T);
impl<T> SyncWrapper<T> {
/// Creates a new SyncWrapper containing the given value.
///
/// # Examples
///
/// ```ignore
/// use hyper::common::sync_wrapper::SyncWrapper;
///
/// let wrapped = SyncWrapper::new(42);
/// ```
pub(crate) fn new(value: T) -> Self {
loop {}
}
/// Acquires a reference to the protected value.
///
/// This is safe because it requires an exclusive reference to the wrapper. Therefore this method
/// neither panics nor does it return an error. This is in contrast to [`Mutex::get_mut`] which
/// returns an error if another thread panicked while holding the lock. It is not recommended
/// to send an exclusive reference to a potentially damaged value to another thread for further
/// processing.
///
/// [`Mutex::get_mut`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html#method.get_mut
///
/// # Examples
///
/// ```ignore
/// use hyper::common::sync_wrapper::SyncWrapper;
///
/// let mut wrapped = SyncWrapper::new(42);
/// let value = wrapped.get_mut();
/// *value = 0;
/// assert_eq!(*wrapped.get_mut(), 0);
/// ```
pub(crate) fn get_mut(&mut self) -> &mut T {
loop {}
}
/// Consumes this wrapper, returning the underlying data.
///
/// This is safe because it requires ownership of the wrapper, aherefore this method will neither
/// panic nor does it return an error. This is in contrast to [`Mutex::into_inner`] which
/// returns an error if another thread panicked while holding the lock. It is not recommended
/// to send an exclusive reference to a potentially damaged value to another thread for further
/// processing.
///
/// [`Mutex::into_inner`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html#method.into_inner
///
/// # Examples
///
/// ```ignore
/// use hyper::common::sync_wrapper::SyncWrapper;
///
/// let mut wrapped = SyncWrapper::new(42);
/// assert_eq!(wrapped.into_inner(), 42);
/// ```
#[allow(dead_code)]
pub(crate) fn into_inner(self) -> T {
loop {}

View file

@ -1,9 +1,9 @@
#[cfg(feature = "http1")]
use super::Never;
pub(crate) use std::task::{Context, Poll};
/// A function to help "yield" a future, such that it is re-scheduled immediately.
///
/// Useful for spin counts, so a future doesn't hog too much time.
#[cfg(feature = "http1")]
pub(crate) fn yield_now(cx: &mut Context<'_>) -> Poll<Never> {
loop {}

View file

@ -1,10 +1,10 @@
//! Error and Result module.
use std::error::Error as StdError;
use std::fmt;
/// Result type often returned from methods that can have hyper `Error`s.
pub type Result<T> = std::result::Result<T, Error>;
type Cause = Box<dyn StdError + Send + Sync>;
/// Represents errors that can occur handling HTTP streams.
pub struct Error {
inner: Box<ErrorImpl>,
}
@ -16,42 +16,42 @@ struct ErrorImpl {
pub(super) enum Kind {
Parse(Parse),
User(User),
/// A message reached EOF, but is not complete.
#[allow(unused)]
IncompleteMessage,
/// A connection received a message (or bytes) when not waiting for one.
#[cfg(feature = "http1")]
UnexpectedMessage,
/// A pending item was dropped before ever being processed.
Canceled,
/// Indicates a channel (client or body sender) is closed.
ChannelClosed,
/// An `io::Error` that occurred while trying to read or write to a network stream.
#[cfg(any(feature = "http1", feature = "http2"))]
Io,
/// Error occurred while connecting.
#[allow(unused)]
Connect,
/// Error creating a TcpListener.
#[cfg(all(feature = "tcp", feature = "server"))]
Listen,
/// Error accepting on an Incoming stream.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "server")]
Accept,
/// User took too long to send headers
#[cfg(all(feature = "http1", feature = "server", feature = "runtime"))]
HeaderTimeout,
/// Error while reading a body from connection.
#[cfg(any(feature = "http1", feature = "http2", feature = "stream"))]
Body,
/// Error while writing a body to connection.
#[cfg(any(feature = "http1", feature = "http2"))]
BodyWrite,
/// Error calling AsyncWrite::shutdown()
#[cfg(feature = "http1")]
Shutdown,
/// A general error from h2.
#[cfg(feature = "http2")]
Http2,
}
@ -82,100 +82,100 @@ pub(super) enum Header {
}
#[derive(Debug)]
pub(super) enum User {
/// Error calling user's HttpBody::poll_data().
#[cfg(any(feature = "http1", feature = "http2"))]
Body,
/// The user aborted writing of the outgoing body.
BodyWriteAborted,
/// Error calling user's MakeService.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "server")]
MakeService,
/// Error from future of user's Service.
#[cfg(any(feature = "http1", feature = "http2"))]
Service,
/// User tried to send a certain header in an unexpected context.
///
/// For example, sending both `content-length` and `transfer-encoding`.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "server")]
UnexpectedHeader,
/// User tried to create a Request with bad version.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "client")]
UnsupportedVersion,
/// User tried to create a CONNECT Request with the Client.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "client")]
UnsupportedRequestMethod,
/// User tried to respond with a 1xx (not 101) response code.
#[cfg(feature = "http1")]
#[cfg(feature = "server")]
UnsupportedStatusCode,
/// User tried to send a Request with Client with non-absolute URI.
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "client")]
AbsoluteUriRequired,
/// User tried polling for an upgrade that doesn't exist.
NoUpgrade,
/// User polled for an upgrade, but low-level API is not using upgrades.
#[cfg(feature = "http1")]
ManualUpgrade,
/// User called `server::Connection::without_shutdown()` on an HTTP/2 conn.
#[cfg(feature = "server")]
WithoutShutdownNonHttp1,
/// The dispatch task is gone.
#[cfg(feature = "client")]
DispatchGone,
/// User aborted in an FFI callback.
#[cfg(feature = "ffi")]
AbortedByCallback,
}
#[derive(Debug)]
pub(super) struct TimedOut;
impl Error {
/// Returns true if this was an HTTP parse error.
pub(crate) fn is_parse(&self) -> bool {
loop {}
}
/// Returns true if this was an HTTP parse error caused by a message that was too large.
pub(crate) fn is_parse_too_large(&self) -> bool {
loop {}
}
/// Returns true if this was an HTTP parse error caused by an invalid response status code or
/// reason phrase.
pub(crate) fn is_parse_status(&self) -> bool {
loop {}
}
/// Returns true if this error was caused by user code.
pub(crate) fn is_user(&self) -> bool {
loop {}
}
/// Returns true if this was about a `Request` that was canceled.
pub(crate) fn is_canceled(&self) -> bool {
loop {}
}
/// Returns true if a sender's channel is closed.
pub(crate) fn is_closed(&self) -> bool {
loop {}
}
/// Returns true if this was an error from `Connect`.
pub(crate) fn is_connect(&self) -> bool {
loop {}
}
/// Returns true if the connection closed before a message could complete.
pub(crate) fn is_incomplete_message(&self) -> bool {
loop {}
}
/// Returns true if the body write was aborted.
pub(crate) fn is_body_write_aborted(&self) -> bool {
loop {}
}
/// Returns true if the error was caused by a timeout.
pub(crate) fn is_timeout(&self) -> bool {
loop {}
}
/// Consumes the error, returning its cause.
pub(crate) fn into_cause(self) -> Option<Box<dyn StdError + Send + Sync>> {
loop {}
}
@ -319,7 +319,7 @@ impl Error {
pub(super) fn new_h2(cause: ::h2::Error) -> Error {
loop {}
}
/// The error's standalone message, without the message from the source.
pub(crate) fn message(&self) -> impl fmt::Display + '_ {
self.description()
}

View file

@ -13,21 +13,21 @@ use std::fmt;
mod h1_reason_phrase;
#[cfg(feature = "http2")]
/// Represents the `:protocol` pseudo-header used by
/// the [Extended CONNECT Protocol].
///
/// [Extended CONNECT Protocol]: https://datatracker.ietf.org/doc/html/rfc8441#section-4
#[derive(Clone, Eq, PartialEq)]
pub(crate) struct Protocol {
inner: h2::ext::Protocol,
}
#[cfg(feature = "http2")]
impl Protocol {
/// Converts a static string to a protocol name.
pub(crate) const fn from_static(value: &'static str) -> Self {
loop {}
}
/// Returns a str representation of the header.
pub(crate) fn as_str(&self) -> &str {
loop {}
}
@ -57,41 +57,41 @@ impl fmt::Debug for Protocol {
loop {}
}
}
/// A map from header names to their original casing as received in an HTTP message.
///
/// If an HTTP/1 response `res` is parsed on a connection whose option
/// [`http1_preserve_header_case`] was set to true and the response included
/// the following headers:
///
/// ```ignore
/// x-Bread: Baguette
/// X-BREAD: Pain
/// x-bread: Ficelle
/// ```
///
/// Then `res.extensions().get::<HeaderCaseMap>()` will return a map with:
///
/// ```ignore
/// HeaderCaseMap({
/// "x-bread": ["x-Bread", "X-BREAD", "x-bread"],
/// })
/// ```
///
/// [`http1_preserve_header_case`]: /client/struct.Client.html#method.http1_preserve_header_case
#[derive(Clone, Debug)]
pub(crate) struct HeaderCaseMap(HeaderMap<Bytes>);
#[cfg(feature = "http1")]
impl HeaderCaseMap {
/// Returns a view of all spellings associated with that header name,
/// in the order they were found.
pub(crate) fn get_all<'a>(
&'a self,
name: &HeaderName,
) -> impl Iterator<Item = impl AsRef<[u8]> + 'a> + 'a {
self.get_all_internal(name).into_iter()
}
/// Returns a view of all spellings associated with that header name,
/// in the order they were found.
pub(crate) fn get_all_internal<'a>(
&'a self,
name: &HeaderName,
@ -114,16 +114,16 @@ impl HeaderCaseMap {
}
#[cfg(feature = "ffi")]
#[derive(Clone, Debug)]
/// Hashmap<Headername, numheaders with that name>
pub(crate) struct OriginalHeaderOrder {
/// Stores how many entries a Headername maps to. This is used
/// for accounting.
num_entries: HashMap<HeaderName, usize>,
/// Stores the ordering of the headers. ex: `vec[i] = (headerName, idx)`,
/// The vector is ordered such that the ith element
/// represents the ith header that came in off the line.
/// The `HeaderName` and `idx` are then used elsewhere to index into
/// the multi map that stores the header values.
entry_order: Vec<(HeaderName, usize)>,
}
#[cfg(all(feature = "http1", feature = "ffi"))]
@ -140,43 +140,43 @@ impl OriginalHeaderOrder {
{
loop {}
}
/// This returns an iterator that provides header names and indexes
/// in the original order received.
///
/// # Examples
/// ```no_run
/// use hyper::ext::OriginalHeaderOrder;
/// use hyper::header::{HeaderName, HeaderValue, HeaderMap};
///
/// let mut h_order = OriginalHeaderOrder::default();
/// let mut h_map = Headermap::new();
///
/// let name1 = b"Set-CookiE";
/// let value1 = b"a=b";
/// h_map.append(name1);
/// h_order.append(name1);
///
/// let name2 = b"Content-Encoding";
/// let value2 = b"gzip";
/// h_map.append(name2, value2);
/// h_order.append(name2);
///
/// let name3 = b"SET-COOKIE";
/// let value3 = b"c=d";
/// h_map.append(name3, value3);
/// h_order.append(name3)
///
/// let mut iter = h_order.get_in_order()
///
/// let (name, idx) = iter.next();
/// assert_eq!(b"a=b", h_map.get_all(name).nth(idx).unwrap());
///
/// let (name, idx) = iter.next();
/// assert_eq!(b"gzip", h_map.get_all(name).nth(idx).unwrap());
///
/// let (name, idx) = iter.next();
/// assert_eq!(b"c=d", h_map.get_all(name).nth(idx).unwrap());
/// ```
pub(crate) fn get_in_order(&self) -> impl Iterator<Item = &(HeaderName, usize)> {
loop {}
}

View file

@ -7,9 +7,9 @@ use libc::{c_int, size_t};
use super::task::{hyper_context, hyper_task, hyper_task_return_type, AsTaskType};
use super::{UserDataPointer, HYPER_ITER_CONTINUE};
use crate::body::{Body, Bytes, HttpBody as _};
/// A streaming HTTP body.
pub(crate) struct hyper_body(pub(super) Body);
/// A buffer of bytes that is sent or received on a `hyper_body`.
pub(crate) struct hyper_buf(pub(crate) Bytes);
pub(crate) struct UserBody {
data_func: hyper_body_data_callback,
@ -101,7 +101,7 @@ impl UserBody {
loop {}
}
}
/// cbindgen:ignore
extern "C" fn data_noop(
_userdata: *mut c_void,
_: *mut hyper_context<'_>,

View file

@ -9,17 +9,17 @@ use super::io::hyper_io;
use super::task::{
hyper_executor, hyper_task, hyper_task_return_type, AsTaskType, WeakExec,
};
/// An options builder to configure an HTTP client connection.
pub(crate) struct hyper_clientconn_options {
builder: conn::Builder,
/// Use a `Weak` to prevent cycles.
exec: WeakExec,
}
/// An HTTP client connection handle.
///
/// These are used to send a request on a single connection. It's possible to
/// send multiple requests on a single connection, such as when HTTP/1
/// keep-alive or HTTP/2 is used.
pub(crate) struct hyper_clientconn {
tx: conn::SendRequest<crate::Body>,
}

View file

@ -1,26 +1,26 @@
use libc::size_t;
/// A more detailed error object returned by some hyper functions.
pub(crate) struct hyper_error(crate::Error);
/// A return code for many of hyper's methods.
#[repr(C)]
pub(crate) enum hyper_code {
/// All is well.
HYPERE_OK,
/// General error, details in the `hyper_error *`.
HYPERE_ERROR,
/// A function argument was invalid.
HYPERE_INVALID_ARG,
/// The IO transport returned an EOF when one wasn't expected.
///
/// This typically means an HTTP request or response was expected, but the
/// connection closed cleanly without sending (all of) it.
HYPERE_UNEXPECTED_EOF,
/// Aborted by a user supplied callback.
HYPERE_ABORTED_BY_CALLBACK,
/// An optional hyper feature was not enabled.
#[cfg_attr(feature = "http2", allow(unused))]
HYPERE_FEATURE_NOT_ENABLED,
/// The peer sent an HTTP message that could not be parsed.
HYPERE_INVALID_PEER_MESSAGE,
}
impl hyper_error {

View file

@ -8,13 +8,13 @@ use super::{UserDataPointer, HYPER_ITER_CONTINUE};
use crate::ext::{HeaderCaseMap, OriginalHeaderOrder, ReasonPhrase};
use crate::header::{HeaderName, HeaderValue};
use crate::{Body, HeaderMap, Method, Request, Response, Uri};
/// An HTTP request.
pub(crate) struct hyper_request(pub(super) Request<Body>);
/// An HTTP response.
pub(crate) struct hyper_response(pub(super) Response<Body>);
/// An HTTP header map.
///
/// These can be part of a request or response.
pub(crate) struct hyper_headers {
pub(super) headers: HeaderMap,
orig_casing: HeaderCaseMap,

View file

@ -4,11 +4,11 @@ use std::task::{Context, Poll};
use libc::size_t;
use tokio::io::{AsyncRead, AsyncWrite};
use super::task::hyper_context;
/// Sentinel value to return from a read or write callback that the operation
/// is pending.
pub(crate) const HYPER_IO_PENDING: size_t = 0xFFFFFFFF;
/// Sentinel value to return from a read or write callback that the operation
/// has errored.
pub(crate) const HYPER_IO_ERROR: size_t = 0xFFFFFFFE;
type hyper_io_read_callback = extern "C" fn(
*mut c_void,
@ -22,7 +22,7 @@ type hyper_io_write_callback = extern "C" fn(
*const u8,
size_t,
) -> size_t;
/// An IO object used to represent a socket or similar concept.
pub(crate) struct hyper_io {
read: hyper_io_read_callback,
write: hyper_io_write_callback,
@ -77,7 +77,7 @@ ffi_fn! {
" should be the return value."] fn hyper_io_set_write(io : * mut hyper_io, func :
hyper_io_write_callback) { non_null!(& mut * io ?= ()) .write = func; }
}
/// cbindgen:ignore
extern "C" fn read_noop(
_userdata: *mut c_void,
_: *mut hyper_context<'_>,
@ -86,7 +86,7 @@ extern "C" fn read_noop(
) -> size_t {
loop {}
}
/// cbindgen:ignore
extern "C" fn write_noop(
_userdata: *mut c_void,
_: *mut hyper_context<'_>,

View file

@ -48,23 +48,23 @@ pub(crate) use self::error::*;
pub(crate) use self::http_types::*;
pub(crate) use self::io::*;
pub(crate) use self::task::*;
/// Return in iter functions to continue iterating.
pub(crate) const HYPER_ITER_CONTINUE: libc::c_int = 0;
/// Return in iter functions to stop iterating.
#[allow(unused)]
pub(crate) const HYPER_ITER_BREAK: libc::c_int = 1;
/// An HTTP Version that is unspecified.
pub(crate) const HYPER_HTTP_VERSION_NONE: libc::c_int = 0;
/// The HTTP/1.0 version.
pub(crate) const HYPER_HTTP_VERSION_1_0: libc::c_int = 10;
/// The HTTP/1.1 version.
pub(crate) const HYPER_HTTP_VERSION_1_1: libc::c_int = 11;
/// The HTTP/2 version.
pub(crate) const HYPER_HTTP_VERSION_2: libc::c_int = 20;
struct UserDataPointer(*mut std::ffi::c_void);
unsafe impl Send for UserDataPointer {}
unsafe impl Sync for UserDataPointer {}
/// cbindgen:ignore
static VERSION_CSTR: &str = concat!(env!("CARGO_PKG_VERSION"), "\0");
ffi_fn! {
#[doc = " Returns a static ASCII (null terminated) string of the hyper version."] fn

View file

@ -13,38 +13,38 @@ use super::error::hyper_code;
use super::UserDataPointer;
type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
type BoxAny = Box<dyn AsTaskType + Send + Sync>;
/// Return in a poll function to indicate it was ready.
pub(crate) const HYPER_POLL_READY: c_int = 0;
/// Return in a poll function to indicate it is still pending.
///
/// The passed in `hyper_waker` should be registered to wake up the task at
/// some later point.
pub(crate) const HYPER_POLL_PENDING: c_int = 1;
/// Return in a poll function indicate an error.
pub(crate) const HYPER_POLL_ERROR: c_int = 3;
/// A task executor for `hyper_task`s.
pub(crate) struct hyper_executor {
/// The executor of all task futures.
///
/// There should never be contention on the mutex, as it is only locked
/// to drive the futures. However, we cannot guarantee proper usage from
/// `hyper_executor_poll()`, which in C could potentially be called inside
/// one of the stored futures. The mutex isn't re-entrant, so doing so
/// would result in a deadlock, but that's better than data corruption.
driver: Mutex<FuturesUnordered<TaskFuture>>,
/// The queue of futures that need to be pushed into the `driver`.
///
/// This is has a separate mutex since `spawn` could be called from inside
/// a future, which would mean the driver's mutex is already locked.
spawn_queue: Mutex<Vec<TaskFuture>>,
/// This is used to track when a future calls `wake` while we are within
/// `hyper_executor::poll_next`.
is_woken: Arc<ExecWaker>,
}
#[derive(Clone)]
pub(crate) struct WeakExec(Weak<hyper_executor>);
struct ExecWaker(AtomicBool);
/// An async task.
pub(crate) struct hyper_task {
future: BoxFuture<BoxAny>,
output: Option<BoxAny>,
@ -53,24 +53,24 @@ pub(crate) struct hyper_task {
struct TaskFuture {
task: Option<Box<hyper_task>>,
}
/// An async context for a task that contains the related waker.
pub(crate) struct hyper_context<'a>(Context<'a>);
/// A waker that is saved and used to waken a pending task.
pub(crate) struct hyper_waker {
waker: std::task::Waker,
}
/// A descriptor for what type a `hyper_task` value is.
#[repr(C)]
pub(crate) enum hyper_task_return_type {
/// The value of this task is null (does not imply an error).
HYPER_TASK_EMPTY,
/// The value of this task is `hyper_error *`.
HYPER_TASK_ERROR,
/// The value of this task is `hyper_clientconn *`.
HYPER_TASK_CLIENTCONN,
/// The value of this task is `hyper_response *`.
HYPER_TASK_RESPONSE,
/// The value of this task is `hyper_buf *`.
HYPER_TASK_BUF,
}
pub(crate) unsafe trait AsTaskType {

View file

@ -18,13 +18,13 @@ use crate::common::{task, Poll, Unpin};
use crate::proto::{BodyLength, MessageHead};
const H2_PREFACE: &[u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
/// This handles a connection, which will have been established over an
/// `AsyncRead + AsyncWrite` (like a socket), and will likely include multiple
/// `Transaction`s over HTTP.
///
/// The connection will determine when a message begins and ends as well as
/// determine if this connection can be kept alive after the message,
/// or if it is complete.
pub(crate) struct Conn<I, B, T> {
io: Buffered<I, EncodedBuf<B>>,
state: State,
@ -217,7 +217,7 @@ where
) -> Poll<io::Result<()>> {
loop {}
}
/// If the read side can be cheaply drained, do so. Otherwise, close.
pub(super) fn poll_drain_or_close_read(&mut self, cx: &mut task::Context<'_>) {
loop {}
}
@ -246,17 +246,17 @@ impl<I, B: Buf, T> fmt::Debug for Conn<I, B, T> {
impl<I: Unpin, B, T> Unpin for Conn<I, B, T> {}
struct State {
allow_half_close: bool,
/// Re-usable HeaderMap to reduce allocating new ones.
cached_headers: Option<HeaderMap>,
/// If an error occurs when there wasn't a direct way to return it
/// back to the user, this is set.
error: Option<crate::Error>,
/// Current keep-alive status.
keep_alive: KA,
/// If mid-message, the HTTP Method that started it.
///
/// This is used to know things such as if the message can include
/// a body or not.
method: Option<Method>,
h1_parser_config: ParserConfig,
#[cfg(all(feature = "server", feature = "runtime"))]
@ -270,23 +270,23 @@ struct State {
preserve_header_order: bool,
title_case_headers: bool,
h09_responses: bool,
/// If set, called with each 1xx informational response received for
/// the current request. MUST be unset after a non-1xx response is
/// received.
#[cfg(feature = "ffi")]
on_informational: Option<crate::ffi::OnInformational>,
#[cfg(feature = "ffi")]
raw_headers: bool,
/// Set to true when the Dispatcher should poll read operations
/// again. See the `maybe_notify` method for more.
notify_read: bool,
/// State of allowed reads
reading: Reading,
/// State of allowed writes
writing: Writing,
/// An expected pending HTTP upgrade.
upgrade: Option<crate::upgrade::Pending>,
/// Either HTTP/1.0 or 1.1 connection
version: Version,
}
#[derive(Debug)]

View file

@ -13,10 +13,10 @@ use super::DecodedLength;
use self::Kind::{Chunked, Eof, Length};
/// Decoders to handle different Transfer-Encodings.
///
/// If a message body does not include a Transfer-Encoding, it *should*
/// include a Content-Length header.
#[derive(Clone, PartialEq)]
pub(crate) struct Decoder {
kind: Kind,
@ -24,26 +24,26 @@ pub(crate) struct Decoder {
#[derive(Debug, Clone, Copy, PartialEq)]
enum Kind {
/// A Reader used when a Content-Length header is passed with a positive integer.
Length(u64),
/// A Reader used when Transfer-Encoding is `chunked`.
Chunked(ChunkedState, u64),
/// A Reader used for responses that don't indicate a length or chunked.
///
/// The bool tracks when EOF is seen on the transport.
///
/// Note: This should only used for `Response`s. It is illegal for a
/// `Request` to be made with both `Content-Length` and
/// `Transfer-Encoding: chunked` missing, as explained from the spec:
///
/// > If a Transfer-Encoding header field is present in a response and
/// > the chunked transfer coding is not the final encoding, the
/// > message body length is determined by reading the connection until
/// > it is closed by the server. If a Transfer-Encoding header field
/// > is present in a request and the chunked transfer coding is not
/// > the final encoding, the message body length cannot be determined
/// > reliably; the server MUST respond with the 400 (Bad Request)
/// > status code and then close the connection.
Eof(bool),
}

View file

@ -64,11 +64,11 @@ where
pub(crate) fn into_inner(self) -> (I, Bytes, D) {
loop {}
}
/// Run this dispatcher until HTTP says this connection is done,
/// but don't call `AsyncWrite::shutdown` on the underlying IO.
///
/// This is useful for old-style HTTP upgrades, but ignores
/// newer-style upgrade API.
pub(crate) fn poll_without_shutdown(
&mut self,
cx: &mut task::Context<'_>,
@ -133,8 +133,8 @@ where
loop {}
}
}
/// A drop guard to allow a mutable borrow of an Option while being able to
/// set whether the `Option` should be cleared on drop.
struct OptGuard<'a, T>(Pin<&'a mut Option<T>>, bool);
impl<'a, T> OptGuard<'a, T> {
fn new(pin: Pin<&'a mut Option<T>>) -> Self {

View file

@ -5,7 +5,7 @@ use bytes::Buf;
use super::io::WriteBuf;
type StaticBuf = &'static [u8];
/// Encoders to handle different Transfer-Encodings.
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct Encoder {
kind: Kind,
@ -19,16 +19,16 @@ pub(crate) struct EncodedBuf<B> {
pub(crate) struct NotEof(u64);
#[derive(Debug, PartialEq, Clone)]
enum Kind {
/// An Encoder for when Transfer-Encoding includes `chunked`.
Chunked,
/// An Encoder for when Content-Length is set.
///
/// Enforces that the body is not longer than the Content-Length header.
Length(u64),
/// An Encoder for when neither Content-Length nor Chunked encoding is set.
///
/// This is mostly only used with HTTP/1.0 with a length. This kind requires
/// the connection to be closed when the body is finished.
#[cfg(feature = "server")]
CloseDelimited,
}
@ -85,11 +85,11 @@ impl Encoder {
{
loop {}
}
/// Encodes the full body, without verifying the remaining length matches.
///
/// This is used in conjunction with HttpBody::__hyper_full_data(), which
/// means we can trust that the buf has the correct size (the buf itself
/// was checked to make the headers).
pub(super) fn danger_full_buf<B>(self, msg: B, dst: &mut WriteBuf<EncodedBuf<B>>)
where
B: Buf,

View file

@ -15,18 +15,18 @@ use tokio::time::Instant;
use super::{Http1Transaction, ParseContext, ParsedMessage};
use crate::common::buf::BufList;
use crate::common::{task, Poll};
/// The initial buffer size allocated before trying to read from IO.
pub(crate) const INIT_BUFFER_SIZE: usize = 8192;
/// The minimum value that can be set to max buffer size.
pub(crate) const MINIMUM_MAX_BUFFER_SIZE: usize = INIT_BUFFER_SIZE;
/// The default maximum read buffer size. If the buffer gets this big and
/// a message is still not complete, a `TooLarge` error is triggered.
pub(crate) const DEFAULT_MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;
/// The maximum number of distinct `Buf`s to hold in a list before requiring
/// a flush. Only affects when the buffer strategy is to queue buffers.
///
/// Note that a flush can happen before reaching the maximum. This simply
/// forces a flush if the queue gets this big.
const MAX_BUF_LIST_BUFFERS: usize = 16;
pub(crate) struct Buffered<T, B> {
flush_pipeline: bool,
@ -77,16 +77,16 @@ where
pub(super) fn read_buf_mut(&mut self) -> &mut BytesMut {
loop {}
}
/// Return the "allocated" available space, not the potential space
/// that could be allocated in the future.
fn read_buf_remaining_mut(&self) -> usize {
loop {}
}
/// Return whether we can append to the headers buffer.
///
/// Reasons we can't:
/// - The write buf is in queue mode, and some of the past body is still
/// needing to be flushed.
pub(crate) fn can_headers_buf(&self) -> bool {
loop {}
}
@ -136,10 +136,10 @@ where
) -> Poll<io::Result<()>> {
loop {}
}
/// Specialized version of `flush` when strategy is Flatten.
///
/// Since all buffered bytes are flattened into the single headers buffer,
/// that skips some bookkeeping around using multiple buffers.
fn poll_flush_flattened(
&mut self,
cx: &mut task::Context<'_>,
@ -217,9 +217,9 @@ impl<T: AsRef<[u8]>> Cursor<T> {
}
}
impl Cursor<Vec<u8>> {
/// If we've advanced the position a bit in this cursor, and wish to
/// extend the underlying vector, we may wish to unshift the "read" bytes
/// off, and move everything else over.
fn maybe_unshift(&mut self, additional: usize) {
loop {}
}
@ -247,10 +247,10 @@ impl<T: AsRef<[u8]>> Buf for Cursor<T> {
}
}
pub(super) struct WriteBuf<B> {
/// Re-usable buffer that holds message headers
headers: Cursor<Vec<u8>>,
max_buf_size: usize,
/// Deque of user buffers if strategy is Queue
queue: BufList<B>,
strategy: WriteStrategy,
}

View file

@ -48,7 +48,7 @@ pub(crate) trait Http1Transaction {
}
fn update_date() {}
}
/// Result newtype for Http1Transaction::parse.
pub(crate) type ParseResult<T> = Result<Option<ParsedMessage<T>>, crate::error::Parse>;
#[derive(Debug)]
pub(crate) struct ParsedMessage<T> {
@ -77,7 +77,7 @@ pub(crate) struct ParseContext<'a> {
#[cfg(feature = "ffi")]
raw_headers: bool,
}
/// Passed to Http1Transaction::encode
pub(crate) struct Encode<'a, T> {
head: &'a mut MessageHead<T>,
body: Option<BodyLength>,
@ -86,7 +86,7 @@ pub(crate) struct Encode<'a, T> {
req_method: &'a mut Option<Method>,
title_case_headers: bool,
}
/// Extra flags that a request "wants", like expect-continue or upgrades.
#[derive(Clone, Copy, Debug)]
struct Wants(u8);
impl Wants {

View file

@ -179,9 +179,9 @@ impl Http1Transaction for Client {
}
#[cfg(feature = "client")]
impl Client {
/// Returns Some(length, wants_upgrade) if successful.
///
/// Returns None if this message head should be skipped (like a 100 status).
fn decoder(
inc: &MessageHead<StatusCode>,
method: &mut Option<Method>,

View file

@ -19,7 +19,7 @@ cfg_client! {
cfg_server! {
pub (crate) mod server; pub (crate) use self::server::Server;
}
/// Default initial stream window size defined in HTTP2 spec.
pub(crate) const SPEC_WINDOW_SIZE: u32 = 65_535;
fn strip_connection_headers(headers: &mut HeaderMap, is_request: bool) {
loop {}

View file

@ -1,23 +1,23 @@
/// HTTP2 Ping usage
///
/// hyper uses HTTP2 pings for two purposes:
///
/// 1. Adaptive flow control using BDP
/// 2. Connection keep-alive
///
/// Both cases are optional.
///
/// # BDP Algorithm
///
/// 1. When receiving a DATA frame, if a BDP ping isn't outstanding:
/// 1a. Record current time.
/// 1b. Send a BDP ping.
/// 2. Increment the number of received bytes.
/// 3. When the BDP ping ack is received:
/// 3a. Record duration from sent time.
/// 3b. Merge RTT with a running average.
/// 3c. Calculate bdp as bytes/rtt.
/// 3d. If bdp is over 2/3 max, set new max to bdp and update windows.
#[cfg(feature = "runtime")]
use std::fmt;
#[cfg(feature = "runtime")]
@ -43,14 +43,14 @@ pub(super) fn channel(ping_pong: PingPong, config: Config) -> (Recorder, Ponger)
#[derive(Clone)]
pub(super) struct Config {
pub(super) bdp_initial_window: Option<WindowSize>,
/// If no frames are received in this amount of time, a PING frame is sent.
#[cfg(feature = "runtime")]
pub(super) keep_alive_interval: Option<Duration>,
/// After sending a keepalive PING, the connection will be closed if
/// a pong is not received in this amount of time.
#[cfg(feature = "runtime")]
pub(super) keep_alive_timeout: Duration,
/// If true, sends pings even when there are no active streams.
#[cfg(feature = "runtime")]
pub(super) keep_alive_while_idle: bool,
}
@ -67,41 +67,41 @@ pub(super) struct Ponger {
struct Shared {
ping_pong: PingPong,
ping_sent_at: Option<Instant>,
/// If `Some`, bdp is enabled, and this tracks how many bytes have been
/// read during the current sample.
bytes: Option<usize>,
/// We delay a variable amount of time between BDP pings. This allows us
/// to send less pings as the bandwidth stabilizes.
next_bdp_at: Option<Instant>,
/// If `Some`, keep-alive is enabled, and the Instant is how long ago
/// the connection read the last frame.
#[cfg(feature = "runtime")]
last_read_at: Option<Instant>,
#[cfg(feature = "runtime")]
is_keep_alive_timed_out: bool,
}
struct Bdp {
/// Current BDP in bytes
bdp: u32,
/// Largest bandwidth we've seen so far.
max_bandwidth: f64,
/// Round trip time in seconds
rtt: f64,
/// Delay the next ping by this amount.
///
/// This will change depending on how stable the current bandwidth is.
ping_delay: Duration,
/// The count of ping round trips where BDP has stayed the same.
stable_count: u32,
}
#[cfg(feature = "runtime")]
struct KeepAlive {
/// If no frames are received in this amount of time, a PING frame is sent.
interval: Duration,
/// After sending a keepalive PING, the connection will be closed if
/// a pong is not received in this amount of time.
timeout: Duration,
/// If true, sends pings even when there are no active streams.
while_idle: bool,
state: KeepAliveState,
timer: Pin<Box<Sleep>>,
@ -132,8 +132,8 @@ impl Recorder {
pub(crate) fn record_non_data(&self) {
loop {}
}
/// If the incoming stream is already closed, convert self into
/// a disabled reporter.
#[cfg(feature = "client")]
pub(super) fn for_stream(self, stream: &h2::RecvStream) -> Self {
loop {}
@ -167,7 +167,7 @@ impl Shared {
loop {}
}
}
/// Any higher than this likely will be hitting the TCP flow control.
const BDP_LIMIT: usize = 1024 * 1024 * 16;
impl Bdp {
fn calculate(&mut self, bytes: usize, rtt: Duration) -> Option<WindowSize> {

View file

@ -6,40 +6,40 @@ cfg_feature! {
}
#[cfg(feature = "http2")]
pub(crate) mod h2;
/// An Incoming Message head. Includes request/status line, and headers.
#[derive(Debug, Default)]
pub(crate) struct MessageHead<S> {
/// HTTP version of the message.
pub(crate) version: http::Version,
/// Subject (request line or status line) of Incoming message.
pub(crate) subject: S,
/// Headers of the Incoming message.
pub(crate) headers: http::HeaderMap,
/// Extensions.
extensions: http::Extensions,
}
/// An incoming request message.
#[cfg(feature = "http1")]
pub(crate) type RequestHead = MessageHead<RequestLine>;
#[derive(Debug, Default, PartialEq)]
#[cfg(feature = "http1")]
pub(crate) struct RequestLine(pub(crate) http::Method, pub(crate) http::Uri);
/// An incoming response message.
#[cfg(all(feature = "http1", feature = "client"))]
pub(crate) type ResponseHead = MessageHead<http::StatusCode>;
#[derive(Debug)]
#[cfg(feature = "http1")]
pub(crate) enum BodyLength {
/// Content-Length
Known(u64),
/// Transfer-Encoding: chunked (if h1)
Unknown,
}
/// Status of when a Disaptcher future completes.
pub(crate) enum Dispatched {
/// Dispatcher completely shutdown connection.
Shutdown,
/// Dispatcher has pending upgrade, and so did not shutdown.
#[cfg(feature = "http1")]
Upgrade(crate::upgrade::Pending),
}

View file

@ -5,8 +5,8 @@
//! If the `runtime` feature is disabled, the types in this module can be used
//! to plug in other runtimes.
/// An executor of futures.
pub trait Executor<Fut> {
/// Place the future into the executor to be run.
fn execute(&self, fut: Fut);
}

View file

@ -13,24 +13,24 @@ use crate::common::{
task::{self, Poll},
Pin,
};
/// Asynchronously accept incoming connections.
pub trait Accept {
/// The connection type that can be accepted.
type Conn;
/// The error type that can occur when accepting a connection.
type Error;
/// Poll to accept the next connection.
fn poll_accept(
self: Pin<&mut Self>,
cx: &mut task::Context<'_>,
) -> Poll<Option<Result<Self::Conn, Self::Error>>>;
}
/// Adapt a `Stream` of incoming connections into an `Accept`.
///
/// # Optional
///
/// This function requires enabling the `stream` feature in your
/// `Cargo.toml`.
#[cfg(feature = "stream")]
pub fn from_stream<S, IO, E>(stream: S) -> impl Accept<Conn = IO, Error = E>
where

View file

@ -65,29 +65,29 @@ cfg_feature! {
}
#[cfg(feature = "tcp")]
pub use super::tcp::{AddrIncoming, AddrStream};
/// A lower-level configuration of the HTTP protocol.
///
/// This structure is used to configure options for an HTTP server connection.
///
/// If you don't have need to manage connections yourself, consider using the
/// higher-level [Server](super) API.
#[derive(Clone, Debug)]
#[cfg(any(feature = "http1", feature = "http2"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
pub(crate) struct Http<E = Exec> {
pub(crate) exec: E,
}
/// The internal mode of HTTP protocol which indicates the behavior when a parse error occurs.
#[cfg(any(feature = "http1", feature = "http2"))]
#[derive(Clone, Debug, PartialEq)]
enum ConnectionMode {
/// Always use HTTP/1 and do not upgrade when a parse error occurs.
#[cfg(feature = "http1")]
H1Only,
/// Always use HTTP/2.
#[cfg(feature = "http2")]
H2Only,
/// Use HTTP/1 and try to upgrade to h2 when a parse error occurs.
#[cfg(all(feature = "http1", feature = "http2"))]
Fallback,
}

View file

@ -29,7 +29,7 @@ pin_project! {
protocol : Http_ < E >,
}
}
/// A builder for a [`Server`](Server).
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
pub struct Builder<I, E = Exec> {
@ -38,7 +38,7 @@ pub struct Builder<I, E = Exec> {
}
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
impl<I> Server<I, ()> {
/// Starts a [`Builder`](Builder) with the provided incoming stream.
pub fn builder(incoming: I) -> Builder<I> {
loop {}
}
@ -49,12 +49,12 @@ impl<I> Server<I, ()> {
doc(cfg(all(feature = "tcp", any(feature = "http1", feature = "http2"))))
)]
impl Server<AddrIncoming, ()> {
/// Binds to the provided address, and returns a [`Builder`](Builder).
///
/// # Panics
///
/// This method will panic if binding to the address fails. For a method
/// to bind to an address and return a `Result`, see `Server::try_bind`.
pub fn bind() -> Builder<AddrIncoming> {
loop {}
}
@ -71,42 +71,42 @@ where
B::Error: Into<Box<dyn StdError + Send + Sync>>,
E: ConnStreamExec<<S::Service as HttpService<Body>>::Future, B>,
{
/// Prepares a server to handle graceful shutdown when the provided future
/// completes.
///
/// # Example
///
/// ```
/// # fn main() {}
/// # #[cfg(feature = "tcp")]
/// # async fn run() {
/// # use hyper::{Body, Response, Server, Error};
/// # use hyper::service::{make_service_fn, service_fn};
/// # let make_service = make_service_fn(|_| async {
/// # Ok::<_, Error>(service_fn(|_req| async {
/// # Ok::<_, Error>(Response::new(Body::from("Hello World")))
/// # }))
/// # });
/// // Make a server from the previous examples...
/// let server = Server::bind(&([127, 0, 0, 1], 3000).into())
/// .serve(make_service);
///
/// // Prepare some signal for when the server should start shutting down...
/// let (tx, rx) = tokio::sync::oneshot::channel::<()>();
/// let graceful = server
/// .with_graceful_shutdown(async {
/// rx.await.ok();
/// });
///
/// // Await the `server` receiving the signal...
/// if let Err(e) = graceful.await {
/// eprintln!("server error: {}", e);
/// }
///
/// // And later, trigger the signal by calling `tx.send(())`.
/// let _ = tx.send(());
/// # }
/// ```
fn poll_next_(
self: Pin<&mut Self>,
@ -148,7 +148,7 @@ impl<I, E> Builder<I, E> {
loop {}
}
///
pub fn serve<S, B>(self, _: S) -> Server<I, S>
where
I: Accept,

View file

@ -52,7 +52,7 @@ impl TcpKeepaliveConfig {
loop {}
}
}
/// A stream of connections from binding to an address.
#[must_use = "streams do nothing unless polled"]
pub struct AddrIncoming {
addr: SocketAddr,
@ -63,15 +63,15 @@ pub struct AddrIncoming {
timeout: Option<Pin<Box<Sleep>>>,
}
impl AddrIncoming {
/// Creates a new `AddrIncoming` binding to provided socket address.
pub fn bind(addr: &SocketAddr) -> crate::Result<Self> {
loop {}
}
/// Get the local address bound to this listener.
pub fn local_addr(&self) -> SocketAddr {
loop {}
}
/// Set the value of `TCP_NODELAY` option for accepted connections.
pub fn set_nodelay(&mut self, enabled: bool) -> &mut Self {
loop {}
}

View file

@ -2,17 +2,17 @@ use std::error::Error as StdError;
use crate::body::HttpBody;
use crate::common::{task, Future, Poll};
use crate::{Request, Response};
/// An asynchronous function from `Request` to `Response`.
pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
/// The `HttpBody` body of the `http::Response`.
type ResBody: HttpBody;
/// The error type that can occur within this `Service`.
///
/// Note: Returning an `Error` to a hyper server will cause the connection
/// to be abruptly aborted. In most cases, it is better to return a `Response`
/// with a 4xx or 5xx status code.
type Error: Into<Box<dyn StdError + Send + Sync>>;
/// The `Future` returned by this `Service`.
type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>;
#[doc(hidden)]
fn poll_ready(

View file

@ -82,42 +82,42 @@ where
B1: HttpBody,
B2: HttpBody,
{}
/// Create a `MakeService` from a function.
///
/// # Example
///
/// ```
/// # #[cfg(feature = "runtime")]
/// # async fn run() {
/// use std::convert::Infallible;
/// use hyper::{Body, Request, Response, Server};
/// use hyper::server::conn::AddrStream;
/// use hyper::service::{make_service_fn, service_fn};
///
/// let addr = ([127, 0, 0, 1], 3000).into();
///
/// let make_svc = make_service_fn(|socket: &AddrStream| {
/// let remote_addr = socket.remote_addr();
/// async move {
/// Ok::<_, Infallible>(service_fn(move |_: Request<Body>| async move {
/// Ok::<_, Infallible>(
/// Response::new(Body::from(format!("Hello, {}!", remote_addr)))
/// )
/// }))
/// }
/// });
///
/// // Then bind and serve...
/// let server = Server::bind(&addr)
/// .serve(make_svc);
///
/// // Finally, spawn `server` onto an Executor...
/// if let Err(e) = server.await {
/// eprintln!("server error: {}", e);
/// }
/// # }
/// # fn main() {}
/// ```
pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F>
where
F: FnMut(&Target) -> Ret,
@ -125,7 +125,7 @@ where
{
loop {}
}
/// `MakeService` returned from [`make_service_fn`]
#[derive(Clone, Copy)]
pub struct MakeServiceFn<F> {
f: F,

View file

@ -4,24 +4,24 @@ use std::marker::PhantomData;
use crate::body::HttpBody;
use crate::common::{task, Future, Poll};
use crate::{Request, Response};
/// Create a `Service` from a function.
///
/// # Example
///
/// ```
/// use hyper::{Body, Request, Response, Version};
/// use hyper::service::service_fn;
///
/// let service = service_fn(|req: Request<Body>| async move {
/// if req.version() == Version::HTTP_11 {
/// Ok(Response::new(Body::from("Hello World")))
/// } else {
/// // Note: it's usually better to return a Response
/// // with an appropriate StatusCode instead of an Err.
/// Err("not HTTP/1.1, abort connection")
/// }
/// });
/// ```
pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
where
F: FnMut(Request<R>) -> S,
@ -29,7 +29,7 @@ where
{
loop {}
}
/// Service returned by [`service_fn`]
pub struct ServiceFn<F, R> {
f: F,
_req: PhantomData<fn(R)>,

View file

@ -49,50 +49,50 @@ use tokio::sync::oneshot;
use crate::common::io::Rewind;
use crate::common::{task, Future, Pin, Poll};
/// An upgraded HTTP connection.
///
/// This type holds a trait object internally of the original IO that
/// was used to speak HTTP before the upgrade. It can be used directly
/// as a `Read` or `Write` for convenience.
///
/// Alternatively, if the exact type is known, this can be deconstructed
/// into its parts.
pub(crate) struct Upgraded {
io: Rewind<Box<dyn Io + Send>>,
}
/// A future for a possible HTTP upgrade.
///
/// If no upgrade was available, or it doesn't succeed, yields an `Error`.
pub(crate) struct OnUpgrade {
rx: Option<oneshot::Receiver<crate::Result<Upgraded>>>,
}
/// The deconstructed parts of an [`Upgraded`](Upgraded) type.
///
/// Includes the original IO type, and a read buffer of bytes that the
/// HTTP state machine may have already read before completing an upgrade.
#[derive(Debug)]
pub(crate) struct Parts<T> {
/// The original IO object used before the upgrade.
pub(crate) io: T,
/// A buffer of bytes that have been read but not processed as HTTP.
///
/// For instance, if the `Connection` is used for an HTTP upgrade request,
/// it is possible the server sent back the first bytes of the new protocol
/// along with the response upgrade.
///
/// You will want to check for any existing bytes if you plan to continue
/// communicating on the IO object.
pub(crate) read_buf: Bytes,
_inner: (),
}
/// Gets a pending HTTP upgrade from this message.
///
/// This can be called on the following types:
///
/// - `http::Request<B>`
/// - `http::Response<B>`
/// - `&mut http::Request<B>`
/// - `&mut http::Response<B>`
pub(crate) fn on<T: sealed::CanUpgrade>(msg: T) -> OnUpgrade {
loop {}
}
@ -112,10 +112,10 @@ impl Upgraded {
{
loop {}
}
/// Tries to downcast the internal trait object to the type passed.
///
/// On success, returns the downcasted parts. On error, returns the
/// `Upgraded` back.
pub(crate) fn downcast<T: AsyncRead + AsyncWrite + Unpin + 'static>(
self,
) -> Result<Parts<T>, Self> {
@ -193,16 +193,16 @@ impl Pending {
loop {}
}
#[cfg(feature = "http1")]
/// Don't fulfill the pending Upgrade, but instead signal that
/// upgrades are handled manually.
pub(super) fn manual(self) {
loop {}
}
}
/// Error cause returned when an upgrade was expected but canceled
/// for whatever reason.
///
/// This likely means the actual `Conn` future wasn't polled and upgraded.
#[derive(Debug)]
struct UpgradeExpected;
impl fmt::Display for UpgradeExpected {