diff --git a/Cargo.toml b/Cargo.toml index 6fb1fc014..776206b13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "ntex-bytes", "ntex-codec", "ntex-io", + "ntex-http", "ntex-router", "ntex-rt", "ntex-service", @@ -20,6 +21,7 @@ ntex = { path = "ntex" } ntex-bytes = { path = "ntex-bytes" } ntex-codec = { path = "ntex-codec" } ntex-io = { path = "ntex-io" } +ntex-http = { path = "ntex-http" } ntex-router = { path = "ntex-router" } ntex-rt = { path = "ntex-rt" } ntex-service = { path = "ntex-service" } diff --git a/ntex-bytes/src/string.rs b/ntex-bytes/src/string.rs index 6d7cda9f9..62719db25 100644 --- a/ntex-bytes/src/string.rs +++ b/ntex-bytes/src/string.rs @@ -14,6 +14,12 @@ impl ByteString { ByteString(Bytes::new()) } + /// Get a str slice. + #[inline] + pub fn as_str(&self) -> &str { + &*self + } + /// Get a reference to the underlying bytes. #[inline] pub fn as_slice(&self) -> &[u8] { diff --git a/ntex-http/CHANGES.md b/ntex-http/CHANGES.md new file mode 100644 index 000000000..df3c3f464 --- /dev/null +++ b/ntex-http/CHANGES.md @@ -0,0 +1,5 @@ +# Changes + +## [0.1.0] - 2022-xx-xx + +* Move http types to separate crate diff --git a/ntex-http/Cargo.toml b/ntex-http/Cargo.toml new file mode 100644 index 000000000..317a4b0f3 --- /dev/null +++ b/ntex-http/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "ntex-http" +version = "0.1.0" +authors = ["ntex contributors "] +description = "Http types for ntex framework" +keywords = ["network", "framework", "async", "futures"] +homepage = "https://ntex.rs" +repository = "https://github.com/ntex-rs/ntex.git" +documentation = "https://docs.rs/ntex-http/" +categories = ["network-programming", "asynchronous"] +license = "MIT" +edition = "2018" + +[lib] +name = "ntex_http" +path = "src/lib.rs" + +[dependencies] +http = "0.2" +log = "0.4" +fxhash = "0.2.1" diff --git a/ntex-http/LICENSE b/ntex-http/LICENSE new file mode 120000 index 000000000..ea5b60640 --- /dev/null +++ b/ntex-http/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/ntex-http/src/lib.rs b/ntex-http/src/lib.rs new file mode 100644 index 000000000..c0b5d04f8 --- /dev/null +++ b/ntex-http/src/lib.rs @@ -0,0 +1,60 @@ +//! Http protocol support. +// pub mod body; +mod map; + +pub use self::map::HeaderMap; +#[doc(hidden)] +pub use self::map::Value; + +// re-exports +pub use http::header::{HeaderName, HeaderValue}; +pub use http::uri::{self, Uri}; +pub use http::{Method, StatusCode, Version}; + +pub mod error { + pub use http::header::{InvalidHeaderName, InvalidHeaderValue}; + pub use http::method::InvalidMethod; + pub use http::status::InvalidStatusCode; +} + +/// Convert http::HeaderMap to a HeaderMap +impl From for HeaderMap { + fn from(map: http::HeaderMap) -> HeaderMap { + let mut new_map = HeaderMap::with_capacity(map.capacity()); + for (h, v) in map.iter() { + new_map.append(h.clone(), v.clone()); + } + new_map + } +} + +pub mod header { + //! Various http headers + + #[doc(hidden)] + pub use crate::map::{AsName, Either, GetAll, Iter, Value}; + + pub use http::header::{ + HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, + }; + pub use http::header::{ + ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES, + ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, + ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, + ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE, + ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE, ALLOW, ALT_SVC, + AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING, + CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE, + CONTENT_SECURITY_POLICY, CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, + DATE, DNT, ETAG, EXPECT, EXPIRES, FORWARDED, FROM, HOST, IF_MATCH, + IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE, IF_UNMODIFIED_SINCE, LAST_MODIFIED, + LINK, LOCATION, MAX_FORWARDS, ORIGIN, PRAGMA, PROXY_AUTHENTICATE, + PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, PUBLIC_KEY_PINS_REPORT_ONLY, RANGE, REFERER, + REFERRER_POLICY, REFRESH, RETRY_AFTER, SEC_WEBSOCKET_ACCEPT, + SEC_WEBSOCKET_EXTENSIONS, SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, + SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE, STRICT_TRANSPORT_SECURITY, TE, TRAILER, + TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS, USER_AGENT, VARY, VIA, + WARNING, WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS, X_DNS_PREFETCH_CONTROL, + X_FRAME_OPTIONS, X_XSS_PROTECTION, + }; +} diff --git a/ntex/src/http/header/map.rs b/ntex-http/src/map.rs similarity index 95% rename from ntex/src/http/header/map.rs rename to ntex-http/src/map.rs index 40a8c1bfd..ae6e2dbd5 100644 --- a/ntex/src/http/header/map.rs +++ b/ntex-http/src/map.rs @@ -1,9 +1,19 @@ -use std::collections::hash_map::{self, Entry}; +use std::collections::{self, hash_map, hash_map::Entry}; use std::convert::TryFrom; use http::header::{HeaderName, HeaderValue}; -use crate::util::{Either, HashMap}; +type HashMap = collections::HashMap; + +/// Combines two different futures, streams, or sinks having the same associated types into a single +/// type. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum Either { + /// First branch of the type + Left(A), + /// Second branch of the type + Right(B), +} /// A set of HTTP headers /// @@ -16,7 +26,7 @@ pub struct HeaderMap { } #[derive(Debug, Clone)] -pub(crate) enum Value { +pub enum Value { One(HeaderValue), Multi(Vec), } @@ -197,6 +207,11 @@ impl HeaderMap { Iter::new(self.inner.iter()) } + #[doc(hidden)] + pub fn iter_inner(&self) -> hash_map::Iter<'_, HeaderName, Value> { + self.inner.iter() + } + /// An iterator visiting all keys. /// /// The iteration order is arbitrary, but consistent across platforms for diff --git a/ntex-io/src/dispatcher.rs b/ntex-io/src/dispatcher.rs index 9d0e422f4..23373e18e 100644 --- a/ntex-io/src/dispatcher.rs +++ b/ntex-io/src/dispatcher.rs @@ -215,6 +215,7 @@ where DispatchItem::Item(el) } Err(RecvError::KeepAlive) => { + log::trace!("keep-alive error, stopping dispatcher"); slf.st.set(DispatcherState::Stop); DispatchItem::KeepAliveTimeout } @@ -229,10 +230,18 @@ where DispatchItem::WBackPressureEnabled } Err(RecvError::Decoder(err)) => { + log::trace!( + "decoder error, stopping dispatcher: {:?}", + err + ); slf.st.set(DispatcherState::Stop); DispatchItem::DecoderError(err) } Err(RecvError::PeerGone(err)) => { + log::trace!( + "peer is gone, stopping dispatcher: {:?}", + err + ); slf.st.set(DispatcherState::Stop); DispatchItem::Disconnect(err) } diff --git a/ntex-util/src/future/either.rs b/ntex-util/src/future/either.rs index 229df0c64..81fb0805b 100644 --- a/ntex-util/src/future/either.rs +++ b/ntex-util/src/future/either.rs @@ -5,9 +5,9 @@ use std::{error, fmt, future::Future, pin::Pin, task::Context, task::Poll}; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Either { /// First branch of the type - Left(/* #[pin] */ A), + Left(A), /// Second branch of the type - Right(/* #[pin] */ B), + Right(B), } impl Either { diff --git a/ntex/CHANGES.md b/ntex/CHANGES.md index 21adbce04..59a7ac536 100644 --- a/ntex/CHANGES.md +++ b/ntex/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## [0.5.19] - 2022-xx-xx + +* http: move basic types to separeate crate + ## [0.5.18] - 2022-06-03 * http: Refactor client pool management diff --git a/ntex/Cargo.toml b/ntex/Cargo.toml index da8c54826..87a50ca6c 100644 --- a/ntex/Cargo.toml +++ b/ntex/Cargo.toml @@ -49,6 +49,7 @@ async-std = ["ntex-rt/async-std", "ntex-async-std"] [dependencies] ntex-codec = "0.6.2" +ntex-http = "0.1.0" ntex-router = "0.5.1" ntex-service = "0.3.1" ntex-macros = "0.1.3" diff --git a/ntex/src/http/h1/encoder.rs b/ntex/src/http/h1/encoder.rs index a0f9bac44..f0ff4c011 100644 --- a/ntex/src/http/h1/encoder.rs +++ b/ntex/src/http/h1/encoder.rs @@ -3,7 +3,7 @@ use std::{cell::Cell, cmp, io, io::Write, mem, ptr, ptr::copy_nonoverlapping, sl use crate::http::body::BodySize; use crate::http::config::DateService; -use crate::http::header::{map, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING}; +use crate::http::header::{Value, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING}; use crate::http::helpers; use crate::http::message::{ConnectionType, RequestHeadType}; use crate::http::response::Response; @@ -106,10 +106,9 @@ pub(super) trait MessageType: Sized { let extra_headers = self.extra_headers().unwrap_or(&empty_headers); let headers = self .headers() - .inner - .iter() + .iter_inner() .filter(|(name, _)| !extra_headers.contains_key(*name)) - .chain(extra_headers.inner.iter()); + .chain(extra_headers.iter_inner()); // write headers let mut pos = 0; @@ -127,7 +126,7 @@ pub(super) trait MessageType: Sized { } let k = key.as_str().as_bytes(); match value { - map::Value::One(ref val) => { + Value::One(ref val) => { let v = val.as_ref(); let v_len = v.len(); let k_len = k.len(); @@ -153,7 +152,7 @@ pub(super) trait MessageType: Sized { pos += len; remaining -= len; } - map::Value::Multi(ref vec) => { + Value::Multi(ref vec) => { for val in vec { let v = val.as_ref(); let v_len = v.len(); diff --git a/ntex/src/http/header/mod.rs b/ntex/src/http/header.rs similarity index 55% rename from ntex/src/http/header/mod.rs rename to ntex/src/http/header.rs index fd94a7d24..276ebba8e 100644 --- a/ntex/src/http/header/mod.rs +++ b/ntex/src/http/header.rs @@ -2,11 +2,10 @@ pub use http::header::{HeaderName, HeaderValue, InvalidHeaderValue}; -pub(crate) mod map; - -pub use self::map::HeaderMap; +pub use http::header::*; #[doc(hidden)] -pub use self::map::{AsName, GetAll}; +pub use ntex_http::header::{AsName, GetAll, Value}; +pub use ntex_http::HeaderMap; /// Represents supported types of content encodings #[derive(Copy, Clone, PartialEq, Debug)] @@ -69,37 +68,6 @@ impl<'a> From<&'a str> for ContentEncoding { } } -/// Convert http::HeaderMap to a HeaderMap -impl From for HeaderMap { - fn from(map: http::HeaderMap) -> HeaderMap { - let mut new_map = HeaderMap::with_capacity(map.capacity()); - for (h, v) in map.iter() { - new_map.append(h.clone(), v.clone()); - } - new_map - } -} - -pub use http::header::{ - ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES, - ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, - ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, - ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE, ACCESS_CONTROL_REQUEST_HEADERS, - ACCESS_CONTROL_REQUEST_METHOD, AGE, ALLOW, ALT_SVC, AUTHORIZATION, CACHE_CONTROL, - CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, - CONTENT_LOCATION, CONTENT_RANGE, CONTENT_SECURITY_POLICY, - CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE, DNT, ETAG, EXPECT, - EXPIRES, FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE, - IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS, ORIGIN, PRAGMA, - PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, PUBLIC_KEY_PINS_REPORT_ONLY, - RANGE, REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER, SEC_WEBSOCKET_ACCEPT, - SEC_WEBSOCKET_EXTENSIONS, SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, - SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE, STRICT_TRANSPORT_SECURITY, TE, TRAILER, - TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS, USER_AGENT, VARY, VIA, WARNING, - WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS, X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS, - X_XSS_PROTECTION, -}; - #[cfg(test)] mod tests { use super::*; diff --git a/ntex/src/http/mod.rs b/ntex/src/http/mod.rs index 16fbcccbc..29d79bb36 100644 --- a/ntex/src/http/mod.rs +++ b/ntex/src/http/mod.rs @@ -26,7 +26,6 @@ pub use self::builder::HttpServiceBuilder; pub use self::client::Client; pub use self::config::{DateService, KeepAlive, ServiceConfig}; pub use self::error::ResponseError; -pub use self::header::HeaderMap; pub use self::httpmessage::HttpMessage; pub use self::message::{ConnectionType, RequestHead, RequestHeadType, ResponseHead}; pub use self::payload::{Payload, PayloadStream}; @@ -36,5 +35,5 @@ pub use self::service::HttpService; pub use crate::io::types::HttpProtocol; // re-exports -pub use http::uri::{self, Uri}; -pub use http::{Method, StatusCode, Version}; +pub use ntex_http::uri::{self, Uri}; +pub use ntex_http::{HeaderMap, Method, StatusCode, Version}; diff --git a/ntex/src/ws/proto.rs b/ntex/src/ws/proto.rs index 126792e04..eeb404498 100644 --- a/ntex/src/ws/proto.rs +++ b/ntex/src/ws/proto.rs @@ -259,6 +259,7 @@ mod test { opcode_from!(OpCode::Pong => 10); } + #[cfg(not(target_os = "macos"))] #[test] #[should_panic] fn test_from_opcode_debug() { diff --git a/ntex/tests/server.rs b/ntex/tests/server.rs index cf8cbc9fb..58351b44e 100644 --- a/ntex/tests/server.rs +++ b/ntex/tests/server.rs @@ -187,6 +187,7 @@ fn test_on_worker_start() { #[test] #[cfg(feature = "tokio")] +#[cfg(not(target_os = "macos"))] #[allow(unreachable_code)] fn test_panic_in_worker() { let counter = Arc::new(AtomicUsize::new(0));