8009251: Add proxy handling and keep-alive fixes to jsse

Reviewed-by: chegar
This commit is contained in:
Rob McKenna 2013-03-21 17:33:15 +00:00
parent 0f8bf3e7c3
commit 8eecfc7522
3 changed files with 73 additions and 19 deletions

View File

@ -46,7 +46,7 @@ public class HttpClient extends NetworkClient {
// whether this httpclient comes from the cache // whether this httpclient comes from the cache
protected boolean cachedHttpClient = false; protected boolean cachedHttpClient = false;
private boolean inCache; protected boolean inCache;
// Http requests we send // Http requests we send
MessageHeader requests; MessageHeader requests;

View File

@ -96,7 +96,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends
http = HttpsClient.New (getSSLSocketFactory(), http = HttpsClient.New (getSSLSocketFactory(),
url, url,
getHostnameVerifier(), getHostnameVerifier(),
useCache); useCache, this);
((HttpsClient)http).afterConnect(); ((HttpsClient)http).afterConnect();
} }
@ -149,7 +149,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends
http = HttpsClient.New (getSSLSocketFactory(), http = HttpsClient.New (getSSLSocketFactory(),
url, url,
getHostnameVerifier(), getHostnameVerifier(),
proxyHost, proxyPort, useCache); proxyHost, proxyPort, useCache, this);
connected = true; connected = true;
} }
@ -189,7 +189,8 @@ public abstract class AbstractDelegateHttpsURLConnection extends
protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout) protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout)
throws IOException { throws IOException {
return HttpsClient.New(getSSLSocketFactory(), url, return HttpsClient.New(getSSLSocketFactory(), url,
getHostnameVerifier(), p, true, connectTimeout); getHostnameVerifier(), p, true, connectTimeout,
this);
} }
// will open new connection // will open new connection
@ -198,7 +199,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends
throws IOException { throws IOException {
return HttpsClient.New(getSSLSocketFactory(), url, return HttpsClient.New(getSSLSocketFactory(), url,
getHostnameVerifier(), p, getHostnameVerifier(), p,
useCache, connectTimeout); useCache, connectTimeout, this);
} }
/** /**

View File

@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL; import java.net.URL;
@ -46,11 +47,15 @@ import javax.security.auth.x500.X500Principal;
import javax.net.ssl.*; import javax.net.ssl.*;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
import sun.net.www.protocol.http.HttpURLConnection;
import sun.security.action.*; import sun.security.action.*;
import sun.security.util.HostnameChecker; import sun.security.util.HostnameChecker;
import sun.security.ssl.SSLSocketImpl; import sun.security.ssl.SSLSocketImpl;
import sun.util.logging.PlatformLogger;
import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*;
/** /**
* This class provides HTTPS client URL support, building on the standard * This class provides HTTPS client URL support, building on the standard
@ -274,15 +279,17 @@ final class HttpsClient extends HttpClient
// This code largely ripped off from HttpClient.New, and // This code largely ripped off from HttpClient.New, and
// it uses the same keepalive cache. // it uses the same keepalive cache.
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv) static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
HttpURLConnection httpuc)
throws IOException { throws IOException {
return HttpsClient.New(sf, url, hv, true); return HttpsClient.New(sf, url, hv, true, httpuc);
} }
/** See HttpClient for the model for this method. */ /** See HttpClient for the model for this method. */
static HttpClient New(SSLSocketFactory sf, URL url, static HttpClient New(SSLSocketFactory sf, URL url,
HostnameVerifier hv, boolean useCache) throws IOException { HostnameVerifier hv, boolean useCache,
return HttpsClient.New(sf, url, hv, (String)null, -1, useCache); HttpURLConnection httpuc) throws IOException {
return HttpsClient.New(sf, url, hv, (String)null, -1, useCache, httpuc);
} }
/** /**
@ -290,37 +297,74 @@ final class HttpsClient extends HttpClient
* the specified proxy server. * the specified proxy server.
*/ */
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
String proxyHost, int proxyPort) throws IOException { String proxyHost, int proxyPort,
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true); HttpURLConnection httpuc) throws IOException {
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true, httpuc);
} }
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
String proxyHost, int proxyPort, boolean useCache) String proxyHost, int proxyPort, boolean useCache,
HttpURLConnection httpuc)
throws IOException { throws IOException {
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1); return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1,
httpuc);
} }
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
String proxyHost, int proxyPort, boolean useCache, String proxyHost, int proxyPort, boolean useCache,
int connectTimeout) int connectTimeout, HttpURLConnection httpuc)
throws IOException { throws IOException {
return HttpsClient.New(sf, url, hv, return HttpsClient.New(sf, url, hv,
(proxyHost == null? null : (proxyHost == null? null :
HttpsClient.newHttpProxy(proxyHost, proxyPort)), HttpsClient.newHttpProxy(proxyHost, proxyPort)),
useCache, connectTimeout); useCache, connectTimeout, httpuc);
} }
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
Proxy p, boolean useCache, Proxy p, boolean useCache,
int connectTimeout) int connectTimeout, HttpURLConnection httpuc)
throws IOException { throws IOException
{
if (p == null) {
p = Proxy.NO_PROXY;
}
HttpsClient ret = null; HttpsClient ret = null;
if (useCache) { if (useCache) {
/* see if one's already around */ /* see if one's already around */
ret = (HttpsClient) kac.get(url, sf); ret = (HttpsClient) kac.get(url, sf);
if (ret != null && httpuc != null &&
httpuc.streaming() &&
httpuc.getRequestMethod() == "POST") {
if (!ret.available())
ret = null;
}
if (ret != null) { if (ret != null) {
ret.cachedHttpClient = true; if ((ret.proxy != null && ret.proxy.equals(p)) ||
(ret.proxy == null && p == null)) {
synchronized (ret) {
ret.cachedHttpClient = true;
assert ret.inCache;
ret.inCache = false;
if (httpuc != null && ret.needsTunneling())
httpuc.setTunnelState(TUNNELING);
PlatformLogger logger = HttpURLConnection.getHttpLogger();
if (logger.isLoggable(PlatformLogger.FINEST)) {
logger.finest("KeepAlive stream retrieved from the cache, " + ret);
}
}
} else {
// We cannot return this connection to the cache as it's
// KeepAliveTimeout will get reset. We simply close the connection.
// This should be fine as it is very rare that a connection
// to the same host will not use the same proxy.
synchronized(ret) {
ret.inCache = false;
ret.closeServer();
}
ret = null;
}
} }
} }
if (ret == null) { if (ret == null) {
@ -328,7 +372,11 @@ final class HttpsClient extends HttpClient
} else { } else {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) { if (security != null) {
security.checkConnect(url.getHost(), url.getPort()); if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) {
security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort());
} else {
security.checkConnect(url.getHost(), url.getPort());
}
} }
ret.url = url; ret.url = url;
} }
@ -607,6 +655,11 @@ final class HttpsClient extends HttpClient
@Override @Override
protected void putInKeepAliveCache() { protected void putInKeepAliveCache() {
if (inCache) {
assert false : "Duplicate put to keep alive cache";
return;
}
inCache = true;
kac.put(url, sslSocketFactory, this); kac.put(url, sslSocketFactory, this);
} }