mirror of https://github.com/apache/jclouds.git
Properly set the request method in HTTPS connections
This commit is contained in:
parent
7dc52f52ea
commit
e86462d499
|
@ -79,7 +79,6 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
private final Supplier<SSLContext> untrustedSSLContextProvider;
|
private final Supplier<SSLContext> untrustedSSLContextProvider;
|
||||||
private final Function<URI, Proxy> proxyForURI;
|
private final Function<URI, Proxy> proxyForURI;
|
||||||
private final HostnameVerifier verifier;
|
private final HostnameVerifier verifier;
|
||||||
private final Field methodField;
|
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
Supplier<SSLContext> sslContextSupplier;
|
Supplier<SSLContext> sslContextSupplier;
|
||||||
|
|
||||||
|
@ -96,8 +95,6 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
|
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
|
||||||
this.verifier = checkNotNull(verifier, "verifier");
|
this.verifier = checkNotNull(verifier, "verifier");
|
||||||
this.proxyForURI = checkNotNull(proxyForURI, "proxyForURI");
|
this.proxyForURI = checkNotNull(proxyForURI, "proxyForURI");
|
||||||
this.methodField = HttpURLConnection.class.getDeclaredField("method");
|
|
||||||
this.methodField.setAccessible(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -175,16 +172,8 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
// ex. Caused by: java.io.IOException: HTTPS hostname wrong: should be
|
// ex. Caused by: java.io.IOException: HTTPS hostname wrong: should be
|
||||||
// <adriancole.s3int0.s3-external-3.amazonaws.com>
|
// <adriancole.s3int0.s3-external-3.amazonaws.com>
|
||||||
connection.setInstanceFollowRedirects(false);
|
connection.setInstanceFollowRedirects(false);
|
||||||
try {
|
|
||||||
connection.setRequestMethod(request.getMethod());
|
setRequestMethodBypassingJREMethodLimitation(connection, request.getMethod());
|
||||||
} catch (ProtocolException e) {
|
|
||||||
try {
|
|
||||||
methodField.set(connection, request.getMethod());
|
|
||||||
} catch (IllegalAccessException e1) {
|
|
||||||
logger.error(e, "could not set request method: ", request.getMethod());
|
|
||||||
propagate(e1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : request.getHeaders().entries()) {
|
for (Map.Entry<String, String> entry : request.getHeaders().entries()) {
|
||||||
connection.setRequestProperty(entry.getKey(), entry.getValue());
|
connection.setRequestProperty(entry.getKey(), entry.getValue());
|
||||||
|
@ -228,6 +217,56 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround for a bug in <code>HttpURLConnection.setRequestMethod(String)</code>
|
||||||
|
* The implementation of Sun Microsystems is throwing a <code>ProtocolException</code>
|
||||||
|
* when the method is other than the HTTP/1.1 default methods. So
|
||||||
|
* to use PATCH and others, we must apply this workaround.
|
||||||
|
*
|
||||||
|
* See issue http://java.net/jira/browse/JERSEY-639
|
||||||
|
*/
|
||||||
|
private void setRequestMethodBypassingJREMethodLimitation(final HttpURLConnection httpURLConnection, final String method) {
|
||||||
|
try {
|
||||||
|
httpURLConnection.setRequestMethod(method);
|
||||||
|
// If the JRE does not support the given method, set it using reflection
|
||||||
|
} catch (final ProtocolException pe) {
|
||||||
|
Class<?> connectionClass = httpURLConnection.getClass();
|
||||||
|
Field delegateField = null;
|
||||||
|
try {
|
||||||
|
// SSL connections may have the HttpURLConnection wrapped inside
|
||||||
|
delegateField = connectionClass.getDeclaredField("delegate");
|
||||||
|
delegateField.setAccessible(true);
|
||||||
|
HttpURLConnection delegateConnection = (HttpURLConnection) delegateField.get(httpURLConnection);
|
||||||
|
setRequestMethodBypassingJREMethodLimitation(delegateConnection, method);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
// Ignore for now, keep going
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.error(e, "could not set request method: ", method);
|
||||||
|
propagate(e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.error(e, "could not set request method: ", method);
|
||||||
|
propagate(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Field methodField = null;
|
||||||
|
while (connectionClass != null) {
|
||||||
|
try {
|
||||||
|
methodField = connectionClass.getDeclaredField("method");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
connectionClass = connectionClass.getSuperclass();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
methodField.setAccessible(true);
|
||||||
|
methodField.set(httpURLConnection, method);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
logger.error(e, "could not set request method: ", method);
|
||||||
|
propagate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void writeNothing(HttpURLConnection connection) {
|
protected void writeNothing(HttpURLConnection connection) {
|
||||||
if (!HttpRequest.NON_PAYLOAD_METHODS.contains(connection.getRequestMethod())) {
|
if (!HttpRequest.NON_PAYLOAD_METHODS.contains(connection.getRequestMethod())) {
|
||||||
connection.setRequestProperty(CONTENT_LENGTH, "0");
|
connection.setRequestProperty(CONTENT_LENGTH, "0");
|
||||||
|
|
Loading…
Reference in New Issue