Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3273,6 +3273,15 @@ private void addProxyIfEmpty(HttpClient target, String host, int port, boolean s

private void setBody(Request request, HTTP2Sampler sampler, HTTPSampleResult result)
throws IOException {
String effectiveMethod = result.getHTTPMethod();
if (!effectiveMethod.equals(sampler.getMethod()) && !isMethodWithBody(effectiveMethod)) {
// The method being sent only differs from the sampler's configured one when JMeter core
// rewrites it while following a redirect (e.g. POST -> GET after a 301/302/303). The
// entity belongs to the original request, so the method-rewritten follow-up must not
// re-send it (RFC 9110 section 15.4), matching HTTPSamplerProxy behavior.
result.setQueryString("");
return;
}
String contentEncoding = sampler.getContentEncoding();
String contentTypeHeader =
request.getHeaders() != null ? request.getHeaders().get(HTTPConstants.HEADER_CONTENT_TYPE)
Expand Down Expand Up @@ -3368,7 +3377,7 @@ private void setBody(Request request, HTTP2Sampler sampler, HTTPSampleResult res
new StringRequestContent(contentTypeHeader, postBody.toString(),
contentCharset);
request.body(requestContent);
} else if (isMethodWithBody(sampler.getMethod())) {
} else if (isMethodWithBody(effectiveMethod)) {
Fields fields = new Fields();
for (JMeterProperty p : sampler.getArguments()) {
HTTPArgument arg = (HTTPArgument) p.getObjectValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_200_ZSTD;
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_200_WITH_BODY;
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_302;
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_302_TO_ECHO;
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_400;
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_BIG_RESPONSE;
import static com.blazemeter.jmeter.http2.core.ServerBuilder.SERVER_PATH_200_DEFLATE;
Expand Down Expand Up @@ -846,6 +847,27 @@ private void validateRedirects(HTTPSampleResult result, HTTPSampleResult expecte
softly.assertThat(result.getRedirectLocation()).isEqualTo(expected.getRedirectLocation());
}

@Test
public void shouldNotResendRequestBodyWhenPostRedirectIsFollowedAsGet() throws Exception {
buildStartedServer();
sampler.setFollowRedirects(true);
sampler.setMethod(HTTPConstants.POST);
sampler.addArgument("test1", TEST_ARGUMENT_1);
sampler.addArgument("test2", TEST_ARGUMENT_2);

HTTPSampleResult result = sample(SERVER_PATH_302_TO_ECHO, HTTPConstants.POST);

softly.assertThat(result.getResponseCode()).isEqualTo("200");
SampleResult[] subResults = result.getSubResults();
softly.assertThat(subResults.length).isGreaterThan(0);
HTTPSampleResult followUp = (HTTPSampleResult) subResults[subResults.length - 1];
softly.assertThat(followUp.getHTTPMethod()).isEqualTo(HTTPConstants.GET);
// The redirect target echoes back any request body it receives. JMeter core rewrites
// POST to GET when following a 302, so the follow-up request must not carry the
// original POST entity (RFC 9110 section 15.4; matches HTTPSamplerProxy behavior).
softly.assertThat(followUp.getResponseDataAsString()).isEmpty();
}

@Test
public void shouldGetOnlyRedirectedResultWhenFollowRedirectDisabledAndRedirected()
throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class ServerBuilder {
public static final String SERVER_PATH_BIG_RESPONSE = "/test/big-response";
public static final String SERVER_PATH_400 = "/test/400";
public static final String SERVER_PATH_302 = "/test/302";
public static final String SERVER_PATH_302_TO_ECHO = "/test/302-to-echo";
public static final String SERVER_PATH_200_WITH_BODY = "/test/body";
public static final String SERVER_PATH_JSON_ONLY = "/test/json-only";
public static final String SERVER_PATH_DELETE_DATA = "/test/delete";
Expand Down Expand Up @@ -294,6 +295,11 @@ protected void service(HttpServletRequest req, HttpServletResponse resp)
"https://localhost:" + req.getLocalPort() + SERVER_PATH_200);
resp.setStatus(HttpStatus.FOUND_302);
break;
case SERVER_PATH_302_TO_ECHO:
resp.addHeader(HTTPConstants.HEADER_LOCATION,
"https://localhost:" + req.getLocalPort() + SERVER_PATH_200_WITH_BODY);
resp.setStatus(HttpStatus.FOUND_302);
break;
case SERVER_PATH_200_WITH_BODY:
String bodyRequest = req.getReader().lines().collect(Collectors.joining());
resp.getWriter().write(bodyRequest);
Expand Down