Skip to content
Open
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
4 changes: 4 additions & 0 deletions ntex-bytes/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes

## [1.5.3] (2026-03-26)

* Add impl From<ByteString> for Bytes

## [1.5.2] (2026-03-01)

* Add io::Write impl to BytesMut
Expand Down
2 changes: 1 addition & 1 deletion ntex-bytes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ntex-bytes"
version = "1.5.2"
version = "1.5.3"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Types and traits for working with bytes (bytes crate fork)"
documentation = "https://docs.rs/ntex-bytes"
Expand Down
6 changes: 6 additions & 0 deletions ntex-bytes/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,12 @@ impl From<&Bytes> for Bytes {
}
}

impl From<crate::ByteString> for Bytes {
fn from(src: crate::ByteString) -> Bytes {
src.into_bytes()
}
}

impl From<Vec<u8>> for Bytes {
/// Convert a `Vec` into a `Bytes`
fn from(src: Vec<u8>) -> Bytes {
Expand Down
4 changes: 2 additions & 2 deletions ntex-tls/examples/webclient.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use ntex::SharedCfg;
use ntex::client::{Client, Connector, error::ClientError};
use ntex::{SharedCfg, error::Error};
use tls_openssl::ssl::{self, SslMethod, SslVerifyMode};

#[ntex::main]
async fn main() -> Result<(), ClientError> {
async fn main() -> Result<(), Error<ClientError>> {
env_logger::init();
println!("Connecting to openssl webserver: 127.0.0.1:8443");

Expand Down
2 changes: 2 additions & 0 deletions ntex/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changes

* Use ntex_error::Error for http client

## [3.7.0] - 2026-03-26

* Rename client::error::SendRequestError to ClientError
Expand Down
4 changes: 2 additions & 2 deletions ntex/examples/client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ntex::client::{Client, error::ClientError};
use ntex::{client::Client, client::error::ClientError, error::Error};

#[ntex::main]
async fn main() -> Result<(), ClientError> {
async fn main() -> Result<(), Error<ClientError>> {
env_logger::init();

let client = Client::new().await;
Expand Down
4 changes: 2 additions & 2 deletions ntex/src/client/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use base64::{Engine, engine::general_purpose::STANDARD as base64};
use crate::http::error::HttpError;
use crate::http::header::{self, HeaderName, HeaderValue};
use crate::service::{Identity, Middleware, Service, ServiceFactory, Stack, boxed};
use crate::{SharedCfg, time::Millis};
use crate::{SharedCfg, error::Error, time::Millis};

use super::error::{ClientBuilderError, ClientError};
use super::sender::Sender;
Expand Down Expand Up @@ -202,7 +202,7 @@ impl<M> ClientBuilder<M> {
where
T: Into<SharedCfg>,
M: Middleware<Sender, ClientConfig>,
M::Service: Service<ServiceRequest, Response = ServiceResponse, Error = ClientError>
M::Service: Service<ServiceRequest, Response = ServiceResponse, Error = Error<ClientError>>
+ 'static,
{
let cfg = cfg.into();
Expand Down
4 changes: 2 additions & 2 deletions ntex/src/client/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{fmt, time};
use crate::http::body::Body;
use crate::http::{Payload, ResponseHead, Version};
use crate::io::{IoBoxed, types::HttpProtocol};
use crate::time::Millis;
use crate::{error::Error, time::Millis};

use super::{ClientRawRequest, error::ClientError, h1proto, h2proto, pool::Acquired};

Expand Down Expand Up @@ -93,7 +93,7 @@ impl Connection {
mut req: ClientRawRequest,
body: Body,
timeout: Millis,
) -> Result<(ResponseHead, Payload), ClientError> {
) -> Result<(ResponseHead, Payload), Error<ClientError>> {
match self.io.take().unwrap() {
ConnectionType::H1(io) => {
req.head.version = Version::HTTP_11;
Expand Down
101 changes: 62 additions & 39 deletions ntex/src/client/connector.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
use std::{error::Error, task::Context, time::Duration};
use std::{error::Error as StdError, task::Context, time::Duration};

use crate::connect::{Connect as TcpConnect, Connector as TcpConnector};
use crate::connect::{Connect as TcpConnect, Connector2 as TcpConnector};
use crate::error::{Error, ErrorMapping, with_service};
use crate::service::{Service, ServiceCtx, ServiceFactory, apply_fn_factory, boxed};
use crate::{SharedCfg, http::Uri, io::IoBoxed, time::Seconds, util::join};

use super::{Connect, Connection, error::ConnectError, pool::ConnectionPool};
use super::error::{ClientError, ConnectError};
use super::{Connect, Connection, pool::ConnectionPool};

#[cfg(feature = "openssl")]
use tls_openssl::ssl::SslConnector as OpensslConnector;

#[cfg(feature = "rustls")]
use tls_rustls::ClientConfig;

type BoxedConnector =
boxed::BoxServiceFactory<SharedCfg, Connect, IoBoxed, ConnectError, Box<dyn Error>>;
type BoxedConnector = boxed::BoxServiceFactory<
SharedCfg,
Connect,
IoBoxed,
Error<ConnectError>,
Box<dyn StdError>,
>;

#[derive(Debug)]
/// Manages http client network connectivity.
Expand Down Expand Up @@ -49,8 +56,8 @@ impl Connector {
svc.call(TcpConnect::new(msg.uri).set_addr(msg.addr)).await
})
.map(IoBoxed::from)
.map_err(ConnectError::from)
.map_init_err(|e| Box::new(e) as Box<dyn Error>),
.map_err(|e| e.map(ConnectError::from))
.map_init_err(|e| Box::new(e) as Box<dyn StdError>),
),
secure_svc: None,
conn_lifetime: Duration::from_secs(75),
Expand Down Expand Up @@ -96,18 +103,18 @@ impl Connector {
#[cfg(feature = "openssl")]
/// Use openssl connector for secured connections.
pub fn openssl(self, connector: OpensslConnector) -> Self {
use crate::connect::openssl::SslConnector;
use crate::connect::openssl::SslConnector2;

self.secure_connector(SslConnector::new(connector))
self.secure_connector(SslConnector2::new(connector))
}

#[must_use]
#[cfg(feature = "rustls")]
/// Use rustls connector for secured connections.
pub fn rustls(self, connector: ClientConfig) -> Self {
use crate::connect::rustls::TlsConnector;
use crate::connect::rustls::TlsConnector2;

self.secure_connector(TlsConnector::new(connector))
self.secure_connector(TlsConnector2::new(connector))
}

#[must_use]
Expand Down Expand Up @@ -147,18 +154,21 @@ impl Connector {
/// Use custom connector to open un-secured connections.
pub fn connector<T>(mut self, connector: T) -> Self
where
T: ServiceFactory<TcpConnect<Uri>, SharedCfg, Error = crate::connect::ConnectError>
+ 'static,
T::InitError: Error,
T: ServiceFactory<
TcpConnect<Uri>,
SharedCfg,
Error = Error<crate::connect::ConnectError>,
> + 'static,
T::InitError: StdError,
IoBoxed: From<T::Response>,
{
self.svc = boxed::factory(
apply_fn_factory(connector, async move |msg: Connect, svc| {
svc.call(TcpConnect::new(msg.uri).set_addr(msg.addr)).await
})
.map(IoBoxed::from)
.map_err(ConnectError::from)
.map_init_err(|e| Box::new(e) as Box<dyn Error>),
.map_err(|e| e.map(ConnectError::from))
.map_init_err(|e| Box::new(e) as Box<dyn StdError>),
);
self
}
Expand All @@ -167,28 +177,31 @@ impl Connector {
/// Use custom connector to open secure connections.
pub fn secure_connector<T>(mut self, connector: T) -> Self
where
T: ServiceFactory<TcpConnect<Uri>, SharedCfg, Error = crate::connect::ConnectError>
+ 'static,
T::InitError: Error,
T: ServiceFactory<
TcpConnect<Uri>,
SharedCfg,
Error = Error<crate::connect::ConnectError>,
> + 'static,
T::InitError: StdError,
IoBoxed: From<T::Response>,
{
self.secure_svc = Some(boxed::factory(
apply_fn_factory(connector, async move |msg: Connect, svc| {
svc.call(TcpConnect::new(msg.uri).set_addr(msg.addr)).await
})
.map(IoBoxed::from)
.map_err(ConnectError::from)
.map_init_err(|e| Box::new(e) as Box<dyn Error>),
.map_err(|e| e.map(ConnectError::from))
.map_init_err(|e| Box::new(e) as Box<dyn StdError>),
));
self
}
}

impl ServiceFactory<Connect, SharedCfg> for Connector {
type Response = Connection;
type Error = ConnectError;
type Error = Error<ClientError>;
type Service = ConnectorService;
type InitError = Box<dyn Error>;
type InitError = Box<dyn StdError>;

async fn create(&self, cfg: SharedCfg) -> Result<Self::Service, Self::InitError> {
let ssl_pool = if let Some(ref svc) = self.secure_svc {
Expand All @@ -207,39 +220,44 @@ impl ServiceFactory<Connect, SharedCfg> for Connector {
self.conn_lifetime,
self.conn_keep_alive,
self.limit,
cfg,
cfg.clone(),
);
Ok(ConnectorService { tcp_pool, ssl_pool })
Ok(ConnectorService {
cfg,
tcp_pool,
ssl_pool,
})
}
}

/// Manages http client network connectivity.
#[derive(Clone, Debug)]
pub struct ConnectorService {
cfg: SharedCfg,
tcp_pool: ConnectionPool,
ssl_pool: Option<ConnectionPool>,
}

impl Service<Connect> for ConnectorService {
type Response = Connection;
type Error = ConnectError;
type Error = Error<ClientError>;

#[inline]
async fn ready(&self, ctx: ServiceCtx<'_, Self>) -> Result<(), Self::Error> {
if let Some(ref ssl_pool) = self.ssl_pool {
let (r1, r2) = join(ctx.ready(&self.tcp_pool), ctx.ready(ssl_pool)).await;
r1?;
r2
r1.into_error()?;
r2.into_error()
} else {
ctx.ready(&self.tcp_pool).await
ctx.ready(&self.tcp_pool).await.into_error()
}
}

#[inline]
fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> {
self.tcp_pool.poll(cx)?;
self.tcp_pool.poll(cx).into_error()?; //.map_err(ClientError::from)?;
if let Some(ref ssl_pool) = self.ssl_pool {
ssl_pool.poll(cx)?;
ssl_pool.poll(cx).into_error()?; //map_err(ClientError::from)?;
}
Ok(())
}
Expand All @@ -256,16 +274,21 @@ impl Service<Connect> for ConnectorService {
req: Connect,
ctx: ServiceCtx<'_, Self>,
) -> Result<Self::Response, Self::Error> {
match req.uri.scheme_str() {
Some("https" | "wss") => {
if let Some(ref conn) = self.ssl_pool {
ctx.call(conn, req).await
} else {
Err(ConnectError::SslIsNotSupported)
with_service(self.cfg.service(), async {
match req.uri.scheme_str() {
Some("https" | "wss") => {
if let Some(ref conn) = self.ssl_pool {
ctx.call(conn, req).await.into_error()
} else {
Err(Error::from(ClientError::from(
ConnectError::SslIsNotSupported,
)))
}
}
_ => ctx.call(&self.tcp_pool, req).await.into_error(),
}
_ => ctx.call(&self.tcp_pool, req).await,
}
})
.await
}
}

Expand Down
Loading
Loading