HttpClient

Struct HttpClient 

Source
pub struct HttpClient { /* private fields */ }
Expand description

Reusable HTTP client configured via HttpClientBuilder.

§Examples

Build a client with a custom timeout and default headers:

use hyper_custom_cert::{HttpClient, RequestOptions};
use std::time::Duration;
use std::collections::HashMap;

let mut headers = HashMap::new();
headers.insert("x-app".into(), "demo".into());

let client = HttpClient::builder()
    .with_timeout(Duration::from_secs(10))
    .with_default_headers(headers)
    .build();

// Placeholder call; does not perform I/O in this crate.
let _ = client.request_with_options("https://example.com", None);

Implementations§

Source§

impl HttpClient

Source

pub fn new() -> Self

Construct a new client using secure defaults by delegating to the builder. This provides a convenient way to get a functional client without explicit configuration, relying on sensible defaults (e.g., 30-second timeout, no custom CAs).

Source

pub fn builder() -> HttpClientBuilder

Start building a client with explicit configuration. This method exposes the HttpClientBuilder to allow granular control over various client settings like timeouts, default headers, and TLS configurations.

Examples found in repository?
examples/self-signed-certs/main.rs (line 11)
6async fn main() {
7    // Default secure client (uses OS trust store when built with default features)
8    let mut headers = HashMap::new();
9    headers.insert("x-app".into(), "example".into());
10
11    let client = HttpClient::builder()
12        .with_timeout(Duration::from_secs(10))
13        .with_default_headers(headers)
14        .build();
15
16    // Demonstrate a request (now returns HttpResponse with raw body data)
17    let _response = client
18        .request_with_options("https://example.com", None)
19        .await
20        .expect("request should succeed on native targets");
21
22    // Production with rustls + custom Root CA (e.g., self-signed for your private service)
23    // Note: Requires building with: --no-default-features --features rustls
24    #[cfg(feature = "rustls")]
25    {
26        // Option 1: Load CA certificate from raw PEM bytes
27        let ca_pem: &[u8] =
28            b"-----BEGIN CERTIFICATE-----\n...your root ca...\n-----END CERTIFICATE-----\n";
29        let _rustls_client = HttpClient::builder()
30            .with_timeout(Duration::from_secs(10))
31            .with_root_ca_pem(ca_pem)
32            .build();
33        let _ = _rustls_client
34            .request_with_options("https://private.local", None)
35            .await;
36
37        // Option 2: Load CA certificate from a file path
38        // Note: This will panic if the file doesn't exist - ensure your cert file is available
39        // let _rustls_client_from_file = HttpClient::builder()
40        //     .with_timeout(Duration::from_secs(10))
41        //     .with_root_ca_file("path/to/your/root-ca.pem")
42        //     .build();
43        // let _ = _rustls_client_from_file.request("https://private.local");
44    }
45
46    // Local development only: accept invalid/self-signed certs (dangerous)
47    // Build with: --features insecure-dangerous (or with rustls,insecure-dangerous)
48    #[cfg(feature = "insecure-dangerous")]
49    {
50        // Shortcut:
51        let _dev_client = HttpClient::with_self_signed_certs();
52        let _ = _dev_client
53            .request_with_options("https://localhost:8443", None)
54            .await;
55
56        // Or explicit builder method:
57        let _dev_client2 = HttpClient::builder()
58            .insecure_accept_invalid_certs(true)
59            .build();
60        let _ = _dev_client2
61            .request_with_options("https://localhost:8443", None)
62            .await;
63    }
64
65    println!("Example finished. See README for feature flags and commands.");
66}
Source

pub fn with_self_signed_certs() -> Self

Convenience constructor that enables acceptance of self-signed/invalid certificates. This is gated behind the insecure-dangerous feature and intended strictly for development and testing. NEVER enable in production.

§Security Warning

⚠️ CRITICAL SECURITY WARNING ⚠️

This method deliberately bypasses TLS certificate validation, creating a serious security vulnerability to man-in-the-middle attacks. When used:

  • ANY certificate will be accepted, regardless of its validity
  • Expired certificates will be accepted
  • Certificates from untrusted issuers will be accepted
  • Certificates for the wrong domain will be accepted

This is equivalent to calling insecure_accept_invalid_certs(true) on the builder and inherits all of its security implications. See that method’s documentation for more details.

§Intended Use Cases

This method should ONLY be used for:

  • Local development with self-signed certificates
  • Testing environments where security is not a concern
  • Debugging TLS connection issues
§Implementation Details

This is a convenience wrapper that calls:

HttpClient::builder()
    .insecure_accept_invalid_certs(true)
    .build()
Examples found in repository?
examples/self-signed-certs/main.rs (line 51)
6async fn main() {
7    // Default secure client (uses OS trust store when built with default features)
8    let mut headers = HashMap::new();
9    headers.insert("x-app".into(), "example".into());
10
11    let client = HttpClient::builder()
12        .with_timeout(Duration::from_secs(10))
13        .with_default_headers(headers)
14        .build();
15
16    // Demonstrate a request (now returns HttpResponse with raw body data)
17    let _response = client
18        .request_with_options("https://example.com", None)
19        .await
20        .expect("request should succeed on native targets");
21
22    // Production with rustls + custom Root CA (e.g., self-signed for your private service)
23    // Note: Requires building with: --no-default-features --features rustls
24    #[cfg(feature = "rustls")]
25    {
26        // Option 1: Load CA certificate from raw PEM bytes
27        let ca_pem: &[u8] =
28            b"-----BEGIN CERTIFICATE-----\n...your root ca...\n-----END CERTIFICATE-----\n";
29        let _rustls_client = HttpClient::builder()
30            .with_timeout(Duration::from_secs(10))
31            .with_root_ca_pem(ca_pem)
32            .build();
33        let _ = _rustls_client
34            .request_with_options("https://private.local", None)
35            .await;
36
37        // Option 2: Load CA certificate from a file path
38        // Note: This will panic if the file doesn't exist - ensure your cert file is available
39        // let _rustls_client_from_file = HttpClient::builder()
40        //     .with_timeout(Duration::from_secs(10))
41        //     .with_root_ca_file("path/to/your/root-ca.pem")
42        //     .build();
43        // let _ = _rustls_client_from_file.request("https://private.local");
44    }
45
46    // Local development only: accept invalid/self-signed certs (dangerous)
47    // Build with: --features insecure-dangerous (or with rustls,insecure-dangerous)
48    #[cfg(feature = "insecure-dangerous")]
49    {
50        // Shortcut:
51        let _dev_client = HttpClient::with_self_signed_certs();
52        let _ = _dev_client
53            .request_with_options("https://localhost:8443", None)
54            .await;
55
56        // Or explicit builder method:
57        let _dev_client2 = HttpClient::builder()
58            .insecure_accept_invalid_certs(true)
59            .build();
60        let _ = _dev_client2
61            .request_with_options("https://localhost:8443", None)
62            .await;
63    }
64
65    println!("Example finished. See README for feature flags and commands.");
66}
Source§

impl HttpClient

Source

pub async fn request(&self, url: &str) -> Result<HttpResponse, ClientError>

👎Deprecated since 0.4.0: Use request(url, Some(options)) instead

Performs a GET request and returns the raw response body. This method constructs a hyper::Request with the GET method and any default headers configured on the client, then dispatches it via perform_request. Returns HttpResponse with raw body data exposed without any permutations.

§Arguments
  • url - The URL to request
  • options - Optional request options to customize this specific request
§Examples
use hyper_custom_cert::{HttpClient, RequestOptions};
use std::collections::HashMap;

let client = HttpClient::new();

// Basic request with no custom options
let response1 = client.request_with_options("https://example.com", None).await?;

// Request with custom options
let mut headers = HashMap::new();
headers.insert("x-request-id".into(), "abc123".into());
let options = RequestOptions::new().with_headers(headers);
let response2 = client.request_with_options("https://example.com", Some(options)).await?;
Source

pub async fn request_with_options( &self, url: &str, options: Option<RequestOptions>, ) -> Result<HttpResponse, ClientError>

Performs a GET request and returns the raw response body. This method constructs a hyper::Request with the GET method and any default headers configured on the client, then dispatches it via perform_request. Returns HttpResponse with raw body data exposed without any permutations.

§Arguments
  • url - The URL to request
  • options - Optional request options to customize this specific request
§Examples
use hyper_custom_cert::{HttpClient, RequestOptions};
use std::collections::HashMap;

let client = HttpClient::new();

// Basic request with no custom options
let response1 = client.request_with_options("https://example.com", None).await?;

// Request with custom options
let mut headers = HashMap::new();
headers.insert("x-request-id".into(), "abc123".into());
let options = RequestOptions::new().with_headers(headers);
let response2 = client.request_with_options("https://example.com", Some(options)).await?;
Examples found in repository?
examples/self-signed-certs/main.rs (line 18)
6async fn main() {
7    // Default secure client (uses OS trust store when built with default features)
8    let mut headers = HashMap::new();
9    headers.insert("x-app".into(), "example".into());
10
11    let client = HttpClient::builder()
12        .with_timeout(Duration::from_secs(10))
13        .with_default_headers(headers)
14        .build();
15
16    // Demonstrate a request (now returns HttpResponse with raw body data)
17    let _response = client
18        .request_with_options("https://example.com", None)
19        .await
20        .expect("request should succeed on native targets");
21
22    // Production with rustls + custom Root CA (e.g., self-signed for your private service)
23    // Note: Requires building with: --no-default-features --features rustls
24    #[cfg(feature = "rustls")]
25    {
26        // Option 1: Load CA certificate from raw PEM bytes
27        let ca_pem: &[u8] =
28            b"-----BEGIN CERTIFICATE-----\n...your root ca...\n-----END CERTIFICATE-----\n";
29        let _rustls_client = HttpClient::builder()
30            .with_timeout(Duration::from_secs(10))
31            .with_root_ca_pem(ca_pem)
32            .build();
33        let _ = _rustls_client
34            .request_with_options("https://private.local", None)
35            .await;
36
37        // Option 2: Load CA certificate from a file path
38        // Note: This will panic if the file doesn't exist - ensure your cert file is available
39        // let _rustls_client_from_file = HttpClient::builder()
40        //     .with_timeout(Duration::from_secs(10))
41        //     .with_root_ca_file("path/to/your/root-ca.pem")
42        //     .build();
43        // let _ = _rustls_client_from_file.request("https://private.local");
44    }
45
46    // Local development only: accept invalid/self-signed certs (dangerous)
47    // Build with: --features insecure-dangerous (or with rustls,insecure-dangerous)
48    #[cfg(feature = "insecure-dangerous")]
49    {
50        // Shortcut:
51        let _dev_client = HttpClient::with_self_signed_certs();
52        let _ = _dev_client
53            .request_with_options("https://localhost:8443", None)
54            .await;
55
56        // Or explicit builder method:
57        let _dev_client2 = HttpClient::builder()
58            .insecure_accept_invalid_certs(true)
59            .build();
60        let _ = _dev_client2
61            .request_with_options("https://localhost:8443", None)
62            .await;
63    }
64
65    println!("Example finished. See README for feature flags and commands.");
66}
Source

pub async fn post<B: AsRef<[u8]>>( &self, url: &str, body: B, ) -> Result<HttpResponse, ClientError>

👎Deprecated since 0.4.0: Use post_with_options(url, body, Some(options)) instead

Performs a POST request with the given body and returns the raw response. Similar to request, this method builds a hyper::Request for a POST operation, handles the request body conversion to Bytes, and applies default headers before calling perform_request. Returns HttpResponse with raw body data exposed without any permutations.

§Arguments
  • url - The URL to request
  • body - The body content to send with the POST request
  • options - Optional request options to customize this specific request
§Examples
use hyper_custom_cert::{HttpClient, RequestOptions};
use std::collections::HashMap;
use std::time::Duration;

let client = HttpClient::new();

// Basic POST request with no custom options
let response1 = client.post_with_options("https://example.com/api", b"{\"key\":\"value\"}", None).await?;

// POST request with custom options
let mut headers = HashMap::new();
headers.insert("Content-Type".into(), "application/json".into());
let options = RequestOptions::new()
    .with_headers(headers)
    .with_timeout(Duration::from_secs(5));
let response2 = client.post_with_options("https://example.com/api", b"{\"key\":\"value\"}", Some(options)).await?;
Source

pub async fn post_with_options<B: AsRef<[u8]>>( &self, url: &str, body: B, options: Option<RequestOptions>, ) -> Result<HttpResponse, ClientError>

Performs a POST request with the given body and returns the raw response. Similar to request, this method builds a hyper::Request for a POST operation, handles the request body conversion to Bytes, and applies default headers before calling perform_request. Returns HttpResponse with raw body data exposed without any permutations.

§Arguments
  • url - The URL to request
  • body - The body content to send with the POST request
  • options - Optional request options to customize this specific request
§Examples
use hyper_custom_cert::{HttpClient, RequestOptions};
use std::collections::HashMap;
use std::time::Duration;

let client = HttpClient::new();

// Basic POST request with no custom options
let response1 = client.post_with_options("https://example.com/api", b"{\"key\":\"value\"}", None).await?;

// POST request with custom options
let mut headers = HashMap::new();
headers.insert("Content-Type".into(), "application/json".into());
let options = RequestOptions::new()
    .with_headers(headers)
    .with_timeout(Duration::from_secs(5));
let response2 = client.post_with_options("https://example.com/api", b"{\"key\":\"value\"}", Some(options)).await?;

Trait Implementations§

Source§

impl Default for HttpClient

Default construction uses builder defaults.

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more