skip to content

In WireMock, what does --enable-browser-proxying change about how a client reaches your stubs?

level: middleimportance: must knowfreq 57%

answer

  1. the client keeps its real URL
  2. WireMock becomes the route, not the target
  3. a tunnel someone has to terminate
  4. a certificate minted per requested host
  5. signed by WireMock's own generated CA

basics

~20 s

It turns WireMock into a forward proxy. Rather than dialling WireMock's base URL, the client keeps requesting the real target host and routes it through WireMock. For HTTPS, WireMock terminates the tunnel with a certificate it mints for that host.

solid answer

~50 s

Without the flag you change the client's configuration: the call-sheet client is pointed at `http://localhost:8080` instead of its real base URL, and WireMock answers whatever arrives. In WireMock, `--enable-browser-proxying` makes the server usable as an **HTTP proxy** instead, so the client keeps its real base URL — `https://calls.stagecrew.internal/call-sheets/v1/shows/42/calls` — and is configured to send requests through WireMock. That matters when the base URL is not configurable, or when you want a browser rather than a test client to go through the stub. The TLS consequence is the awkward part: for an HTTPS target the client asks the proxy to open a tunnel, so WireMock must answer the handshake itself and **mints a certificate for the requested host**, signed by its own CA. Nothing trusts that CA until you install it, which is what WireMock's `GET /__admin/certs/wiremock-ca.crt` is for.

code

bash · 7 lines
bash
java -jar wiremock-standalone.jar \
  --enable-browser-proxying \
  --ca-keystore /etc/callsheet/wiremock-ca.jks

curl --proxy http://localhost:8080 \
  --cacert /etc/callsheet/wiremock-ca.pem \
  https://calls.stagecrew.internal/call-sheets/v1/shows/42/calls

go deeper

for a junior

Be able to say that browser proxying means the client keeps the real URL and goes through WireMock, instead of being repointed at WireMock's own address. Knowing that a certificate has to be trusted is enough.

for a middle

Explain why an HTTPS target forces WireMock to present a certificate for the requested host, why that certificate is minted rather than fixed, and what the client must install before any stub is reached.

for a senior

Diagnose the three failure classes apart: connection trust, proxy routing and mapping. Show how you would wire the CA into a container image or job so a browser-proxied suite is reproducible.

for a principal

Decide when proxying is worth its setup cost at all. Substituting a configurable base URL is cheaper and fails more clearly, so proxying should be reserved for clients whose address you genuinely cannot change.

## Two ways a client can end up at a stub There are only two shapes, and browser proxying is the second one. 1. **Substitute the address.** You change configuration so the stage-crew suite calls `http://localhost:8080/call-sheets/v1/shows/42/calls` instead of the real service. WireMock is the target; every request that arrives is one you meant to send it. 2. **Substitute the route.** The client keeps asking for `https://calls.stagecrew.internal/call-sheets/v1/shows/42/calls` and is told to reach it *through* a proxy. In WireMock, `--enable-browser-proxying` is what makes the server willing to act as that proxy. The second shape exists because the first is not always available. A base URL may be compiled in, buried in a third-party client, or belong to a browser you are driving rather than to code you configure. Routing through a proxy leaves the application's own idea of the world untouched, which is precisely the point. ## What the flag turns on With `--enable-browser-proxying` set, WireMock will accept requests addressed to other hosts and handle them as a proxy rather than rejecting them as unknown paths on itself. The stub set does not change shape; the difference is that the request now carries a real target host, and WireMock is the intermediary that sees it. For a plain HTTP target that is unremarkable. For an HTTPS target it is not, and the reason is worth stating carefully. ## Why a certificate has to be minted per host When the target is HTTPS, the client does not simply hand WireMock a request; it asks the proxy to open a tunnel to `calls.stagecrew.internal` and then expects to negotiate TLS with that host. If WireMock is going to answer with a stub, it has to be the party on the other end of that negotiation, which means presenting a certificate **for the host the client asked for**. A fixed keystore cannot do that job. `--https-keystore` supplies one certificate for WireMock's own TLS listener, and a proxied client may ask for any number of hosts. So WireMock **generates a certificate per requested host** and signs it with a certificate authority of its own — a generated one, or the one you supply with `--ca-keystore`. That is where the friction comes from, and it is entirely predictable: - The client has never heard of WireMock's CA, so it rejects the connection before any stub is consulted. - The rejection looks like an issuer problem, not like a mocking problem, so people go hunting in their mappings. - Adding the target host to a mapping does not help, because matching happens after the connection is established. ## Making the client trust it 1. **Fetch the CA certificate** from the running WireMock: `GET /__admin/certs/wiremock-ca.crt` returns it. 2. **Install it where that client looks for trust** — a trust store for a JVM suite, curl's own `--cacert` flag for a curl call, the browser's store for a browser. 3. **Or pin your own CA** with WireMock's `--ca-keystore`, so the certificate you distribute is one you generated and can hand out ahead of time. The fourth option people reach for is `--trust-all-proxy-targets`, and it does not help at all: that flag governs what **WireMock** accepts from an upstream it proxies onward to, not what your client accepts from WireMock. ## When browser proxying is the right shape - The base URL genuinely cannot be changed, because it is fixed in a dependency or in a shipped binary. - You are driving a browser and want its own requests, not just your test code's, to reach the stand-in. - You want the application to behave exactly as in production down to the host name it dials, including the fact that it is speaking TLS to that name. And when it is the wrong shape: if the base URL *is* configurable, substituting the address is simpler, needs no CA, and fails in more obvious ways. Reaching for proxying because it sounds more realistic buys a class of setup problem for nothing. ## Reading the failures | symptom | what it means | |---|---| | The client reports an unknown or untrusted issuer | The CA from WireMock's `GET /__admin/certs/wiremock-ca.crt` has not been installed where that client reads trust | | The request reaches the real service instead of WireMock | The client is not actually configured to use the proxy; its own base URL is still winning | | The connection succeeds but the response is not your stub | A matching problem. The proxy layer did its job and the mapping did not match | | It works with curl and not in the browser | Trust was installed in one store and not the other; a browser generally does not read the same store as a command-line tool | The order to check them in is always the same: the connection first, the routing second, the mapping last. Anything that fails during the connection never reached your stub set at all, which is the single most useful diagnostic split on this whole subject.

  • Why does browser proxying need a CA when --https-keystore already gives WireMock a certificate?
    Because a proxied client can ask for any host. In WireMock, `--https-keystore` supplies a single certificate for its own TLS listener, which cannot answer for `calls.stagecrew.internal` and a dozen other names as well. Signing lets WireMock produce a fresh certificate for whichever host the client asked for, which is why the client has to trust the signer rather than one certificate.
  • How would you point a JVM call-sheet client through a browser-proxying WireMock?
    Leave the application's base URL alone, configure the HTTP client's proxy setting to WireMock's address, and give the JVM a trust store containing the CA certificate from `GET /__admin/certs/wiremock-ca.crt`. The code under test then still believes it is calling the real host, which is the whole reason to choose this shape over substituting the URL.

saying these in an interview costs you the question

  • Thinks the flag only changes which port WireMock listens on
  • Expects the real upstream's certificate to be served unchanged
  • Believes clients trust WireMock's generated certificate automatically
  • Confuses browser proxying with repointing the client's base URL
  • Assumes WireMock's --https-keystore covers every proxied host
  • Reaches for --trust-all-proxy-targets when the client rejects WireMock