diff --git a/.pubnub.yml b/.pubnub.yml index 5b80d062..162b638b 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,9 +1,18 @@ name: rust -version: 0.7.0 +version: 0.8.0 schema: 1 scm: github.com/pubnub/rust files: [] changelog: + - date: 2026-06-08 + version: 0.8.0 + changes: + - type: feature + text: "Enable HTTP/2 negotiation on the default `TransportReqwest` by turning on reqwest’s `native-tls-alpn` feature, so ALPN can select `h2` when the origin supports it while preserving HTTP/1.1 fallback." + - type: bug + text: "Fix a Clippy `derivable_impls` lint in `RequestRetryConfiguration` (derive `Default` on the enum instead of a manual impl)." + - type: improvement + text: " Add debug-level protocol logging in async and blocking `TransportReqwest::send()` after each completed request, including HTTP method, path, and the Reqwest-reported protocol version." - date: 2025-10-28 version: 0.7.0 changes: diff --git a/Cargo.toml b/Cargo.toml index ee47bfa0..4c2895fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pubnub" -version = "0.7.0" +version = "0.8.0" edition = "2021" license-file = "LICENSE" authors = ["PubNub "] @@ -94,7 +94,9 @@ serde = { version = "1.0", features = ["derive", "alloc"], optional = true, defa serde_json = { version = "1.0", optional = true, features = ["alloc"], default-features = false } # reqwest -reqwest = { version = "0.12", optional = true } +# `native-tls-alpn` enables ALPN on the default native-tls backend so HTTP/2 +# (`h2`) can be negotiated; without it reqwest falls back to HTTP/1.1. +reqwest = { version = "0.12", optional = true, features = ["native-tls-alpn"] } bytes = { version = "1.4", default-features = false, optional = true } # crypto diff --git a/README.md b/README.md index 55588cfb..bf8613c2 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,11 @@ Add `pubnub` to your Rust project in the `Cargo.toml` file: ```toml # default features [dependencies] -pubnub = "0.7.0" +pubnub = "0.8.0" # all features [dependencies] -pubnub = { version = "0.7.0", features = ["full"] } +pubnub = { version = "0.8.0", features = ["full"] } ``` ### Example @@ -164,11 +164,11 @@ disable them in the `Cargo.toml` file, like so: ```toml # only blocking and access + default features [dependencies] -pubnub = { version = "0.7.0", features = ["blocking", "access"] } +pubnub = { version = "0.8.0", features = ["blocking", "access"] } # only parse_token + default features [dependencies] -pubnub = { version = "0.7.0", features = ["parse_token"] } +pubnub = { version = "0.8.0", features = ["parse_token"] } ``` ### Available features @@ -207,7 +207,7 @@ you need, for example: ```toml [dependencies] -pubnub = { version = "0.7.0", default-features = false, features = ["serde", "publish", +pubnub = { version = "0.8.0", default-features = false, features = ["serde", "publish", "blocking"] } ``` diff --git a/src/core/retry_policy.rs b/src/core/retry_policy.rs index caaf92bd..b0b07391 100644 --- a/src/core/retry_policy.rs +++ b/src/core/retry_policy.rs @@ -48,9 +48,10 @@ pub enum Endpoint { } /// Request retry policy. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Default)] pub enum RequestRetryConfiguration { /// Requests shouldn't be tried again. + #[default] None, /// Retry the request after the same amount of time. @@ -316,12 +317,6 @@ impl RequestRetryConfiguration { } } -impl Default for RequestRetryConfiguration { - fn default() -> Self { - Self::None - } -} - impl From for Endpoint { fn from(value: String) -> Self { match value.as_str() { diff --git a/src/lib.rs b/src/lib.rs index c67ae515..a5635846 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,11 +39,11 @@ //! ```toml //! # default features //! [dependencies] -//! pubnub = "0.7.0" +//! pubnub = "0.8.0" //! //! # all features //! [dependencies] -//! pubnub = { version = "0.7.0", features = ["full"] } +//! pubnub = { version = "0.8.0", features = ["full"] } //! ``` //! //! ### Example @@ -167,11 +167,11 @@ //! ```toml //! # only blocking and access + default features //! [dependencies] -//! pubnub = { version = "0.7.0", features = ["blocking", "access"] } +//! pubnub = { version = "0.8.0", features = ["blocking", "access"] } //! //! # only parse_token + default features //! [dependencies] -//! pubnub = { version = "0.7.0", features = ["parse_token"] } +//! pubnub = { version = "0.8.0", features = ["parse_token"] } //! ``` //! //! ### Available features @@ -210,7 +210,7 @@ //! //! ```toml //! [dependencies] -//! pubnub = { version = "0.7.0", default-features = false, features = ["serde", "publish", +//! pubnub = { version = "0.8.0", default-features = false, features = ["serde", "publish", //! "blocking"] } //! ``` //! diff --git a/src/transport/reqwest.rs b/src/transport/reqwest.rs index c164dfae..cbda3b66 100644 --- a/src/transport/reqwest.rs +++ b/src/transport/reqwest.rs @@ -6,6 +6,8 @@ //! //! It requires the [`reqwest` feature] to be enabled. //! +//! Negotiates HTTP/2 when the origin supports it; otherwise uses HTTP/1.1. +//! //! [`TransportReqwest`]: ./struct.TransportReqwest.html //! [`PubNub API`]: https://www.pubnub.com/docs //! [`reqwest`]: https://docs.rs/reqwest @@ -37,7 +39,7 @@ use crate::{ PubNubClientBuilder, }; use bytes::Bytes; -use log::info; +use log::{debug, info}; use reqwest::{ header::{HeaderMap, HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue}, StatusCode, @@ -83,6 +85,8 @@ impl Transport for TransportReqwest { ); let headers = prepare_headers(&request.headers)?; + let method = request.method.clone(); + let path = request.path.clone(); #[cfg(feature = "std")] let timeout = request.timeout; @@ -116,6 +120,10 @@ impl Transport for TransportReqwest { let headers = result.headers().clone(); let status = result.status(); + debug!( + "Request completed: method={method} path={path} protocol={:?}", + result.version() + ); result .bytes() .await @@ -341,6 +349,8 @@ pub mod blocking { //! //! It requires the [`reqwest` and `blocking` feature] to be enabled. //! + //! Negotiates HTTP/2 when the origin supports it; otherwise uses HTTP/1.1. + //! //! [`TransportReqwest`]: ./struct.TransportReqwest.html //! [`PubNub API`]: https://www.pubnub.com/docs //! [`reqwest`]: https://docs.rs/reqwest @@ -368,7 +378,7 @@ pub mod blocking { transport::reqwest::{create_result, extract_headers, prepare_headers, prepare_url}, PubNubClientBuilder, }; - use log::info; + use log::{debug, info}; /// This struct is used to send requests to the [`PubNub API`] using the /// [`reqwest`] crate. It is used as the transport type for the @@ -407,6 +417,8 @@ pub mod blocking { request.method, request.headers, request_url ); let headers = prepare_headers(&request.headers)?; + let method = request.method.clone(); + let path = request.path.clone(); #[cfg(feature = "std")] let timeout = request.timeout; @@ -439,6 +451,10 @@ pub mod blocking { let headers = result.headers().clone(); let status = result.status(); + debug!( + "Request completed: method={method} path={path} protocol={:?}", + result.version() + ); result .bytes() .map_err(|e| PubNubError::Transport {