Mixed HTTP Protocols
Expose the same application over multiple listeners each constrained to a specific HTTP protocol version (HTTP/1.1, HTTP/2, HTTP/3), plus an example of a combined protocol listener.
HTTP/3 requires OS + .NET support (QUIC). If unavailable the listener will fail or downgrade.
Full source
File: pwsh/tutorial/examples/7.6-Mixed-HttpProtocols.ps1
<#
Sample: Mixed HTTP Protocol Versions
Purpose: Demonstrate configuring multiple listeners each with a different HTTP protocol set (HTTP/1.1, HTTP/2, HTTP/3*) plus a combined HTTP/1.1+HTTP/2 listener.
File: 7.6-Mixed-HttpProtocols.ps1
Notes: HTTP/3 requires platform & runtime support + QUIC enabled. If HTTP/3 is not available, that listener may fail to bind.
#>
param(
[int]$Port = 5000,
[IPAddress]$IPAddress = [IPAddress]::Loopback
)
# 1. Logging (console)
New-KrLogger | Add-KrSinkConsole | Register-KrLogger -Name 'console' -SetAsDefault | Out-Null
# 2. Create server
New-KrServer -Name 'Endpoints Mixed Protocols'
# For HTTPS listeners, create a self-signed cert (or load from store/file as needed)
$cert = New-KrSelfSignedCertificate -DnsNames localhost, 127.0.0.1 -Exportable -ValidDays 30
# 3. Listeners with explicit protocol selections
# - 5001: HTTP/1.1 only
Add-KrEndpoint -Port $Port -IPAddress $IPAddress -Protocols ([Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http1) -X509Certificate $cert
# - 5002: HTTP/2 only (no HTTP/1.1)
Add-KrEndpoint -Port ($Port + 1) -IPAddress $IPAddress -Protocols ([Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http2) -X509Certificate $cert
# - 5003: HTTP/3 only (QUIC) Requires OS + runtime support; may need environment variable ASPNETCORE_URLS / alt config.
Add-KrEndpoint -Port ($Port + 2) -IPAddress $IPAddress -Protocols ([Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http3) -X509Certificate $cert
# - 5004: Combined HTTP/1.1 + HTTP/2 (single listener negotiating via ALPN when TLS used; here plain for demo)
Add-KrEndpoint -Port ($Port + 3) -IPAddress $IPAddress -Protocols ([Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http1AndHttp2) -X509Certificate $cert
# 5. Enable configuration
Enable-KrConfiguration
# 6. Single route served by all listeners
Add-KrMapRoute -Verbs Get -Pattern '/version' -ScriptBlock {
$proto = $Context.HttpContext.Request.Protocol
Write-KrTextResponse -InputObject "Hello via $proto" -ContentType 'text/plain'
}
# 7. Start server (Ctrl+C to stop)
Start-KrServer -CloseLogsOnExit
Step-by-step
- Create server & logger.
- Add four listeners with explicit
-Protocolsvalues:Http1,Http2,Http3, andHttp1AndHttp2(combined). - Enable configuration.
- Map
/versionroute returning negotiated protocol. - Start server.
Try it
With Curl:
curl -v --http1.1 -k https://127.0.0.1:5001/version
curl -v --http2-prior-knowledge -k https://127.0.0.1:5002/version
# HTTP/3 (requires curl built with HTTP/3 + QUIC):
curl -v --http3 -k https://127.0.0.1:5003/version
# Combined (shows negotiated protocol or HTTP/1.1 without TLS):
curl -v -k https://127.0.0.1:5004/version
With Invoke-WebRequest:
# HTTP/1.1
Invoke-WebRequest -Uri "https://127.0.0.1:5001/version" -HttpVersion 1.1 -SkipCertificateCheck -Verbose
# HTTP/2 (prior knowledge)
Invoke-WebRequest -Uri "https://127.0.0.1:5002/version" -HttpVersion 2.0 -SkipCertificateCheck -Verbose
# HTTP/3 (requires .NET + OS support for QUIC)
Invoke-WebRequest -Uri "https://127.0.0.1:5003/version" -HttpVersion 3.0 -SkipCertificateCheck -Verbose
# Combined (let it negotiate, default is 1.1 without TLS)
Invoke-WebRequest -Uri "https://127.0.0.1:5004/version" -SkipCertificateCheck -Verbose
Each response prints: Hello via HTTP/<version>.
Enum values
[Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols] supports: Http1, Http2, Http3, and flag combinations (Http1AndHttp2, Http1AndHttp3, Http2AndHttp3, Http1AndHttp2AndHttp3). You can also combine flags manually:
$all = [Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http1 -bor \
[Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http2 -bor \
[Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols]::Http3
Add-KrEndpoint -Port 5010 -IPAddress ([IPAddress]::Loopback) -Protocols $all
HTTP/2 generally requires TLS in browsers; HTTP/3 always requires QUIC + TLS.
References
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| HTTP/3 listener fails | QUIC not supported | Remove HTTP/3 line or upgrade OS/runtime |
| All versions say HTTP/1.1 | H2/H3 not negotiated | Use proper curl flags or ALPN support |
| Port in use | Already bound | Change port numbers |
See also: Multiple Listeners · HTTPS
Previous / Next
- Previous: Unix Sockets
- Next: URI Endpoints