mirror of
https://github.com/seemueller-io/hyper-custom-cert.git
synced 2025-09-08 22:46:45 +00:00
Ensure the all the actions defined in the ci.yml workflow pass locally.
This commit is contained in:
1219
Cargo.lock
generated
Normal file
1219
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
#[cfg(feature = "rustls")]
|
||||
use std::fs;
|
||||
#[cfg(feature = "rustls")]
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -265,15 +267,19 @@ impl HttpClientBuilder {
|
||||
/// ```
|
||||
#[cfg(feature = "rustls")]
|
||||
pub fn with_root_ca_file<P: AsRef<Path>>(mut self, path: P) -> Self {
|
||||
let pem_bytes = fs::read(path.as_ref())
|
||||
.unwrap_or_else(|e| panic!("Failed to read CA certificate file '{}': {}",
|
||||
path.as_ref().display(), e));
|
||||
let pem_bytes = fs::read(path.as_ref()).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Failed to read CA certificate file '{}': {}",
|
||||
path.as_ref().display(),
|
||||
e
|
||||
)
|
||||
});
|
||||
self.root_ca_pem = Some(pem_bytes);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure certificate pinning using SHA256 fingerprints for additional security.
|
||||
///
|
||||
///
|
||||
/// Certificate pinning provides an additional layer of security beyond CA validation
|
||||
/// by verifying that the server's certificate matches one of the provided fingerprints.
|
||||
/// This helps protect against compromised CAs and man-in-the-middle attacks.
|
||||
@@ -303,7 +309,7 @@ impl HttpClientBuilder {
|
||||
/// 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00,
|
||||
/// 0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf6, 0x07, 0x18
|
||||
/// ];
|
||||
///
|
||||
///
|
||||
/// let pin2: [u8; 32] = [
|
||||
/// 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
|
||||
/// 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
|
||||
@@ -397,7 +403,7 @@ mod tests {
|
||||
// Create a temporary file with test certificate content
|
||||
let temp_dir = std::env::temp_dir();
|
||||
let cert_file = temp_dir.join("test-ca.pem");
|
||||
|
||||
|
||||
let test_cert = b"-----BEGIN CERTIFICATE-----
|
||||
MIICxjCCAa4CAQAwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAe
|
||||
Fw0yNTA4MTQwMDAwMDBaFw0yNjA4MTQwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3Qg
|
||||
@@ -407,13 +413,12 @@ Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTest...
|
||||
// Write test certificate to temporary file
|
||||
{
|
||||
let mut file = fs::File::create(&cert_file).expect("Failed to create temp cert file");
|
||||
file.write_all(test_cert).expect("Failed to write cert to temp file");
|
||||
file.write_all(test_cert)
|
||||
.expect("Failed to write cert to temp file");
|
||||
}
|
||||
|
||||
// Test that the builder can read the certificate file
|
||||
let client = HttpClient::builder()
|
||||
.with_root_ca_file(&cert_file)
|
||||
.build();
|
||||
let client = HttpClient::builder().with_root_ca_file(&cert_file).build();
|
||||
|
||||
// Verify the certificate was loaded
|
||||
assert!(client.root_ca_pem.is_some());
|
||||
|
@@ -1,39 +1,35 @@
|
||||
//! Integration tests for default features (native-tls only)
|
||||
//!
|
||||
//!
|
||||
//! These tests verify that the library works correctly with only the default
|
||||
//! features enabled (native-tls backend using OS trust store).
|
||||
|
||||
use hyper_custom_cert::{HttpClient, HttpClientBuilder};
|
||||
use hyper_custom_cert::HttpClient;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
fn default_client_creation() {
|
||||
// Test that we can create a client with default features
|
||||
let client = HttpClient::new();
|
||||
|
||||
let _client = HttpClient::new();
|
||||
|
||||
// Basic smoke test - the client should be created successfully
|
||||
// In a real scenario, this would make an actual HTTP request
|
||||
assert!(true); // Placeholder - client creation succeeded
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_client_from_builder() {
|
||||
// Test builder pattern with default features
|
||||
let client = HttpClient::builder().build();
|
||||
|
||||
let _client = HttpClient::builder().build();
|
||||
|
||||
// Verify builder works with default features
|
||||
assert!(true); // Placeholder - builder succeeded
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builder_with_timeout() {
|
||||
// Test timeout configuration with default features
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(30))
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - timeout configuration succeeded
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -42,12 +38,8 @@ fn builder_with_headers() {
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("User-Agent".to_string(), "test-agent".to_string());
|
||||
headers.insert("Accept".to_string(), "application/json".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
.with_default_headers(headers)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - header configuration succeeded
|
||||
|
||||
let _client = HttpClient::builder().with_default_headers(headers).build();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -55,25 +47,22 @@ fn builder_combined_configuration() {
|
||||
// Test combining multiple configuration options with default features
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("Custom-Header".to_string(), "custom-value".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(45))
|
||||
.with_default_headers(headers)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - combined configuration succeeded
|
||||
}
|
||||
|
||||
#[cfg(feature = "native-tls")]
|
||||
#[test]
|
||||
fn native_tls_specific_functionality() {
|
||||
// Test functionality that's specific to native-tls backend
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(10))
|
||||
.build();
|
||||
|
||||
|
||||
// This test should only run when native-tls feature is enabled
|
||||
assert!(true); // Placeholder - native-tls specific test
|
||||
}
|
||||
|
||||
// Test that methods requiring other features are not available
|
||||
@@ -82,29 +71,28 @@ fn rustls_methods_not_available() {
|
||||
// This is a compile-time test - if rustls feature is not enabled,
|
||||
// rustls-specific methods should not be available
|
||||
let _builder = HttpClient::builder();
|
||||
|
||||
|
||||
// The following would cause compilation errors if rustls feature is not enabled:
|
||||
// builder.with_root_ca_pem(b"test");
|
||||
// builder.with_root_ca_file("test.pem");
|
||||
// builder.with_pinned_cert_sha256(vec![[0u8; 32]]);
|
||||
|
||||
assert!(true); // If this compiles, the test passes
|
||||
|
||||
// If this compiles, the test passes
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insecure_methods_not_available() {
|
||||
// Test that insecure methods are not available without the feature
|
||||
let _builder = HttpClient::builder();
|
||||
|
||||
|
||||
// The following would cause compilation errors if insecure-dangerous feature is not enabled:
|
||||
// builder.insecure_accept_invalid_certs(true);
|
||||
|
||||
assert!(true); // If this compiles, the test passes
|
||||
|
||||
// If this compiles, the test passes
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_client_static_method() {
|
||||
// Test the static convenience method
|
||||
let client = HttpClient::default();
|
||||
assert!(true); // Placeholder - default() method succeeded
|
||||
}
|
||||
let _client = HttpClient::default();
|
||||
}
|
||||
|
@@ -1,14 +1,21 @@
|
||||
//! Integration tests for various feature combinations
|
||||
//!
|
||||
//!
|
||||
//! These tests verify that the library works correctly with different
|
||||
//! combinations of features enabled/disabled, ensuring proper conditional
|
||||
//! compilation and feature interactions.
|
||||
|
||||
use hyper_custom_cert::{HttpClient, HttpClientBuilder};
|
||||
use hyper_custom_cert::HttpClient;
|
||||
#[cfg(any(
|
||||
all(feature = "rustls", feature = "insecure-dangerous"),
|
||||
all(feature = "native-tls", feature = "insecure-dangerous"),
|
||||
not(any(feature = "rustls", feature = "insecure-dangerous")),
|
||||
all(feature = "native-tls", feature = "rustls", feature = "insecure-dangerous")
|
||||
))]
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
// Test CA certificate for combination tests
|
||||
#[allow(dead_code)]
|
||||
const TEST_CA_PEM: &[u8] = b"-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIJAKoK/heBjcOuMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
@@ -23,32 +30,31 @@ CgKCAQEAuuExKtKjKEw91uR8gqyUZx+wW3qZjUHq3oLe+RxbEUVFWApwrKE3XxKJ
|
||||
#[test]
|
||||
fn rustls_and_insecure_combination() {
|
||||
// Test combining rustls custom CA with insecure certificate acceptance
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - rustls + insecure combination
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rustls", feature = "insecure-dangerous"))]
|
||||
#[test]
|
||||
fn rustls_pinning_and_insecure_combination() {
|
||||
// Test combining certificate pinning with insecure mode (unusual but valid)
|
||||
let pins = vec![
|
||||
[0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00,
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08],
|
||||
];
|
||||
|
||||
let client = HttpClient::builder()
|
||||
let pins = vec![[
|
||||
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
0x07, 0x08,
|
||||
]];
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_pinned_cert_sha256(pins)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.with_timeout(Duration::from_secs(30))
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - pinning + insecure combination
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rustls", feature = "insecure-dangerous"))]
|
||||
@@ -57,10 +63,10 @@ fn full_rustls_insecure_configuration() {
|
||||
// Test using all rustls and insecure features together
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("X-Custom".to_string(), "test".to_string());
|
||||
|
||||
|
||||
let pins = vec![[0u8; 32]];
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(45))
|
||||
.with_default_headers(headers)
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
@@ -68,8 +74,8 @@ fn full_rustls_insecure_configuration() {
|
||||
.with_pinned_cert_sha256(pins)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - full rustls + insecure configuration
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test with native-tls + insecure-dangerous (default + insecure)
|
||||
@@ -77,12 +83,12 @@ fn full_rustls_insecure_configuration() {
|
||||
#[test]
|
||||
fn native_tls_and_insecure_combination() {
|
||||
// Test combining native-tls (default) with insecure mode
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(20))
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - native-tls + insecure combination
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "native-tls", feature = "insecure-dangerous"))]
|
||||
@@ -92,13 +98,13 @@ fn native_tls_insecure_with_headers() {
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("Authorization".to_string(), "Bearer test".to_string());
|
||||
headers.insert("Content-Type".to_string(), "application/json".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_default_headers(headers)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - native-tls + insecure with headers
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test with no optional features (base functionality only)
|
||||
@@ -106,11 +112,11 @@ fn native_tls_insecure_with_headers() {
|
||||
#[test]
|
||||
fn minimal_feature_set() {
|
||||
// Test with only the default native-tls feature
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(30))
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - minimal feature set
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "rustls", feature = "insecure-dangerous")))]
|
||||
@@ -119,46 +125,54 @@ fn minimal_with_headers_only() {
|
||||
// Test minimal feature set with headers configuration
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("User-Agent".to_string(), "minimal-client".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_default_headers(headers)
|
||||
.with_timeout(Duration::from_millis(5000))
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - minimal with headers
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test with all features enabled
|
||||
#[cfg(all(feature = "native-tls", feature = "rustls", feature = "insecure-dangerous"))]
|
||||
#[cfg(all(
|
||||
feature = "native-tls",
|
||||
feature = "rustls",
|
||||
feature = "insecure-dangerous"
|
||||
))]
|
||||
#[test]
|
||||
fn all_features_enabled() {
|
||||
// Test when all features are available
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("X-All-Features".to_string(), "enabled".to_string());
|
||||
|
||||
|
||||
let pins = vec![[0x42; 32]];
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(60))
|
||||
.with_default_headers(headers)
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.with_pinned_cert_sha256(pins)
|
||||
.insecure_accept_invalid_certs(false) // Safe default even with insecure available
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - all features enabled
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "native-tls", feature = "rustls", feature = "insecure-dangerous"))]
|
||||
#[cfg(all(
|
||||
feature = "native-tls",
|
||||
feature = "rustls",
|
||||
feature = "insecure-dangerous"
|
||||
))]
|
||||
#[test]
|
||||
fn all_features_insecure_enabled() {
|
||||
// Test all features with insecure mode actually enabled
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM) // Use PEM instead of file for CI/CD compatibility
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - all features with insecure enabled
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test feature availability at compile time
|
||||
@@ -166,27 +180,24 @@ fn all_features_insecure_enabled() {
|
||||
fn feature_availability_check() {
|
||||
// This test documents which features are available at compile time
|
||||
let _client = HttpClient::builder();
|
||||
|
||||
|
||||
// Always available (default)
|
||||
let _default_client = HttpClient::new();
|
||||
let _builder = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(10));
|
||||
|
||||
let _builder = HttpClient::builder().with_timeout(Duration::from_secs(10));
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
{
|
||||
// rustls features should be available
|
||||
let _rustls_client = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM);
|
||||
let _rustls_client = HttpClient::builder().with_root_ca_pem(TEST_CA_PEM);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
{
|
||||
// insecure features should be available
|
||||
let _insecure_client = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(true);
|
||||
let _insecure_client = HttpClient::builder().insecure_accept_invalid_certs(true);
|
||||
}
|
||||
|
||||
assert!(true); // Feature availability test completed
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test builder method chaining with different feature combinations
|
||||
@@ -195,13 +206,13 @@ fn feature_availability_check() {
|
||||
fn rustls_method_chaining() {
|
||||
// Test method chaining with rustls features
|
||||
// Note: Using only PEM method to avoid file I/O in tests
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(30))
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.with_root_ca_pem(TEST_CA_PEM) // Chain multiple PEM calls instead of file
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - rustls method chaining
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
@@ -210,25 +221,25 @@ fn insecure_method_chaining() {
|
||||
// Test method chaining with insecure features
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("Test".to_string(), "chaining".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_millis(1000))
|
||||
.with_default_headers(headers)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure method chaining
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test error conditions with different feature combinations
|
||||
#[test]
|
||||
fn basic_error_handling() {
|
||||
// Test basic error handling regardless of features
|
||||
let client = HttpClient::new();
|
||||
|
||||
let _client = HttpClient::new();
|
||||
|
||||
// This would test actual error scenarios in a real implementation
|
||||
// For now, just verify the client was created successfully
|
||||
assert!(true); // Placeholder - basic error handling
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rustls", feature = "insecure-dangerous"))]
|
||||
@@ -238,7 +249,7 @@ fn complex_configuration_order() {
|
||||
let pins = vec![[1u8; 32], [2u8; 32]];
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("Order".to_string(), "test".to_string());
|
||||
|
||||
|
||||
// Configuration in one order
|
||||
let client1 = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(true)
|
||||
@@ -247,7 +258,7 @@ fn complex_configuration_order() {
|
||||
.with_timeout(Duration::from_secs(15))
|
||||
.with_default_headers(headers.clone())
|
||||
.build();
|
||||
|
||||
|
||||
// Configuration in different order
|
||||
let client2 = HttpClient::builder()
|
||||
.with_default_headers(headers)
|
||||
@@ -256,6 +267,6 @@ fn complex_configuration_order() {
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - configuration order test
|
||||
}
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
@@ -1,47 +1,45 @@
|
||||
//! Integration tests for insecure-dangerous features
|
||||
//!
|
||||
//!
|
||||
//! These tests verify that the library works correctly with the insecure-dangerous
|
||||
//! feature enabled. This feature should ONLY be used for development and testing.
|
||||
//!
|
||||
//!
|
||||
//! ⚠️ WARNING: The insecure-dangerous feature disables important security checks.
|
||||
//! Never use this in production environments!
|
||||
|
||||
use hyper_custom_cert::{HttpClient, HttpClientBuilder};
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
use hyper_custom_cert::HttpClient;
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
#[test]
|
||||
fn insecure_accept_invalid_certs_enabled() {
|
||||
// Test enabling insecure certificate acceptance (development only!)
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure mode enabled
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
#[test]
|
||||
fn insecure_accept_invalid_certs_disabled() {
|
||||
// Test explicitly disabling insecure certificate acceptance
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(false)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure mode disabled
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
#[test]
|
||||
fn insecure_with_timeout_configuration() {
|
||||
// Test insecure mode combined with timeout configuration
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(30))
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure mode with timeout
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
@@ -51,13 +49,13 @@ fn insecure_with_headers_configuration() {
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("X-Test-Header".to_string(), "test-value".to_string());
|
||||
headers.insert("Accept".to_string(), "application/json".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_default_headers(headers)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure mode with headers
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
@@ -66,14 +64,14 @@ fn insecure_combined_configuration() {
|
||||
// Test insecure mode with multiple configuration options
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("User-Agent".to_string(), "test-insecure-client".to_string());
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(60))
|
||||
.with_default_headers(headers)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure combined configuration
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "insecure-dangerous", feature = "rustls"))]
|
||||
@@ -88,13 +86,13 @@ MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAuuExKtKjKEw91uR8gqyUZx+wW3qZjUHq3oLe+RxbEUVFWApwrKE3XxKJ
|
||||
-----END CERTIFICATE-----";
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure with rustls CA
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "insecure-dangerous", feature = "rustls"))]
|
||||
@@ -102,22 +100,22 @@ CgKCAQEAuuExKtKjKEw91uR8gqyUZx+wW3qZjUHq3oLe+RxbEUVFWApwrKE3XxKJ
|
||||
fn insecure_with_certificate_pinning() {
|
||||
// Test insecure mode with certificate pinning (unusual but possible combination)
|
||||
let pins = vec![[0u8; 32]]; // Test pin
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_pinned_cert_sha256(pins)
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - insecure with cert pinning
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
#[test]
|
||||
fn insecure_static_convenience_method() {
|
||||
// Test the static convenience method for self-signed certs
|
||||
let client = HttpClient::with_self_signed_certs();
|
||||
|
||||
assert!(true); // Placeholder - static insecure method
|
||||
let _client = HttpClient::with_self_signed_certs();
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "insecure-dangerous")]
|
||||
@@ -127,17 +125,17 @@ fn insecure_multiple_configurations() {
|
||||
let client1 = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
|
||||
let client2 = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(false)
|
||||
.build();
|
||||
|
||||
|
||||
let client3 = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(10))
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - multiple insecure configurations
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test that runs only when insecure-dangerous feature is NOT enabled
|
||||
@@ -146,14 +144,14 @@ fn insecure_multiple_configurations() {
|
||||
fn insecure_methods_not_available_without_feature() {
|
||||
// This test should only compile and run when insecure-dangerous feature is disabled
|
||||
let _builder = HttpClient::builder();
|
||||
|
||||
|
||||
// The following would cause compilation errors if insecure-dangerous feature is not enabled:
|
||||
// builder.insecure_accept_invalid_certs(true);
|
||||
|
||||
|
||||
// The static method should also not be available:
|
||||
// let _client = HttpClient::with_self_signed_certs();
|
||||
|
||||
assert!(true); // If this compiles without insecure-dangerous, the test passes
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "insecure-dangerous"))]
|
||||
@@ -161,12 +159,12 @@ fn insecure_methods_not_available_without_feature() {
|
||||
fn insecure_static_method_not_available() {
|
||||
// Verify that the static convenience method is not available without the feature
|
||||
// HttpClient::with_self_signed_certs(); // This should cause a compilation error
|
||||
|
||||
|
||||
// Instead, we can only use the safe default methods
|
||||
let _client = HttpClient::new();
|
||||
let _client2 = HttpClient::default();
|
||||
|
||||
assert!(true); // Safe methods are available
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Documentation test to ensure proper feature gating
|
||||
@@ -174,20 +172,20 @@ fn insecure_static_method_not_available() {
|
||||
#[test]
|
||||
fn insecure_feature_documentation_reminder() {
|
||||
// This test serves as a documentation reminder about the dangers of this feature
|
||||
|
||||
|
||||
// ⚠️ CRITICAL SECURITY WARNING ⚠️
|
||||
// The insecure-dangerous feature should NEVER be used in production!
|
||||
// It disables certificate validation and makes connections vulnerable to
|
||||
// man-in-the-middle attacks.
|
||||
|
||||
|
||||
// This feature is only intended for:
|
||||
// - Local development with self-signed certificates
|
||||
// - Testing environments where security is not a concern
|
||||
// - Debugging TLS connection issues
|
||||
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.insecure_accept_invalid_certs(true)
|
||||
.build();
|
||||
|
||||
assert!(true); // Documentation test passes
|
||||
}
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
@@ -1,13 +1,16 @@
|
||||
//! Integration tests for rustls features
|
||||
//!
|
||||
//!
|
||||
//! These tests verify that the library works correctly with the rustls feature
|
||||
//! enabled, including custom CA certificate support and certificate pinning.
|
||||
|
||||
use hyper_custom_cert::{HttpClient, HttpClientBuilder};
|
||||
use hyper_custom_cert::HttpClient;
|
||||
#[cfg(feature = "rustls")]
|
||||
use std::collections::HashMap;
|
||||
#[cfg(feature = "rustls")]
|
||||
use std::time::Duration;
|
||||
|
||||
// Sample PEM certificate for testing (self-signed test cert)
|
||||
#[allow(dead_code)]
|
||||
const TEST_CA_PEM: &[u8] = b"-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIJAKoK/heBjcOuMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
@@ -21,21 +24,19 @@ CgKCAQEAuuExKtKjKEw91uR8gqyUZx+wW3qZjUHq3oLe+RxbEUVFWApwrKE3XxKJ
|
||||
#[test]
|
||||
fn rustls_client_creation() {
|
||||
// Test that we can create a client with rustls feature
|
||||
let client = HttpClient::new();
|
||||
|
||||
let _client = HttpClient::new();
|
||||
|
||||
// Basic smoke test - the client should be created successfully
|
||||
assert!(true); // Placeholder - client creation succeeded
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
#[test]
|
||||
fn builder_with_root_ca_pem() {
|
||||
// Test adding custom CA certificate via PEM bytes
|
||||
let client = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - CA PEM configuration succeeded
|
||||
let _client = HttpClient::builder().with_root_ca_pem(TEST_CA_PEM).build();
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
@@ -45,11 +46,11 @@ fn builder_with_root_ca_file() {
|
||||
// Note: In actual usage, this would read from a real file
|
||||
// For CI/CD compatibility, we test method availability without file I/O
|
||||
let _builder = HttpClient::builder();
|
||||
|
||||
|
||||
// This demonstrates the API is available when rustls feature is enabled
|
||||
// In real usage: client = builder.with_root_ca_file("ca.pem").build();
|
||||
|
||||
assert!(true); // Placeholder - CA file method availability verified
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
@@ -57,21 +58,21 @@ fn builder_with_root_ca_file() {
|
||||
fn builder_with_pinned_cert_sha256() {
|
||||
// Test certificate pinning functionality
|
||||
let pins = vec![
|
||||
[0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00,
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08],
|
||||
[0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x98,
|
||||
0x76, 0x54, 0x32, 0x10, 0xef, 0xcd, 0xab, 0x89,
|
||||
0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc,
|
||||
0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44],
|
||||
[
|
||||
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
|
||||
0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04,
|
||||
0x05, 0x06, 0x07, 0x08,
|
||||
],
|
||||
[
|
||||
0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xef, 0xcd,
|
||||
0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
|
||||
0x77, 0x66, 0x55, 0x44,
|
||||
],
|
||||
];
|
||||
|
||||
let client = HttpClient::builder()
|
||||
.with_pinned_cert_sha256(pins)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - certificate pinning configuration succeeded
|
||||
|
||||
let _client = HttpClient::builder().with_pinned_cert_sha256(pins).build();
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
@@ -80,34 +81,32 @@ fn builder_rustls_combined_configuration() {
|
||||
// Test combining rustls features with other configuration options
|
||||
let mut headers = HashMap::new();
|
||||
headers.insert("Authorization".to_string(), "Bearer token".to_string());
|
||||
|
||||
|
||||
let pins = vec![[0u8; 32]]; // Single test pin
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_secs(60))
|
||||
.with_default_headers(headers)
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.with_pinned_cert_sha256(pins)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - combined rustls configuration succeeded
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
#[test]
|
||||
fn rustls_with_multiple_ca_certificates() {
|
||||
// Test adding multiple CA certificates
|
||||
let client1 = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.build();
|
||||
|
||||
let _client1 = HttpClient::builder().with_root_ca_pem(TEST_CA_PEM).build();
|
||||
|
||||
// In practice, you could chain multiple with_root_ca_pem calls
|
||||
let client2 = HttpClient::builder()
|
||||
let _client2 = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.with_root_ca_pem(TEST_CA_PEM) // Same cert twice for testing
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - multiple CA configuration succeeded
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
@@ -115,12 +114,12 @@ fn rustls_with_multiple_ca_certificates() {
|
||||
fn rustls_ca_file_and_pem_combination() {
|
||||
// Test combining multiple PEM-based CA loading (simulating file + PEM combination)
|
||||
// For CI/CD compatibility, we use multiple PEM calls instead of file I/O
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_root_ca_pem(TEST_CA_PEM) // Simulates file-based CA
|
||||
.with_root_ca_pem(TEST_CA_PEM) // Additional PEM-based CA
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - multiple CA combination succeeded
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
@@ -128,24 +127,24 @@ fn rustls_ca_file_and_pem_combination() {
|
||||
fn rustls_empty_pin_list() {
|
||||
// Test with empty certificate pin list
|
||||
let empty_pins: Vec<[u8; 32]> = vec![];
|
||||
|
||||
let client = HttpClient::builder()
|
||||
|
||||
let _client = HttpClient::builder()
|
||||
.with_pinned_cert_sha256(empty_pins)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - empty pins configuration succeeded
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
#[test]
|
||||
#[test]
|
||||
fn rustls_with_timeout_and_ca() {
|
||||
// Test rustls-specific functionality with timeout
|
||||
let client = HttpClient::builder()
|
||||
let _client = HttpClient::builder()
|
||||
.with_timeout(Duration::from_millis(500))
|
||||
.with_root_ca_pem(TEST_CA_PEM)
|
||||
.build();
|
||||
|
||||
assert!(true); // Placeholder - rustls with timeout succeeded
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
||||
// Test that runs only when rustls feature is NOT enabled
|
||||
@@ -154,11 +153,11 @@ fn rustls_with_timeout_and_ca() {
|
||||
fn rustls_methods_not_available_without_feature() {
|
||||
// This test should only compile and run when rustls feature is disabled
|
||||
let _builder = HttpClient::builder();
|
||||
|
||||
|
||||
// The following would cause compilation errors if rustls feature is not enabled:
|
||||
// builder.with_root_ca_pem(TEST_CA_PEM);
|
||||
// builder.with_root_ca_file("test.pem");
|
||||
// builder.with_pinned_cert_sha256(vec![[0u8; 32]]);
|
||||
|
||||
assert!(true); // If this compiles without rustls, the test passes
|
||||
}
|
||||
|
||||
// Test passes if compilation succeeds
|
||||
}
|
||||
|
Reference in New Issue
Block a user