Skip to content

TLS Configuration

orb-mockhttp can automatically generate TLS certificates or use custom ones for HTTPS testing.

The simplest way to enable TLS is with .with_tls():

let server = TestServerBuilder::new()
.with_tls()
.build();

This automatically generates a self-signed certificate valid for:

  • localhost
  • 127.0.0.1
use std::path::PathBuf;
let server = TestServerBuilder::new()
.with_certs(
PathBuf::from("path/to/certificate.pem"),
PathBuf::from("path/to/private-key.pem")
)
.build();
use orb_mockhttp::TlsConfig;
use std::path::PathBuf;
// Load from files
let tls_config = TlsConfig::from_files(
PathBuf::from("cert.pem"),
PathBuf::from("key.pem")
).expect("Failed to load certificates");
let server = TestServerBuilder::new()
.with_tls_config(tls_config)
.build();
use orb_mockhttp::TlsConfig;
// Generate new self-signed certificate
let tls_config = TlsConfig::generate();
let server = TestServerBuilder::new()
.with_tls_config(tls_config)
.build();

After building the server, you can access the certificate for client configuration:

let server = TestServerBuilder::new().with_tls().build();
// Get PEM-encoded certificate (for most HTTP clients)
if let Some(pem) = server.cert_pem() {
println!("Certificate:\n{}", pem);
}
// Get DER-encoded certificate (raw bytes)
if let Some(der) = server.cert_der() {
println!("Certificate: {} bytes", der.len());
}
use reqwest::Certificate;
let server = TestServerBuilder::new().with_tls().build();
let cert_pem = server.cert_pem().unwrap();
let cert = Certificate::from_pem(cert_pem.as_bytes()).unwrap();
let client = reqwest::Client::builder()
.add_root_certificate(cert)
.build()
.unwrap();
// Now client trusts the mock server's certificate
let response = client.get(server.url("/test")).send().await.unwrap();
use rustls::{RootCertStore, Certificate};
let server = TestServerBuilder::new().with_tls().build();
let cert_der = server.cert_der().unwrap();
let mut root_store = RootCertStore::empty();
root_store.add(&Certificate(cert_der.to_vec())).unwrap();
// Use root_store with your TLS configuration

When TLS is enabled, you can use all HTTP protocols on the same port:

use orb_mockhttp::HttpProtocol;
// All protocols (default with TLS)
let server = TestServerBuilder::new()
.with_tls()
.build();
assert!(server.supports_protocol(HttpProtocol::Http1));
assert!(server.supports_protocol(HttpProtocol::Http2));
assert!(server.supports_protocol(HttpProtocol::Http3));
// Specific protocols
let http2_only = TestServerBuilder::new()
.with_tls()
.with_protocols(&[HttpProtocol::Http2])
.build();

Certificate and key files must be in PEM format:

-----BEGIN CERTIFICATE-----
MIIBkTCB+wIJAK...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBg...
-----END PRIVATE KEY-----
  • RSA
  • ECDSA (P-256, P-384)
  • Ed25519
use orb_mockhttp::{TestServerBuilder, TlsConfig};
use std::path::PathBuf;
#[tokio::test]
async fn test_with_tls() {
// Option 1: Auto-generated certificate
let server = TestServerBuilder::new()
.with_tls()
.build();
server.on_request("/secure")
.respond_with(200, "Secret data");
// Configure client with server's certificate
let cert = reqwest::Certificate::from_pem(
server.cert_pem().unwrap().as_bytes()
).unwrap();
let client = reqwest::Client::builder()
.add_root_certificate(cert)
.build()
.unwrap();
let resp = client.get(server.url("/secure"))
.send()
.await
.unwrap();
assert_eq!(resp.status(), 200);
assert_eq!(resp.text().await.unwrap(), "Secret data");
}
#[tokio::test]
async fn test_with_custom_certs() {
// Option 2: Custom certificates
let server = TestServerBuilder::new()
.with_certs(
PathBuf::from("tests/certs/server.pem"),
PathBuf::from("tests/certs/server-key.pem")
)
.build();
// Test as above...
}

If your HTTP client rejects the connection:

  1. Make sure you’re adding the certificate to your client’s trust store
  2. Use cert_pem() for most clients, cert_der() for low-level APIs
  3. Verify the URL matches certificate SANs (localhost or 127.0.0.1)

If HTTP/2 or HTTP/3 fails:

  1. Ensure TLS is enabled (.with_tls())
  2. Check that the client supports the protocol
  3. Use verbose logging to see ALPN negotiation