Skip to content

Protocol Support

orb-mockhttp supports all major HTTP versions, allowing you to test protocol-specific behavior.

use orb_mockhttp::HttpProtocol;
// Available protocols
HttpProtocol::Http1 // HTTP/1.1
HttpProtocol::Http2 // HTTP/2
HttpProtocol::Http3 // HTTP/3 (QUIC)
// Get all protocols
let all = HttpProtocol::all(); // [Http1, Http2, Http3]
let server = TestServerBuilder::new().build();
// Only HTTP/1.1 is available
assert!(server.supports_protocol(HttpProtocol::Http1));
assert!(!server.supports_protocol(HttpProtocol::Http2));
assert!(!server.supports_protocol(HttpProtocol::Http3));
let server = TestServerBuilder::new()
.with_tls()
.build();
// All protocols available on the same port
assert!(server.supports_protocol(HttpProtocol::Http1));
assert!(server.supports_protocol(HttpProtocol::Http2));
assert!(server.supports_protocol(HttpProtocol::Http3));

Use with_protocols() to limit available protocols:

// HTTP/2 only
let server = TestServerBuilder::new()
.with_tls()
.with_protocols(&[HttpProtocol::Http2])
.build();
// HTTP/1.1 and HTTP/2 (no HTTP/3)
let server = TestServerBuilder::new()
.with_tls()
.with_protocols(&[HttpProtocol::Http1, HttpProtocol::Http2])
.build();
// HTTP/3 only
let server = TestServerBuilder::new()
.with_tls()
.with_protocols(&[HttpProtocol::Http3])
.build();

Access the protocol in request handlers:

server.on_request_fn("/version", |req| {
let protocol = match req.protocol() {
HttpProtocol::Http1 => "HTTP/1.1",
HttpProtocol::Http2 => "HTTP/2",
HttpProtocol::Http3 => "HTTP/3",
};
ResponseBuilder::new()
.text(format!("Protocol: {}", protocol))
.build()
});

Or check the HTTP version:

server.on_request_fn("/version", |req| {
let version = req.version(); // http::Version
ResponseBuilder::new()
.text(format!("Version: {:?}", version))
.build()
});

When TLS is enabled, all protocols share the same port number:

let server = TestServerBuilder::new()
.with_tls()
.build();
let port = server.port();
// HTTP/1.1 and HTTP/2 use TCP on this port
// HTTP/3 uses QUIC (UDP) on this port
// Same URL works for all protocols
let url = server.url("/api");
// The client's protocol choice determines which is used
#[tokio::test]
async fn test_http2_multiplexing() {
let server = TestServerBuilder::new()
.with_tls()
.with_protocols(&[HttpProtocol::Http2])
.build();
server.on_request("/slow")
.delay(Duration::from_millis(100))
.respond_with(200, "slow");
server.on_request("/fast")
.respond_with(200, "fast");
// Multiple concurrent requests over single connection
let client = create_http2_client(&server);
let (slow, fast) = tokio::join!(
client.get(server.url("/slow")),
client.get(server.url("/fast"))
);
// fast should complete before slow
}
#[tokio::test]
async fn test_http3() {
let server = TestServerBuilder::new()
.with_tls()
.with_protocols(&[HttpProtocol::Http3])
.build();
server.on_request("/test")
.respond_with(200, "OK");
// Use an HTTP/3 client
let client = create_http3_client(&server);
let response = client.get(server.url("/test")).await.unwrap();
assert_eq!(response.status(), 200);
}
#[tokio::test]
async fn test_protocol_negotiation() {
let server = TestServerBuilder::new()
.with_tls()
.build();
server.on_request_fn("/check", |req| {
ResponseBuilder::new()
.json(&json!({
"protocol": format!("{:?}", req.protocol())
}))
.build()
});
// HTTP/2 client
let h2_client = create_http2_client(&server);
let resp = h2_client.get(server.url("/check")).await.unwrap();
assert!(resp.text().await.unwrap().contains("Http2"));
// HTTP/1.1 client
let h1_client = create_http1_client(&server);
let resp = h1_client.get(server.url("/check")).await.unwrap();
assert!(resp.text().await.unwrap().contains("Http1"));
}
ProtocolTLS RequiredTransportPort
HTTP/1.1NoTCPAny
HTTP/2YesTCPShared
HTTP/3YesQUIC (UDP)Shared
use orb_mockhttp::{TestServerBuilder, HttpProtocol, ResponseBuilder};
use serde_json::json;
#[tokio::test]
async fn test_multi_protocol() {
// Server supporting all protocols
let server = TestServerBuilder::new()
.with_tls()
.build();
// Handler that reports which protocol was used
server.on_request_fn("/api", |req| {
ResponseBuilder::new()
.json(&json!({
"protocol": match req.protocol() {
HttpProtocol::Http1 => "HTTP/1.1",
HttpProtocol::Http2 => "HTTP/2",
HttpProtocol::Http3 => "HTTP/3",
},
"method": req.method().as_str(),
"path": req.path(),
}))
.build()
});
// Check protocol support
println!("Supported protocols:");
for protocol in server.protocols() {
println!(" - {:?}", protocol);
}
// Test with different clients...
}