From 2d77b2726c6385e16b61af2f2fa302d3989713e8 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 12 Mar 2026 08:13:31 +0100 Subject: [PATCH] CXF-8746: Support forcing GET method on 301/302 redirects Add http.redirect.force.GET property to HTTPConduit that, when enabled, changes the request method from POST to GET on 301/302 redirects per RFC 7231 Sections 6.4.2/6.4.3 historical behavior. Co-Authored-By: Claude Opus 4.6 --- .../org/apache/cxf/transport/http/HTTPConduit.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java index dcbcc8fbe59..b49db36ef78 100644 --- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java +++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java @@ -205,6 +205,7 @@ public abstract class HTTPConduit private static final String AUTO_REDIRECT_ALLOW_REL_URI = "http.redirect.relative.uri"; private static final String AUTO_REDIRECT_ALLOWED_URI = "http.redirect.allowed.uri"; private static final String AUTO_REDIRECT_MAX_SAME_URI_COUNT = "http.redirect.max.same.uri.count"; + private static final String AUTO_REDIRECT_FORCE_GET = "http.redirect.force.GET"; private static final String HTTP_POST_METHOD = "POST"; private static final String HTTP_GET_METHOD = "GET"; @@ -1546,6 +1547,16 @@ protected boolean redirectRetransmit() throws IOException { if (newURL != null) { new Headers(outMessage).removeAuthorizationHeaders(); + // RFC 7231 Sections 6.4.2/6.4.3: For historical reasons, a user agent MAY + // change the request method from POST to GET for 301/302 redirects. + // This is enabled via the "http.redirect.force.GET" property. + int responseCode = getResponseCode(); + if ((responseCode == HttpURLConnection.HTTP_MOVED_PERM + || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) + && MessageUtils.getContextualBoolean(outMessage, AUTO_REDIRECT_FORCE_GET)) { + outMessage.put(Message.HTTP_REQUEST_METHOD, HTTP_GET_METHOD); + } + // If user configured this Conduit with preemptive authorization // it is meant to make it to the end. (Too bad that information // went to every URL along the way, but that's what the user