Add HTTP response processing mode with lazy decompression#6708
Open
vlsi wants to merge 2 commits into
Open
Conversation
3117c93 to
b8789af
Compare
Store the raw, possibly compressed, response body in SampleResult and decompress it on demand in getResponseData() rather than eagerly while the response is read. The original bytes stay available for checksums, and responses that are never read are never decompressed. Add a ServiceLoader-based ResponseDecoder SPI with a registry and built-in gzip, deflate, and brotli decoders, so protocols can register further content encodings. Replace the boolean "Store as MD5" option with a responseProcessingMode that controls how the body is handled: store it compressed (the new default), fetch and discard it, or store an MD5 checksum of the compressed or the decompressed stream. HTTP implementations pass the raw body and its Content-Encoding to SampleResult, so decompression runs lazily through the decoder registry. The GUI shows the mode as a plain combo box with a leading "Default" entry; selecting Default leaves the property unset so it can be inherited from HTTP Request Defaults. Old test plans keep working: when responseProcessingMode is unset, getResponseProcessingMode() falls back to the legacy HTTPSampler.md5 property, whether set on the sampler or inherited from HTTP Request Defaults. This reuses the boolean merge semantics, so an explicit md5=false on a sampler still overrides md5=true on the defaults. The GUI reflects the resolved mode and rewrites it to responseProcessingMode on save. Based on the work in apache#6389. Co-authored-by: Vladimir Sitnikov <sitnikov.vladimir@gmail.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SaveService can rename keys and classes on load via NameUpdater, but it cannot transform property *values*. Add a TestElementUpgrader service interface, discovered with ServiceLoader, that upgrades legacy properties on a loaded test plan. SaveService runs all registered upgraders to a fix point after reading a plan, so chained upgrades converge without numbering the migrations. Add the first upgrader: an HTTP-side ResponseProcessingModeUpgrader maps the legacy HTTPSampler.md5 flag to responseProcessingMode. It keys off the property name, so it upgrades both HTTP samplers and HTTP Request Defaults (a ConfigTestElement), which core cannot reference directly. This normalises old plans into the new property on load and on re-save. Runtime correctness for plans built another way still relies on getResponseProcessingMode() falling back to the legacy flag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
b8789af to
53e8bb5
Compare
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.
What
Replaces the boolean "Save response as MD5 hash?" option on HTTP Request and HTTP Request Defaults with a
Processing modecombo that controls how the response body is handled:It also adds a
ResponseDecoderSPI with gzip, deflate, and brotli decoders (so decompression runs lazily and is pluggable) and a tooltip explaining the field.Builds on #6389 by @jgaalen (discussion in #6388); the first commit keeps him as author.
Why the migration is resolve-on-read
The legacy behaviour is driven by the boolean
HTTPSampler.md5, which can live in two places: on the sampler (HTTPSamplerBase) and on HTTP Request Defaults (aConfigTestElement). Old plans must keep working, and an explicitmd5=falseon a sampler must still overridemd5=trueinherited from the defaults.A migration that rewrites
md5 → responseProcessingModeinsetPropertycannot close both cases:ConfigTestElementlives in core, which cannot reference the HTTP enum/schema (the dependency is http → core), so the defaults element can't be migrated there.setPropertymigration only sees an element's own properties; themd5inherited from the defaults reaches the sampler through config merge (mergeIn/addProperty), which bypassessetProperty.So correctness is resolved on read:
getResponseProcessingMode()returns the explicitresponseProcessingModewhen set, otherwise falls back to the legacymd5— the sampler's own, or the one inherited from the defaults via merge — otherwise the schema default. This reuses the existing boolean merge semantics (an explicitmd5=falseoverrides an inheritedmd5=true), so both the sampler and the HTTP Request Defaults cases behave exactly as before, for any origin: loaded JMX, plans built programmatically, or direct property access. The GUI additionally rewrites the property toresponseProcessingModeand dropsmd5when the element is saved.TestElementUpgraderSPI — will be split into a separate PRThe second commit adds a small core SPI —
TestElementUpgrader, discovered viaServiceLoaderand run bySaveServiceright after a plan is loaded — that upgrades legacy property values on load (NameUpdateronly renames keys/classes). The HTTP-sideResponseProcessingModeUpgraderrewritesmd5 → responseProcessingMode; because it keys off the property name, it upgrades both samplers and theConfigTestElementdefaults, without core depending on http.It is not required for correctness (resolve-on-read already covers runtime); it just normalises old plans into the new property on load and re-save. I will extract it into its own PR — it is included here only to show the full picture and a concrete usage example. Happy to drop that commit from this PR if you prefer.
How to verify
./gradlew :src:core:testClasses :src:protocol:http:testClassesResponseProcessingModeInheritanceTest(resolve-on-read, inheritance and override),HttpTestSampleGuiResponseProcessingModeTest/HttpDefaultsGuiResponseProcessingModeTest(GUI round-trip),ResponseProcessingModeUpgraderTest/ResponseProcessingModeUpgradeOnLoadTest(the SPI), plus the portedResponseDecoderRegistryTestand gzip/deflate/brotli decoder tests.🤖 Generated with Claude Code