Interface HttpProxyServerBootstrap


public interface HttpProxyServerBootstrap
Configures and starts a HttpProxyServer.
  • Method Details

    • withName

      Name used for thread names and logging.
      Parameters:
      name - the name used for logging and thread names
      Returns:
      this bootstrap
    • withAddress

      Sets the proxy listener address.
      Parameters:
      address - the proxy listener address
      Returns:
      this bootstrap
    • withPort

      HttpProxyServerBootstrap withPort(int port)
      Port to listen on; 0 picks an ephemeral port.
      Parameters:
      port - the listening port, or zero for an ephemeral port
      Returns:
      this bootstrap
    • withAllowLocalOnly

      HttpProxyServerBootstrap withAllowLocalOnly(boolean allowLocalOnly)
      Listen on the loopback interface only.
      Parameters:
      allowLocalOnly - whether to listen only on the loopback interface
      Returns:
      this bootstrap
    • withSslContextSource

      HttpProxyServerBootstrap withSslContextSource(SslContextSource sslContextSource)
      Serve the proxy itself over TLS (an "HTTPS proxy").
      Parameters:
      sslContextSource - the TLS context provider for the proxy listener
      Returns:
      this bootstrap
    • withAuthenticateSslClients

      HttpProxyServerBootstrap withAuthenticateSslClients(boolean authenticateSslClients)
      Require client certificates on the proxy's TLS listener.
      Parameters:
      authenticateSslClients - whether the TLS listener requires client certificates
      Returns:
      this bootstrap
    • withProxyAuthenticator

      HttpProxyServerBootstrap withProxyAuthenticator(ProxyAuthenticator proxyAuthenticator)
      Requires clients to authenticate: with Basic credentials by default, or with any scheme through ProxyAuthenticator.authenticate(org.microproxy.http.HttpRequest, FlowContext).
      Parameters:
      proxyAuthenticator - the client authentication policy
      Returns:
      this bootstrap
    • withChainProxyManager

      HttpProxyServerBootstrap withChainProxyManager(ChainedProxyManager chainProxyManager)
      Sets the manager selecting upstream proxies.
      Parameters:
      chainProxyManager - the manager selecting upstream proxies
      Returns:
      this bootstrap
    • getChainProxyManager

      default ChainedProxyManager getChainProxyManager()
      The chained proxy manager configured so far, or null; lets extensions wrap it.
      Returns:
      the configured chained proxy manager, or null
    • withManInTheMiddle

      HttpProxyServerBootstrap withManInTheMiddle(MitmManager mitmManager)
      Intercepts CONNECT tunnels with mitmManager. To decide per client connection (per user, client address, ...), override its FlowContext overloads or use MitmManager.perConnection(java.util.function.Function<? super org.microproxy.FlowContext, ? extends org.microproxy.MitmManager>).
      Parameters:
      mitmManager - the manager providing interception TLS contexts
      Returns:
      this bootstrap
    • withFiltersSource

      HttpProxyServerBootstrap withFiltersSource(HttpFiltersSource filtersSource)
      Sets the source of per-request filters.
      Parameters:
      filtersSource - the source of per-request filters
      Returns:
      this bootstrap
    • plusFiltersSource

      HttpProxyServerBootstrap plusFiltersSource(HttpFiltersSource filtersSource)
      Adds a filters source after those already configured; they run as a HttpFiltersChain.
      Parameters:
      filtersSource - the source of per-request filters
      Returns:
      this bootstrap
    • getFiltersSource

      HttpFiltersSource getFiltersSource()
      Returns the filters source configured so far (never null).
      Returns:
      the filters source configured so far (never null)
    • withHttpCache

      HttpProxyServerBootstrap withHttpCache(HttpCache cache)
      Caches responses (HttpCache). The cache always runs after the filters sources, whichever order they were configured in.
      Parameters:
      cache - the HTTP cache to use
      Returns:
      this bootstrap
    • withStats

      default HttpProxyServerBootstrap withStats(StatsRegistry registry)
      Keeps the proxy's metrics in registry: Envoy's stats (http.<name>.*, cluster.<name>.*, listener.<address>.*, server.*, ...; see StatsRegistry), which StatsFormatter renders for Prometheus and StatsdSink pushes to statsd. The http stats are named after the proxy's name. StatsRegistry.NOOP (the default) turns metrics off, which costs nothing.
      Parameters:
      registry - the registry, shared with whatever else counts into it
      Returns:
      this bootstrap
    • withMetrics

      default HttpProxyServerBootstrap withMetrics(boolean enabled)
      Turns metrics on with a registry of the default settings (or keeps the one withStats(org.microproxy.stats.StatsRegistry) gave), or off.
      Parameters:
      enabled - whether to keep metrics
      Returns:
      this bootstrap
    • getStats

      default StatsRegistry getStats()
      Returns the registry configured so far: StatsRegistry.NOOP without metrics.
      Returns:
      the registry configured so far: StatsRegistry.NOOP without metrics
    • withTracer

      default HttpProxyServerBootstrap withTracer(FlowTracer tracer)
      Traces the proxy's exchanges and flows with tracer (see FlowTracer): the microproxy-otel module's OpenTelemetry tracing and OTLP export, or another. FlowTracer.NOOP (the default) traces nothing, and costs nothing. The proxy closes the tracer when it stops.
      Parameters:
      tracer - the tracer
      Returns:
      this bootstrap
    • getTracer

      default FlowTracer getTracer()
      Returns the tracer configured so far: FlowTracer.NOOP without one.
      Returns:
      the tracer configured so far: FlowTracer.NOOP without one
    • withFailureResponder

      HttpProxyServerBootstrap withFailureResponder(FailureResponder responder)
      Makes the proxy's own answers when requests fail (see ProxyFailure): unreachable or misbehaving servers, timeouts, an exhausted connection pool, refused requests. Filters' HttpFilters.proxyToServerFailure(org.microproxy.ProxyFailure) answers take precedence; null (the default) or a responder returning null keeps the proxy's plain-text answers.
      Parameters:
      responder - the function creating a rejection or failure response
      Returns:
      this bootstrap
    • withTransparent

      HttpProxyServerBootstrap withTransparent(boolean transparent)
      Transparent proxying: forward messages without adding Via or stripping hop-by-hop headers, and accept TLS connections that arrive without a CONNECT, such as ones a firewall redirects to the proxy. Such a connection is routed by its ClientHello's server name (SNI) to that host's port 443 (see withTransparentTlsPort(int)), and is intercepted or tunnelled as a CONNECT to that host would be. Java cannot read a redirected connection's original destination address, so a ClientHello without SNI cannot be routed: the connection is refused with a TLS unrecognized_name alert. Plain HTTP is routed by its Host field when withAllowRequestToOriginServer(boolean) allows origin-form requests.
      Parameters:
      transparent - whether to proxy transparently
      Returns:
      this bootstrap
    • withTransparentTlsPort

      default HttpProxyServerBootstrap withTransparentTlsPort(int port)
      The port that TLS connections arriving without a CONNECT in transparent mode are routed to, on the host their SNI names (default 443).
      Parameters:
      port - the server port, 1 to 65535
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if the port is out of range
    • withTransparentQuicPort

      default HttpProxyServerBootstrap withTransparentQuicPort(int port)
      Opens a transparent QUIC listener on UDP port (0 for any): the UDP counterpart of transparent TLS, for QUIC (HTTP/3, UDP 443) that a firewall redirects to the proxy, such as iptables -t nat -A PREROUTING -p udp --dport 443 -j REDIRECT --to-ports <port>. Needs transparent mode and the optional quic and http3-codec modules.

      Java cannot read a redirected datagram's original destination either, so each new client flow (a client address and the Destination Connection ID of its Initial packets) is routed by the SNI of the ClientHello in its Initial packets, which the proxy decrypts, to that host's transparent TLS port. The rules and hooks that decide on TLS decide on it too: ignored and allowed hosts, HttpFilters.proxyToServerAllowMitm() and HttpFilters.proxyToServerAllowMitm(ClientHello) on a CONNECT the proxy makes up, and MitmManager.shouldIntercept(org.microproxy.ClientHello, org.microproxy.FlowContext). An intercepted client offering ALPN h3 gets a certificate the CertificateAuthorityMitmManager issues for its SNI and is served HTTP/3 like any client, with its requests going to that host (over HTTP/3 with withHttp3Upstream(boolean), else over TCP). Everything else (no MITM manager, a declined or ignored host, other ALPN protocols) is relayed untouched to the server as UDP, from a socket per flow, until the flow is idle for Http3Options.transparentRelayIdleTimeout().

      Parameters:
      port - the UDP port, 0 for any
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if the port is out of range
      See Also:
    • withIgnoreHosts

      default HttpProxyServerBootstrap withIgnoreHosts(String... patterns)
      Hosts whose TLS connections are never intercepted, but tunnelled untouched, so their clients see the real server's certificate (mitmproxy's ignore_hosts). Each pattern is a regular expression searched for, ignoring case, in host:port names of the connection: the CONNECT target and the client's SNI with that port. For example, example\.com ignores example.com:443 and www.example.com:443; ^example\.com:443$ ignores only that one. A connection whose CONNECT target matches is tunnelled without waiting for its ClientHello. Replaces earlier patterns; none by default. Only matters with a MITM manager.
      Parameters:
      patterns - the regular expressions
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if a pattern is not a valid regular expression
    • withAllowHosts

      default HttpProxyServerBootstrap withAllowHosts(String... patterns)
      Hosts whose TLS connections are intercepted; all others are tunnelled untouched (mitmproxy's allow_hosts). Patterns are matched as for withIgnoreHosts(java.lang.String...), which still applies to the allowed hosts. Replaces earlier patterns; none (everything allowed) by default.
      Parameters:
      patterns - the regular expressions
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if a pattern is not a valid regular expression
    • withReverseProxy

      default HttpProxyServerBootstrap withReverseProxy(ReverseProxyMode mode)
      Runs as a reverse proxy for one upstream server (see ReverseProxyMode); null (the default) is a forward proxy.
      Parameters:
      mode - the upstream, or null
      Returns:
      this bootstrap
    • withReverseProxy

      default HttpProxyServerBootstrap withReverseProxy(String spec)
      Runs as a reverse proxy for the upstream spec, such as https://example.com (see ReverseProxyMode.parse(java.lang.String)).
      Parameters:
      spec - the upstream, [scheme://]host[:port]
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if the specification is invalid
    • withSocksServer

      default HttpProxyServerBootstrap withSocksServer(boolean socks)
      Makes the listener a SOCKS server (mitmproxy's socks5 mode): SOCKS5 (RFC 1928), and SOCKS4 and 4a, with the CONNECT command only. With a proxy authenticator, SOCKS5 clients authenticate with a username and password (RFC 1929), which the authenticator sees as Proxy-Authorization: Basic; a client without credentials, SOCKS4's included, may proceed only if the authenticator accepts a request without them.

      Each request is served as a CONNECT to its destination would be, a CONNECT that filters and trackers see but that the client never sent: routing and chained proxies, the server connection, then the client's first bytes decide (see HttpFilters.proxyToServerAllowMitm(ClientHello)): TLS is intercepted or tunnelled, plain HTTP is served as HTTP, through the filters, even without a MITM manager, and anything else is tunnelled. The client is answered once the server is connected, with a reply code that tells why it could not be. FlowContext.socksVersion() tells such clients apart. Off by default; starting fails with withReverseProxy(org.microproxy.ReverseProxyMode) or withSslContextSource(org.microproxy.SslContextSource).

      Parameters:
      socks - whether the listener serves SOCKS clients only
      Returns:
      this bootstrap
    • withSocksDetection

      default HttpProxyServerBootstrap withSocksDetection(boolean detect)
      Serves SOCKS clients on the listener besides HTTP ones, told apart by their first byte: 5 for SOCKS5, 4 for SOCKS4 and 4a, which no HTTP request starts with. They are served as with withSocksServer(boolean), and not with a reverse proxy or a TLS listener either. Off by default.
      Parameters:
      detect - whether to serve SOCKS clients too
      Returns:
      this bootstrap
    • withKeepHostHeader

      default HttpProxyServerBootstrap withKeepHostHeader(boolean keep)
      In reverse proxy mode, keeps the Host field the client sent instead of setting it to the upstream's (mitmproxy's keep_host_header). Off by default.
      Parameters:
      keep - whether to keep the client's Host
      Returns:
      this bootstrap
    • withIdleConnectionTimeout

      HttpProxyServerBootstrap withIdleConnectionTimeout(int idleConnectionTimeoutInSeconds)
      Sets the maximum idle time for client and server connections.
      Parameters:
      idleConnectionTimeoutInSeconds - the maximum idle time in seconds
      Returns:
      this bootstrap
    • withIdleConnectionTimeout

      HttpProxyServerBootstrap withIdleConnectionTimeout(Duration idleConnectionTimeout)
      Sets the maximum idle time for client and server connections.
      Parameters:
      idleConnectionTimeout - the maximum time a connection may remain idle
      Returns:
      this bootstrap
    • withRequestHeadTimeout

      HttpProxyServerBootstrap withRequestHeadTimeout(Duration timeout)
      Sets the maximum time for an HTTP/1 request head to arrive, from its first byte through the terminating blank line. A timed-out request receives 408 Request Timeout; the connection is closed. Zero disables the deadline. The default is 30 seconds. An HTTP/1 protocol policy may override this value with Http1PolicyBuilder.requestHeadTimeout(java.time.Duration).
      Parameters:
      timeout - the maximum request-head time, or zero for no deadline
      Returns:
      this bootstrap
    • withConnectTimeout

      HttpProxyServerBootstrap withConnectTimeout(int connectTimeoutMs)
      Connect timeout for outbound connections in milliseconds.
      Parameters:
      connectTimeoutMs - the outbound connect timeout in milliseconds; zero uses the system default
      Returns:
      this bootstrap
    • withTlsHandshakeTimeout

      HttpProxyServerBootstrap withTlsHandshakeTimeout(Duration timeout)
      The longest a TLS handshake may take, with clients and with servers (default 10 seconds; zero for no limit). The idle timeout alone does not bound it, since it restarts with every byte received.
      Parameters:
      timeout - the maximum TLS handshake duration
      Returns:
      this bootstrap
    • withTlsProtocols

      default HttpProxyServerBootstrap withTlsProtocols(String... protocols)
      The TLS versions allowed on every TLS socket the proxy creates: its TLS listener (withSslContextSource(org.microproxy.SslContextSource)), both sides of an intercepted session, and connections to TLS chained proxies. Default TLSv1.3 and TLSv1.2. Each socket enables those of them that its SSLContext supports; if it supports none, the handshake fails with an error naming both lists. The protocols are set right after the socket is created, before SslContextSource.configure(javax.net.ssl.SSLSocket, boolean), MitmManager.configureServerSocket(javax.net.ssl.SSLSocket, FlowContext) or SslContextSource.configure(javax.net.ssl.SSLSocket, boolean) run, so a hook that sets its own protocols wins. No protocols leaves every context's own defaults; the JDK's jdk.tls.disabledAlgorithms applies either way.
      Parameters:
      protocols - the enabled TLS protocol names, such as TLSv1.3
      Returns:
      this bootstrap
    • withTlsRetryWithoutSni

      default HttpProxyServerBootstrap withTlsRetryWithoutSni(boolean retry)
      Whether a TLS handshake with a server that ends with the server's fatal unrecognized_name alert (RFC 6066 section 3, RFC 8446 section 6.2), its answer to a server name (SNI) it does not recognize, is tried once more on a new connection, without SNI. Some misconfigured servers answer so for names they do serve; the JDK's HttpsURLConnection once retried the same way, and LittleProxy forks copied it.

      Only the SNI extension is left out: the retry offers the same versions and ALPN protocols, and the certificate is validated with the same trust and checked against the same host name as the first attempt's. SNI authenticates nothing, so leaving it out weakens no check; the server may present another (default) certificate, which must then pass the same checks. The retry is logged, and counted in the cluster's ssl.retry_without_sni; a retry that fails too fails the request as the first attempt would have. Each new connection to such a server pays the extra handshake: nothing is remembered about the server. It applies to servers (intercepted sessions, TLS origination, a reverse proxy's https:// upstream), not to TLS chained proxies, and not to HTTP/3.

      Off by default, so that a server that rejects its name fails visibly, as it does for browsers and the JDK's HttpClient, and the proxy never sends a ClientHello other than the one asked for; on by default for HTTP/1 clients with withLittleProxyCompatibility(boolean). This sets the field for every client protocol (onAllProtocols(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>), ProtocolPolicy.tlsRetryWithoutSni()), where it wins over that preset; a protocol's own policy (onHttp1(java.util.function.Consumer<org.microproxy.Http1PolicyBuilder>), ...) wins over it.

      Parameters:
      retry - whether to retry without SNI after an unrecognized_name alert
      Returns:
      this bootstrap
    • onAllProtocols

      default HttpProxyServerBootstrap onAllProtocols(Consumer<ProtocolPolicy.Builder> policy)
      Sets fields of the ProtocolPolicy of every client protocol: below each protocol's own (onHttp1(java.util.function.Consumer<org.microproxy.Http1PolicyBuilder>), onHttp2(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>), onHttp3(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>)), above the protocols' defaults. Calls add up: a later one overwrites only the fields it sets. The bootstrap's setters for those fields (withTlsRetryWithoutSni(boolean)) set them here too.
      
       bootstrap.onAllProtocols(p -> p.tlsRetryWithoutSni(true));
       
      Parameters:
      policy - sets fields on the builder it is given
      Returns:
      this bootstrap
    • onHttp1

      Sets fields of the ProtocolPolicy of HTTP/1.x clients, which win over those set for every protocol (onAllProtocols(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>)) and over HTTP/1's defaults. The builder also takes the fields only HTTP/1 has (Http1PolicyBuilder.allowChunkedLength(boolean)). Calls add up: a later one overwrites only the fields it sets.
      
       bootstrap.onHttp1(p -> p.preset(ProtocolPolicy.littleProxy()).filterConnectAnswer(true));
       
      Parameters:
      policy - sets fields on the builder it is given
      Returns:
      this bootstrap
    • onHttp2

      Sets fields of the ProtocolPolicy of HTTP/2 clients (h2 and h2c), which win over those set for every protocol (onAllProtocols(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>)). Calls add up.
      Parameters:
      policy - sets fields on the builder it is given
      Returns:
      this bootstrap
    • onHttp3

      Sets fields of the ProtocolPolicy of HTTP/3 clients (the HTTP/3 listener, transparent QUIC, QUIC inside CONNECT-UDP flows), which win over those set for every protocol (onAllProtocols(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>)). Calls add up.
      Parameters:
      policy - sets fields on the builder it is given
      Returns:
      this bootstrap
    • withLittleProxyCompatibility

      HttpProxyServerBootstrap withLittleProxyCompatibility(boolean compatible)
      Makes ProtocolPolicy.littleProxy() the defaults of HTTP/1.x clients' policy, so that the proxy behaves like LittleProxy where MicroProxy deliberately differs, for filters that depend on it. LittleProxy only ever spoke HTTP/1.x: HTTP/2 and HTTP/3 clients keep MicroProxy's defaults unless their own policies say otherwise (onHttp2(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>), onHttp3(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>)). Every field set explicitly, for HTTP/1 (onHttp1(java.util.function.Consumer<org.microproxy.Http1PolicyBuilder>)) or for all protocols (onAllProtocols(java.util.function.Consumer<org.microproxy.ProtocolPolicy.Builder>), withTlsRetryWithoutSni(boolean)), wins over the preset. The fields and their LittleProxy sources are listed at ProtocolPolicy.littleProxy():

      HttpFilters.proxyToClientResponse(org.microproxy.http.HttpObject) may replace the proxy's own responses, as in LittleProxy 2.x and by default (GeneratedResponses.REPLACEABLE); forks of LittleProxy 1.x let it change them in place only, which onHttp1(p -> p.generatedResponses(GeneratedResponses.IN_PLACE)) restores.

      Security fixes (strict request parsing, error pages that do not echo the request) are not affected. Off by default.

      Parameters:
      compatible - whether HTTP/1's defaults are LittleProxy's
      Returns:
      this bootstrap
    • withLittleProxyCompatibility

      default HttpProxyServerBootstrap withLittleProxyCompatibility()
      Same as withLittleProxyCompatibility(true).
      Returns:
      this bootstrap
    • withServerResolver

      HttpProxyServerBootstrap withServerResolver(HostResolver serverResolver)
      Sets the resolver used for upstream host names.
      Parameters:
      serverResolver - the resolver for upstream host names
      Returns:
      this bootstrap
    • withStrippedRequestHeaders

      default HttpProxyServerBootstrap withStrippedRequestHeaders(String... names)
      Removes these headers (case-insensitively) from every request right before it is written upstream: after all filters, so headers that filters added are removed too. It applies to plain requests, requests inside intercepted (MITM) sessions, upgrade requests, and the CONNECT requests sent to HTTP chained proxies; the bytes of an uninspected tunnel are never touched. Replaces the names set so far; no names turns it off.
      Parameters:
      names - the request header names to strip before forwarding
      Returns:
      this bootstrap
    • plusStrippedRequestHeaders

      default HttpProxyServerBootstrap plusStrippedRequestHeaders(String... names)
      Adds to the headers removed from requests sent upstream (see withStrippedRequestHeaders(java.lang.String...)).
      Parameters:
      names - the additional request header names to strip before forwarding
      Returns:
      this bootstrap
    • withoutTracingHeadersUpstream

      default HttpProxyServerBootstrap withoutTracingHeadersUpstream()
      Removes distributed tracing headers (HttpHeaderNames.TRACING_HEADERS: traceparent, tracestate, baggage, the B3 headers, uber-trace-id, X-Amzn-Trace-Id, X-Cloud-Trace-Context, grpc-trace-bin, sentry-trace) from requests sent upstream, so clients' trace ids and baggage do not leak to servers. Adds to plusStrippedRequestHeaders(java.lang.String...).
      Returns:
      this bootstrap
    • withAltSvcH3Stripping

      default HttpProxyServerBootstrap withAltSvcH3Stripping(boolean strip)
      Whether to remove HTTP/3 alternatives (h3, h3-29, h3-Q050, ..., and Google QUIC's quic) from Alt-Svc response headers, keeping the other alternatives (such as h2=":443") and their parameters as they are. A header left with no alternative is removed; Alt-Svc: clear is never touched.

      A client that learns an origin speaks HTTP/3 may move to QUIC over UDP, which bypasses the proxy: browsers never send QUIC through an HTTP proxy, and a transparent deployment often redirects only TCP. Where the proxy is meant to see the traffic, that is a hole, so this is on by default when interception or transparent mode is configured, and off otherwise; except, with a transparent QUIC listener, for clients whose traffic was redirected to the proxy, whose QUIC reaches it too. Clients can still learn about HTTP/3 from DNS HTTPS records, so transparent deployments without a QUIC listener should also block UDP port 443, which makes clients fall back to TCP. Setting this applies to every client.

      Responses from servers are rewritten before HttpFilters.proxyToClientResponse(org.microproxy.http.HttpObject) sees them; short-circuit responses from filters (and the cache) after it.

      Parameters:
      strip - whether to remove HTTP/3 and QUIC advertisements from Alt-Svc headers
      Returns:
      this bootstrap
    • withoutHttp3Advertisement

      default HttpProxyServerBootstrap withoutHttp3Advertisement()
      Same as withAltSvcH3Stripping(true): clients are not told about HTTP/3 (see there).
      Returns:
      this bootstrap
    • withChainedProxyRetryBackoff

      default HttpProxyServerBootstrap withChainedProxyRetryBackoff(RetryBackoff backoff)
      Waits between attempts when a connection through one chained proxy (or the direct fallback) fails and the next candidate from the ChainedProxyManager is tried, as backoff says: RetryBackoff.exponential(java.time.Duration, java.time.Duration) for exact doubling waits, RetryBackoff.exponentialWithJitter(java.time.Duration, java.time.Duration) for random ones ("full jitter"), RetryBackoff.fixed(java.time.Duration) for the same wait every time. It never waits before the first attempt or after the last, stops waiting (and gives up on the request) when the client disconnects meanwhile, and by default waits at most 30 seconds or the connect timeout in total per request, whichever is less; once that is spent, the remaining candidates are tried without waiting. The policy can set another budget (RetryBackoff.withBudget(java.time.Duration)) or none (RetryBackoff.unbudgeted()), to wait every time it names as LittleProxy forks that added a backoff did. The wait counts towards the connect phase of FlowContext.timings(). A request's filters can choose another backoff (HttpFilters.chainedProxyRetryBackoff()). Off (RetryBackoff.none()) by default, as in LittleProxy, which tries the next chained proxy at once; null turns it off again.
      Parameters:
      backoff - the backoff between attempts, or null for none
      Returns:
      this bootstrap
    • withChainedProxyRetryBackoff

      default HttpProxyServerBootstrap withChainedProxyRetryBackoff(Duration initial, Duration max)
      Exponential backoff with full jitter between chained proxy attempts: withChainedProxyRetryBackoff(RetryBackoff.exponentialWithJitter(initial, max)). Before attempt n + 1 the proxy waits a random time between zero and initial * 2^(n-1), capped at max. A null maximum is the initial wait; a null initial wait turns the backoff off. For exact, unjittered waits use withChainedProxyRetryBackoff(RetryBackoff) with RetryBackoff.exponential(java.time.Duration, java.time.Duration).
      Parameters:
      initial - the ceiling of the delay before the first retry
      max - the ceiling of every retry delay
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if initial is not positive or max is below it
    • withHttp2

      default HttpProxyServerBootstrap withHttp2(boolean enabled)
      Serves HTTP/2 to clients on intercepted TLS (withManInTheMiddle(org.microproxy.MitmManager)) and the proxy TLS listener (withSslContextSource(org.microproxy.SslContextSource)): the client handshake offers h2 and http/1.1 through ALPN, and a client that picks h2 has each of its streams handled as an exchange of its own, concurrently, with the same filters, cache, authentication, failure answers and trackers as HTTP/1 requests. Requests reach servers as HTTP/1.1, each stream on a server connection of its own, unless withHttp2Upstream(boolean) lets them share an HTTP/2 connection (as it does by default). Limits are set with withHttp2Options(org.microproxy.Http2Options).

      On by default when the optional http2-codec module is on the class path; false offers clients HTTP/1.1 only. Without the module, a server left at the default speaks HTTP/1.1 to clients (and logs so once), while starting one with true fails with IllegalStateException.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • withHttp2Upstream

      default HttpProxyServerBootstrap withHttp2Upstream(boolean enabled)
      Speaks HTTP/2 to origin servers that offer it: TLS connections to servers (intercepted HTTPS, and the https:// requests of withTlsOrigination(boolean), secure WebSockets included) offer h2 and http/1.1 through ALPN, and a server that picks h2 gets every exchange for it as a stream on one connection, shared by concurrent exchanges up to the server's stream limit; others keep HTTP/1.1. Independent of withHttp2(boolean), which is about clients.

      On by default when the optional http2-codec module is on the class path; false offers servers HTTP/1.1 only. Without the module, a server left at the default speaks HTTP/1.1 to servers (and logs so once), while starting one with true fails with IllegalStateException.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • withHttp2Cleartext

      default HttpProxyServerBootstrap withHttp2Cleartext(boolean enabled)
      Serves HTTP/2 with prior knowledge (h2c, RFC 9113 section 3.3) on the plain listener: a connection that starts with the HTTP/2 connection preface is served as HTTP/2, its streams being proxy requests like HTTP/1 ones (:scheme and :authority name the target). Other connections stay HTTP/1.x; Upgrade: h2c is not supported. Off by default; limits are set with withHttp2Options(org.microproxy.Http2Options).

      Needs the optional http2-codec module on the class path: starting a server with it enabled without the module fails with IllegalStateException.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • withHttp2CleartextOnly

      default HttpProxyServerBootstrap withHttp2CleartextOnly(boolean enabled)
      Serves only HTTP/2 with prior knowledge on the plain listener: as withHttp2Cleartext(boolean) (which this implies), except that a connection that does not start with the HTTP/2 connection preface is not served as HTTP/1.x but treated as a connection error of type PROTOCOL_ERROR (RFC 9113 section 3.4): it is sent GOAWAY and closed. For a listener only HTTP/2 clients use, such as a reverse proxy in front of gRPC servers. Off by default.

      A server with it fails to start with a TLS listener (withSslContextSource(org.microproxy.SslContextSource)), SOCKS (withSocksServer(boolean), withSocksDetection(boolean)), transparent mode or a tcp:// reverse proxy, which all need connections that are not HTTP/2; and, like withHttp2Cleartext(boolean), without the optional http2-codec module.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • getHttp2Options

      default Http2Options getHttp2Options()
      Returns the HTTP/2 limits configured so far (never null).
      Returns:
      the HTTP/2 limits configured so far (never null)
    • withHttp2Options

      default HttpProxyServerBootstrap withHttp2Options(Http2Options options)
      Limits for HTTP/2 connections (see Http2Options); null restores the defaults.
      Parameters:
      options - the HTTP/2 connection limits
      Returns:
      this bootstrap
    • withHttp3

      default HttpProxyServerBootstrap withHttp3(boolean enabled)
      Serves HTTP/3 (RFC 9114, over QUIC): a UDP listener on the TCP listener's port number takes QUIC connections with ALPN h3, and each request stream is an exchange of its own, concurrently, with the same filters, cache, authentication, failure answers, logging and trackers as HTTP/1 and HTTP/2 requests. Off by default; limits are set with withHttp3Options(org.microproxy.Http3Options).

      A reverse proxy (withReverseProxy(org.microproxy.ReverseProxyMode)) serves its upstream this way: requests reach it as HTTP/1.1, HTTP/2 (withHttp2Upstream(boolean)) or HTTP/3 (withHttp3Upstream(boolean)), as it speaks, and responses sent over TCP advertise the listener with Alt-Svc: h3=":<port>" (see Http3Options.Builder.altSvc).

      A forward proxy serves HTTP/3 next to its own TLS listener (withSslContextSource(org.microproxy.SslContextSource)), to clients that know it does, such as MASQUE clients: requests name their targets with :scheme and :authority, CONNECT (RFC 9114 section 4.4) opens a tunnel as an HTTP/1 or HTTP/2 one does, and CONNECT-UDP (RFC 9298) proxies UDP in HTTP Datagrams (see Http3Options.Builder.connectUdpTemplate), here and, as withConnectUdp(boolean) describes, on the TCP listener. Every HTTP/3 connection to clients takes WebSockets over extended CONNECT (RFC 9220).

      The listener presents the certificate of the proxy's TLS listener, which must provide it as KeyMaterial (SslContextSource.getKeyMaterial(java.lang.String)), or, for a reverse proxy without a TLS listener, one that a CertificateAuthorityMitmManager issues for the name the client asks for. A forward proxy without a TLS listener, a transparent proxy (its clients' QUIC goes to withTransparentQuicPort(int)) and a reverse:tcp:// proxy fail to start with HTTP/3 enabled.

      Needs the optional quic and http3-codec modules on the class path: starting a server with HTTP/3 enabled without them fails with IllegalStateException.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • withHttp3Upstream

      default HttpProxyServerBootstrap withHttp3Upstream(boolean enabled)
      Speaks HTTP/3 to origin servers known to support it, whatever the client spoke: one QUIC connection per server, shared by concurrent exchanges as streams. A server is known to support HTTP/3 once one of its responses over TLS advertised h3 on the same host in Alt-Svc (remembered for its ma, and learned before the advertisement is removed for clients), or when its host matches withHttp3UpstreamHosts(java.lang.String...). A QUIC handshake that fails or takes longer than Http3Options.upstreamHandshakeTimeout() sends the request over TCP instead, and keeps the server on TCP for Http3Options.upstreamFailureTimeout(). Only direct connections use HTTP/3: not those through chained proxies or tunnels, nor those with a PROXY protocol header. Off by default.

      Servers are validated with the MITM manager's trust (MitmManager.serverTrustManager(java.lang.String, int, org.microproxy.FlowContext)), or the JDK's default trust store without one.

      Needs the optional quic and http3-codec modules on the class path: starting a server with it enabled without them fails with IllegalStateException.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • withHttp3UpstreamHosts

      default HttpProxyServerBootstrap withHttp3UpstreamHosts(String... patterns)
      Servers reached over HTTP/3 without waiting for an Alt-Svc advertisement, on the port of their https URI: those whose host:port one of these regular expressions is found in, case-insensitively, as for withIgnoreHosts(java.lang.String...). Takes effect with withHttp3Upstream(boolean); replaces any previous patterns, and none (the default) relies on Alt-Svc alone.
      Parameters:
      patterns - regular expressions for host:port names
      Returns:
      this bootstrap
    • getHttp3Options

      default Http3Options getHttp3Options()
      Returns the HTTP/3 limits configured so far (never null).
      Returns:
      the HTTP/3 limits configured so far (never null)
    • withHttp3Options

      default HttpProxyServerBootstrap withHttp3Options(Http3Options options)
      Limits and timers for HTTP/3 (see Http3Options); null restores the defaults.
      Parameters:
      options - the HTTP/3 options
      Returns:
      this bootstrap
    • withConnectUdp

      default HttpProxyServerBootstrap withConnectUdp(boolean enabled)
      Serves CONNECT-UDP (MASQUE, RFC 9298) on a forward proxy's TCP listener, with or without HTTP/3: an extended CONNECT with :protocol connect-udp on an HTTP/2 connection (h2 on the TLS listener with withHttp2(boolean), or h2c), and the HTTP/1.1 form, a GET with Upgrade: connect-udp. UDP payloads travel both ways in DATAGRAM capsules on the stream (RFC 9297 section 3.5). A forward proxy with withHttp3(boolean) serves CONNECT-UDP on its HTTP/3 listener and on its TCP listener whether or not this is set. The template, bounds and QUIC inspection are Http3Options's (Http3Options.Builder.connectUdpTemplate and the rest). Off by default.

      A reverse proxy fails to start with it. Needs the optional quic and http3-codec modules on the class path: starting a server with it enabled without them fails with IllegalStateException.

      Parameters:
      enabled - whether the feature is enabled
      Returns:
      this bootstrap
    • withFrameInterceptor

      default HttpProxyServerBootstrap withFrameInterceptor(FrameInterceptor interceptor)
      Shows every HTTP/2 frame the proxy receives or sends, on the client side and on connections to servers, to interceptor, which may edit, drop and add frames within the rules FrameInterceptor describes. One per proxy: a later call replaces it, and null removes it. Without one (the default), frames cost nothing extra. It takes effect where HTTP/2 is enabled (withHttp2(boolean), withHttp2Upstream(boolean), withHttp2Cleartext(boolean)), and sees HTTP/3 frames where HTTP/3 is (withHttp3(boolean), withHttp3Upstream(boolean)); other HTTP/3 traffic reaches an interceptor through an Http3FramePipeline.
      Parameters:
      interceptor - the interceptor, or null for none
      Returns:
      this bootstrap
    • getFrameInterceptor

      default FrameInterceptor getFrameInterceptor()
      Returns the frame interceptor configured so far, or null.
      Returns:
      the frame interceptor configured so far, or null
    • withScriptCallObserver

      default HttpProxyServerBootstrap withScriptCallObserver(ScriptCallObserver observer)
      Shows every call into a script's hooks to observer (see ScriptCallObserver): the scripting module (--script) passes it on to the script it loads. One per proxy: a later call replaces it, and null removes it.
      Parameters:
      observer - the observer, or null for none
      Returns:
      this bootstrap
    • getScriptCallObserver

      default ScriptCallObserver getScriptCallObserver()
      Returns the script call observer configured so far, or null.
      Returns:
      the script call observer configured so far, or null
    • withTcpInterceptor

      default HttpProxyServerBootstrap withTcpInterceptor(TcpInterceptor interceptor)
      Shows the bytes of every raw TCP tunnel to interceptor, which may rewrite, drop and add them (mitmproxy's tcp_message and related hooks; see TcpInterceptor for which tunnels). One per proxy: a later call replaces it, and null removes it. Without one (the default), tunnels copy bytes through pooled buffers and cost nothing extra.

      With an interceptor, TLS that does not carry HTTP is intercepted too, so the hooks see it decrypted: a client whose ALPN offers only other protocols (imap, mqtt, ...) is intercepted, the server being offered the same protocols and the client getting the server's choice, rather than tunnelled (unless the other rules decline it; acme-tls/1 never is). Whatever the interceptor, an intercepted session is relayed as raw TCP rather than served as HTTP when its ALPN protocol is not HTTP's, when its host is a TCP host, or, without ALPN, when its decrypted bytes do not start like an HTTP request or its server speaks first (an SMTP banner).

      Parameters:
      interceptor - the interceptor, or null for none
      Returns:
      this bootstrap
    • getTcpInterceptor

      default TcpInterceptor getTcpInterceptor()
      Returns the TCP interceptor configured so far, or null.
      Returns:
      the TCP interceptor configured so far, or null
    • withUdpInterceptor

      default HttpProxyServerBootstrap withUdpInterceptor(UdpInterceptor interceptor)
      Shows the datagrams of every UDP flow the proxy relays (CONNECT-UDP, MASQUE, on a forward proxy's HTTP/3 listener) to interceptor, which may rewrite, drop and add them; see UdpInterceptor. One per proxy: a later call replaces it, and null removes it.
      Parameters:
      interceptor - the interceptor, or null for none
      Returns:
      this bootstrap
    • getUdpInterceptor

      default UdpInterceptor getUdpInterceptor()
      Returns the UDP interceptor configured so far, or null.
      Returns:
      the UDP interceptor configured so far, or null
    • withTcpHosts

      default HttpProxyServerBootstrap withTcpHosts(String... patterns)
      Hosts whose connections are relayed as raw TCP even when they look like HTTP (mitmproxy's tcp_hosts): plain bytes after a CONNECT are not served as HTTP, and an intercepted TLS session is relayed decrypted rather than served as HTTP, its bytes going through the TCP hooks. TLS is still intercepted, as for other hosts; use withIgnoreHosts(java.lang.String...) to leave it untouched. Each pattern is a regular expression searched for, ignoring case, in the target's host name and in the client's SNI (without the port, as mitmproxy matches them). Replaces earlier patterns; none by default.
      Parameters:
      patterns - the regular expressions
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if a pattern is not a valid regular expression
    • withQuicInterceptor

      default HttpProxyServerBootstrap withQuicInterceptor(QuicInterceptor interceptor)
      Shows the streams and datagrams of QUIC connections that the proxy intercepts without speaking their protocol to interceptor, which may rewrite, drop and add their bytes; see QuicInterceptor. One per proxy: a later call replaces it, and null removes it.

      With an interceptor, transparent QUIC (and QUIC inside CONNECT-UDP flows, with Http3Options.Builder.connectUdpInterceptQuic) whose ClientHello offers no HTTP/3 is intercepted, rather than relayed untouched, unless the host rules, MitmManager.shouldIntercept(org.microproxy.ClientHello, org.microproxy.FlowContext) or the filters decline it: the proxy terminates the client's QUIC with a certificate its CA issues, connects to the server with the client's ALPN protocols, and relays each stream through the hooks. HTTP/3 is still served as HTTP/3, except for the QUIC hosts.

      Parameters:
      interceptor - the interceptor, or null for none
      Returns:
      this bootstrap
    • getQuicInterceptor

      default QuicInterceptor getQuicInterceptor()
      Returns the QUIC interceptor configured so far, or null.
      Returns:
      the QUIC interceptor configured so far, or null
    • withQuicFraming

      default HttpProxyServerBootstrap withQuicFraming(QuicFraming framing)
      Which intercepted QUIC connections' streams a QuicInterceptor that overrides QuicInterceptor.streamMessage(org.microproxy.quic.QuicMessage, org.microproxy.quic.QuicStreamContext) sees as whole messages, cut by a MessageFramer chosen by ALPN or host; how large a message may be; and the error code a stream is reset with when one is too large. QuicFraming.defaults() (DNS over QUIC with its two-byte length prefix) by default.
      Parameters:
      framing - the framing
      Returns:
      this bootstrap
    • getQuicFraming

      default QuicFraming getQuicFraming()
      Returns the QUIC framing configured so far.
      Returns:
      the QUIC framing configured so far
    • withQuicHosts

      default HttpProxyServerBootstrap withQuicHosts(String... patterns)
      Hosts whose intercepted QUIC is relayed stream by stream, as raw QUIC, whatever its ALPN: the QUIC counterpart of withTcpHosts(java.lang.String...). Their HTTP/3 is not served as HTTP/3 (filters and frame hooks do not see it); its streams go through the QUIC hooks, as other protocols' do, and QUIC that offers no HTTP/3 is intercepted even without an interceptor. The other rules still decide whether to intercept at all; use withIgnoreHosts(java.lang.String...) to relay a host untouched. Each pattern is a regular expression searched for, ignoring case, in the server's host name and in the client's SNI (without the port). Replaces earlier patterns; none by default.
      Parameters:
      patterns - the regular expressions
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if a pattern is not a valid regular expression
    • plusActivityTracker

      HttpProxyServerBootstrap plusActivityTracker(ActivityTracker activityTracker)
      Adds an observer alongside the configured activity trackers.
      Parameters:
      activityTracker - the observer to add
      Returns:
      this bootstrap
    • withThrottling

      HttpProxyServerBootstrap withThrottling(long readThrottleBytesPerSecond, long writeThrottleBytesPerSecond)
      Global bandwidth limits for server traffic; 0 means unlimited.
      Parameters:
      readThrottleBytesPerSecond - the inbound bandwidth limit in bytes per second, or zero for unlimited
      writeThrottleBytesPerSecond - the outbound bandwidth limit in bytes per second, or zero for unlimited
      Returns:
      this bootstrap
    • withNetworkInterface

      HttpProxyServerBootstrap withNetworkInterface(InetSocketAddress inetSocketAddress)
      Local address to bind for outbound connections.
      Parameters:
      inetSocketAddress - the local address to bind for outbound connections
      Returns:
      this bootstrap
    • withMaxInitialLineLength

      HttpProxyServerBootstrap withMaxInitialLineLength(int maxInitialLineLength)
      Sets the maximum HTTP request or status line length in bytes.
      Parameters:
      maxInitialLineLength - the maximum request or status line length in bytes
      Returns:
      this bootstrap
    • withMaxHeaderSize

      HttpProxyServerBootstrap withMaxHeaderSize(int maxHeaderSize)
      Sets the maximum HTTP header section size in bytes.
      Parameters:
      maxHeaderSize - the maximum header section size in bytes
      Returns:
      this bootstrap
    • withMaxChunkSize

      HttpProxyServerBootstrap withMaxChunkSize(int maxChunkSize)
      Largest body piece handed to filters when streaming.
      Parameters:
      maxChunkSize - the maximum streamed body chunk size in bytes
      Returns:
      this bootstrap
    • withAllowRequestToOriginServer

      HttpProxyServerBootstrap withAllowRequestToOriginServer(boolean allowRequestToOriginServer)
      Accept origin-form requests (GET /path) as if the proxy were the origin.
      Parameters:
      allowRequestToOriginServer - whether to accept origin-form requests
      Returns:
      this bootstrap
    • withTlsOrigination

      default HttpProxyServerBootstrap withTlsOrigination(boolean enabled)
      Whether a forward proxy fetches an https:// URI a client asks for directly, rather than through CONNECT, by opening TLS to the server itself: an absolute-form GET https://example.com/ sent in plain HTTP, an HTTP/2 stream with :scheme https on an h2c connection or the proxy's TLS listener, or a secure WebSocket (an absolute wss:// URI, or extended CONNECT with :scheme https). The server's certificate is checked as an intercepted server's is (the MitmManager's server TLS context, or the JVM's default trust without one), and the connection is pooled, and speaks HTTP/2 (withHttp2Upstream(boolean)) or HTTP/3 (withHttp3Upstream(boolean)), as an intercepted server's would. On by default.

      Turned off, such requests are refused with ProxyFailure.BadRequest (400), so that plain-HTTP clients reach TLS servers only through tunnels, which host rules and HttpFilters.proxyToServerAllowMitm() see as such. An https:// URI that a filter or script gives a request is fetched over TLS either way, as are requests inside intercepted sessions and a reverse proxy's https:// upstream: they are the proxy's choice, not the client's.

      Parameters:
      enabled - whether to originate TLS for clients' https:// requests
      Returns:
      this bootstrap
    • withProxyAlias

      HttpProxyServerBootstrap withProxyAlias(String alias)
      Name used in the Via header; defaults to the host name.
      Parameters:
      alias - the name used in Via headers
      Returns:
      this bootstrap
    • withAcceptProxyProtocol

      HttpProxyServerBootstrap withAcceptProxyProtocol(boolean acceptProxyProtocol)
      Require a PROXY protocol (v1 or v2) header on every inbound connection: the same as withAcceptProxyProtocol(ProxyProtocolMode) with ProxyProtocolMode.REQUIRED, or ProxyProtocolMode.OFF for false.
      Parameters:
      acceptProxyProtocol - whether to accept PROXY protocol on client connections
      Returns:
      this bootstrap
    • withAcceptProxyProtocol

      default HttpProxyServerBootstrap withAcceptProxyProtocol(ProxyProtocolMode mode)
      Whether client connections start with a PROXY protocol header (v1 or v2), read before anything else on the connection (before TLS on a TLS listener, before SOCKS or HTTP/2 detection). The source it names is the client from then on: FlowContext.getClientAddress(), ClientDetails, access logs ( %DOWNSTREAM_REMOTE_ADDRESS%) and the header sent on with withSendProxyProtocol(boolean). Once a connection's first byte has come, the rest of a header must arrive within 5 seconds (or the idle timeout, if shorter), or the connection is closed.

      ProxyProtocolMode.OPTIONAL lets any client that can reach the listener claim any source address: use it only behind a load balancer on a trusted network, ideally with withProxyProtocolTrustedSources(java.lang.String...) naming the load balancers.

      Parameters:
      mode - ProxyProtocolMode.OFF (the default), ProxyProtocolMode.REQUIRED or ProxyProtocolMode.OPTIONAL
      Returns:
      this bootstrap
    • withProxyProtocolTrustedSources

      default HttpProxyServerBootstrap withProxyProtocolTrustedSources(String... sources)
      The peers whose PROXY protocol headers are honored, as IP addresses or CIDR ranges ( 10.0.0.0/8, 192.0.2.10, fd00::/8): the load balancers in front of the proxy. A connection from another peer that starts with a PROXY header is closed, whichever the mode; with ProxyProtocolMode.REQUIRED every connection from another peer is closed, and with ProxyProtocolMode.OPTIONAL one without a header is served as it came. None (the default) honors headers from every peer.
      Parameters:
      sources - IP addresses or CIDR ranges; none to trust every peer
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if an entry is not an IP literal or a CIDR range
    • withSendProxyProtocol

      HttpProxyServerBootstrap withSendProxyProtocol(boolean sendProxyProtocol)
      Send a PROXY protocol v1 header to the final server: first on a direct connection, or through the tunnel once an HTTP chained proxy has accepted the CONNECT. It is not sent where there is no tunnel to the final server: through SOCKS chained proxies, or with plain requests forwarded to an HTTP chained proxy. Server connections that carry the header belong to one client, so the shared server connection pool is not used while this is on.
      Parameters:
      sendProxyProtocol - whether to send PROXY protocol to upstream servers
      Returns:
      this bootstrap
    • withAllowChunkedLength

      default HttpProxyServerBootstrap withAllowChunkedLength(boolean allow)
      Accept HTTP/1.1 requests that carry both Transfer-Encoding and Content-Length, as RFC 9112 section 6.1 allows a server to: the Content-Length is removed, the body is read by its chunked coding alone, and the client connection is closed after the response, so that whatever follows the body is never read as another request. Only a sound transfer coding qualifies: chunked exactly once, as the final coding, with a Content-Length that is valid on its own, on a request that is neither a CONNECT nor an Upgrade. Anything else, and every such request from an HTTP/1.0 client, is still answered 400. Accepted requests are flagged: FlowContext.isChunkedWithContentLength(), %MP_CHUNKED_LENGTH% in access logs, and the downstream_rq_chunked_length counter.

      Off by default, with LittleProxy compatibility too (LittleProxy answers such requests 400): a request with both framings is the classic request smuggling vector, and rejecting it is the safe answer. Turn it on only for clients known to send such requests. HTTP/1's own policy can decide too (Http1PolicyBuilder.allowChunkedLength(boolean)), and wins over this.

      Parameters:
      allow - whether to accept requests with both Transfer-Encoding and Content-Length
      Returns:
      this bootstrap
    • withMaxWebSocketFrameBufferSize

      HttpProxyServerBootstrap withMaxWebSocketFrameBufferSize(int maxBytes)
      Largest WebSocket frame payload buffered for HttpFilters.webSocketFrameReceived(org.microproxy.http.WebSocketFrame, boolean); larger frames are streamed and reported as truncated. Default 1 MiB.
      Parameters:
      maxBytes - the maximum buffered WebSocket frame size in bytes
      Returns:
      this bootstrap
    • withMaxWebSocketMessageSize

      HttpProxyServerBootstrap withMaxWebSocketMessageSize(int maxBytes)
      Largest WebSocket message, in bytes, that the proxy joins from its frames for HttpFilters.filterWebSocketMessage(org.microproxy.http.WebSocketMessage, boolean) or inflates (permessage-deflate) for the frame and message hooks. A larger message, or one that inflates past it (a decompression bomb), fails the connection with close code 1009. Default 16 MiB.
      Parameters:
      maxBytes - the maximum message size in bytes
      Returns:
      this bootstrap
    • withSharedServerConnectionPool

      HttpProxyServerBootstrap withSharedServerConnectionPool(boolean useSharedServerConnectionPool)
      Shares server connections between all clients instead of keeping them per client connection. A connection is leased for one exchange and returned to the pool when the response completes with keep-alive. Disabled by default.
      Parameters:
      useSharedServerConnectionPool - whether to share reusable upstream connections
      Returns:
      this bootstrap
    • withServerConnectionPoolType

      HttpProxyServerBootstrap withServerConnectionPoolType(ServerConnectionPoolType poolType)
      Selects the shared upstream connection pool implementation.
      Parameters:
      poolType - the shared connection pool implementation
      Returns:
      this bootstrap
    • withMaxConnectionsPerHost

      HttpProxyServerBootstrap withMaxConnectionsPerHost(int maxConnectionsPerHost)
      Pooled connections per target (host:port); default 10.
      Parameters:
      maxConnectionsPerHost - the maximum pooled connections per destination
      Returns:
      this bootstrap
    • withMaxConnections

      HttpProxyServerBootstrap withMaxConnections(int maxConnections)
      Pooled connections in total; default 200. When the limit is reached, requests wait up to the connect timeout for a connection and then get 503.
      Parameters:
      maxConnections - the maximum pooled connections across destinations
      Returns:
      this bootstrap
    • withPoolIdleTimeout

      HttpProxyServerBootstrap withPoolIdleTimeout(Duration idleTimeout)
      Closes pooled connections idle for longer than this; null keeps them.
      Parameters:
      idleTimeout - the maximum idle time before a pooled connection is closed
      Returns:
      this bootstrap
    • withPoolSharedMitmConnections

      HttpProxyServerBootstrap withPoolSharedMitmConnections(boolean poolSharedMitmConnections)
      Lets intercepted (MITM) sessions take their server connection from the pool and return it when the client disconnects, so other clients can reuse it. Requires the shared pool. Connections are only shared by clients given the same manager, and not at all when the manager sets up server connections per client (see MitmManager).
      Parameters:
      poolSharedMitmConnections - whether intercepted sessions share upstream connections
      Returns:
      this bootstrap
    • withPoolPerRequestInMitm

      HttpProxyServerBootstrap withPoolPerRequestInMitm(boolean poolPerRequestInMitm)
      With withPoolSharedMitmConnections(boolean), leases the server connection per intercepted request rather than per session.
      Parameters:
      poolPerRequestInMitm - whether intercepted requests lease upstream connections individually
      Returns:
      this bootstrap
    • withUseDnsSec

      HttpProxyServerBootstrap withUseDnsSec(boolean useDnsSec)
      Resolves server names with the validating DNSSEC resolver (DnssecHostResolver) instead of the system resolver.
      Parameters:
      useDnsSec - whether to validate DNSSEC locally
      Returns:
      this bootstrap
    • withDrainTime

      default HttpProxyServerBootstrap withDrainTime(Duration drainTime)
      How long exchanges in progress may take to finish when the proxy stops, and how long a drain lasts when the admin's /drain_listeners?graceful starts one (default 10 seconds, Envoy's --drain-time-s).
      Parameters:
      drainTime - the drain time, not negative
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if it is negative
    • withDrainStrategy

      default HttpProxyServerBootstrap withDrainStrategy(DrainStrategy strategy)
      How a draining proxy tells clients to go elsewhere (default DrainStrategy.GRADUAL, as Envoy's --drain-strategy); see HttpProxyServer.drain(java.time.Duration).
      Parameters:
      strategy - the strategy
      Returns:
      this bootstrap
    • withHealthCheckPath

      default HttpProxyServerBootstrap withHealthCheckPath(String path, boolean passThrough)
      Answers health checks on the proxy's own listener, as Envoy's health check filter does: a request for path (its path without the query, exactly) gets 200 OK from the proxy, or 503 with x-envoy-immediate-health-check-fail: true while the health check fails or the proxy is draining. With passThrough, a healthy proxy forwards the request to its server instead (in reverse mode, the upstream's own health); only the failures are answered by the proxy. Null turns it off (the default).
      Parameters:
      path - the path, starting with /, or null for none
      passThrough - whether a healthy proxy forwards the request
      Returns:
      this bootstrap
      Throws:
      IllegalArgumentException - if the path does not start with /
    • withAdmin

      default HttpProxyServerBootstrap withAdmin(InetSocketAddress address)
      Serves Envoy's admin API on its own HTTP listener at address, apart from the proxy's listeners: /stats, /stats/prometheus, /ready, /server_info, /listeners, /clusters, /config_dump, /logging, and, with POST, /healthcheck/fail, /healthcheck/ok, /drain_listeners and /quitquitquit; / lists them. Bind it to a loopback address (as --admin-port does) unless a token guards it: it can stop the proxy. It turns metrics on. Null (the default) means no admin listener.
      Parameters:
      address - the address to listen on (port 0 for any free port), or null for none
      Returns:
      this bootstrap
    • withAdminToken

      default HttpProxyServerBootstrap withAdminToken(String token)
      Requires token on every admin request but /ready: as a bearer token (Authorization: Bearer <token>), or as the password of basic authentication with any user name (or as user:password itself, when the token has a colon). Null (the default) requires nothing.
      Parameters:
      token - the token, or null for none
      Returns:
      this bootstrap
    • withCommandLineOptions

      default HttpProxyServerBootstrap withCommandLineOptions(List<String> options)
      The command line the proxy was started with, which the admin's /server_info shows (secret values redacted) as Envoy shows its own; the launcher passes its arguments.
      Parameters:
      options - the arguments
      Returns:
      this bootstrap
    • start

      Starts the proxy with this configuration.
      Returns:
      the running proxy server