fix(deps): update dependency org.mock-server:mockserver-client-java to v7.3.0#1161
Merged
SylvainJuge merged 1 commit intoJul 1, 2026
Merged
Conversation
SylvainJuge
approved these changes
Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
7.2.0->7.3.0Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Release Notes
mock-server/mockserver-monorepo (org.mock-server:mockserver-client-java)
v7.3.0Added
client libraries gain first-class methods for clock control (freeze / advance / reset / status), metrics
(the JSON counter snapshot and the Prometheus scrape), configuration read/update, Pact import / export / verify,
the file store (store / retrieve / list / delete), HAR and Postman import, the high-level operating mode
(
SIMULATE/SPY/CAPTURE), and generating expectations from a WSDL — so these no longer require a manualPUT /mockserver/…request. Rolling out across the Java, Node, Python, Ruby, Go, .NET, Rust and PHP clients.Security
unparseable secrets. When redacting recorded traffic (HAR/Postman imports, the LLM optimisation report, the
MCP capture tools) the redactor previously only masked sensitive headers and named JSON body fields. It now also
(a) masks the values of credential-bearing query parameters by default (such as
key,api_key,apikey,access_token,token,signature,sig, and the AWS SigV4X-Amz-Signature/X-Amz-Security-Token) —e.g. Gemini's
?key=API key; (b) redacts configured fields inside each Server-Sent-Eventsdata:payload ofa streamed body, leaving non-JSON markers such as
[DONE]intact (and failing closed on adata:payload itcannot parse that still mentions a configured field); and (c) when a body is configured for field redaction but
cannot be parsed yet still mentions a configured field name, replaces the whole body rather than risk leaking it.
Ordinary unstructured bodies (plain text, HTML, decoded binary) that mention no configured field are left
unchanged.
messagePatternis now escaped completely. Every clientlibrary (Java, Node, Python, Ruby, Go, Rust, PHP, .NET) inlines
messagePatterninto a JSONPath=~ /…/regexliteral but previously escaped only the
/delimiter, so a pattern ending in a lone backslash (or containing\/) could escape the closing delimiter and break out of the regex literal into the surrounding JSONPath/JSON(CodeQL
rb/incomplete-sanitization). The escaping now preserves valid regex escape sequences (e.g.\d) whileneutralising the delimiter-breakout; normal patterns are unaffected.
URL assembled from the user-configured connection to
window.openwithout checking its scheme; it now opens thereport only when the URL resolves to
http/https, ruling outjavascript:/data:redirection (CodeQLjs/client-side-unvalidated-url-redirection)./bindand/stopnow honour control-plane authentication/authorization. These mutating lifecycleendpoints were serviced before the auth gate; they now require the same control-plane auth as
/mockserver/configuration. Default deployments with no control-plane auth configured are unaffected, and/status//readyremain open for health probes. Closes the lifecycle-endpoint gap noted in 7.2.0.controlPlaneAuthorizationEnabled, each MCPtool is classified read vs mutate (fail-closed) and checked against the same role model as the HTTP control
plane, so a read-only principal can no longer invoke mutating MCP tools (create/clear/reset/…). Default
(authorization disabled) behaviour is unchanged; enforced across HTTP and HTTP/3, single and batch. Closes
the per-tool MCP gap noted in 7.2.0.
JWTValidatorreconfigured theNimbus processor (key selector + claims verifier) on every call, so concurrent control-plane requests could be
verified against another request's policy. The processor is now configured once and
validate()is stateless.the authentication path used the JOSE library defaults (infinite connect/read timeout, no size limit); they now
use finite timeouts and a size cap, so a slow or hostile identity-provider endpoint can no longer hang the auth
path or be used as an amplification vector.
ImportTool(which exposes$import.read(url|file)) was registered in the template toolbox; it has beenremoved, closing an SSRF / local-file-disclosure vector in response templates.
validated only that the certificate chained to the configured CA; it now also enforces the certificate
validity window, so an expired or not-yet-valid (but correctly signed) client certificate is rejected.
Added
Load injection, chaos & SRE
sloCriteria; on termination MockServer attaches a terminalexperimentVerdict(PASS/FAIL/INCONCLUSIVE) evaluated strictly over the experiment's window —PASSonly if every objective heldthroughout,
FAILon any breach or auto-halt,INCONCLUSIVEbelow the minimum sample count. Turns"inject faults" into "verify resilience held."
sloCriteriais halted immediately(status
halted_by_slo_breach, verdictFAIL) when an SLO objective is breached mid-run. No behaviourchange when
sloCriteriais absent. The dashboard's chaos panel now shows the terminalexperimentVerdict(PASS / FAIL / INCONCLUSIVE) with per-objective observed-vs-threshold detail.
Request matching & response generation
JavaScript template (for example one containing an infinite loop) could previously pin the data-plane
worker thread handling that request indefinitely. A new
javascriptTemplateExecutionTimeoutproperty(milliseconds) caps how long a template may run; on expiry a watchdog cancels the evaluation and the
request fails fast with a clear, logged timeout error. The default is
5000(5 seconds), far longerthan any legitimate template needs. Set it to
0(or a negative value) to disable the timeout andrestore the previous unbounded behaviour. NOTE: this introduces a bounded behaviour change — templates
that genuinely run longer than 5 seconds (previously allowed) will now be cancelled unless the timeout
is raised or disabled.
(
$scenario.get('orderId')) and JavaScript (scenario.get('orderId')) could already readscenario/captured state in a response template; the Mustache engine now exposes the same through a
section lambda —
{{#scenario.get}}orderId{{/scenario.get}}, where the state name is the sectionbody (jmustache cannot pass a method argument inline the way Velocity and JavaScript can). This
completes
capture→ template value reuse across all three template engines, so an id capturedfrom one request can be returned in the response body of a later request regardless of template
engine. Documented on the Stateful Scenarios page with a per-engine example.
closestMatchHintEnabled, default on). When a requestmatches no expectation, the
404response now carries a compact, length-boundedx-mockserver-closest-match-hintheader naming the closest expectation and the first field that differed —answering "why didn't my mock match?" without enabling verbose diagnostics. Set
closestMatchHintEnabled=falseto suppress. (The opt-in
attachMismatchDiagnosticToResponse, which adds a full JSON diagnostic body, isunchanged and still off by default.)
OpenAPI & contract testing
PUT /mockserver/trafficValidate). A newcontrol-plane endpoint validates the request/response traffic MockServer has already recorded against a
provided OpenAPI spec (URL, file path, or inline), returning a structured pass/fail report
(
totalRequests/passed/failed/allPassedplus per-requestmatchedOperation,requestErrors,and
responseErrors) — mirroring the/contractTestreport. The endpoint is gated by the samecontrol-plane authentication as its siblings, and a spec URL is fetched only after passing the same SSRF
policy enforced on proxy/forward paths.
MockServerClientnow exposes fluent, typedmethods for the contract-testing endpoints:
contractTest(spec, baseUrl[, operationId]),trafficValidate(spec),pactImport(json),pactExport(consumer, provider), andpactVerify(json). Thecontract-test and traffic-validation reports parse into typed
ContractReport/ContractResultobjects socallers no longer hand-roll raw HTTP.
values for a single import via a
"realisticValues": trueentry in the reserved__generationOptions__map (alongside the existing
seedandfieldOverridesoptions), without changing the globalgenerateRealisticExampleValuesconfiguration. When the entry is absent, behaviour is unchanged and theglobal default still applies.
Dashboard UI
servers (e.g.
chrome-devtools,devbot) are frequently the real latency bottleneck. The panel aggregatescaptured MCP (JSON-RPC) traffic per server and shows, worst-first, each server's call count, error count and
rate (JSON-RPC errors or non-2xx responses), median / p95 / max latency, and its slowest method — with slow
(≥5s) and erroring servers flagged — so it is obvious which MCP server is stalling, rather than guessing.
app_open,view_change,feature_used,error_shown) to a cookieless, EU-hosted PostHog project to help improve the UI. No request URLs, hostnames, headers, bodies, or expectation data are ever sent, and no tracking cookie is set. The official Docker images ship with this enabled; it is inactive in any build withoutdashboardAnalyticsEndpoint+dashboardAnalyticsKey(so plain JARs/WARs and source/fork builds send nothing). Disable globally withdashboardAnalyticsEnabled=false(orMOCKSERVER_DASHBOARD_ANALYTICS_ENABLED=false); respects Do Not Track, Global Privacy Control, and a per-browser opt-out banner. See dashboard privacy.distributionlabel (from the newdashboardAnalyticsDistributionconfig property) identifying which artefact produced the event (docker-standard,docker-graaljs,docker-clustered,helm, orbinary); values outside the closed allow-list are normalised tounknown— free text is never forwarded.p50/p95/p99, error-rate) and runs them against the existing
/mockserver/verifySLOendpoint, showingobserved-vs-threshold per objective and an overall PASS / FAIL / INCONCLUSIVE verdict.
reloads, and the view is reflected in the URL hash (e.g.
#/contract) so views are linkable. A first visitstill opens Get Started.
status:>=400,method:POST,path:/api/*,/regex/) via the placeholder and an accessible help tooltip.Client libraries
.NET, PHP, and Rust clients gained the new scenario fields (
thresholds,abortOnFail,abortGraceMillis,pacing,feeder,stepSelection, per-stepcaptures/weight, profileshape), the new run-statusfields (
p999Millis,droppedIterations,verdict,abortedByThreshold,thresholdResults), and threenew methods —
getLoadScenarioReport(with optionaljunitformat),generateLoadScenarioFromOpenAPI,and
generateLoadScenarioFromRecording.when().respond()DSL in the Node client. The Node client now offers a chainablewhen(request).respond(response)— plus.forward(),.error(),.callback(), and.withTimes()/.withTimeToLive()/.withPriority()builders — mirroring the Java client, alongside theexisting procedural methods (which are unchanged).
@MockServerSettings(resetBeforeEach = true)resets theshared MockServer before each test (matching the JUnit 4 rule and Spring listener). Default off, so existing
behaviour is unchanged.
Clustering & observability
mock_server_forward_upstream_protocolmetric. A Prometheus counter labeled byupstream_hostandprotocolrecords the protocol each forward/proxy connection actually negotiated to the upstream (http2viaALPN, or
http1_1), with a matching DEBUG log. This is the authoritative way to confirm whetherforwardProxyHttp2Upgradeis taking effect — the recorded request only carries the inbound protocol, not theupstream-negotiated one, so a forward stuck on
http1_1to a backend that withholds its streaming SSE headover HTTP/1.1 (a cause of high forward time-to-first-byte) was previously invisible.
mockserver.otelEndpoint/MOCKSERVER_OTEL_ENDPOINTis unset,MockServer now falls back to the OpenTelemetry-standard
OTEL_EXPORTER_OTLP_ENDPOINTenvironment variable.Proxy & TLS setup
forwardProxyHttp2Upgradesetting (default off). Forwards a secure request to the upstream over HTTP/2 even when the inbound client is HTTP/1.1 (ALPN-negotiated, automatic fallback to HTTP/1.1 if the upstream does not offer HTTP/2; TLS only). This fixes a header-timeout some streaming upstreams exhibit, where the Server-Sent Events response head is sent immediately over HTTP/2 but withheld over HTTP/1.1.mockserver.proxySetupLoggingproperty(env
MOCKSERVER_PROXY_SETUP_LOGGING, defaultfalse; auto-enabled by the standalone JAR, Docker image,and
mockserverCLI) writes the active CA certificate tomockserver-ca.pemin the dynamic-SSL directoryat startup and prints a "Proxy Setup" block with ready-to-paste environment variable exports (
HTTPS_PROXY,NODE_EXTRA_CA_CERTS,SSL_CERT_FILE,REQUESTS_CA_BUNDLE) for both Unix and Windows PowerShell. Theblock includes a security warning when the default public CA is in use. Embedded usage
(
new ClientAndServer(...)) stays silent by default to avoid polluting test output; whenproxySetupLoggingis off, the CA file is written on the first
GET /mockserver/proxyConfigurationcall instead. The endpointitself is always available regardless of this setting.
GET /mockserver/proxyConfigurationendpoint. Returns the CA certificate path, CA PEM, proxy address,environment variable exports, and a flag indicating whether the default public CA is in use. Responds with
JSON by default or a plain copy-paste text block when called with
Accept: text/plain. Never exposes theprivate key.
--proxy-setupflag for a unique, secure CA. The new--proxy-setupCLI flag (propertymockserver.proxySetup, envMOCKSERVER_PROXY_SETUP, defaultfalse) forces generation of a unique localCA on first startup, equivalent to
dynamicallyCreateCertificateAuthorityCertificate=true. Recommended forany shared, persistent, or team-facing proxy deployment. Without it, MockServer uses the built-in default CA
whose private key is published in the git repository (safe only for isolated local development).
memory. Proxying large request/response bodies (LLM tool schemas, growing conversation context, accumulated
SSE) previously retained every exchange in full in the in-memory event log, which is bounded only by entry
count (
maxLogEntries), never by size — so a long capture session could exhaust the heap and crash theproxy. Three new opt-in properties address this:
mockserver.maxEventLogSizeInBytes(envMOCKSERVER_MAX_EVENT_LOG_SIZE_IN_BYTES, default0= disabled) caps the retained body bytes and evicts theoldest entries from memory once exceeded;
mockserver.persistRecordedRequestsToDisk(envMOCKSERVER_PERSIST_RECORDED_REQUESTS_TO_DISK, defaultfalse) withmockserver.persistedRecordedRequestsPath(default
recordedRequests.ndjson) appends every proxied exchange — full request and response — as one compactJSON object per line (NDJSON) to disk as it completes, flushed per line, so the complete session survives even
as the in-memory window evicts; and
mockserver.maxLoggedBodyBytes(envMOCKSERVER_MAX_LOGGED_BODY_BYTES,default
0= unlimited) truncates bodies kept in memory beyond a byte limit (marking the copy with anx-mockserver-body-truncatedheader) without affecting the disk archive. The NDJSON archive honoursredactSecretsInLog, masking credentials on disk exactly as the dashboard does. The recommended pairing —byte budget plus disk capture — keeps memory bounded while disk holds everything; the
mockserver-ui/scripts/launch-with-llm-capture.shcapture launcher now enables it by default (2 GB heap,256 MB byte budget, NDJSON disk capture).
Changed
(e.g.
SSLHandshakeException: Received fatal alert: unknown_ca, meaning the client does not trustMockServer's CA), the WARN log now appends the SNI hostname the connection was for — e.g.
… closing pipeline [id: 0x…] (SNI: chatgpt.com)— across the relay, SOCKS, port-unification, binary-proxy,MCP and dashboard/websocket handlers, so the failing target/client is identifiable instead of anonymous. The
message is unchanged when no SNI was negotiated.
titles, tab labels, navigation labels, and the tools/clear menu items now use Title Case throughout
(e.g. "Server configuration" → "Server Configuration", "MCP server health" → "MCP Server Health"),
so a menu item and the dialog it opens always match. Acronyms and brand names (MockServer, AsyncAPI,
OpenAPI, gRPC, OIDC, SAML, SLO, CRUD, MCP, LLM, Pact) are preserved, and descriptive/help text, tooltips,
and form labels are unchanged.
generateFromRecordinginTEMPLATIZEDmode now reproduces the recorded traffic mix. Each generatedstep's
weightis set to the route's observed hit count and the scenario usesstepSelection: WEIGHTED,so replaying picks routes in proportion to how often they appeared in the recording (instead of plain
ordered steps).
VERBATIMmode is unchanged.-XX:MaxRAMPercentage=75.0, inevery published image that runs the server — standard, snapshot, root, root-snapshot, graaljs, local, and
clustered), making memory use predictable and avoiding OOM-kills that looked
like hangs. Always run with an explicit container memory limit. To set a fixed heap, pass an explicit
-Xmx(a second
MaxRAMPercentageviaJAVA_TOOL_OPTIONShas no effect — it is applied before the image's flag).A build-time guard (
.buildkite/scripts/steps/docker-validate-sync.sh) now fails the build if anyserver image's entrypoint is missing the cap, so it cannot drift back out of one variant.
The Helm chart now ships commented
resourcesandapp.jvmOptionsexamples.leaf/server, and HTTP/3 self-signed certificates, so pinned-CA test setups no longer expire after a year.
groups (Mock / Observe / Verify / Resilience / AI / Inspect) with submenus, replacing the flat overflow tab
bar, so features are easier to discover.
including LLM agent runs — so it is now listed under AI alongside LLM Optimise, while remaining under Observe,
making it easier to find when debugging multi-step AI flows.
CLI (e.g. the OpenAI Codex backend used by
opencode) resends its entire growing conversation/reasoning contexton every turn, so consecutive recorded requests each "contained everything so far" and the view read as endless
duplicates. Consecutive requests whose message history is a growing prefix of the next (same provider and host)
now render as a single conversation showing each turn's new content, instead of N full-history blobs. Grouping
is conservative (edited history, a different provider, or a different host never merge) and non-destructive — the
raw per-request data is still reachable.
(method, exact-path)expectations so a request evaluates only plausible candidates instead of scanningevery expectation; non-literal matchers (regex/notted/optional/schema/path-param) are always checked, so
matching is byte-for-byte unchanged. The index engages automatically only above a size threshold (default
64, overridable via
-Dmockserver.candidateIndexThreshold); small expectation sets run the unchangedlinear scan, so there is no regression at small scale and a large speed-up at thousands of expectations.
Fixed
Correctness & reliability
connected to MockServer's HTTPS forward proxy over HTTP/2 and MockServer forwarded to an upstream that also served
HTTP/2, Netty's inbound HTTP/2→HTTP adapter tagged the decoded upstream response with a synthetic
x-http2-stream-idheader carrying the upstream stream id. That internal header leaked through the responsemappers and was re-emitted to the client, so the response was written on the wrong (upstream) stream id — the
client's HTTP/2 codec rejected it with a
PROTOCOL_ERROR/GO_AWAYand the request hung until timeout. Theresponse mappers now strip the Netty
x-http2-*extension-header family so the outbound stream id is governedsolely by the inbound request's stream id. HTTP/1.1 clients and directly-mocked HTTP/2 responses were never
affected; captured/recorded responses also no longer carry the internal
x-http2-stream-idheader.…InMillisnames, fixing silently-ignored overrides.The Java API (e.g.
Configuration.maxSocketTimeoutInMillis()) and the/mockserver/configurationJSON expose thesesettings under
…InMillisnames, but the system property / environment variable were only read under the unit-lessmockserver.maxSocketTimeout/MOCKSERVER_MAX_SOCKET_TIMEOUTform. Setting the natural-Dmockserver.maxSocketTimeoutInMillis=…(the name shown everywhere else) was therefore silently dropped and the20s default stood — long enough to 502 a healthy but slow first-byte response (e.g. a reasoning LLM backend that
takes longer than 20s to emit its first token when proxied/forwarded). MockServer now also accepts the unit-bearing
mockserver.maxSocketTimeoutInMillis,mockserver.socketConnectionTimeoutInMillisandmockserver.maxFutureTimeoutInMillisnames (and theirMOCKSERVER_*_IN_MILLISenvironment-variable forms) as exactsynonyms for the existing names — set whichever you prefer. The primary (unit-less) name is read first, so a value
applied at runtime via the programmatic setter is never silently overridden by a launch-time alias.
(SSE) forward/proxy exchange stored a log entry whose response still referenced the live streaming body — its
in-memory capture buffer, the upstream event loop, and the per-chunk callbacks — for the entry's whole lifetime
in the log ring buffer, roughly doubling per-entry memory and pinning event-loop-adjacent objects. The retained
log copy now holds only the fixed captured bytes and releases the live streaming reference.
forwardProxyHttp2Upgradenow applies to every forward route, fixing slow streaming captures. TheHTTP/2-upgrade setting was honoured only by matched
forward()expectations; it now also covers thetransparent (unmatched) proxy path that most LLM/agent capture uses and the
proxyPassMappingsreverse-proxyroute. Previously a coding-assistant CLI proxied over HTTP/1.1 was always forwarded upstream over HTTP/1.1, and
some streaming backends (notably the OpenAI Codex SSE endpoint used by the
opencodeCLI) withhold theresponse head over HTTP/1.1 and only flush at completion, so time-to-first-byte collapsed to total time and
surfaced as a client-side streaming timeout. With
forwardProxyHttp2Upgradeenabled, a secure request on anyforward route is now forwarded upstream over HTTP/2 via ALPN (falling back to HTTP/1.1 if the upstream
declines), so the backend streams the head immediately. Off by default; only the opt-in flag with a secure
(
https) target triggers it.Content-Typeare no longer buffered, fixing a streaming header-timeout (notablyfor
opencode). MockServer previously relayed a response incrementally only when the upstream advertisedContent-Type: text/event-stream; a backend that streams Server-Sent Events with no content-type at all —notably the OpenAI Codex endpoint used by
opencode— was buffered to completion before any headers were sent,so the client failed with "Provider response headers timed out after 10000ms". Streaming is now driven by the
client's streaming intent (an
Accept: text/event-streamheader or a"stream": truerequest body),propagated per request to both the forward path and the transparent (CONNECT) loopback relay, so the response
head reaches the client immediately regardless of the upstream's content-type. Ordinary buffered responses
(including chunked-without-
Content-Lengthservlet responses) andFORWARD_REPLACEoverrides are unaffected.opt-in forward connection pool (
forwardConnectionPoolKeepAlive) enabled, a pooled keep-alive connectioncarries no read timeout while it sits idle in the pool (a blanket one would fire during legitimate idle
keep-alive). But a request dispatched on such a channel — a reused connection, or a fresh pooled channel's
first request — was left with nothing to bound it, so an upstream that connected/kept-alive but then went
silent hung the request until the far larger forward future timeout. An in-flight read timeout
(
maxSocketTimeout) is now armed when a request is dispatched on a pooled channel and removed again when thechannel is returned to the pool, so a stalled reuse fails promptly. The default (pooling off) path is
unchanged.
response switches to streaming, the per-request socket read timeout (
maxSocketTimeout, default 20s) is nowalways replaced by the stream-appropriate idle bound (
streamIdleTimeoutSeconds, default 60s), so a streamingLLM response that pauses longer than 20s between chunks (model reasoning) is not cut off mid-stream. Setting
streamIdleTimeoutSeconds=0now genuinely runs the stream unbounded as documented (previously the 20s sockettimeout was left armed, truncating long inter-chunk gaps). The default (60s) is unchanged.
PUT /mockserver/retrieveand the LLM optimisation report no longer stall logging or time out.Retrieving logs, requests, recorded expectations, or request-responses serialized the (potentially large, e.g.
captured streaming bodies) result inside the single log-consumer thread's callback, which could exceed the
retrieve future timeout and — worse — block all further logging (filling the ring buffer and dropping events)
while it ran. Every retrieve branch —
LOGS,REQUESTS,RECORDED_EXPECTATIONS, andREQUEST_RESPONSESinall its formats (JSON, log entries, HAR, OpenAPI, Postman, Bruno, cURL) — now materializes the (cheap, redacted)
result on the consumer thread and runs the expensive serialization on the caller thread; the LLM
optimisation-report endpoint likewise builds its report off the Netty event loop. Output is byte-for-byte
identical; only the thread doing the work changed.
nullwhile a run is completing. The orchestratorremoved a finishing run from its active map before publishing the run's terminal status, so a status poll
landing in that brief window saw neither and returned
null. The terminal status is now published before therun is de-registered, so
statusFor/getStatusalways observe either the live or the completed status.so genuine TLS/decoder problems are visible without the noise of benign connection closes.
integer-truncated to 0 ms (flattening fast streams); pacing now accumulates with fractional carry so
cumulative timing stays accurate.
opencodeCLI calls the OpenAI Responses API through its Codex backend atchatgpt.com/backend-api/codex/responses, a non-standard path the detectors did not match — so its calls wererecorded under the generic Traffic view but never appeared in the LLM Traces or LLM Optimise views. Responses-API
detection (
LlmProviderSniffer,ProviderDetector, and the dashboard'sllmTraffic.ts) now matches the Codexpath alongside the hosted
/v1/responses, and thechatgpt.comhost on it. Detection also gains a host/path-independent body-shape fallback (read-only analysis only — Traffic, LLM Traces, LLM Optimise; never the live
forward/cost path): LLM traffic is recognised from its wire format, so a coding assistant that moves to a new
endpoint or a private gateway, or a new tool, stays classified without a code change. Claude Code (
/v1/messages)and Tabnine CLI (
…/chat/completions) were already recognised.Content-Typeis logged as readable text, not empty binary. The capturedbody of a streamed forward response with no content-type (opencode's OpenAI Codex SSE backend) was stored as a
BINARYbody, so it appeared empty in the dashboard's LLM Traces / Optimise text views. The captured bytes arenow sniffed when no content-type is present — UTF-8 text (SSE/JSON) is stored as a readable
STRING, whilegenuinely binary streams stay
BINARY. Content-typed responses are unchanged.rebuilt on the same multiplex stack the server uses (
Http2FrameCodec+Http2MultiplexHandler), reusing theexisting HTTP/1.1 streaming relay per stream — a streamed upstream response (SSE) now has its head relayed to the
client as soon as it arrives rather than after the whole body. Non-streaming HTTP/2 responses are still aggregated.
requests are no longer mis-classified as the OpenAI Responses API; the MCP
provider=AUTOanalysis now uses thesame host + body-shape detection as the dashboard and optimisation report; and Cohere, Voyage, Vertex AI Gemini,
and the AWS Bedrock Converse API are now recognised.
detecting the provider (a header-less Anthropic call is no longer mis-labelled OpenAI), and a call whose model
has no known price — or only a placeholder rate — is flagged as unpriced/approximate instead of being shown as a
confident
$0.00. The copy-paste optimisation brief also masks obvious credential shapes in prompt text.that carry no
Content-Typeheader now reassemble and display instead of showing empty; Anthropic prompt-cachetokens are surfaced; a hostile/malformed Server-Sent Events index can no longer exhaust browser memory; and a
truncated or unparseable response body now shows a clear notice rather than a silent blank.
Authorization,x-api-key,api-key, cookies and similar headers are masked in the Traffic raw/diff views (the original value is still usedfor replay), so a shared or screen-shared dashboard no longer exposes live credentials.
address so DNS runs on the Netty event loop; SSRF validation still resolves and rejects private/loopback
targets first, and a missing SSRF guard was added to the forward-validate path.
surfaced and fixed a set of latent defects:
hashCodebroke matching.KeyToMultiValue.replaceValues()/addNottableValues()mutated thevalue list without refreshing the cached
hashCode(unlikeaddValue()), so a header/parameter objectreused on the matching hot path (e.g. via
ExpandedParameterDecoder) could violate theequals/hashCodecontract. The cache is now refreshed on every mutation, and the
0-sentinel hashCode caches onHttpRequest/HttpResponse/Action/Notno longer defeat themselves when a hash legitimately computes to 0.NullPointerExceptionserialising a chunked response with no body — the chunked body encoder now guards anull body.
forward-object-callback handler wrote the HTTP response twice and left a
CompletableFuturethat nevercompleted (pinning a scheduler thread until the future timeout); the disconnect path now writes once,
unregisters the callback, and returns. Response/forward callback registry entries are also unregistered on
every disconnect branch.
already builds its own GraalVM context; the lock was removed so concurrent JS templates run in parallel.
ObjectMappers, the OpenAPI parse cache viacomputeIfAbsent,JsonStringMatcher, the Java client's Nettyclient and event bus, action-handler template engines,
LogEntryoverride cache, scheduler thread numbering).controlPlaneScopeMapping, the proxy-pass mappings, andproxyRemoteHost/proxyRemotePortnow round-trip throughPUT /mockserver/config; an unrecognisedlogLevelnow fails fast with a clear message instead of an NPE during start-up; the conventionalmockserver.perExpectationMetricsEnabledproperty key is accepted (the legacy key still works).awaitUninterruptibly()calls were removedfrom the proxy/SOCKS/relay event-loop paths; the outbound HTTP client now applies a read timeout so a
stalled upstream cannot pin a connection/future indefinitely; CONNECT-relay aggregators are bounded to the
configured maximum body size instead of ~2 GB.
MemoryMonitoringnow unregisters its log/expectation listeners on stop(and writes its CSV via try-with-resources); the LLM completion cache and quota registry are now bounded;
gRPC gzip frames are capped on decompressed size (decompression-bomb guard).
subscribers expose a health flag after a broker disconnect.
(identity-conditional remove/replace).
load-metric label arrays), and generated TLS certificates are now anchored to issuance time rather than the
JVM start time.
respondBeforeBody) expectation. Acatch-all
respondBeforeBodyexpectation (for example one seeded from an initialization file) was matchedbefore the control-plane dispatch, so it could answer the server's own management requests (e.g.
PUT /mockserver/reset). Early header matching now excludes the reserved/mockservercontrol-plane pathprefix, so management endpoints always reach the control plane.
Dashboard UI
(e.g. Opus 4.8 shown at 15/75 instead of 5/25); the table is now synced to the server's pricing and guarded
by a drift test.
IDE extensions (VS Code & JetBrains)
Verifier gate now runs in CI against the full recommended IDE set (IntelliJ IDEA 2024.3 through the 2026.2 EAP)
and rejects internal, deprecated, and scheduled-for-removal API usages — the same classes the Marketplace
flags. The plugin's self-version lookup is resolved from its own plugin class loader
(
PluginAwareClassLoader.pluginDescriptor.version), because the id-basedPluginManager.getPluginByClass(...)/PluginManagerCore.getPlugin(PluginId)lookups are both marked internal on newer platforms; the tool-windowbuttons fire their actions via the stable
AnActionEvent.createEvent(...)+update/actionPerformedprimitives instead of the deprecated
ActionUtil.invokeAction(...); and the deprecatedJBCefBrowser(...)constructors use the
JBCefBrowser.createBuilder()...build()API. No behaviour change; keeps the plugininstallable on current and future IDE builds.
OpenAPI & contract testing
format: date/date-timeexamples render as ISO strings again (#2370).An inline
example: '2021-01-30'on atype: string, format: dateproperty was serialised in generatedresponses as epoch-millis (
1611964800000) instead of the ISO string, because swagger-parser deserialisesthe example into a
java.util.Datethat the explicit-example path handed straight to Jackson. Date/date-timeexamples are now normalised back to their schema string form before serialisation (regression since 6.0.0).
Client libraries & integrations
@MockServerTestworks with JUnit 5@Nestedclasses again (#2371).Injecting the
MockServerClientdeclared on an outer test class into a@Nestedinner test instance threwIllegalArgumentExceptionbecause the field was set on the inner instance rather than the enclosing instancethat declares it. Injection now resolves the correct enclosing instance via the synthetic outer reference
(regression since 6.0.0).
Build & dependencies
mockserver-coreno longer triggers dependency-convergence errors in downstream builds(#1970). Projects that depend on
mockserver-coreand runmaven-enforcer'sdependencyConvergencerule saw conflicts for guava, jsr305,rhino, libphonenumber, snakeyaml, commons-, slf4j-api, jackson- and jakarta.xml.bind-api, because those
versions are pinned in MockServer's parent
dependencyManagement(which is not transitive) whileswagger-parser, json-patch, velocity and protobuf-java-util dragged in older transitive copies. The stale
transitive edges are now pruned with
<exclusion>s (the resolved classpath is unchanged — the pinned/newerversions already won nearest-wins), and
jackson-dataformat-yamlandjsr305are declared directly so asingle version of each reaches consumers. (The
mockserver-client-javahalf of this was fixed in 7.1.0.)Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Renovate Bot.