Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ws and http2 feature flags #2618

Merged
merged 4 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ actix-service = "2.0.0"
actix-utils = "3.0.0"
actix-tls = { version = "3.0.0", default-features = false, optional = true }

actix-http = "3.0.0-beta.19"
actix-http = { version = "3.0.0-beta.19", features = ["http2", "ws"] }
actix-router = "0.5.0-rc.2"
actix-web-codegen = "0.5.0-rc.1"

Expand Down
3 changes: 3 additions & 0 deletions actix-http/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- Implement `From<Duration>` for `KeepAlive`. [#2611]
- Implement `From<Option<Duration>>` for `KeepAlive`. [#2611]
- Implement `Default` for `HttpServiceBuilder`. [#2611]
- Crate `ws` feature flag, disabled by default. [#2618]
- Crate `http2` feature flag, disabled by default. [#2618]

### Changed
- Rename `ServiceConfig::{client_timer_expire => client_request_deadline}`. [#2611]
Expand All @@ -27,6 +29,7 @@
- `HttpServiceBuilder::new`; use `default` instead. [#2611]

[#2611]: https://github.com/actix/actix-web/pull/2611
[#2618]: https://github.com/actix/actix-web/pull/2618


## 3.0.0-beta.19 - 2022-01-21
Expand Down
47 changes: 31 additions & 16 deletions actix-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,54 +29,69 @@ path = "src/lib.rs"
[features]
default = []

# openssl
# HTTP/2 protocol support
http2 = ["h2"]

# WebSocket protocol implementation
ws = [
"local-channel",
"base64",
"rand",
"sha-1",
]

# TLS via OpenSSL
openssl = ["actix-tls/accept", "actix-tls/openssl"]

# rustls support
# TLS via Rustls
rustls = ["actix-tls/accept", "actix-tls/rustls"]

# enable compression support
compress-brotli = ["brotli", "__compress"]
compress-gzip = ["flate2", "__compress"]
compress-zstd = ["zstd", "__compress"]
# Compression codecs
compress-brotli = ["__compress", "brotli"]
compress-gzip = ["__compress", "flate2"]
compress-zstd = ["__compress", "zstd"]

# Internal (PRIVATE!) features used to aid testing and cheking feature status.
# Don't rely on these whatsoever. They may disappear at anytime.
# Don't rely on these whatsoever. They are semver-exempt and may disappear at anytime.
__compress = []

[dependencies]
actix-service = "2.0.0"
actix-service = "2"
actix-codec = "0.4.1"
actix-utils = "3.0.0"
actix-utils = "3"
actix-rt = { version = "2.2", default-features = false }

ahash = "0.7"
base64 = "0.13"
bitflags = "1.2"
bytes = "1"
bytestring = "1"
derive_more = "0.99.5"
encoding_rs = "0.8"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
h2 = "0.3.9"
http = "0.2.5"
httparse = "1.5.1"
httpdate = "1.0.1"
itoa = "1"
language-tags = "0.3"
local-channel = "0.1"
log = "0.4"
mime = "0.3"
percent-encoding = "2.1"
pin-project-lite = "0.2"
rand = "0.8"
sha-1 = "0.10"
smallvec = "1.6.1"

# tls
# http2
h2 = { version = "0.3.9", optional = true }

# websockets
local-channel = { version = "0.1", optional = true }
base64 = { version = "0.13", optional = true }
rand = { version = "0.8", optional = true }
sha-1 = { version = "0.10", optional = true }

# openssl/rustls
actix-tls = { version = "3.0.0", default-features = false, optional = true }

# compression
# compress-*
brotli = { version = "3.3.3", optional = true }
flate2 = { version = "1.0.13", optional = true }
zstd = { version = "0.9", optional = true }
Expand Down
7 changes: 4 additions & 3 deletions actix-http/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use actix_service::{IntoServiceFactory, Service, ServiceFactory};
use crate::{
body::{BoxBody, MessageBody},
h1::{self, ExpectHandler, H1Service, UpgradeHandler},
h2::H2Service,
service::HttpService,
ConnectCallback, Extensions, KeepAlive, Request, Response, ServiceConfig,
};
Expand Down Expand Up @@ -211,7 +210,8 @@ where
}

/// Finish service configuration and create a HTTP service for HTTP/2 protocol.
pub fn h2<F, B>(self, service: F) -> H2Service<T, S, B>
#[cfg(feature = "http2")]
pub fn h2<F, B>(self, service: F) -> crate::h2::H2Service<T, S, B>
where
F: IntoServiceFactory<S, Request>,
S::Error: Into<Response<BoxBody>> + 'static,
Expand All @@ -228,7 +228,8 @@ where
self.local_addr,
);

H2Service::with_config(cfg, service.into_factory()).on_connect_ext(self.on_connect_ext)
crate::h2::H2Service::with_config(cfg, service.into_factory())
.on_connect_ext(self.on_connect_ext)
}

/// Finish service configuration and create `HttpService` instance.
Expand Down
1 change: 1 addition & 0 deletions actix-http/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl ServiceConfig {
dst.extend_from_slice(&buf);
}

#[allow(unused)] // used with `http2` feature flag
pub(crate) fn write_date_header_value(&self, dst: &mut BytesMut) {
self.0
.date_service
Expand Down
8 changes: 4 additions & 4 deletions actix-http/src/encoding/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ impl ContentEncoder {
ContentEncoder::Brotli(ref mut encoder) => match encoder.write_all(data) {
Ok(_) => Ok(()),
Err(err) => {
trace!("Error decoding br encoding: {}", err);
log::trace!("Error decoding br encoding: {}", err);
Err(err)
}
},
Expand All @@ -361,7 +361,7 @@ impl ContentEncoder {
ContentEncoder::Gzip(ref mut encoder) => match encoder.write_all(data) {
Ok(_) => Ok(()),
Err(err) => {
trace!("Error decoding gzip encoding: {}", err);
log::trace!("Error decoding gzip encoding: {}", err);
Err(err)
}
},
Expand All @@ -370,7 +370,7 @@ impl ContentEncoder {
ContentEncoder::Deflate(ref mut encoder) => match encoder.write_all(data) {
Ok(_) => Ok(()),
Err(err) => {
trace!("Error decoding deflate encoding: {}", err);
log::trace!("Error decoding deflate encoding: {}", err);
Err(err)
}
},
Expand All @@ -379,7 +379,7 @@ impl ContentEncoder {
ContentEncoder::Zstd(ref mut encoder) => match encoder.write_all(data) {
Ok(_) => Ok(()),
Err(err) => {
trace!("Error decoding ztsd encoding: {}", err);
log::trace!("Error decoding ztsd encoding: {}", err);
Err(err)
}
},
Expand Down
26 changes: 18 additions & 8 deletions actix-http/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Err
use derive_more::{Display, Error, From};
use http::{uri::InvalidUri, StatusCode};

use crate::{body::BoxBody, ws, Response};
use crate::{body::BoxBody, Response};

pub use http::Error as HttpError;

Expand Down Expand Up @@ -61,6 +61,7 @@ impl Error {
Self::new(Kind::Encoder)
}

#[allow(unused)] // used with `ws` feature flag
pub(crate) fn new_ws() -> Self {
Self::new(Kind::Ws)
}
Expand Down Expand Up @@ -139,14 +140,16 @@ impl From<HttpError> for Error {
}
}

impl From<ws::HandshakeError> for Error {
fn from(err: ws::HandshakeError) -> Self {
#[cfg(feature = "ws")]
impl From<crate::ws::HandshakeError> for Error {
fn from(err: crate::ws::HandshakeError) -> Self {
Self::new_ws().with_cause(err)
}
}

impl From<ws::ProtocolError> for Error {
fn from(err: ws::ProtocolError) -> Self {
#[cfg(feature = "ws")]
impl From<crate::ws::ProtocolError> for Error {
fn from(err: crate::ws::ProtocolError) -> Self {
Self::new_ws().with_cause(err)
}
}
Expand Down Expand Up @@ -277,8 +280,9 @@ pub enum PayloadError {
UnknownLength,

/// HTTP/2 payload error.
#[cfg(feature = "http2")]
#[display(fmt = "{}", _0)]
Http2Payload(h2::Error),
Http2Payload(::h2::Error),

/// Generic I/O error.
#[display(fmt = "{}", _0)]
Expand All @@ -293,14 +297,16 @@ impl std::error::Error for PayloadError {
PayloadError::EncodingCorrupted => None,
PayloadError::Overflow => None,
PayloadError::UnknownLength => None,
#[cfg(feature = "http2")]
PayloadError::Http2Payload(err) => Some(err as &dyn std::error::Error),
PayloadError::Io(err) => Some(err as &dyn std::error::Error),
}
}
}

impl From<h2::Error> for PayloadError {
fn from(err: h2::Error) -> Self {
#[cfg(feature = "http2")]
impl From<::h2::Error> for PayloadError {
fn from(err: ::h2::Error) -> Self {
PayloadError::Http2Payload(err)
}
}
Expand Down Expand Up @@ -356,6 +362,7 @@ pub enum DispatchError {

/// HTTP/2 error.
#[display(fmt = "{}", _0)]
#[cfg(feature = "http2")]
H2(h2::Error),

/// The first request did not complete within the specified timeout.
Expand All @@ -379,7 +386,10 @@ impl StdError for DispatchError {
DispatchError::Body(err) => Some(&**err),
DispatchError::Io(err) => Some(err),
DispatchError::Parse(err) => Some(err),

#[cfg(feature = "http2")]
DispatchError::H2(err) => Some(err),

_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion actix-http/src/h2/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ where
DispatchError::SendResponse(err) => {
trace!("Error sending HTTP/2 response: {:?}", err)
}
DispatchError::SendData(err) => warn!("{:?}", err),
DispatchError::SendData(err) => log::warn!("{:?}", err),
DispatchError::ResponseBody(err) => {
error!("Response payload stream error: {:?}", err)
}
Expand Down
2 changes: 1 addition & 1 deletion actix-http/src/h2/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ where
}

Err(err) => {
trace!("H2 handshake error: {}", err);
log::trace!("H2 handshake error: {}", err);
Poll::Ready(Err(err))
}
},
Expand Down
2 changes: 1 addition & 1 deletion actix-http/src/http_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub trait HttpMessage: Sized {
""
}

/// Get content type encoding
/// Get content type encoding.
///
/// UTF-8 is used by default, If request charset is not set.
fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> {
Expand Down
1 change: 1 addition & 0 deletions actix-http/src/keep_alive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl KeepAlive {
!matches!(self, Self::Disabled)
}

#[allow(unused)] // used with `http2` feature flag
pub(crate) fn duration(&self) -> Option<Duration> {
match self {
KeepAlive::Timeout(dur) => Some(*dur),
Expand Down
5 changes: 2 additions & 3 deletions actix-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

#[macro_use]
extern crate log;

pub use ::http::{uri, uri::Uri};
pub use ::http::{Method, StatusCode, Version};

Expand All @@ -39,6 +36,7 @@ pub mod encoding;
pub mod error;
mod extensions;
pub mod h1;
#[cfg(feature = "http2")]
pub mod h2;
pub mod header;
mod helpers;
Expand All @@ -52,6 +50,7 @@ mod requests;
mod responses;
mod service;
pub mod test;
#[cfg(feature = "ws")]
pub mod ws;

pub use self::builder::HttpServiceBuilder;
Expand Down
21 changes: 19 additions & 2 deletions actix-http/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ pub type BoxedPayloadStream = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadErr
#[deprecated(since = "4.0.0", note = "Renamed to `BoxedPayloadStream`.")]
pub type PayloadStream = BoxedPayloadStream;

#[cfg(not(feature = "http2"))]
pin_project! {
/// A streaming payload.
#[project = PayloadProj]
pub enum Payload<S = BoxedPayloadStream> {
None,
H1 { payload: crate::h1::Payload },
Stream { #[pin] payload: S },
}
}

#[cfg(feature = "http2")]
pin_project! {
/// A streaming payload.
#[project = PayloadProj]
Expand All @@ -33,14 +45,16 @@ impl<S> From<crate::h1::Payload> for Payload<S> {
}
}

#[cfg(feature = "http2")]
impl<S> From<crate::h2::Payload> for Payload<S> {
fn from(payload: crate::h2::Payload) -> Self {
Payload::H2 { payload }
}
}

impl<S> From<h2::RecvStream> for Payload<S> {
fn from(stream: h2::RecvStream) -> Self {
#[cfg(feature = "http2")]
impl<S> From<::h2::RecvStream> for Payload<S> {
fn from(stream: ::h2::RecvStream) -> Self {
Payload::H2 {
payload: crate::h2::Payload::new(stream),
}
Expand Down Expand Up @@ -71,7 +85,10 @@ where
match self.project() {
PayloadProj::None => Poll::Ready(None),
PayloadProj::H1 { payload } => Pin::new(payload).poll_next(cx),

#[cfg(feature = "http2")]
PayloadProj::H2 { payload } => Pin::new(payload).poll_next(cx),

PayloadProj::Stream { payload } => payload.poll_next(cx),
}
}
Expand Down
Loading