Skip to main content

ntex/http/
mod.rs

1//! HTTP protocol support.
2//!
3//! This module contains HTTP request and response types, HTTP/1 and HTTP/2
4//! services, payload streaming, protocol configuration, and common header
5//! types.
6mod config;
7#[cfg(feature = "compress")]
8pub mod encoding;
9pub(crate) mod helpers;
10mod httpcodes;
11mod httpmessage;
12mod message;
13mod payload;
14mod request;
15mod response;
16mod service;
17
18pub mod error;
19pub mod h1;
20pub mod h2;
21pub mod test;
22
23pub(crate) use self::message::{CurrentIo, IoAccess, Message};
24
25pub use self::config::{DateService, HttpServiceConfig, KeepAlive};
26pub use self::error::ResponseError;
27pub use self::httpmessage::HttpMessage;
28pub use self::message::{ConnectionType, RequestHead, ResponseHead};
29pub use self::payload::{Payload, PayloadStream};
30pub use self::request::Request;
31pub use self::response::{Response, ResponseBuilder};
32pub use self::service::HttpService;
33pub use crate::io::types::HttpProtocol;
34
35// re-exports
36pub use ntex_http::{HeaderMap, Method, StatusCode, Version, body, header};
37
38/// ALPN protocol identifiers for HTTP/1.1.
39pub const ALPN_PROTO_H1: &[&str] = &["http/1.1"];
40/// ALPN protocol identifiers for HTTP/2.
41pub const ALPN_PROTO_H2: &[&str] = &["h2"];
42/// ALPN protocol identifiers for negotiating HTTP/2 or HTTP/1.1.
43pub const ALPN_PROTOS: &[&str] = &["h2", "http/1.1"];
44
45/// A parsed header that preserves its original name and value.
46#[derive(Clone, PartialEq, Eq, Debug)]
47pub struct HeaderItem {
48    /// Parsed header name.
49    pub name: header::HeaderName,
50    /// Header name as it appeared in the original message.
51    pub origin: crate::util::ByteString,
52    /// Parsed header value.
53    pub value: header::HeaderValue,
54}
55
56#[cfg(feature = "openssl")]
57use crate::server::openssl::{SslAcceptor, SslFilter};
58#[cfg(any(feature = "openssl", feature = "rustls"))]
59use crate::{IntoService, Service, io::Filter, io::Io, io::Layer, server::TlsError};
60
61#[cfg(feature = "openssl")]
62/// Wraps an HTTP service in an OpenSSL TLS acceptor.
63///
64/// ALPN behavior comes from the supplied `acceptor`; configure it with
65/// [`ALPN_PROTO_H1`], [`ALPN_PROTO_H2`], or [`ALPN_PROTOS`] as appropriate.
66/// TLS failures and inner-service failures are mapped to the corresponding
67/// [`TlsError`] variants.
68pub fn openssl<F, S, St>(
69    acceptor: tls_openssl::ssl::SslAcceptor,
70    service: impl IntoService<S, St, Io<Layer<SslFilter, F>>>,
71) -> impl Service<St, Io<F>, Res = S::Res, Error = TlsError<S::Error>>
72where
73    F: Filter,
74    S: Service<St, Io<Layer<SslFilter, F>>>,
75{
76    SslAcceptor::new(acceptor)
77        .map_err(TlsError::Tls)
78        .and_then(service.into_service().map_err(TlsError::Service))
79}
80
81#[cfg(feature = "rustls")]
82use crate::server::rustls::{TlsAcceptor, TlsServerFilter};
83
84#[cfg(feature = "rustls")]
85/// Creates a rustls-based HTTP service.
86///
87/// Pass the supported ALPN protocol identifiers in `protos` to enable HTTP/2
88/// negotiation. If the configuration already contains ALPN protocols, they
89/// are preserved. TLS failures and inner-service failures are mapped to the
90/// corresponding [`TlsError`] variants.
91pub fn rustls<F, S, St>(
92    mut config: tls_rustls::ServerConfig,
93    protos: &[&str],
94    service: impl IntoService<S, St, Io<Layer<TlsServerFilter, F>>>,
95) -> impl Service<St, Io<F>, Res = S::Res, Error = TlsError<S::Error>>
96where
97    F: Filter,
98    S: Service<St, Io<Layer<TlsServerFilter, F>>>,
99{
100    if !protos.is_empty() && config.alpn_protocols.is_empty() {
101        config.alpn_protocols = protos.iter().map(|s| s.to_string().into()).collect();
102    }
103
104    TlsAcceptor::new(std::sync::Arc::new(config))
105        .map_err(TlsError::Tls)
106        .and_then(service.into_service().map_err(TlsError::Service))
107}
108
109use crate::error::Error;
110use crate::service::pipeline::PipelineFactory;
111
112type HttpPipeline<St, Err> = PipelineFactory<St, Request, Response, Err, error::DispatchError>;
113type Ctl1Pipeline<St, F, Err> = PipelineFactory<
114    St,
115    h1::Control<F, Err>,
116    h1::ControlAck<F>,
117    error::DispatchError,
118    error::DispatchError,
119>;
120type Ctl2Pipeline<St> = PipelineFactory<
121    St,
122    h2::Control<Error<error::H2Error>>,
123    h2::ControlAck,
124    error::DispatchError,
125    error::DispatchError,
126>;