提交 0e5a23ca 编写于 作者: C chegar

6687282: URLConnection for HTTPS connection through Proxy w/ Digest...

6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
Summary: Change http/digest implementation to use host:port from CONNECT request
Reviewed-by: michaelm
上级 9ff1e2e3
......@@ -36,6 +36,7 @@ import java.util.Random;
import sun.net.www.HeaderParser;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import static sun.net.www.protocol.http.HttpURLConnection.HTTP_CONNECT;
/**
......@@ -210,10 +211,38 @@ class DigestAuthentication extends AuthenticationInfo {
/**
* Reclaculates the request-digest and returns it.
*
* <P> Used in the common case where the requestURI is simply the
* abs_path.
*
* @param url
* the URL
*
* @param method
* the HTTP method
*
* @return the value of the HTTP header this authentication wants set
*/
String getHeaderValue(URL url, String method) {
return getHeaderValueImpl (url.getFile(), method);
return getHeaderValueImpl(url.getFile(), method);
}
/**
* Reclaculates the request-digest and returns it.
*
* <P> Used when the requestURI is not the abs_path. The exact
* requestURI can be passed as a String.
*
* @param requestURI
* the Request-URI from the HTTP request line
*
* @param method
* the HTTP method
*
* @return the value of the HTTP header this authentication wants set
*/
String getHeaderValue(String requestURI, String method) {
return getHeaderValueImpl(requestURI, method);
}
/**
......@@ -249,7 +278,16 @@ class DigestAuthentication extends AuthenticationInfo {
params.setOpaque (p.findValue("opaque"));
params.setQop (p.findValue("qop"));
String uri = conn.getURL().getFile();
String uri;
String method;
if (type == PROXY_AUTHENTICATION &&
conn.tunnelState() == HttpURLConnection.TunnelState.SETUP) {
uri = HttpURLConnection.connectRequestURI(conn.getURL());
method = HTTP_CONNECT;
} else {
uri = conn.getURL().getFile();
method = conn.getMethod();
}
if (params.nonce == null || authMethod == null || pw == null || realm == null) {
return false;
......@@ -275,7 +313,7 @@ class DigestAuthentication extends AuthenticationInfo {
params.setNewCnonce();
}
String value = getHeaderValueImpl (uri, conn.getMethod());
String value = getHeaderValueImpl (uri, method);
if (value != null) {
conn.setAuthenticationProperty(getHeaderName(), value);
return true;
......
......@@ -75,6 +75,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
private static Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
static String HTTP_CONNECT = "CONNECT";
static final String version;
public static final String userAgent;
......@@ -266,6 +268,20 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
/* If we decide we want to reuse a client, we put it here */
private HttpClient reuseClient = null;
/* Tunnel states */
enum TunnelState {
/* No tunnel */
NONE,
/* Setting up a tunnel */
SETUP,
/* Tunnel has been successfully setup */
TUNNELING
}
private TunnelState tunnelState = TunnelState.NONE;
/* Redefine timeouts from java.net.URLConnection as we nee -1 to mean
* not set. This is to ensure backward compatibility.
*/
......@@ -338,7 +354,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
* others that have been set
*/
// send any pre-emptive authentication
if (http.usingProxy) {
if (http.usingProxy && tunnelState() != TunnelState.TUNNELING) {
setPreemptiveProxyAuthentication(requests);
}
if (!setRequests) {
......@@ -1404,11 +1420,17 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
String raw = auth.raw();
if (proxyAuthentication.isAuthorizationStale (raw)) {
/* we can retry with the current credentials */
requests.set (proxyAuthentication.getHeaderName(),
proxyAuthentication.getHeaderValue(
url, method));
String value;
if (tunnelState() == TunnelState.SETUP &&
proxyAuthentication instanceof DigestAuthentication) {
value = ((DigestAuthentication)proxyAuthentication)
.getHeaderValue(connectRequestURI(url), HTTP_CONNECT);
} else {
value = proxyAuthentication.getHeaderValue(url, method);
}
requests.set(proxyAuthentication.getHeaderName(), value);
currentProxyCredentials = proxyAuthentication;
return proxyAuthentication;
return proxyAuthentication;
} else {
proxyAuthentication.removeFromCache();
}
......@@ -1418,6 +1440,24 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
return proxyAuthentication;
}
/**
* Returns the tunnel state.
*
* @return the state
*/
TunnelState tunnelState() {
return tunnelState;
}
/**
* Set the tunneling status.
*
* @param the state
*/
void setTunnelState(TunnelState tunnelState) {
this.tunnelState = tunnelState;
}
/**
* establish a tunnel through proxy server
*/
......@@ -1437,6 +1477,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
boolean inNegotiateProxy = false;
try {
/* Actively setting up a tunnel */
setTunnelState(TunnelState.SETUP);
do {
if (!checkReuseConnection()) {
proxiedConnect(url, proxyHost, proxyPort, false);
......@@ -1512,11 +1555,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
}
if (respCode == HTTP_OK) {
setTunnelState(TunnelState.TUNNELING);
break;
}
// we don't know how to deal with other response code
// so disconnect and report error
disconnectInternal();
setTunnelState(TunnelState.NONE);
break;
} while (retryTunnel < maxRedirects);
......@@ -1538,6 +1583,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
responses.reset();
}
static String connectRequestURI(URL url) {
String host = url.getHost();
int port = url.getPort();
port = port != -1 ? port : url.getDefaultPort();
return host + ":" + port;
}
/**
* send a CONNECT request for establishing a tunnel to proxy server
*/
......@@ -1551,8 +1604,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
// otherwise, there may have 2 http methods in headers
if (setRequests) requests.set(0, null, null);
requests.prepend("CONNECT " + url.getHost() + ":"
+ (port != -1 ? port : url.getDefaultPort())
requests.prepend(HTTP_CONNECT + " " + connectRequestURI(url)
+ " " + httpVersion, null);
requests.setIfNotSet("User-Agent", userAgent);
......@@ -1583,9 +1635,17 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
= AuthenticationInfo.getProxyAuth(http.getProxyHostUsed(),
http.getProxyPortUsed());
if (pauth != null && pauth.supportsPreemptiveAuthorization()) {
String value;
if (tunnelState() == TunnelState.SETUP &&
pauth instanceof DigestAuthentication) {
value = ((DigestAuthentication)pauth)
.getHeaderValue(connectRequestURI(url), HTTP_CONNECT);
} else {
value = pauth.getHeaderValue(url, method);
}
// Sets "Proxy-authorization"
requests.set(pauth.getHeaderName(),
pauth.getHeaderValue(url,method));
requests.set(pauth.getHeaderName(), value);
currentProxyCredentials = pauth;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册