Class ProxyServer
Translates an HTTP/1.1 client connection onto an h2-only origin (Http2
with AllowHttpProtocolTranslation enabled - see ResolveHttp2ForClientAsync(SessionEventArgsBase, bool, string, int, string, int?, UpstreamHttpProtocol, bool, bool, CancellationToken, bool)), leasing
one h2 stream per HTTP/1.1 request from a shared Titanium.Web.Proxy.Http2.Http2OriginConnection via
Titanium.Web.Proxy.ProxyServer.Http2OriginConnectionPool rather than opening a new TCP/TLS connection for every request.
Implements
Inherited Members
Namespace: Titanium.Web.Proxy
Assembly: Titanium.Web.Proxy.dll
Syntax
public class ProxyServer : IDisposable
Remarks
This re-implements the HTTP/1.1 client read loop (request line, headers, BeforeRequest,
authorization, header preparation, CancelRequest/replaced-response handling) rather than reusing
the private HandleHttpSessionRequest/HandleHttpSessionResponse methods, because those
methods send/receive over TcpServerConnection.Stream using the raw HTTP/1.1 wire format, which an
h2 origin connection cannot speak. This mirrors the precedent set by the h2-to-HTTP/1.1 bridge
(Http2ToHttp11BridgeHandler), which similarly bypasses the wire-format-specific machinery for the
leg that does not match it.
Origin connections are multiplexed across independent HTTP/1.1 clients through Titanium.Web.Proxy.ProxyServer.Http2OriginConnectionPool (fan-in share). Response bodies are delivered via Titanium.Web.Proxy.Http2.Http2OriginConnection streaming writers where available.
Constructors
| Edit this page View SourceProxyServer(bool, bool, bool)
Initializes a new instance of ProxyServer class with provided parameters.
Declaration
public ProxyServer(bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | userTrustRootCertificate | When true (the default), EnsureRootCertificate() installs the MITM root into the current-user Personal and Trusted Root stores. Prefer user-only trust for interactive apps; pass false when trust must be fully opt-in. |
| bool | machineTrustRootCertificate | When true, also trust in the local-machine stores (needs elevation). Defaults to false — machine trust is opt-in for services/admin installs, not for normal desktop use. |
| bool | trustRootCertificateAsAdmin | When true, attempt elevated trust via UAC (Windows only). Defaults to false. |
ProxyServer(string?, string?, bool, bool, bool)
Initializes a new instance of ProxyServer class with provided parameters.
Declaration
public ProxyServer(string? rootCertificateName, string? rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false)
Parameters
| Type | Name | Description |
|---|---|---|
| string | rootCertificateName | Name of the root certificate. |
| string | rootCertificateIssuerName | Name of the root certificate issuer. |
| bool | userTrustRootCertificate | When true (the default), EnsureRootCertificate() installs the MITM root into the current-user Personal and Trusted Root stores. Prefer user-only trust for interactive apps; pass false when trust must be fully opt-in. |
| bool | machineTrustRootCertificate | When true, also trust in the local-machine stores (needs elevation). Defaults to false — machine trust is opt-in for services/admin installs, not for normal desktop use. |
| bool | trustRootCertificateAsAdmin | When true, attempt elevated trust via UAC (Windows only). Defaults to false. |
Fields
| Edit this page View SourceDefaultViaHeaderPseudonym
Default Via header pseudonym (RFC 9110 §7.6.3). Used by ViaHeaderPseudonym and by Inspector when Add Via header is enabled.
Declaration
public const string DefaultViaHeaderPseudonym = "titanium-web-proxy"
Field Value
| Type | Description |
|---|---|
| string |
Properties
| Edit this page View SourceAdmittedClientConnectionCount
Number of client connections currently admitted (accepted and past the admission gate, not yet finished being handled), across all TCP-based endpoints. Unlike ClientConnectionCount, this drops to zero as soon as the handler returns, without the trailing TIME_WAIT delay.
Declaration
public int AdmittedClientConnectionCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
BlockLoopbackDestinations
Outbound destination policy hook: when true, every resolved destination
IP address is checked for loopback (127.0.0.0/8, ::1, including IPv4-mapped
forms such as ::ffff:127.0.0.1) before connecting, and the connection attempt is
rejected with an OutboundDestinationBlockedException if it matches.
Private (RFC 1918), link-local, and cloud metadata addresses (including
169.254.169.254) remain reachable under this flag alone.
Off by default. Use when the proxy must allow intranet destinations (for example
10.*) but must still stop clients from pivoting to the proxy host's own loopback.
BlockPrivateNetworkDestinations already covers loopback as part of its
broader set; when that flag is enabled, this property is not consulted for the reject.
Assigning Profile does not read or clear this property.
Enforced on TCP outbound connects only (the same call sites as
BlockPrivateNetworkDestinations). Origin HTTP/3 (QUIC) dials a hostname
and is not covered. An explicitly configured upstream proxy address is always exempt.
Not currently enforced for a SOCKS upstream with ProxyDnsRequests enabled.
Declaration
public bool BlockLoopbackDestinations { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
BlockPrivateNetworkDestinations
Outbound destination policy hook: when true, every resolved destination IP address is checked against loopback, private (RFC 1918/4193), link-local (which subsumes the 169.254.169.254 cloud metadata endpoint), and other non-globally-routable ranges before connecting, and the connection attempt is rejected with an OutboundDestinationBlockedException if it matches.
Off by default: blocking private destinations would break this library's most common
configurations, including upstream-proxy chaining to localhost and interception of
local development servers. Only enable this when the proxy accepts requests from
untrusted clients (an SSRF-relevant deployment), where those same destinations become an
attacker-reachable pivot into the host's private network instead of an operator's own
intentional configuration.
An explicitly configured upstream proxy address (UpStreamHttpProxy,
UpStreamHttpsProxy, or a per-session external proxy) is always exempt -
that address is operator intent, not attacker-controlled. Checked against the resolved
address actually used to connect (no re-resolution afterward, which would make the check
a TOCTOU no-op against DNS rebinding). Not currently enforced for a SOCKS upstream with
ProxyDnsRequests enabled, since the proxy never resolves the origin itself in that
mode and has no address of its own to validate.
Declaration
public bool BlockPrivateNetworkDestinations { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
BufferPool
The buffer pool used throughout this proxy instance. Set custom implementations by implementing this interface. By default this uses DefaultBufferPool implementation available in StreamExtended library package. Buffer size should be at least 10 bytes.
Declaration
public IBufferPool BufferPool { get; set; }
Property Value
| Type | Description |
|---|---|
| IBufferPool |
CertificateManager
Manages certificates used by this proxy.
Declaration
public CertificateManager CertificateManager { get; }
Property Value
| Type | Description |
|---|---|
| CertificateManager |
CheckCertificateRevocation
Should we check for certificate revocation during SSL authentication to servers Note: If enabled can reduce performance. Defaults to false.
Declaration
public X509RevocationMode CheckCertificateRevocation { get; set; }
Property Value
| Type | Description |
|---|---|
| X509RevocationMode |
ClientConnectionCount
Total number of active TCP client connections. Does not include inbound HTTP/3 (QUIC) clients; see Http3ClientConnectionCount.
Declaration
public int ClientConnectionCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
ClientHandshakeRejectThreshold
Learns from clients that keep rejecting the MITM certificate: consecutive aborted client TLS handshakes for one host (no successful handshake in between) before the host is bypassed on later CONNECTs. Typical cause: certificate pinning, or a client that does not trust the proxy root. Only active while EnableDecryptFailureBypass is on. 0 disables. Default 5.
Declaration
public int ClientHandshakeRejectThreshold { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
ClientHandshakeRejectWindow
Window in which ClientHandshakeRejectThreshold failures must occur. Default 2 minutes.
Declaration
public TimeSpan ClientHandshakeRejectWindow { get; set; }
Property Value
| Type | Description |
|---|---|
| TimeSpan |
ClientHeaderTimeoutSeconds
Seconds to wait for a client to finish sending the request line and headers, from the moment
this proxy starts reading a new request on the connection. Enforced with a linked
CancellationTokenSource around the request-line and header
read, not Socket.ReceiveTimeout: that property only bounds a single blocking
Receive call, not the asynchronous reads this proxy actually issues, so without this
deadline a client that opens a connection and trickles bytes arbitrarily slowly (or stops
sending entirely) after the first byte ties up a read loop indefinitely.
Default is 0 (disabled), matching every other deadline in this class - no per-session
override exists because there is no SessionEventArgs for this
request yet at the point this deadline applies.
Declaration
public int ClientHeaderTimeoutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
CompatibilityMode100Continue
When true, the proxy immediately responds with a synthetic
100 Continue to any client request carrying Expect: 100-continue,
before forwarding the headers to the origin and without waiting for the origin
to respond. This breaks the strict handshake (client → proxy 100 → client body
→ origin body) but prevents the deadlock that occurs with strict clients when
Enable100ContinueBehaviour is false (the default).
Has no effect when Enable100ContinueBehaviour is true.
Default: false.
Declaration
public bool CompatibilityMode100Continue { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
ConnectTimeOutSeconds
Seconds server connection are to wait for connection to be established. Default value is 20 seconds.
Declaration
public int ConnectTimeOutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
ConnectionTimeOutSeconds
Seconds client/server connection are to be kept alive when waiting for read/write to complete. This will also determine the pool eviction time when connection pool is enabled. Default value is 60 seconds.
Declaration
public int ConnectionTimeOutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
CustomUpStreamProxyFailureFunc
A callback to provide a chance for an upstream proxy failure to be handled by a new upstream proxy. User should return the ExternalProxy object with valid credentials or null.
Declaration
public Func<SessionEventArgsBase, Task<IExternalProxy?>>? CustomUpStreamProxyFailureFunc { get; set; }
Property Value
| Type | Description |
|---|---|
| Func<SessionEventArgsBase, Task<IExternalProxy>> |
DecryptFailureBypassMaxEntries
Maximum learned hosts retained (approximate LRU eviction). Default 256.
Declaration
public int DecryptFailureBypassMaxEntries { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
DecryptFailureBypassThreshold
Origin TLS failure strikes required before a host is bypassed on later CONNECTs. Same-CONNECT opaque fallback after an awaited H2 probe failure marks bypass immediately. Default 2.
Declaration
public int DecryptFailureBypassThreshold { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
DecryptFailureBypassTtl
How long a learned decrypt-bypass entry remains valid. Default 30 minutes.
Declaration
public TimeSpan DecryptFailureBypassTtl { get; set; }
Property Value
| Type | Description |
|---|---|
| TimeSpan |
DnsServerEndPoint
DNS server endpoint used by Titanium.Web.Proxy.Http3.Dns.UdpSvcbDnsResolver for HTTPS/SVCB queries. Defaults to the first usable OS-configured plain-UDP DNS server discovered via NetworkInterface. This is a best-effort default and does not honor Windows NRPT, DoH, or VPN split-DNS policy.
When no OS-configured DNS server can be discovered, the property reports
0.0.0.0:0 and proactive SVCB discovery is skipped (never falls back to a public
third-party resolver). Assign an explicit endpoint to override discovery.
Declaration
[Experimental("TWP001")]
public IPEndPoint DnsServerEndPoint { get; set; }
Property Value
| Type | Description |
|---|---|
| IPEndPoint |
Enable100ContinueBehaviour
Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 continue implementations on server/client may cause problems if enabled. Defaults to false.
Declaration
public bool Enable100ContinueBehaviour { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableConnectionPool
Should we enable the server connection pool. Defaults to true. When connection pooling is enabled, instead of creating a new TCP connection to the server for each client TCP connection, we check if an idle server connection is available in our cached pool. If a compatible connection (same destination, scheme, upstream proxy, credentials and negotiated protocol) created from an earlier request is available, we reuse it. Only connections that are safe to reuse under the HTTP protocol are pooled: the response body must be fully received and the connection must be persistent (HTTP/1.1 keep-alive, or an HTTP/1.0 connection that explicitly opted in via "Connection: keep-alive"). Connections whose response asked to close, that failed, or that carry connection-oriented authentication state (WinAuth NTLM/Negotiate) or a per-session client certificate are never returned to the shared pool. The ConnectionTimeOutSeconds parameter determines the eviction time for inactive server connections. This reduces TCP (and TLS) connection establishment cost, both in wall clock time and CPU cycles. Set to false to force a fresh server connection for every client connection.
Declaration
public bool EnableConnectionPool { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableDecryptFailureBypass
When true, the proxy learns hosts whose origin TLS handshake fails under MITM (non-ALPN AuthenticationException, typically bot / TLS-fingerprint rejection) and tunnels subsequent CONNECTs without decrypt. Default false so library and RPS baselines are unchanged. Inspector enables this by default. Success-path cost when on is one dictionary lookup per CONNECT.
Declaration
public bool EnableDecryptFailureBypass { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableHttp2
Enable disable HTTP/2 support.
Client-facing HTTP/2 is negotiated via TLS ALPN, or as prior-knowledge cleartext h2c on a
transparent reverse endpoint (DecryptSsl: false). No Upgrade: h2c.
Origin-facing HTTP/2 uses TLS ALPN h2 by default; with
ForwardCleartext and
Http2, the origin speaks cleartext HTTP/2
prior-knowledge (outbound h2c).
A client/server that does not support HTTP/2 transparently falls back to HTTP/1.1 when policy allows.
Request/response header and body modification in BeforeRequest/BeforeResponse, chunked trailers,
interim (1xx) responses, and the synthetic-response APIs (Ok/Respond/Redirect/GenericResponse/
RespondStreaming) are all supported over HTTP/2, the same as over HTTP/1.x.
Not supported: HTTP/2 server push (the wire frames are transcoded but there is no public API to
originate a push) and Upgrade: h2c. Explicit-proxy inbound h2c is not implemented.
See the protocol support matrix on the wiki for exact, up-to-date HTTP/1.x/HTTP/2 feature coverage.
Declaration
public bool EnableHttp2 { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableHttp3
Enable HTTP/3 (QUIC) support. When true:
-
Any
TransparentQuicProxyEndPointis started as a UDP-only QUIC listener for transparent/NAT HTTP/3 interception. -
Any
TransparentProxyEndPointwithEnableHttp3also listens for HTTP/3 on the same IP:port (TCP H1/H2 + UDP H3) and injects client-facingAlt-Svc. - With Auto (default), a cached Alt-Svc / HTTPS/SVCB capability selects outbound HTTP/3 on the next CONNECT or new HTTP/1.1 request. Background QUIC warm-up starts when the cache is filled so that handshake is often already done. An already-open H2↔H2 MITM session is not upgraded mid-connection. Forced Http3 fails closed with no TCP fallback.
Requires MsQuic native library and a supported operating-system version (IsSupported). Setting to true with no inbound HTTP/3 endpoint is fine when an explicit/SOCKS/transparent TCP endpoint is present (origin-side QUIC only). A warning is emitted only when EnableHttp3 is set with no client-facing endpoints at all. Default: false (opt-in).
Experimental: HTTP/3 support has not yet completed the full interop/soak/fuzz gate
process. Suppress TWP001 to opt in; the attribute is removed when the feature
graduates to stable.
Declaration
[Experimental("TWP001")]
public bool EnableHttp3 { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableHttpInterception
Forces the full interception path (SessionEventArgs, BeforeRequest, etc.) even when no event handlers are subscribed. Set this when consuming SessionEventArgs for timing or metrics without subscribing to any event. Default: false.
Declaration
public bool EnableHttpInterception { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableHttpsSvcbDnsDiscovery
When true, the proxy queues a background HTTPS/SVCB RR (DNS type 65) lookup
after an Auto-mode capability-cache miss. A positive result (ALPN h3 found) warms
Titanium.Web.Proxy.Http3.Http3OriginCapabilityCache for subsequent connections; the CONNECT /
request path itself never awaits DNS. Negative results are cached for 1 minute; transient
failures use a short backoff.
Defaults to true whenever EnableHttp3 is
true. Set explicitly to false to disable discovery
even when HTTP/3 is enabled — for example, when the configured DNS server is untrusted
or unreachable. First-connection HTTP/3 adoption then comes from Alt-Svc.
Declaration
[Experimental("TWP001")]
public bool EnableHttpsSvcbDnsDiscovery { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableIpv6UnreachableSoftSkip
When true (default), after one IPv6 connect failure with NetworkUnreachable (or equivalent), temporarily omit IPv6 addresses from the Happy Eyeballs race for 30 seconds. Reduces first-chance SocketException noise on dual-stack hosts with a broken IPv6 path. Disable if operators require strict IPv6 preference even when the path is unreachable.
Declaration
public bool EnableIpv6UnreachableSoftSkip { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableQpackDynamicTable
When true, enables RFC 9204 QPACK dynamic table encoding and decoding for inbound HTTP/3 connections. Each connection gets its own Titanium.Web.Proxy.Http3.Qpack.QpackContext with two independent 4096-byte tables (one inbound, one outbound). Defaults to false (static-table-only); existing deployments are unaffected.
Declaration
[Experimental("TWP001")]
public bool EnableQpackDynamicTable { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableRequestTimingCapture
Enables structured request/connection timing capture. When false (the default) no timing objects are allocated and no UtcNow calls are made for timing purposes anywhere in the proxy, so there is zero overhead on the hot path.
When enabled, every SessionEventArgsBase exposes a populated
Timing (per-request phases: client header read,
connection wait, request send, time-to-first-byte, response delivery, total), every
upstream connection exposes a populated UpstreamConnectionTiming (reachable from a
session via UpstreamConnectionTiming, describing DNS,
TCP connect, optional upstream-proxy CONNECT, and TLS handshake durations), and a decrypted
TunnelConnectSessionEventArgs exposes the client-facing TLS
handshake duration via ClientTlsTiming.
Can be toggled at any time; it only affects sessions/connections created after the change, never mutating timing objects already handed out. Defaults to false.
Declaration
public bool EnableRequestTimingCapture { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableRfc8441
When true, the proxy enables RFC 8441 WebSocket-over-HTTP/2:
-
Accepts extended CONNECT (
:protocol = websocket) from h2 clients and advertisesSETTINGS_ENABLE_CONNECT_PROTOCOL=1to them. Per origin: if the origin is HTTP/2 and advertises RFC 8441 support, DATA frames are relayed directly; if the origin is HTTP/2 and does not, the stream is reset withREFUSED_STREAM; if the origin is HTTP/1.1, the h2→h1 WebSocket upgrade bridge is used. -
On the HTTP/1.1-client-to-h2-origin translation bridge, translates
Upgrade: websocketinto extended CONNECT when the origin advertises the setting; otherwise falls back to a dedicated HTTP/1.1 origin connection for that WebSocket. When this property is false, that bridge still returns synthetic501 Not Implementedfor WebSocket upgrades (historical default).
Default: false (must opt-in).
Declaration
public bool EnableRfc8441 { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableTcpKeepAlive
Enable TCP KeepAlive on client and server sockets so NAT/firewall mappings for long-lived CONNECT tunnels are refreshed. Default: true.
Declaration
public bool EnableTcpKeepAlive { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableTcpServerConnectionPrefetch
Should we enable tcp server connection prefetching? When enabled, as soon as we receive a client connection we concurrently initiate corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request we will have the server connection immediately ready or in the process of getting ready. If a server connection is available in cache then this prefetch task will immediately return with the available connection from cache. Defaults to true.
Declaration
public bool EnableTcpServerConnectionPrefetch { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EnableWinAuth
Enable disable Windows Authentication (NTLM/Kerberos). By default SSPI uses the process identity. To authenticate as another user, set WinAuthCredentialsProvider (issue #461). Defaults to false.
Declaration
public bool EnableWinAuth { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
EndpointAdmissionRejectionCount
Total number of client connections rejected by any endpoint's MaxConcurrentClients since this instance was created.
Declaration
public long EndpointAdmissionRejectionCount { get; }
Property Value
| Type | Description |
|---|---|
| long |
ForwardToUpstreamGateway
Gets or sets a value indicating whether requests will be chained to upstream gateway. Defaults to false.
Declaration
public bool ForwardToUpstreamGateway { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
GetCustomUpStreamProxyFunc
A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP(S) requests. User should return the ExternalProxy object with valid credentials.
Declaration
public Func<SessionEventArgsBase, Task<IExternalProxy?>>? GetCustomUpStreamProxyFunc { get; set; }
Property Value
| Type | Description |
|---|---|
| Func<SessionEventArgsBase, Task<IExternalProxy>> |
GlobalAdmissionRejectionCount
Total number of client connections rejected by MaxConcurrentClientConnections since this instance was created.
Declaration
public long GlobalAdmissionRejectionCount { get; }
Property Value
| Type | Description |
|---|---|
| long |
Http3ClientConnectionCount
Total number of active inbound HTTP/3 (QUIC) client connections.
Declaration
public int Http3ClientConnectionCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
Http3ServerConnectionCount
Total number of active upstream HTTP/3 (QUIC) server connections. These are also included in ServerConnectionCount.
Declaration
public int Http3ServerConnectionCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
HttpResponseCacheFiller
Fills the GET/HEAD response cache from a session that is already on the interception path. Does not subscribe BeforeResponse or AfterResponse, so it does not turn NeedsHttpInterception(ProxyEndPoint) on.
Declaration
public Action<SessionEventArgs>? HttpResponseCacheFiller { get; set; }
Property Value
| Type | Description |
|---|---|
| Action<SessionEventArgs> |
IdleReadTimeoutSeconds
Seconds of idle time allowed while reading from the origin (stalled header/body waits).
Applied via CancelAfter on the active read operation. Default is 0 (disabled).
Per-session override: IdleReadTimeout.
Declaration
public int IdleReadTimeoutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
IdleWriteTimeoutSeconds
Seconds of idle time allowed while writing to the origin (stalled header/body waits).
Applied via CancelAfter on the active write operation. Default is 0 (disabled).
Per-session override: IdleWriteTimeout.
Declaration
public int IdleWriteTimeoutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
IgnoreServerCertificateErrors
When true, origin TLS certificates that fail OS chain validation are still accepted (MITM of loopback/self-signed/private CAs). Inspector's "Ignore server certificate errors" maps here. Default false. A subscribed ServerCertificateValidationCallback still wins.
Declaration
public bool IgnoreServerCertificateErrors { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
ListenerBackLog
TCP listener accept backlog. Default: 1024 for burst connection handling.
Declaration
public int ListenerBackLog { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
Logger
The live, shared logger used throughout this proxy instance. Reflects the most recent call to ApplyLoggingConfiguration().
Declaration
public ILogger Logger { get; }
Property Value
| Type | Description |
|---|---|
| ILogger |
Logging
Configuration for this proxy instance's built-in diagnostic logging - the replacement for the
removed ExceptionFunc callback. Every exception the proxy catches (even when handled
internally and never surfaced to user code) is reported through this logger at an appropriate
severity; see ProxyLoggingOptions for the console/file sinks, enable/disable
switch, and minimum level.
Mutate the returned instance (or assign a new one) at any point; each assignment/mutation you
want to take effect must be followed by ApplyLoggingConfiguration() (which
Start(bool) also calls automatically, so the configuration active at the moment the
proxy starts running is picked up for the run even if you never call it yourself). Calling it
again later - including while the proxy is already running - immediately swaps in the new
configuration; this is safe because logging never blocks or otherwise affects proxy traffic.
Declaration
public ProxyLoggingOptions Logging { get; set; }
Property Value
| Type | Description |
|---|---|
| ProxyLoggingOptions |
MaxBufferedBodyBytes
Maximum bytes the proxy will buffer for a single request or response body when
whole-body buffering is required (GetRequestBody / GetResponseBody,
authentication retry, and other paths that materialize the body). Bodies larger than
this limit are rejected with 413 (upstream request) or connection teardown (upstream
response). Streaming relays (H1, H2, and H3, including bridges) are not counted against
this budget: they are bounded by protocol flow control. Set to 0 to disable the limit
(not recommended). Default: 4,194,304 (4 MiB).
Declaration
public int MaxBufferedBodyBytes { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
MaxCachedConnections
Maximum number of concurrent connections per remote host in cache. Only meaningful when EnableConnectionPool is true; to disable pooling, set EnableConnectionPool to false rather than setting this to 0 - the pool eviction loop treats a value below 1 as "evict without limit while holding the pool-wide lock", which spins indefinitely once the cache for that host is empty and would stall every other connection acquire/release in the process. Rejected outright at assignment so that state cannot be reached. Default value is 128.
Declaration
public int MaxCachedConnections { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | The assigned value is less than 1. |
MaxConcurrentClientConnections
Maximum number of client connections admitted across all TCP-based endpoints at once. null (the default) disables the global admission gate, preserving today's unbounded behavior. When set, a connection beyond this limit is rejected and disposed immediately after accept, before a handler task is even started.
Enforced independently of ClientConnectionCount: see Titanium.Web.Proxy.ProxyServer.admittedClientConnectionCount for why. See also MaxConcurrentClients for a per-endpoint cap layered on top of this global one.
Declaration
public int? MaxConcurrentClientConnections { get; set; }
Property Value
| Type | Description |
|---|---|
| int? |
MaxConcurrentHttp11HttpsOriginCreates
Caps concurrent new HTTPS origin TCP/TLS opens on the H2→H1 bridge only
(MITM / re-encrypt). Pool hits (warm keep-alive) are uncapped. Cleartext H1 origins
are not gated. Default is Clamp(ProcessorCount, 4, 32). Set before the first
H2→H1 HTTPS origin open (typically before Start(bool)); changing the value
after the create gate has been used has no effect on the live semaphore.
Declaration
public int MaxConcurrentHttp11HttpsOriginCreates { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | The assigned value is less than 1. |
MaxDecodedHeaderListBytes
Maximum decoded HTTP/2 header list size in bytes, using RFC 7541 accounting (name.Length + value.Length + 32 per field). Requests or responses with a decoded header list exceeding this limit will be refused with RST_STREAM(ENHANCE_YOUR_CALM) (code 0xb). Set to 0 to disable the limit (not recommended). Default: 65,536 (64 KiB). Advertised via SETTINGS_MAX_HEADER_LIST_SIZE.
Declaration
public int MaxDecodedHeaderListBytes { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
MaxWebSocketFramePayloadBytes
Maximum WebSocket frame payload size in bytes that the proxy will accept during
frame-level interception (i.e. when BeforeWebSocketFrame has at least one
subscriber). Frames whose decoded payload exceeds this limit are handled by
WebSocketFrameBudget. Enforce
(the default) closes the connection with Close code 1009 (Message Too Big) before the
payload is buffered. Observe relays the frame unbuffered
and raises WebSocketFrameElided instead of invoking BeforeWebSocketFrame.
Raw-relay sessions (no BeforeWebSocketFrame subscriber) bypass this check
entirely and pass all frames through unvalidated.
Default: 16,777,216 (16 MiB).
Declaration
public int MaxWebSocketFramePayloadBytes { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
NetworkFailureRetryAttempts
Number of times to retry upon network failures when connection pool is enabled.
Declaration
public int NetworkFailureRetryAttempts { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
NoDelay
Gets or sets a Boolean value that specifies whether server and client stream Sockets are using the Nagle algorithm. Defaults to true, no nagle algorithm is used.
Declaration
public bool NoDelay { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
OriginHttpVersionPolicy
Controls which HTTP version is declared to the origin server on the request line, independently of the version the client declared to the proxy. Defaults to PreserveClientVersion, which matches the proxy's historical pass-through behavior exactly. Set to NormalizeToHttp11 to let HTTP/1.0 clients share pooled, persistent origin connections the same way HTTP/1.1 clients already do. This only changes the wire version written to the origin request line - it never changes the client-facing Http.Request.HttpVersion that event handlers observe, nor the version/persistence used to write the response back to the client.
Declaration
public OriginHttpVersionPolicy OriginHttpVersionPolicy { get; set; }
Property Value
| Type | Description |
|---|---|
| OriginHttpVersionPolicy |
PolicyModes
Which resource-bound PolicyFamily is enforced, observed, or disabled, per the plan's rollout section. Read live by each family's enforcement call site - not baked into a per-request snapshot at connection accept time - so assigning a new value here (a whole-object replacement, never a mutation of the previous instance) takes effect for the next check any in-flight or new request makes, without restarting the proxy. This is the "runtime switch to drop to Observe without redeploying" the plan requires; see WithAllObservedExceptDisabled() for the one-call way to do that.
Defaults to Balanced's modes (resource families enforced, Http2RelayValidation disabled so compressed H2 relay stays the verbatim-HPACK fast path). AllEnforce additionally enforces relay validation and is what PublicFacing applies. Assigning Profile also replaces this value with that profile's bundle; assign PolicyModes afterward to deviate from the selected profile's modes without changing anything else the profile set.
Declaration
public ProxyPolicyModes PolicyModes { get; set; }
Property Value
| Type | Description |
|---|---|
| ProxyPolicyModes |
Profile
The last profile applied via this property's setter, defaulting to
Balanced - the profile every field on this instance already
starts at, so a fresh new ProxyServer() reports Balanced
without needing its setter to run once at construction time.
Assigning this property applies its entire ProxyProfileSettings bundle - ResourceLimits, PolicyModes, SupportedSslProtocols, BlockPrivateNetworkDestinations, MaxConcurrentClientConnections and the deadline-seconds properties - as a single atomic assignment, so a reader can never observe a half-applied profile. Assigning any of those properties individually afterward overrides just that one, without reverting the rest of the profile's bundle.
Logged once per Start(bool) call, by name only - never with hosts, URLs or secrets, per the plan's rollout section.
Declaration
public ProxyProfile Profile { get; set; }
Property Value
| Type | Description |
|---|---|
| ProxyProfile |
ProxyAuthenticationRealm
Realm used during Proxy Basic Authentication.
Declaration
public string ProxyAuthenticationRealm { get; set; }
Property Value
| Type | Description |
|---|---|
| string |
ProxyAuthenticationSchemes
A collection of scheme types, e.g. basic, NTLM, Kerberos, Negotiate, to return if scheme authentication is required. Works in relation with ProxySchemeAuthenticateFunc.
Declaration
public IEnumerable<string> ProxyAuthenticationSchemes { get; set; }
Property Value
| Type | Description |
|---|---|
| IEnumerable<string> |
ProxyBasicAuthenticateFunc
A callback to authenticate proxy clients via basic authentication. Parameters are username and password as provided by client. Should return true for successful authentication.
Declaration
public Func<SessionEventArgsBase?, string, string, Task<bool>>? ProxyBasicAuthenticateFunc { get; set; }
Property Value
| Type | Description |
|---|---|
| Func<SessionEventArgsBase, string, string, Task<bool>> |
ProxyEndPoints
A list of IpAddress and port this proxy is listening to.
Declaration
public List<ProxyEndPoint> ProxyEndPoints { get; set; }
Property Value
| Type | Description |
|---|---|
| List<ProxyEndPoint> |
ProxyRunning
Is the proxy currently running?
Declaration
public bool ProxyRunning { get; }
Property Value
| Type | Description |
|---|---|
| bool |
ProxySchemeAuthenticateFunc
A pluggable callback to authenticate clients by scheme instead of requiring basic authentication through ProxyBasicAuthenticateFunc. Parameters are current working session, schemeType, and token as provided by a calling client. Should return success for successful authentication, continuation if the package requests, or failure.
Declaration
public Func<SessionEventArgsBase, string, string, Task<ProxyAuthenticationContext>>? ProxySchemeAuthenticateFunc { get; set; }
Property Value
| Type | Description |
|---|---|
| Func<SessionEventArgsBase, string, string, Task<ProxyAuthenticationContext>> |
RequestTimeoutSeconds
Total seconds allowed for a single request/response exchange after BeforeRequest returns (connect, send, wait for headers, and body copy). Default is 0 (disabled). Per-session override: RequestTimeout.
Declaration
public int RequestTimeoutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
ResourceLimits
The shared, immutable resource-bound snapshot (concurrent-stream cap, CONTINUATION
frame-count/wall-clock bounds, peer-initiated incomplete-stream-reset budget, and the
other limits described in ProxyResourceLimits) consulted by the HTTP/2
relay so a single proxy-owned value governs both what is enforced and what is advertised
to each peer, rather than admitting purely against whatever the origin advertised.
Assign a new ProxyResourceLimits (constructed via
Create(long, int, long, long?, long?, double?, int?, int, int?, int, TimeSpan, bool, int, int?)) to override the Default
snapshot. There is no artificial upper clamp: high-CPU/RAM hosts may pass larger
maxCachedConnectionsPerHost, maxConcurrentStreamsPerConnection, etc. as needed.
The live TCP pool depth knob MaxCachedConnections remains independently settable
and should usually be kept in sync with MaxCachedConnectionsPerHost.
Declaration
public ProxyResourceLimits ResourceLimits { get; set; }
Property Value
| Type | Description |
|---|---|
| ProxyResourceLimits |
ResponseHeaderContributor
Adds response headers on the way to the client without subscribing BeforeResponse. Plus CORS uses this so a listener can stay on H1 terminate-lite.
Declaration
public Action<Response>? ResponseHeaderContributor { get; set; }
Property Value
| Type | Description |
|---|---|
| Action<Response> |
ResponseHeaderTimeoutSeconds
Seconds to wait for the origin to send the response status line and headers after the request has been sent. Enforced with a linked CancellationTokenSource (not Socket receive timeout alone). When the deadline elapses a ProxyTimeoutException with ResponseHeader is raised (and may be converted to HTTP 504 before any response bytes have been committed to the client). Default is 0 (disabled). WebSocket upgrades, Server-Sent Events, raw tunnels, and sessions that already wrote a response status to the client are exempt; those waits use IdleReadTimeoutSeconds when configured. Per-session override: ResponseHeaderTimeout.
Declaration
public int ResponseHeaderTimeoutSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
ReuseSocket
When true (default), SO_REUSEADDR is requested where Titanium.Web.Proxy.Helpers.RunTime.IsSocketReuseAvailable() reports support (always on Windows; on non-Windows, .NET Core 3+ / compatible runtimes).
Declaration
public bool ReuseSocket { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
ReverseProxy
Optional reverse-proxy route/cluster configuration. When null (default),
Core keeps 6.x ForwardHost behavior with zero added cost on the hot path.
Declaration
public ReverseProxyOptions? ReverseProxy { get; set; }
Property Value
| Type | Description |
|---|---|
| ReverseProxyOptions |
ServerConnectionCount
Total number of active server connections (TCP plus upstream QUIC). For HTTP/3-only upstreams see Http3ServerConnectionCount.
Declaration
public int ServerConnectionCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
ShouldInterceptHttp
Optional per-request/stream predicate consulted only when the global interception gate is active. Return true to use the full SessionEventArgs path; return false to use the fast-forward path. null (the default) intercepts every request — preserving today's behavior.
Declaration
public Func<HttpInterceptionContext, bool>? ShouldInterceptHttp { get; set; }
Property Value
| Type | Description |
|---|---|
| Func<HttpInterceptionContext, bool> |
SupportedServerSslProtocols
Ssl versions offered on outbound HTTPS connections to origins (and upstream proxies).
Default None means “use SupportedSslProtocols” (typically TLS 1.2 and 1.3). Set an explicit mask to restrict or expand outbound-only independently of inbound client TLS.
Older docs described None as “same as the proxy client.” That coupling is incorrect across protocol translations (e.g. inbound QUIC is always TLS 1.3 while outbound TCP SslStream on macOS SecureTransport cannot offer TLS 1.3).
Declaration
public SslProtocols SupportedServerSslProtocols { get; set; }
Property Value
| Type | Description |
|---|---|
| SslProtocols |
SupportedSslProtocols
List of supported Ssl versions.
Defaults to TLS 1.2/1.3 only as of 5.0 - a breaking change from 4.x, which also enabled
SSL 3.0/TLS 1.0/1.1. Those legacy, broken-by-design protocols require an explicit opt-in
by assigning this property directly (e.g. SslProtocols.Tls | SslProtocols.Tls11 |
SslProtocols.Tls12 | SslProtocols.Tls13) if a legacy client/server genuinely requires
them.
Declaration
public SslProtocols SupportedSslProtocols { get; set; }
Property Value
| Type | Description |
|---|---|
| SslProtocols |
TcpTimeWaitSeconds
SO_LINGER timeout in seconds applied to client and upstream sockets via
LingerOption (enabled with this timeout).
This is not the kernel TCP TIME_WAIT duration — TIME_WAIT is controlled by the OS.
A positive value means Close may block up to that many seconds flushing send buffers;
use 0 for an abortive close (RST). Default is 0 so high-churn proxies avoid TIME_WAIT
accumulation; the 1-second connection disposal delay already prefers peer-first close.
Declaration
public int TcpTimeWaitSeconds { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
ThreadPoolWorkerThread
Customize the minimum ThreadPool size (increase it on a server).
Defaults to max(ProcessorCount * 2, 16) so short loopback/proxy workloads are not
starved while the pool is still ramping workers.
Declaration
public int ThreadPoolWorkerThread { get; set; }
Property Value
| Type | Description |
|---|---|
| int |
UpStreamEndPoint
Local adapter/NIC endpoint where proxy makes request via. Defaults via any IP addresses of this machine. When the resolved destination address family does not match this endpoint, it is ignored so dual-stack destinations can still connect (see UpStreamEndPointIPv4 / UpStreamEndPointIPv6).
Declaration
public IPEndPoint? UpStreamEndPoint { get; set; }
Property Value
| Type | Description |
|---|---|
| IPEndPoint |
UpStreamEndPointIPv4
Local bind endpoint used when the resolved upstream destination is IPv4. Takes precedence over UpStreamEndPoint for IPv4 destinations.
Declaration
public IPEndPoint? UpStreamEndPointIPv4 { get; set; }
Property Value
| Type | Description |
|---|---|
| IPEndPoint |
UpStreamEndPointIPv6
Local bind endpoint used when the resolved upstream destination is IPv6. Takes precedence over UpStreamEndPoint for IPv6 destinations.
Declaration
public IPEndPoint? UpStreamEndPointIPv6 { get; set; }
Property Value
| Type | Description |
|---|---|
| IPEndPoint |
UpStreamHttpProxy
External proxy used for Http requests.
Declaration
public IExternalProxy? UpStreamHttpProxy { get; set; }
Property Value
| Type | Description |
|---|---|
| IExternalProxy |
UpStreamHttpsProxy
External proxy used for Https requests.
Declaration
public IExternalProxy? UpStreamHttpsProxy { get; set; }
Property Value
| Type | Description |
|---|---|
| IExternalProxy |
UpstreamProxyConfigurationScript
If set, the upstream proxy will be detected by a script that will be loaded from the provided Uri
Declaration
public Uri? UpstreamProxyConfigurationScript { get; set; }
Property Value
| Type | Description |
|---|---|
| Uri |
ViaHeaderPseudonym
Pseudonym used in Via header fields appended to forwarded requests and responses (RFC 9110 §7.6.3). Defaults to DefaultViaHeaderPseudonym. Set to an empty string to disable Via header injection entirely. Loop detection uses this value: a request arriving with this pseudonym already present in Via is refused with 508 Loop Detected.
Declaration
public string ViaHeaderPseudonym { get; set; }
Property Value
| Type | Description |
|---|---|
| string |
WinAuthCredentialsProvider
Optional per-session credential provider for server 401 WinAuth (NTLM/Negotiate/Kerberos). Return null to use the current process identity (legacy behavior). Do not put plaintext passwords on SessionEventArgs — use this callback instead. Windows SSPI only; ignored on non-Windows platforms.
Declaration
public Func<SessionEventArgs, Task<WinAuthCredentials?>>? WinAuthCredentialsProvider { get; set; }
Property Value
| Type | Description |
|---|---|
| Func<SessionEventArgs, Task<WinAuthCredentials>> |
Methods
| Edit this page View SourceAddEndPoint(ProxyEndPoint)
Add a proxy end point.
Declaration
public void AddEndPoint(ProxyEndPoint endPoint)
Parameters
| Type | Name | Description |
|---|---|---|
| ProxyEndPoint | endPoint | The proxy endpoint. |
ApplyLoggingConfiguration()
Rebuilds the active logger/logger factory from the current Logging configuration, disposing any previously owned built-in providers. Called automatically from the constructor (with the default configuration) and from Start(bool). Call this explicitly any time after changing Logging and you want the change to take effect immediately - whether the proxy is stopped (e.g. before using CertificateManager directly) or already running.
Declaration
public void ApplyLoggingConfiguration()
ClearDecryptFailureBypass()
Clears all learned decrypt-bypass entries.
Declaration
public void ClearDecryptFailureBypass()
DisableAllSystemProxies()
Clear all proxy settings for current machine.
Declaration
public void DisableAllSystemProxies()
DisableSystemHttpProxy()
Clear HTTP proxy settings of current machine.
Declaration
public void DisableSystemHttpProxy()
DisableSystemHttpsProxy()
Clear HTTPS proxy settings of current machine.
Declaration
public void DisableSystemHttpsProxy()
DisableSystemProxy(ProxyProtocolType)
Clear the specified proxy setting for current machine.
Declaration
public void DisableSystemProxy(ProxyProtocolType protocolType)
Parameters
| Type | Name | Description |
|---|---|---|
| ProxyProtocolType | protocolType |
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Declaration
public void Dispose()
Dispose(bool)
Declaration
[SuppressMessage("ApiDesign", "RS0016:Add public types and members to the declared API", Justification = "Protected Dispose(bool) is required by the standard IDisposable pattern but is not public API.")]
protected virtual void Dispose(bool disposing)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | disposing |
ForceDecryptFailureBypass(string)
Marks host as actively bypassed (same as a forced learn after origin TLS failure).
Raises DecryptFailureBypassChanged when bypass newly becomes active.
Declaration
public bool ForceDecryptFailureBypass(string host)
Parameters
| Type | Name | Description |
|---|---|---|
| string | host |
Returns
| Type | Description |
|---|---|
| bool |
GetDecryptFailureBypassEntries()
Snapshot of current learned decrypt-bypass entries (may include non-active strikes).
Declaration
public IReadOnlyList<DecryptFailureBypassEntry> GetDecryptFailureBypassEntries()
Returns
| Type | Description |
|---|---|
| IReadOnlyList<DecryptFailureBypassEntry> |
RemoveDecryptFailureBypass(string)
Removes one host from the learned decrypt-bypass cache.
Declaration
public bool RemoveDecryptFailureBypass(string host)
Parameters
| Type | Name | Description |
|---|---|---|
| string | host |
Returns
| Type | Description |
|---|---|
| bool |
RemoveEndPoint(ProxyEndPoint)
Remove a proxy end point. Will throw error if the end point doesn't exist.
Declaration
public void RemoveEndPoint(ProxyEndPoint endPoint)
Parameters
| Type | Name | Description |
|---|---|---|
| ProxyEndPoint | endPoint | The existing endpoint to remove. |
RestoreOriginalProxySettings()
Restores the original proxy settings.
Declaration
public void RestoreOriginalProxySettings()
SetAsSystemHttpProxy(ExplicitProxyEndPoint)
Set the given explicit end point as the default proxy server for current machine.
Declaration
public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | The explicit endpoint. |
SetAsSystemHttpProxy(ExplicitProxyEndPoint, SystemProxySettings)
Set the given explicit end point as the default HTTP proxy server for current machine.
Declaration
public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint, SystemProxySettings settings)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | The explicit endpoint. |
| SystemProxySettings | settings | The Windows system proxy settings. |
SetAsSystemHttpsProxy(ExplicitProxyEndPoint)
Set the given explicit end point as the default proxy server for current machine.
Declaration
public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | The explicit endpoint. |
SetAsSystemHttpsProxy(ExplicitProxyEndPoint, SystemProxySettings)
Set the given explicit end point as the default HTTPS proxy server for current machine.
Declaration
public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint, SystemProxySettings settings)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | The explicit endpoint. |
| SystemProxySettings | settings | The Windows system proxy settings. |
SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType)
Set the given explicit end point as the default proxy server for current machine.
Declaration
public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | The explicit endpoint. |
| ProxyProtocolType | protocolType | The proxy protocol type. |
SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType, SystemProxySettings?)
Set the given explicit end point as the default proxy server for current machine.
Declaration
public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType, SystemProxySettings? settings)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | The explicit endpoint. |
| ProxyProtocolType | protocolType | The proxy protocol type. |
| SystemProxySettings | settings | The Windows system proxy settings, or null to preserve the current bypass list. |
SetHttp3Enabled(bool)
Enables or disables EnableHttp3. Enabling still requires MsQuic (IsSupported); disabling is always applied. Safe to call while the proxy is running — new origin connections pick up the change. Existing sessions keep the protocol they already negotiated.
Declaration
public bool SetHttp3Enabled(bool enabled)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | enabled |
Returns
| Type | Description |
|---|---|
| bool | true when HTTP/3 is enabled after the call. |
ShouldBypassDecryptForLearnedHost(string?)
When EnableDecryptFailureBypass is on and host is actively
bypassed, returns true (decrypt should be skipped).
Declaration
public bool ShouldBypassDecryptForLearnedHost(string? host)
Parameters
| Type | Name | Description |
|---|---|---|
| string | host |
Returns
| Type | Description |
|---|---|
| bool |
Start(bool)
Start this proxy server instance.
Transactional: if any endpoint fails to start, every listener this call already started is stopped, the system-upstream-proxy resolver (if this call created one) is disposed, and ProxyRunning is left false before the exception propagates. A caller that catches the exception is left with an instance in exactly the same state as before calling Start(bool), not a partially-bound proxy with some endpoints silently listening.
Declaration
public void Start(bool changeSystemProxySettings = true)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | changeSystemProxySettings | Whether or not clear any system proxy settings which is pointing to our own endpoint (causing a cycle). E.g due to ungracious proxy shutdown before. |
Stop()
Stop this proxy server instance. Endpoints remain registered so Start(bool) can re-listen on the same ports. In-flight sessions are cancelled; pooled upstream connections are cleared. The connection factory itself stays usable for a subsequent Start (it is only disposed with the proxy).
Declaration
public void Stop()
StopAsync(TimeSpan?)
Asynchronously stop this proxy server, cancel in-flight sessions, and wait briefly for client connection count to drain before clearing the upstream pool.
Declaration
public Task StopAsync(TimeSpan? drainTimeout = null)
Parameters
| Type | Name | Description |
|---|---|---|
| TimeSpan? | drainTimeout | Maximum time to wait for active client handlers to exit after cancellation. Defaults to 5 seconds. |
Returns
| Type | Description |
|---|---|
| Task |
TryDisableAllSystemProxies()
Clear all OS proxy settings without throwing.
Declaration
public SystemProxyChangeResult TryDisableAllSystemProxies()
Returns
| Type | Description |
|---|---|
| SystemProxyChangeResult |
TryDisableSystemProxy(ProxyProtocolType)
Clear OS proxy for the given protocols without throwing.
Declaration
public SystemProxyChangeResult TryDisableSystemProxy(ProxyProtocolType protocolType)
Parameters
| Type | Name | Description |
|---|---|---|
| ProxyProtocolType | protocolType |
Returns
| Type | Description |
|---|---|
| SystemProxyChangeResult |
TryEnableHttp3IfSupported()
Turns on EnableHttp3 when MsQuic is available (IsSupported). Hosts (CLI, Inspector, examples) should call this instead of setting EnableHttp3 blindly. Returns true when HTTP/3 was enabled.
Declaration
public bool TryEnableHttp3IfSupported()
Returns
| Type | Description |
|---|---|
| bool |
TryRestoreOriginalProxySettings()
Restore OS proxy without throwing.
Declaration
public SystemProxyChangeResult TryRestoreOriginalProxySettings()
Returns
| Type | Description |
|---|---|
| SystemProxyChangeResult |
TrySetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType, SystemProxySettings?)
Enable OS system proxy without throwing. Failures are logged and returned so Inspector/CLI can show a status message instead of crashing.
Declaration
public SystemProxyChangeResult TrySetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType, SystemProxySettings? settings = null)
Parameters
| Type | Name | Description |
|---|---|---|
| ExplicitProxyEndPoint | endPoint | |
| ProxyProtocolType | protocolType | |
| SystemProxySettings | settings |
Returns
| Type | Description |
|---|---|
| SystemProxyChangeResult |
Events
| Edit this page View SourceAfterResponse
Intercept after response event from server.
Declaration
public event AsyncEventHandler<SessionEventArgs>? AfterResponse
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<SessionEventArgs> |
BeforeRequest
Intercept request event to server.
Declaration
public event AsyncEventHandler<SessionEventArgs>? BeforeRequest
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<SessionEventArgs> |
BeforeResponse
Intercept response event from server.
Declaration
public event AsyncEventHandler<SessionEventArgs>? BeforeResponse
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<SessionEventArgs> |
BeforeUpStreamConnectRequest
Intercept connect request sent to upstream proxy.
Declaration
public event AsyncEventHandler<ConnectRequest>? BeforeUpStreamConnectRequest
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<ConnectRequest> |
ClientCertificateSelectionCallback
Event to override client certificate selection during mutual SSL authentication.
Declaration
public event AsyncEventHandler<CertificateSelectionEventArgs>? ClientCertificateSelectionCallback
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<CertificateSelectionEventArgs> |
ClientConnectionCountChanged
Event occurs when client connection count changed.
Declaration
public event EventHandler? ClientConnectionCountChanged
Event Type
| Type | Description |
|---|---|
| EventHandler |
DecryptFailureBypassChanged
Raised when a host becomes actively bypassed (threshold reached or same-CONNECT mark). Handlers must not block; Inspector marshals to the UI thread.
Declaration
public event EventHandler<DecryptFailureBypassEntry>? DecryptFailureBypassChanged
Event Type
| Type | Description |
|---|---|
| EventHandler<DecryptFailureBypassEntry> |
Http3ClientConnectionCountChanged
Event occurs when inbound HTTP/3 client connection count changed.
Declaration
public event EventHandler? Http3ClientConnectionCountChanged
Event Type
| Type | Description |
|---|---|
| EventHandler |
Http3ServerConnectionCountChanged
Event occurs when upstream HTTP/3 server connection count changed.
Declaration
public event EventHandler? Http3ServerConnectionCountChanged
Event Type
| Type | Description |
|---|---|
| EventHandler |
OnClientConnectionCreate
Customize TcpClient used for client connection upon create.
Declaration
public event AsyncEventHandler<Socket>? OnClientConnectionCreate
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<Socket> |
OnRequestBodyWrite
Intercept request body send event to server. Subscribe to inspect or modify the request body chunk-by-chunk as it streams to the server, without buffering the whole body. Do not combine with SessionEventArgs.GetRequestBody (which buffers).
Declaration
public event AsyncEventHandler<BeforeBodyWriteEventArgs>? OnRequestBodyWrite
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<BeforeBodyWriteEventArgs> |
OnResponseBodyWrite
Intercept response body send event to client. Subscribe to inspect or modify the response body chunk-by-chunk as it streams to the client, without buffering the whole body. Do not combine with SessionEventArgs.GetResponseBody (which buffers).
Declaration
public event AsyncEventHandler<BeforeBodyWriteEventArgs>? OnResponseBodyWrite
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<BeforeBodyWriteEventArgs> |
OnServerConnectionCreate
Customize TcpClient used for server connection upon create.
Declaration
public event AsyncEventHandler<Socket>? OnServerConnectionCreate
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<Socket> |
ServerCertificateValidationCallback
Event to override the default verification logic of remote SSL certificate received during authentication.
Declaration
public event AsyncEventHandler<CertificateValidationEventArgs>? ServerCertificateValidationCallback
Event Type
| Type | Description |
|---|---|
| AsyncEventHandler<CertificateValidationEventArgs> |
ServerConnectionCountChanged
Event occurs when server connection count changed.
Declaration
public event EventHandler? ServerConnectionCountChanged
Event Type
| Type | Description |
|---|---|
| EventHandler |