Tuesday, 16 June 2026

Traffic Parrot 5.60.3 released, what's new?

We have just released version 5.60.3. Here is a list of the changes that came with the release:

Features

  • The HTTP Add/Edit mapping form now lets you edit a file-backed response (one served from a bodyFileName file) directly in the editor: a Response from file note above the response body field shows the file name, the body field is editable in place, and saving writes the edited content back to the body file in the __files directory through the mapping repository (so the in-memory cache stays in sync). When the same body file is shared by other mappings a warning is shown, because saving changes the response for all of them. You can flip a response between inline and file-backed in both directions — Switch to inline detaches the file and stores the body on the mapping, and Switch to file externalises an inline body to a new file under responses/ on save. Binary body files stay read-only and are edited on disk. Previously a file-backed response appeared as an empty body field with no indication it was served from a file.
  • The same file-backed response handling is now available on the gRPC Add/Edit mapping form: when a gRPC mapping's response is served from a response.bodyFileName file, a Response from file note shows the file name, the body field is editable in place and pre-filled from the __files directory, and saving writes the edited content back to the body file through the mapping repository. A warning is shown when the file is shared by other mappings, and you can flip a response between inline and file-backed in both directions (Switch to inline / Switch to file). Binary body files stay read-only.
  • Added support for externalising a request body matcher into a file in the __files directory via bodyFileName, mirroring the response-side bodyFileName convention. Any of the request body matchers (equalTo, equalToJson, equalToXml, binaryEqualTo, contains, doesNotContain, matches, doesNotMatch, matchesJsonPath, matchesXPath, matchesXml) can load the value it compares against from a file instead of inlining it in the mapping, resolved relative to the mapping's sibling __files directory and loaded once at mapping-load time. A file-backed matcher is shown in the HTTP Add/Edit mappings GUI with a Content from file note, and the mappings-list Request body column renders the matcher content inlined from the file. The externalised form is also accepted through the WireMock admin API (POST /__admin/mappings, PUT /__admin/mappings/{id} and POST /__admin/mappings/import): the file is resolved when the mapping is registered, a reference to a missing file is rejected at registration with HTTP 422 naming the file, combining bodyFileName with any other key in the same matcher entry is rejected, and mappings saved to disk keep the bodyFileName reference instead of the file's contents.
  • Added a Static Files browser under the HTTP menu that lists the active scenario's __files directory, marks each file as referenced or orphaned by cross-referencing the HTTP mappings, and previews a selected file's content (JSON and XML are pretty-printed; image files are rendered inline and other binary files show their content type and size). The browser also lets you:
    • Create a new text file under the __files directory directly from the admin UI: a New file affordance prompts for a relative file name and content and adds the file to the browser, where it appears with an orphaned badge until a mapping references it.
    • Edit a text file in place: selecting a non-binary file and clicking Edit replaces the preview with an editable text area and Save/Cancel buttons, and saving overwrites the file's content in the __files directory. When the file is referenced by one or more mappings (through response.bodyFileName) a warning is shown, because saving changes the response for all of them. Binary files remain read-only and are edited on disk.
    • Delete a file: each row has a Delete button that reveals an inline Confirm/Cancel step (no browser pop-up), and confirming the deletion of an unreferenced file removes it from disk and the row disappears. The delete is reference-safe — if the file still backs a mapping the deletion is refused, a banner lists the referencing mapping(s) and the file stays listed. The reference check is complete: it covers both a file used as an HTTP response body (response.bodyFileName) and a file used as a request body matcher, so a file that the browser's orphaned badge reports as unreferenced (the badge inspects only response references) can still be blocked from deletion when it is genuinely in use, protecting you from silently breaking a request matcher. Overriding the refusal is not currently supported; to delete a referenced file, first remove or repoint the mapping(s) that use it.
    • Rename a file within the __files directory: each row has a Rename button that reveals an inline editable target-name field with Confirm/Cancel (no browser pop-up). Renaming an unreferenced file moves it to the new name, creating any intermediate sub-directories the new name implies. Like delete, the rename is reference-safe — if the file still backs a mapping the rename is refused, a banner lists the referencing mapping(s) and the file keeps its old name, because renaming would leave the mapping pointing at a name that no longer exists. The reference check is complete in the same way: it covers both a file used as an HTTP response body (response.bodyFileName) and a file used as a request body matcher, so a file that the orphaned badge reports as unreferenced (the badge inspects only response references) can still be blocked from renaming when it is genuinely in use. Renaming onto a name that already exists is refused as well, so you never silently overwrite another file. To rename a referenced file, first remove or repoint the mapping(s) that use it; automatically updating the referencing mappings to the new name is not currently supported.
    • Upload an existing file into the __files directory straight from your browser: an Upload button next to New file opens a file picker, and the chosen file is uploaded and added to the browser. Both text and binary files are accepted — the bytes are stored verbatim, so an uploaded image is listed and rendered inline in the preview pane, and any other uploaded binary file is listed and shown with its content type and size. Uploading a file whose name already exists is refused so you never silently overwrite another file, and unsafe file names (for example an absolute path or one containing .. that would escape the scenario's __files directory) are rejected. The upload has a configurable size limit, set by the new trafficparrot.multipart.upload.max.size.mb property (default 10 MB, shared by all admin-UI file uploads); a file larger than the limit is rejected with HTTP 413 and the message File exceeds the maximum upload size of N MB shown in the upload form. The limit applies only to file uploads through the admin UI and does not affect recorded traffic or mapping sizes.
    • Resize the panes with a draggable divider between the file list and the preview, so you can widen either side to suit the file you are reading. Drag the divider to set the split (it stays between 20% and 80% so neither pane collapses), and double-click it to snap back to the default split. The split you choose is remembered in your browser across page reloads. On narrow screens the panes stack vertically as before.
    • Browse files as a directory tree: files in sub-directories of __files are now grouped under expandable folder rows instead of being listed by full relative path. Each folder shows a caret you can click to collapse or expand its contents (all folders are expanded by default), and each file is labelled by its own name and indented under its folder. Selecting a file previews it, and the referenced/orphaned badges and rename, delete, edit and upload actions all work exactly as before.
    • Preview images and other binary files: selecting an image file (PNG, JPEG, GIF, SVG, WebP, BMP, ICO, APNG or AVIF) now renders the image inline in the preview pane instead of the bare not previewable note, so you can see at a glance which image a mapping serves. Selecting any other binary file shows a Binary file — <content type>, <size> note (for example Binary file — application/octet-stream, 2.3 KB) instead, so you can tell its type and size without downloading it. Text, JSON and XML files are still pretty-printed and editable in place as before; images and other binary files remain read-only and are edited on disk. Image and binary files are served back for the preview with a nosniff content-type guard and as an attachment, so a file whose bytes happen to contain active content (such as a script-bearing SVG) can never run in your browser from the preview.
  • Added a Logging documentation page covering how to enable verbose logging, change the log level, find the log files (logs/trafficparrot.log), turn logging down or off, and use the Request Log near-miss view to see why an HTTP request did not match.
  • The HTTP mappings list now shows a Recording active banner above the table while a recording session is running, as a reminder that deleting a mapping while recording also stops that endpoint being re-recorded for the rest of the session.
  • The HTTP Record page now shows a Live coverage panel while a recording session is active, refreshing about once a second. It gives a running tally of the distinct endpoints seen so far — how many now have a mapping, how many were observed but are still unmapped, and how many mappings have not been observed — plus the per-endpoint observed and unmatched request counts, so you can tell during the session whether a recording has captured everything you expected. Endpoints are grouped by HTTP method and normalised path using the same convention as Mapping cleanup, and the panel notes how many requests in the request journal the tally is based on.
  • Added a Verifying requests guide for WireMock users, mapping the verify() DSL onto Traffic Parrot's request journal: assert a request was made, was made exactly N times, or was NOT made via POST /api/http/requests/count, inspect captured bodies via POST /api/http/requests/find, list unmatched requests and near misses, and reset the journal — with a WireMock-to-Traffic-Parrot translation table and copy-paste curl recipes.
  • The Application logs view (HTTP menu → Logs → Application logs) now offers a structured view of the server log in addition to the existing raw text view. The raw view remains the default; clicking Structured view parses each entry into its timestamp, level, thread and message, with a coloured band and a level badge (the level text is always shown, not signalled by colour alone, so the view stays readable in greyscale and for colour-blind users). Multi-line stack traces fold into a single collapsible entry (with Expand all / Collapse all), you can filter entries by level and by free text, and any line that does not match the log pattern is shown in full rather than hidden. The existing search, last-10,000-lines truncation and Download raw affordances are unchanged.
  • Added an Available helpers panel at form level — below both the request and response cards — on the HTTP and messaging (JMS, IBM MQ and file-message) Add/Edit mapping forms, so you can discover what Traffic Parrot offers without leaving the product. The collapsible, read-only panel is a sectioned shell with three catalogues: a Response templating helpers section listing the helpers grouped by category; a Request matchers section listing the available request matchers; and an Other functionality section covering Scenarios & state, Response delays, Fault simulation, response proxying, serving a response from a file, webhook callbacks and request-matching scripts. Each entry has a one-line description, a copy-ready snippet (already scaffolded with example parameters) and a docs link, with a filter box that narrows every section as you type (matching name and description) and a per-entry Copy button. It is discovery-only and does not change how mappings are saved or how responses are rendered.
  • The HTTP Add/Edit mapping form now lets you author the advanced response delay and fault shapes that were previously only configurable in mapping JSON: a log-normal random delay (median, sigma and an optional maximum, to model realistic response-time spread), a chunked dribble delay (split the response body into a number of chunks sent over a total duration, to simulate a slow trickle), and the CONNECTION_RESET_BY_PEER response fault. Because the editor now understands these shapes, opening and saving a WireMock-format JSON mapping in the GUI no longer silently strips them — previously a form open-save dropped a log-normal delayDistribution, a chunkedDribbleDelay or a CONNECTION_RESET_BY_PEER fault, so this also fixes that data loss.
  • Added a matches GraphQL request body matcher for stubbing a POST /graphql endpoint, where many operations share one URL. Its full-query form matches the request's query semantically — tolerant of insignificant whitespace, selection-set field order, and argument order, so differently formatted but equivalent queries select the same response (aliases and directives stay significant). Its object form matches on operationName alone to disambiguate operations on one URL, with an optional variables object to also assert on the request's variables. Select matches GraphQL in the Request body matcher dropdown on the HTTP Add/Edit mapping form to author the full-query form; the operation-name form is authored by importing mapping JSON. A request that is not valid GraphQL simply does not match (it is never an error), and a mapping whose own GraphQL query is invalid is rejected at save/import time.
  • Added a trafficparrot validate command that checks your mappings against their bound schemas without starting the server, for use as a continuous integration step. For HTTP it reports both schema drift (a mapping whose URL path and method are not declared in any OpenAPI specification in openapi/) and under-coverage (an operation declared in a specification that no mapping covers), so a partially-mocked API cannot silently drift from its contract; gRPC mappings are validated against their proto schema. It prints a labelled report and exits 0 (no drift), 1 (drift detected) or 2 (usage or configuration error, including a files-root with no mappings). Operations you deliberately do not mock can be excluded with an exclude.operations list in an openapi-coverage.properties file in the files-root; an allowlist entry that matches no operation in the specification is itself reported as drift so the list cannot quietly go stale.
  • Added an external-process HTTP response transformer that passes the response through a user-supplied executable (the "middleware") written in any language — familiar to Hoverfly users. For each matched request on an opted-in mapping, Traffic Parrot serialises a versioned JSON envelope (the matched request plus the response about to be sent) to the executable's stdin and applies the mutated response read back from stdout (status, headers, body); request mutation is not supported in this release. The feature is off by default (trafficparrot.http.externalprocess.enabled) and confined to a single operator-vetted directory (trafficparrot.http.externalprocess.allowedDir) — the executable runs as the Traffic Parrot OS user with no sandbox, so enable it only on trusted hosts. Each mapping configures the executable, optional args, a per-invocation timeoutMs (default 5000, the process is killed on expiry), and an onError fallback (fail-open returns the original response, fail-closed returns HTTP 500) applied on non-zero exit, timeout, malformed output, or a missing/disallowed executable.
  • The external-process transformer can now be enabled and configured directly in the HTTP mapping editor, instead of only by hand-editing the mapping JSON. When an operator has set trafficparrot.http.externalprocess.enabled=true, an ExternalProcessTransformer toggle appears in the Response transformers list under Advanced parameters; turning it on reveals an External Process tab in the Transformer parameters panel with structured fields for the executable, args (space or newline separated), timeoutMs, and onError (fail-open/fail-closed). The option is offered only when the feature is enabled, and selecting it does not bypass the trafficparrot.http.externalprocess.allowedDir allow-list that still gates which executables may run. Saving writes the same transformerParameters.external-process JSON the editor, the mapping file on disk, and the WireMock Admin API all share. See Configuring it in the editor GUI.

Documentation

  • Added an Environment variables in responses how-to page covering the {{systemValue}} Handlebars helper: reading an environment variable (type='ENVIRONMENT') or a JVM system property (type='PROPERTY') into a response body or header, the default= fallback, the wiremock* allow-list and the [ERROR: Access to … is denied] failure mode, and the underscore-vs-dot naming rule for environment variables.
  • Added a CORS for stub responses how-to answering the common WireMock “CORS not working” question. It documents that the Traffic Parrot virtual service is CORS-friendly out of the box for every path — the browser CORS preflight (OPTIONS) is auto-answered HTTP 200 with Access-Control-Allow-Methods, Access-Control-Allow-Headers and Access-Control-Max-Age, and the request Origin is reflected into Access-Control-Allow-Origin on the actual response — with no flag and no per-stub configuration (unlike WireMock's off-by-default --enable-stub-cors). It also shows how to pin a specific origin by setting Access-Control-Allow-Origin in a stub's response.headers, and clarifies that this CORS behaviour is independent of the trafficparrot.http.optionsResponse.enabled property (which emits only an Allow header).
  • Expanded the JVM arguments section of the User Guide with a full reference for the jvm.args file: where it lives in the install directory, how each non-empty line is passed to the server JVM at startup, a table describing every shipped default (including -Xmx128m, the line to raise for large recordings or datasets), and typical adjustments.

Fixes

  • The Duplicate and Delete buttons in the gRPC mappings list work again — a regression had stopped them working, so a gRPC mapping could not be duplicated or deleted from the admin UI. Both actions now behave as they do for HTTP mappings.
  • A stub configured with the INCORRECT_SMALL_CONTENT_LENGTH response fault now injects the fault correctly — it serves the stubbed status with a too-small Content-Length header and a body truncated to that length — instead of returning an HTTP 500 error.
  • File-message mappings now honour the priority field when resolving match precedence. Previously, when two file-message mappings both matched an inbound message, priority was ignored and the mapping loaded first always won; HTTP, JMS and IBM MQ mappings already honoured priority correctly.
  • Library upgrades to fix OWASP issues.

Changes

  • When the external-process transformer is enabled, Traffic Parrot now validates the trafficparrot.http.externalprocess.allowedDir directory once at startup and logs a warning if it is empty, does not exist, is not a directory, or is non-canonical, so a misconfigured allow-list is surfaced at startup rather than at the first matched request. The check is warn-only — the server still starts.
  • The Import skeleton… upload on the HTTP and gRPC Add/Edit mapping pages (importing an OpenAPI/Swagger HTTP skeleton or a proto/descriptor-set gRPC message skeleton) now has a configurable size limit, set by the trafficparrot.multipart.upload.max.size.mb property (default 10 MB) — the same property that caps the Static Files browser upload. A file larger than the limit is rejected with HTTP 413 and the message The uploaded file exceeds the maximum upload size of N MB shown in the import error area, instead of being buffered unbounded. Previously these imports had no size limit.
  • The HTTP Import mappings REST endpoint (/http/management/importMappings) now enforces the same trafficparrot.multipart.upload.max.size.mb cap (HTTP 413 on an oversize upload) as the skeleton-import and Static Files uploads. Previously this endpoint had no size limit.
  • Upgraded bundled JRE from 21.0.7 to 21.0.11

No comments:

Post a Comment