Skip to content

Fix request body re-sent on method-rewritten redirect follows#124

Closed
benjithompson wants to merge 1 commit into
Blazemeter:masterfrom
benjithompson:FIX_REDIRECT_BODY_RESEND
Closed

Fix request body re-sent on method-rewritten redirect follows#124
benjithompson wants to merge 1 commit into
Blazemeter:masterfrom
benjithompson:FIX_REDIRECT_BODY_RESEND

Conversation

@benjithompson

@benjithompson benjithompson commented Jul 10, 2026

Copy link
Copy Markdown

Summary

When "Follow Redirects" is enabled and a request with a body is answered with a 301/302/303, the follow-up request re-sends the original request body. JMeter core rewrites the method to GET for the follow-up (matching browser behavior and RFC 9110 §15.4), but the sampler still attaches the POST entity to that GET.

Observed on the wire (POST with form parameters, server answers 302 Location: ...):

POST /auth HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 37

password=...&username=...

followed by

GET /secure HTTP/1.1          <- the redirect follow
Content-Type: application/x-www-form-urlencoded
Content-Length: 37

password=...&username=...     <- the POST body, re-sent

Why it's wrong

  • RFC 9110 §15.4.4 (303) requires the redirected request to be GET, which carries no entity from the original request; browsers and JMeter's stock HTTPSamplerProxy (HC4) apply the same POST→GET rewrite for 301/302 and drop the body on the rewritten request. This sampler diverges from both, so plans migrated from the stock sampler change their wire behavior.
  • Strict HTTP/1.1 servers that never read a body on GET leave the stray bytes in the connection buffer; on a keep-alive connection they corrupt the framing of the next request (e.g. 501 Unsupported method ('password=...GET') from Python's stdlib http.server). Tolerant servers silently accept the mis-shaped traffic, which hides the problem while still distorting load-test fidelity.

Root cause

In HTTP2JettyClient, samplePrepareRequest sets the request line's method from the result (correct — GET on a redirect follow):

String method = result.getHTTPMethod();
request.method(method);

but setBody gated body attachment on the sampler's configured method, which is still POST:

} else if (isMethodWithBody(sampler.getMethod())) {

Fix

Fix: isMethodWithBody should check result.getHTTPMethod() — the method actually being sent — not sampler.getMethod():

} else if (isMethodWithBody(method)) {   // use the local `method` var (= result.getHTTPMethod())

Same fix applies to the raw-body branch (sampler.getSendParameterValuesAsPostBody()), which has the identical bug — it also needs to gate on the actual outgoing method rather than the sampler's configured one.

It's a one-line change (swap which variable isMethodWithBody is called with), confirmed present in both the pinned v3.0.1 tag and current master.

🤖 Generated with Claude Code

When JMeter core follows a 301/302/303 it rewrites POST to GET, but
setBody() gated body attachment on the sampler's configured method
instead of the method actually being sent (result.getHTTPMethod()).
The follow-up GET therefore carried the original POST entity, unlike
HTTPSamplerProxy and RFC 9110 semantics.

Skip body attachment when the effective method differs from the
sampler's configured method and does not admit a body.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H3q9uueSAmCEz3P8MS8crD
@3dgiordano

Copy link
Copy Markdown
Collaborator

Thanks @benjithompson

We were casually working on incorporating JMeter regression tests, which would help us detect the issues you reported.

This was addressed at the time by PR 134 #134. However, since we saw that JMeter's regression tests didn't cover all redirect states and found that JMeter had unresolved bugs regarding the RFC (which were fixed after the release of version 5.6.3), we worked on creating a PR to fix the JMeter 5.6.3 issue in PR 142 #142.

Thanks to your report, we've taken a closer look at JMeter's discrepancy with the RFC.

Jetty's core doesn't have these problems when running with Automatic Redirect, but when JMeter is instructed to use Follow Redirect, where JMeter takes control and creates a samples for each redirect, that's where the problems arise because JMeter doesn't comply with the RFC standard.

I'm closing this pull request since the fix was formally implemented in pull request 134 and its compatibility was improved in pull request 142. The fixes will be included in the next release.

Without your report, we wouldn't have looked into that detail.

Thank you very much for your contribution.

@3dgiordano 3dgiordano closed this Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants