diff --git a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java index 96a09757d21..fae96ffa0db 100755 --- a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java +++ b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java @@ -130,10 +130,11 @@ public AsyncHTTPConduitFactory getAsyncHTTPConduitFactory() { } @Override - protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { + protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, + boolean forceGET) throws IOException { if (factory.isShutdown()) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, address, csPolicy); + super.setupConnection(message, address, csPolicy, forceGET); return; } propagateJaxwsSpecTimeoutSettings(message, csPolicy); @@ -187,7 +188,7 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic } if (!PropertyUtils.isTrue(o)) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy); + super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy, forceGET); return; } if (StringUtils.isEmpty(uri.getPath())) { @@ -202,7 +203,11 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic message.put("http.scheme", uri.getScheme()); String httpRequestMethod = (String)message.get(Message.HTTP_REQUEST_METHOD); - if (httpRequestMethod == null) { + + if (forceGET) { + httpRequestMethod = "GET"; + message.put(Message.HTTP_REQUEST_METHOD, httpRequestMethod); + } else if (httpRequestMethod == null) { httpRequestMethod = "POST"; message.put(Message.HTTP_REQUEST_METHOD, httpRequestMethod); } @@ -837,7 +842,7 @@ protected boolean authorizationRetransmit() throws IOException { //ignore } cookies.writeToMessageHeaders(outMessage); - retransmit(url.toString()); + retransmit(url.toString(), false); return true; } return b; @@ -851,7 +856,7 @@ protected void retransmitStream() throws IOException { wrappedStream.close(); } - protected void setupNewConnection(String newURL) throws IOException { + protected void setupNewConnection(String newURL, boolean forceGET) throws IOException { httpResponse = null; isAsync = outMessage != null && outMessage.getExchange() != null && !outMessage.getExchange().isSynchronous(); @@ -868,11 +873,11 @@ protected void setupNewConnection(String newURL) throws IOException { outbuf = new SharedOutputBuffer(bufSize, allocator); try { if (defaultAddress.getString().equals(newURL)) { - setupConnection(outMessage, defaultAddress, csPolicy); + setupConnection(outMessage, defaultAddress, csPolicy, forceGET); } else { Address address = new Address(newURL); this.url = address.getURI(); - setupConnection(outMessage, address, csPolicy); + setupConnection(outMessage, address, csPolicy, forceGET); } entity = outMessage.get(CXFHttpRequest.class); basicEntity = (BasicHttpEntity)entity.getEntity(); diff --git a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java index 3802db7b36f..33143380178 100644 --- a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java +++ b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java @@ -131,10 +131,11 @@ public AsyncHTTPConduitFactory getAsyncHTTPConduitFactory() { } @Override - protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { + protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, + boolean forceGET) throws IOException { if (factory.isShutdown()) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, address, csPolicy); + super.setupConnection(message, address, csPolicy, forceGET); return; } propagateJaxwsSpecTimeoutSettings(message, csPolicy); @@ -198,7 +199,7 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic if (!PropertyUtils.isTrue(o)) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy); + super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy, forceGET); return; } @@ -214,7 +215,11 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic message.put("http.scheme", uri.getScheme()); String httpRequestMethod = (String)message.get(Message.HTTP_REQUEST_METHOD); - if (httpRequestMethod == null) { + + if (forceGET) { + httpRequestMethod = "GET"; + message.put(Message.HTTP_REQUEST_METHOD, httpRequestMethod); + } else if (httpRequestMethod == null) { httpRequestMethod = "POST"; message.put(Message.HTTP_REQUEST_METHOD, httpRequestMethod); } @@ -834,7 +839,7 @@ protected boolean authorizationRetransmit() throws IOException { //ignore } cookies.writeToMessageHeaders(outMessage); - retransmit(url.toString()); + retransmit(url.toString(), false); return true; } return b; @@ -848,7 +853,7 @@ protected void retransmitStream() throws IOException { wrappedStream.close(); } - protected void setupNewConnection(String newURL) throws IOException { + protected void setupNewConnection(String newURL, boolean forceGET) throws IOException { httpResponse = null; isAsync = outMessage != null && outMessage.getExchange() != null && !outMessage.getExchange().isSynchronous(); @@ -864,11 +869,11 @@ protected void setupNewConnection(String newURL) throws IOException { outbuf = new SharedOutputBuffer(bufSize); try { if (defaultAddress.getString().equals(newURL)) { - setupConnection(outMessage, defaultAddress, csPolicy); + setupConnection(outMessage, defaultAddress, csPolicy, forceGET); } else { Address address = new Address(newURL); this.url = address.getURI(); - setupConnection(outMessage, address, csPolicy); + setupConnection(outMessage, address, csPolicy, forceGET); } entity = outMessage.get(CXFHttpRequest.class); basicEntity = (MutableHttpEntity)entity.getEntity(); diff --git a/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java b/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java index cd358d43149..c3892237d37 100644 --- a/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java +++ b/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java @@ -102,7 +102,11 @@ public NettyHttpConduitFactory getNettyHttpConduitFactory() { } // Using Netty API directly - protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { + /*protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { + setupConnection(message, address, csPolicy, false) + }*/ + protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, + boolean forceGET) throws IOException { URI uri = address.getURI(); boolean addressChanged = false; @@ -155,7 +159,7 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic } if (!PropertyUtils.isTrue(o)) { message.put(USE_ASYNC, Boolean.FALSE); - super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy); + super.setupConnection(message, addressChanged ? new Address(uriString, uri) : address, csPolicy, forceGET); return; } message.put(USE_ASYNC, Boolean.TRUE); @@ -168,7 +172,10 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic message.put("http.scheme", uri.getScheme()); String httpRequestMethod = (String)message.get(Message.HTTP_REQUEST_METHOD); - if (httpRequestMethod == null) { + if (forceGET) { + httpRequestMethod = "GET"; + message.put(Message.HTTP_REQUEST_METHOD, httpRequestMethod); + } else if (httpRequestMethod == null) { httpRequestMethod = "POST"; message.put(Message.HTTP_REQUEST_METHOD, httpRequestMethod); } @@ -604,7 +611,7 @@ protected InputStream getPartialResponse() throws IOException { } @Override - protected void setupNewConnection(String newURL) throws IOException { + protected void setupNewConnection(String newURL, boolean forceGET) throws IOException { httpResponse = null; isAsync = false; exception = null; @@ -622,7 +629,7 @@ protected void setupNewConnection(String newURL) throws IOException { this.url = new URI(newURL); address = new Address(newURL, this.url); } - setupConnection(outMessage, address, csPolicy); + setupConnection(outMessage, address, csPolicy, forceGET); entity = outMessage.get(NettyHttpClientRequest.class); //reset the buffers outBuffer.clear(); 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 72253c6c4c6..66227c83292 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 @@ -197,6 +197,8 @@ public abstract class HTTPConduit 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_ON_301_302 = "http.redirect.force.GET"; + private static final String HTTP_POST_METHOD = "POST"; private static final String HTTP_GET_METHOD = "GET"; private static final Set KNOWN_HTTP_VERBS_WITH_NO_CONTENT = @@ -478,7 +480,8 @@ public Map getCookies() { } - protected abstract void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) + protected abstract void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, + boolean forceGET) throws IOException; /** @@ -517,7 +520,7 @@ public void prepare(Message message) throws IOException { boolean needToCacheRequest = false; HTTPClientPolicy csPolicy = getClient(message); - setupConnection(message, currentAddress, csPolicy); + setupConnection(message, currentAddress, csPolicy, false); // If the HTTP_REQUEST_METHOD is not set, the default is "POST". String httpRequestMethod = @@ -1188,7 +1191,7 @@ public void thresholdNotReached() { protected abstract InputStream getPartialResponse() throws IOException; //methods to support retransmission for auth or redirects - protected abstract void setupNewConnection(String newURL) throws IOException; + protected abstract void setupNewConnection(String newURL, boolean forceGET) throws IOException; protected abstract void retransmitStream() throws IOException; protected abstract void updateCookiesBeforeRetransmit() throws IOException; @@ -1272,8 +1275,8 @@ public void run() { } - protected void retransmit(String newURL) throws IOException { - setupNewConnection(newURL); + protected void retransmit(String newURL, boolean forceGET) throws IOException { + setupNewConnection(newURL, forceGET); if (cachedStream != null && cachedStream.size() < Integer.MAX_VALUE) { setFixedLengthStreamingMode((int)cachedStream.size()); } @@ -1470,7 +1473,7 @@ protected boolean processRetransmit() throws IOException { case HttpURLConnection.HTTP_SEE_OTHER: case 307: case 308: - return redirectRetransmit(); + return redirectRetransmit(responseCode); case HttpURLConnection.HTTP_UNAUTHORIZED: case HttpURLConnection.HTTP_PROXY_AUTH: return authorizationRetransmit(); @@ -1479,7 +1482,7 @@ protected boolean processRetransmit() throws IOException { } return false; } - protected boolean redirectRetransmit() throws IOException { + protected boolean redirectRetransmit(int responseCode) throws IOException { // If we are not redirecting by policy, then we don't. if (!getClient(outMessage).isAutoRedirect()) { return false; @@ -1490,10 +1493,13 @@ protected boolean redirectRetransmit() throws IOException { String newURL = extractLocation(Headers.getSetProtocolHeaders(m)); String urlString = url.toString(); + boolean forceGET = false; + try { newURL = convertToAbsoluteUrlIfNeeded(conduitName, urlString, newURL, outMessage); detectRedirectLoop(conduitName, urlString, newURL, outMessage); checkAllowedRedirectUri(conduitName, urlString, newURL, outMessage); + forceGET = forceGET(responseCode, outMessage); } catch (IOException ex) { // Consider introducing ClientRedirectException instead - it will require // those client runtimes which want to check for it have a direct link to it @@ -1515,7 +1521,7 @@ protected boolean redirectRetransmit() throws IOException { } cookies.writeToMessageHeaders(outMessage); outMessage.put("transport.retransmit.url", newURL); - retransmit(newURL); + retransmit(newURL, forceGET); return true; } return false; @@ -1555,7 +1561,7 @@ protected boolean authorizationRetransmit() throws IOException { } new Headers(outMessage).setAuthorization(authorizationToken); cookies.writeToMessageHeaders(outMessage); - retransmit(url.toString()); + retransmit(url.toString(), false); return true; } @@ -1845,6 +1851,12 @@ protected void makeTrustDecision() throws IOException { } } + private static boolean forceGET(int responseCode, Message message) { + return MessageUtils.getContextualBoolean(message, AUTO_REDIRECT_FORCE_GET_ON_301_302) + && (responseCode == HttpURLConnection.HTTP_MOVED_PERM + || responseCode == HttpURLConnection.HTTP_MOVED_TEMP); + } + private static void checkAllowedRedirectUri(String conduitName, String lastURL, String newURL, diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java index e31b2c5782a..0aa0c4dff1b 100644 --- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java +++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/URLConnectionHTTPConduit.java @@ -121,7 +121,8 @@ private HttpURLConnection createConnection(Message message, Address address, HTT return connectionFactory.createConnection(clientParameters, proxy != null ? proxy : address.getDefaultProxy(), url); } - protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { + protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, + boolean forceGET) throws IOException { HttpURLConnection connection = createConnection(message, address, csPolicy); connection.setDoOutput(true); @@ -140,10 +141,15 @@ protected void setupConnection(Message message, Address address, HTTPClientPolic // If the HTTP_REQUEST_METHOD is not set, the default is "POST". String httpRequestMethod = (String)message.get(Message.HTTP_REQUEST_METHOD); - if (httpRequestMethod == null) { + + if (forceGET) { + httpRequestMethod = "GET"; + message.put(Message.HTTP_REQUEST_METHOD, "GET"); + } else if (httpRequestMethod == null) { httpRequestMethod = "POST"; message.put(Message.HTTP_REQUEST_METHOD, "POST"); } + try { connection.setRequestMethod(httpRequestMethod); } catch (java.net.ProtocolException ex) { @@ -411,7 +417,7 @@ protected void handleNoOutput() throws IOException { connection.getOutputStream().close(); } } - protected void setupNewConnection(String newURL) throws IOException { + protected void setupNewConnection(String newURL, boolean forceGET) throws IOException { HTTPClientPolicy cp = getClient(outMessage); Address address; try { @@ -423,9 +429,13 @@ protected void setupNewConnection(String newURL) throws IOException { } catch (URISyntaxException e) { throw new IOException(e); } - setupConnection(outMessage, address, cp); + setupConnection(outMessage, address, cp, false); this.url = address.getURI(); connection = (HttpURLConnection)outMessage.get(KEY_HTTP_CONNECTION); + + if (forceGET) { + connection.setRequestMethod("GET"); + } } @Override diff --git a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/MockHTTPConduit.java b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/MockHTTPConduit.java index 94b5d120f83..baf5d8bc9dc 100644 --- a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/MockHTTPConduit.java +++ b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/MockHTTPConduit.java @@ -38,7 +38,7 @@ public MockHTTPConduit(Bus b, EndpointInfo ei, HTTPClientPolicy policy) throws I } @Override - protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) + protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, boolean forceGET) throws IOException { // TODO Auto-generated method stub @@ -136,7 +136,7 @@ protected InputStream getPartialResponse() throws IOException { } @Override - protected void setupNewConnection(String newURL) throws IOException { + protected void setupNewConnection(String newURL, boolean forceGet) throws IOException { // TODO Auto-generated method stub } diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java index 9fff4f7f426..54f3d4d8bfb 100644 --- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java +++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/ahc/AhcWebSocketConduit.java @@ -77,9 +77,11 @@ public AhcWebSocketConduit(Bus b, EndpointInfo ei, EndpointReferenceType t) thro } @Override - protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) + protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy, boolean forceGET) throws IOException { + forceGET = false; // this option is not enabled in this AhcWebSocket context + URI currentURL = address.getURI(); String s = currentURL.getScheme(); if (!"ws".equals(s) && !"wss".equals(s)) { @@ -272,7 +274,7 @@ protected InputStream getPartialResponse() throws IOException { } @Override - protected void setupNewConnection(String newURL) throws IOException { + protected void setupNewConnection(String newURL, boolean forceGET) throws IOException { // TODO throw new IOException("not supported"); }