feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.net.www.protocol.https;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.Proxy;
|
||||
import java.net.SecureCacheResponse;
|
||||
import java.security.Principal;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import sun.net.www.http.*;
|
||||
import sun.net.www.protocol.http.HttpURLConnection;
|
||||
|
||||
/**
|
||||
* HTTPS URL connection support.
|
||||
* We need this delegate because HttpsURLConnection is a subclass of
|
||||
* java.net.HttpURLConnection. We will avoid copying over the code from
|
||||
* sun.net.www.protocol.http.HttpURLConnection by having this class
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractDelegateHttpsURLConnection extends
|
||||
HttpURLConnection {
|
||||
|
||||
protected AbstractDelegateHttpsURLConnection(URL url,
|
||||
sun.net.www.protocol.http.Handler handler) throws IOException {
|
||||
this(url, null, handler);
|
||||
}
|
||||
|
||||
protected AbstractDelegateHttpsURLConnection(URL url, Proxy p,
|
||||
sun.net.www.protocol.http.Handler handler) throws IOException {
|
||||
super(url, p, handler);
|
||||
}
|
||||
|
||||
protected abstract javax.net.ssl.SSLSocketFactory getSSLSocketFactory();
|
||||
|
||||
protected abstract javax.net.ssl.HostnameVerifier getHostnameVerifier();
|
||||
|
||||
/**
|
||||
* No user application is able to call these routines, as no one
|
||||
* should ever get access to an instance of
|
||||
* DelegateHttpsURLConnection (sun.* or com.*)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new HttpClient object, bypassing the cache of
|
||||
* HTTP client objects/connections.
|
||||
*
|
||||
* Note: this method is changed from protected to public because
|
||||
* the com.sun.ssl.internal.www.protocol.https handler reuses this
|
||||
* class for its actual implemantation
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
*/
|
||||
public void setNewClient (URL url)
|
||||
throws IOException {
|
||||
setNewClient (url, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a HttpClient object. Use the cached copy if specified.
|
||||
*
|
||||
* Note: this method is changed from protected to public because
|
||||
* the com.sun.ssl.internal.www.protocol.https handler reuses this
|
||||
* class for its actual implemantation
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
* @param useCache whether the cached connection should be used
|
||||
* if present
|
||||
*/
|
||||
public void setNewClient (URL url, boolean useCache)
|
||||
throws IOException {
|
||||
int readTimeout = getReadTimeout();
|
||||
http = HttpsClient.New (getSSLSocketFactory(),
|
||||
url,
|
||||
getHostnameVerifier(),
|
||||
null,
|
||||
-1,
|
||||
useCache,
|
||||
getConnectTimeout(),
|
||||
this);
|
||||
http.setReadTimeout(readTimeout);
|
||||
((HttpsClient)http).afterConnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new HttpClient object, set up so that it uses
|
||||
* per-instance proxying to the given HTTP proxy. This
|
||||
* bypasses the cache of HTTP client objects/connections.
|
||||
*
|
||||
* Note: this method is changed from protected to public because
|
||||
* the com.sun.ssl.internal.www.protocol.https handler reuses this
|
||||
* class for its actual implemantation
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
* @param proxyHost the proxy host to use
|
||||
* @param proxyPort the proxy port to use
|
||||
*/
|
||||
public void setProxiedClient (URL url, String proxyHost, int proxyPort)
|
||||
throws IOException {
|
||||
setProxiedClient(url, proxyHost, proxyPort, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a HttpClient object, set up so that it uses per-instance
|
||||
* proxying to the given HTTP proxy. Use the cached copy of HTTP
|
||||
* client objects/connections if specified.
|
||||
*
|
||||
* Note: this method is changed from protected to public because
|
||||
* the com.sun.ssl.internal.www.protocol.https handler reuses this
|
||||
* class for its actual implemantation
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
* @param proxyHost the proxy host to use
|
||||
* @param proxyPort the proxy port to use
|
||||
* @param useCache whether the cached connection should be used
|
||||
* if present
|
||||
*/
|
||||
public void setProxiedClient (URL url, String proxyHost, int proxyPort,
|
||||
boolean useCache) throws IOException {
|
||||
proxiedConnect(url, proxyHost, proxyPort, useCache);
|
||||
if (!http.isCachedConnection()) {
|
||||
doTunneling();
|
||||
}
|
||||
((HttpsClient)http).afterConnect();
|
||||
}
|
||||
|
||||
protected void proxiedConnect(URL url, String proxyHost, int proxyPort,
|
||||
boolean useCache) throws IOException {
|
||||
if (connected)
|
||||
return;
|
||||
int readTimeout = getReadTimeout();
|
||||
http = HttpsClient.New (getSSLSocketFactory(),
|
||||
url,
|
||||
getHostnameVerifier(),
|
||||
proxyHost,
|
||||
proxyPort,
|
||||
useCache,
|
||||
getConnectTimeout(),
|
||||
this);
|
||||
http.setReadTimeout(readTimeout);
|
||||
connected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by subclass to access "connected" variable.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by subclass to access "connected" variable.
|
||||
*/
|
||||
public void setConnected(boolean conn) {
|
||||
connected = conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the HTTP protocol handler's "connect" method,
|
||||
* establishing an SSL connection to the server as necessary.
|
||||
*/
|
||||
public void connect() throws IOException {
|
||||
if (connected)
|
||||
return;
|
||||
plainConnect();
|
||||
if (cachedResponse != null) {
|
||||
// using cached response
|
||||
return;
|
||||
}
|
||||
if (!http.isCachedConnection() && http.needsTunneling()) {
|
||||
doTunneling();
|
||||
}
|
||||
((HttpsClient)http).afterConnect();
|
||||
}
|
||||
|
||||
// will try to use cached HttpsClient
|
||||
protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout)
|
||||
throws IOException {
|
||||
return HttpsClient.New(getSSLSocketFactory(), url,
|
||||
getHostnameVerifier(), p, true, connectTimeout,
|
||||
this);
|
||||
}
|
||||
|
||||
// will open new connection
|
||||
protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout,
|
||||
boolean useCache)
|
||||
throws IOException {
|
||||
return HttpsClient.New(getSSLSocketFactory(), url,
|
||||
getHostnameVerifier(), p,
|
||||
useCache, connectTimeout, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cipher suite in use on this connection.
|
||||
*/
|
||||
public String getCipherSuite () {
|
||||
if (cachedResponse != null) {
|
||||
return ((SecureCacheResponse)cachedResponse).getCipherSuite();
|
||||
}
|
||||
if (http == null) {
|
||||
throw new IllegalStateException("connection not yet open");
|
||||
} else {
|
||||
return ((HttpsClient)http).getCipherSuite ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the certificate chain the client sent to the
|
||||
* server, or null if the client did not authenticate.
|
||||
*/
|
||||
public java.security.cert.Certificate[] getLocalCertificates() {
|
||||
if (cachedResponse != null) {
|
||||
List<java.security.cert.Certificate> l = ((SecureCacheResponse)cachedResponse).getLocalCertificateChain();
|
||||
if (l == null) {
|
||||
return null;
|
||||
} else {
|
||||
return l.toArray(new java.security.cert.Certificate[0]);
|
||||
}
|
||||
}
|
||||
if (http == null) {
|
||||
throw new IllegalStateException("connection not yet open");
|
||||
} else {
|
||||
return (((HttpsClient)http).getLocalCertificates ());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's certificate chain, or throws
|
||||
* SSLPeerUnverified Exception if
|
||||
* the server did not authenticate.
|
||||
*/
|
||||
public java.security.cert.Certificate[] getServerCertificates()
|
||||
throws SSLPeerUnverifiedException {
|
||||
if (cachedResponse != null) {
|
||||
List<java.security.cert.Certificate> l = ((SecureCacheResponse)cachedResponse).getServerCertificateChain();
|
||||
if (l == null) {
|
||||
return null;
|
||||
} else {
|
||||
return l.toArray(new java.security.cert.Certificate[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (http == null) {
|
||||
throw new IllegalStateException("connection not yet open");
|
||||
} else {
|
||||
return (((HttpsClient)http).getServerCertificates ());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's X.509 certificate chain, or null if
|
||||
* the server did not authenticate.
|
||||
*/
|
||||
public javax.security.cert.X509Certificate[] getServerCertificateChain()
|
||||
throws SSLPeerUnverifiedException {
|
||||
if (cachedResponse != null) {
|
||||
throw new UnsupportedOperationException("this method is not supported when using cache");
|
||||
}
|
||||
if (http == null) {
|
||||
throw new IllegalStateException("connection not yet open");
|
||||
} else {
|
||||
return ((HttpsClient)http).getServerCertificateChain ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's principal, or throws SSLPeerUnverifiedException
|
||||
* if the server did not authenticate.
|
||||
*/
|
||||
Principal getPeerPrincipal()
|
||||
throws SSLPeerUnverifiedException
|
||||
{
|
||||
if (cachedResponse != null) {
|
||||
return ((SecureCacheResponse)cachedResponse).getPeerPrincipal();
|
||||
}
|
||||
|
||||
if (http == null) {
|
||||
throw new IllegalStateException("connection not yet open");
|
||||
} else {
|
||||
return (((HttpsClient)http).getPeerPrincipal());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal the client sent to the
|
||||
* server, or null if the client did not authenticate.
|
||||
*/
|
||||
Principal getLocalPrincipal()
|
||||
{
|
||||
if (cachedResponse != null) {
|
||||
return ((SecureCacheResponse)cachedResponse).getLocalPrincipal();
|
||||
}
|
||||
|
||||
if (http == null) {
|
||||
throw new IllegalStateException("connection not yet open");
|
||||
} else {
|
||||
return (((HttpsClient)http).getLocalPrincipal());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.net.www.protocol.https;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
/**
|
||||
* <code>HostnameVerifier</code> provides a callback mechanism so that
|
||||
* implementers of this interface can supply a policy for
|
||||
* handling the case where the host to connect to and
|
||||
* the server name from the certificate mismatch.
|
||||
*
|
||||
* The default implementation will deny such connections.
|
||||
*
|
||||
* @author Xuelei Fan
|
||||
*/
|
||||
final public class DefaultHostnameVerifier implements HostnameVerifier {
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.net.www.protocol.https;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.Proxy;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class was introduced to provide an additional level of
|
||||
* abstraction between javax.net.ssl.HttpURLConnection and
|
||||
* com.sun.net.ssl.HttpURLConnection objects. <p>
|
||||
*
|
||||
* javax.net.ssl.HttpURLConnection is used in the new sun.net version
|
||||
* of protocol implementation (this one)
|
||||
* com.sun.net.ssl.HttpURLConnection is used in the com.sun version.
|
||||
*
|
||||
*/
|
||||
public class DelegateHttpsURLConnection extends AbstractDelegateHttpsURLConnection {
|
||||
|
||||
// we need a reference to the HttpsURLConnection to get
|
||||
// the properties set there
|
||||
// we also need it to be public so that it can be referenced
|
||||
// from sun.net.www.protocol.http.HttpURLConnection
|
||||
// this is for ResponseCache.put(URI, URLConnection)
|
||||
// second parameter needs to be cast to javax.net.ssl.HttpsURLConnection
|
||||
// instead of AbstractDelegateHttpsURLConnection
|
||||
public javax.net.ssl.HttpsURLConnection httpsURLConnection;
|
||||
|
||||
DelegateHttpsURLConnection(URL url,
|
||||
sun.net.www.protocol.http.Handler handler,
|
||||
javax.net.ssl.HttpsURLConnection httpsURLConnection)
|
||||
throws IOException {
|
||||
this(url, null, handler, httpsURLConnection);
|
||||
}
|
||||
|
||||
DelegateHttpsURLConnection(URL url, Proxy p,
|
||||
sun.net.www.protocol.http.Handler handler,
|
||||
javax.net.ssl.HttpsURLConnection httpsURLConnection)
|
||||
throws IOException {
|
||||
super(url, p, handler);
|
||||
this.httpsURLConnection = httpsURLConnection;
|
||||
}
|
||||
|
||||
protected javax.net.ssl.SSLSocketFactory getSSLSocketFactory() {
|
||||
return httpsURLConnection.getSSLSocketFactory();
|
||||
}
|
||||
|
||||
protected javax.net.ssl.HostnameVerifier getHostnameVerifier() {
|
||||
return httpsURLConnection.getHostnameVerifier();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by layered delegator's finalize() method to handle closing
|
||||
* the underlying object.
|
||||
*/
|
||||
protected void dispose() throws Throwable {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
64
jdkSrc/jdk8/sun/net/www/protocol/https/Handler.java
Normal file
64
jdkSrc/jdk8/sun/net/www/protocol/https/Handler.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* HTTP stream opener
|
||||
*/
|
||||
|
||||
package sun.net.www.protocol.https;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.Proxy;
|
||||
|
||||
/** open an http input stream given a URL */
|
||||
public class Handler extends sun.net.www.protocol.http.Handler {
|
||||
protected String proxy;
|
||||
protected int proxyPort;
|
||||
|
||||
protected int getDefaultPort() {
|
||||
return 443;
|
||||
}
|
||||
|
||||
public Handler () {
|
||||
proxy = null;
|
||||
proxyPort = -1;
|
||||
}
|
||||
|
||||
public Handler (String proxy, int port) {
|
||||
this.proxy = proxy;
|
||||
this.proxyPort = port;
|
||||
}
|
||||
|
||||
protected java.net.URLConnection openConnection(URL u)
|
||||
throws IOException {
|
||||
return openConnection(u, (Proxy)null);
|
||||
}
|
||||
|
||||
protected java.net.URLConnection openConnection(URL u, Proxy p)
|
||||
throws IOException {
|
||||
return new HttpsURLConnectionImpl(u, p, this);
|
||||
}
|
||||
}
|
||||
796
jdkSrc/jdk8/sun/net/www/protocol/https/HttpsClient.java
Normal file
796
jdkSrc/jdk8/sun/net/www/protocol/https/HttpsClient.java
Normal file
@@ -0,0 +1,796 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package sun.net.www.protocol.https;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.*;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.security.AccessController;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import sun.net.www.http.HttpClient;
|
||||
import sun.net.www.protocol.http.HttpURLConnection;
|
||||
import sun.security.action.*;
|
||||
|
||||
import sun.security.util.HostnameChecker;
|
||||
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
|
||||
* "sun.net.www" HTTP protocol handler. HTTPS is the same protocol as HTTP,
|
||||
* but differs in the transport layer which it uses: <UL>
|
||||
*
|
||||
* <LI>There's a <em>Secure Sockets Layer</em> between TCP
|
||||
* and the HTTP protocol code.
|
||||
*
|
||||
* <LI>It uses a different default TCP port.
|
||||
*
|
||||
* <LI>It doesn't use application level proxies, which can see and
|
||||
* manipulate HTTP user level data, compromising privacy. It uses
|
||||
* low level tunneling instead, which hides HTTP protocol and data
|
||||
* from all third parties. (Traffic analysis is still possible).
|
||||
*
|
||||
* <LI>It does basic server authentication, to protect
|
||||
* against "URL spoofing" attacks. This involves deciding
|
||||
* whether the X.509 certificate chain identifying the server
|
||||
* is trusted, and verifying that the name of the server is
|
||||
* found in the certificate. (The application may enable an
|
||||
* anonymous SSL cipher suite, and such checks are not done
|
||||
* for anonymous ciphers.)
|
||||
*
|
||||
* <LI>It exposes key SSL session attributes, specifically the
|
||||
* cipher suite in use and the server's X509 certificates, to
|
||||
* application software which knows about this protocol handler.
|
||||
*
|
||||
* </UL>
|
||||
*
|
||||
* <P> System properties used include: <UL>
|
||||
*
|
||||
* <LI><em>https.proxyHost</em> ... the host supporting SSL
|
||||
* tunneling using the conventional CONNECT syntax
|
||||
*
|
||||
* <LI><em>https.proxyPort</em> ... port to use on proxyHost
|
||||
*
|
||||
* <LI><em>https.cipherSuites</em> ... comma separated list of
|
||||
* SSL cipher suite names to enable.
|
||||
*
|
||||
* <LI><em>http.nonProxyHosts</em> ...
|
||||
*
|
||||
* </UL>
|
||||
*
|
||||
* @author David Brownell
|
||||
* @author Bill Foote
|
||||
*/
|
||||
|
||||
// final for export control reasons (access to APIs); remove with care
|
||||
final class HttpsClient extends HttpClient
|
||||
implements HandshakeCompletedListener
|
||||
{
|
||||
// STATIC STATE and ACCESSORS THERETO
|
||||
|
||||
// HTTPS uses a different default port number than HTTP.
|
||||
private static final int httpsPortNumber = 443;
|
||||
|
||||
// default HostnameVerifier class canonical name
|
||||
private static final String defaultHVCanonicalName =
|
||||
"javax.net.ssl.HttpsURLConnection.DefaultHostnameVerifier";
|
||||
|
||||
/** Returns the default HTTPS port (443) */
|
||||
@Override
|
||||
protected int getDefaultPort() { return httpsPortNumber; }
|
||||
|
||||
private HostnameVerifier hv;
|
||||
private SSLSocketFactory sslSocketFactory;
|
||||
|
||||
// HttpClient.proxyDisabled will always be false, because we don't
|
||||
// use an application-level HTTP proxy. We might tunnel through
|
||||
// our http proxy, though.
|
||||
|
||||
|
||||
// INSTANCE DATA
|
||||
|
||||
// last negotiated SSL session
|
||||
private SSLSession session;
|
||||
|
||||
private String [] getCipherSuites() {
|
||||
//
|
||||
// If ciphers are assigned, sort them into an array.
|
||||
//
|
||||
String ciphers [];
|
||||
String cipherString = AccessController.doPrivileged(
|
||||
new GetPropertyAction("https.cipherSuites"));
|
||||
|
||||
if (cipherString == null || "".equals(cipherString)) {
|
||||
ciphers = null;
|
||||
} else {
|
||||
StringTokenizer tokenizer;
|
||||
Vector<String> v = new Vector<String>();
|
||||
|
||||
tokenizer = new StringTokenizer(cipherString, ",");
|
||||
while (tokenizer.hasMoreTokens())
|
||||
v.addElement(tokenizer.nextToken());
|
||||
ciphers = new String [v.size()];
|
||||
for (int i = 0; i < ciphers.length; i++)
|
||||
ciphers [i] = v.elementAt(i);
|
||||
}
|
||||
return ciphers;
|
||||
}
|
||||
|
||||
private String [] getProtocols() {
|
||||
//
|
||||
// If protocols are assigned, sort them into an array.
|
||||
//
|
||||
String protocols [];
|
||||
String protocolString = AccessController.doPrivileged(
|
||||
new GetPropertyAction("https.protocols"));
|
||||
|
||||
if (protocolString == null || "".equals(protocolString)) {
|
||||
protocols = null;
|
||||
} else {
|
||||
StringTokenizer tokenizer;
|
||||
Vector<String> v = new Vector<String>();
|
||||
|
||||
tokenizer = new StringTokenizer(protocolString, ",");
|
||||
while (tokenizer.hasMoreTokens())
|
||||
v.addElement(tokenizer.nextToken());
|
||||
protocols = new String [v.size()];
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
protocols [i] = v.elementAt(i);
|
||||
}
|
||||
}
|
||||
return protocols;
|
||||
}
|
||||
|
||||
private String getUserAgent() {
|
||||
String userAgent = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("https.agent"));
|
||||
if (userAgent == null || userAgent.length() == 0) {
|
||||
userAgent = "JSSE";
|
||||
}
|
||||
return userAgent;
|
||||
}
|
||||
|
||||
// CONSTRUCTOR, FACTORY
|
||||
|
||||
|
||||
/**
|
||||
* Create an HTTPS client URL. Traffic will be tunneled through any
|
||||
* intermediate nodes rather than proxied, so that confidentiality
|
||||
* of data exchanged can be preserved. However, note that all the
|
||||
* anonymous SSL flavors are subject to "person-in-the-middle"
|
||||
* attacks against confidentiality. If you enable use of those
|
||||
* flavors, you may be giving up the protection you get through
|
||||
* SSL tunneling.
|
||||
*
|
||||
* Use New to get new HttpsClient. This constructor is meant to be
|
||||
* used only by New method. New properly checks for URL spoofing.
|
||||
*
|
||||
* @param URL https URL with which a connection must be established
|
||||
*/
|
||||
private HttpsClient(SSLSocketFactory sf, URL url)
|
||||
throws IOException
|
||||
{
|
||||
// HttpClient-level proxying is always disabled,
|
||||
// because we override doConnect to do tunneling instead.
|
||||
this(sf, url, (String)null, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTPS client URL. Traffic will be tunneled through
|
||||
* the specified proxy server.
|
||||
*/
|
||||
HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort)
|
||||
throws IOException {
|
||||
this(sf, url, proxyHost, proxyPort, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an HTTPS client URL. Traffic will be tunneled through
|
||||
* the specified proxy server, with a connect timeout
|
||||
*/
|
||||
HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort,
|
||||
int connectTimeout)
|
||||
throws IOException {
|
||||
this(sf, url,
|
||||
(proxyHost == null? null:
|
||||
HttpClient.newHttpProxy(proxyHost, proxyPort, "https")),
|
||||
connectTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as previous constructor except using a Proxy
|
||||
*/
|
||||
HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy,
|
||||
int connectTimeout)
|
||||
throws IOException {
|
||||
PlatformLogger logger = HttpURLConnection.getHttpLogger();
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
logger.finest("Creating new HttpsClient with url:" + url + " and proxy:" + proxy +
|
||||
" with connect timeout:" + connectTimeout);
|
||||
}
|
||||
this.proxy = proxy;
|
||||
setSSLSocketFactory(sf);
|
||||
this.proxyDisabled = true;
|
||||
|
||||
this.host = url.getHost();
|
||||
this.url = url;
|
||||
port = url.getPort();
|
||||
if (port == -1) {
|
||||
port = getDefaultPort();
|
||||
}
|
||||
setConnectTimeout(connectTimeout);
|
||||
openServer();
|
||||
}
|
||||
|
||||
|
||||
// This code largely ripped off from HttpClient.New, and
|
||||
// it uses the same keepalive cache.
|
||||
|
||||
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
|
||||
HttpURLConnection httpuc)
|
||||
throws IOException {
|
||||
return HttpsClient.New(sf, url, hv, true, httpuc);
|
||||
}
|
||||
|
||||
/** See HttpClient for the model for this method. */
|
||||
static HttpClient New(SSLSocketFactory sf, URL url,
|
||||
HostnameVerifier hv, boolean useCache,
|
||||
HttpURLConnection httpuc) throws IOException {
|
||||
return HttpsClient.New(sf, url, hv, (String)null, -1, useCache, httpuc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a HTTPS client to the URL. Traffic will be tunneled through
|
||||
* the specified proxy server.
|
||||
*/
|
||||
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
|
||||
String proxyHost, int proxyPort,
|
||||
HttpURLConnection httpuc) throws IOException {
|
||||
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true, httpuc);
|
||||
}
|
||||
|
||||
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
|
||||
String proxyHost, int proxyPort, boolean useCache,
|
||||
HttpURLConnection httpuc)
|
||||
throws IOException {
|
||||
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1,
|
||||
httpuc);
|
||||
}
|
||||
|
||||
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
|
||||
String proxyHost, int proxyPort, boolean useCache,
|
||||
int connectTimeout, HttpURLConnection httpuc)
|
||||
throws IOException {
|
||||
|
||||
return HttpsClient.New(sf, url, hv,
|
||||
(proxyHost == null? null :
|
||||
HttpClient.newHttpProxy(proxyHost, proxyPort, "https")),
|
||||
useCache, connectTimeout, httpuc);
|
||||
}
|
||||
|
||||
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
|
||||
Proxy p, boolean useCache,
|
||||
int connectTimeout, HttpURLConnection httpuc)
|
||||
throws IOException
|
||||
{
|
||||
if (p == null) {
|
||||
p = Proxy.NO_PROXY;
|
||||
}
|
||||
PlatformLogger logger = HttpURLConnection.getHttpLogger();
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
logger.finest("Looking for HttpClient for URL " + url +
|
||||
" and proxy value of " + p);
|
||||
}
|
||||
HttpsClient ret = null;
|
||||
if (useCache) {
|
||||
/* see if one's already around */
|
||||
ret = (HttpsClient) kac.get(url, sf);
|
||||
if (ret != null && httpuc != null &&
|
||||
httpuc.streaming() &&
|
||||
"POST".equals(httpuc.getRequestMethod())) {
|
||||
if (!ret.available())
|
||||
ret = null;
|
||||
}
|
||||
|
||||
if (ret != null) {
|
||||
if ((ret.proxy != null && ret.proxy.equals(p)) ||
|
||||
(ret.proxy == null && p == Proxy.NO_PROXY)) {
|
||||
synchronized (ret) {
|
||||
ret.cachedHttpClient = true;
|
||||
assert ret.inCache;
|
||||
ret.inCache = false;
|
||||
if (httpuc != null && ret.needsTunneling())
|
||||
httpuc.setTunnelState(TUNNELING);
|
||||
if (logger.isLoggable(PlatformLogger.Level.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) {
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
logger.finest("Not returning this connection to cache: " + ret);
|
||||
}
|
||||
ret.inCache = false;
|
||||
ret.closeServer();
|
||||
}
|
||||
ret = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == null) {
|
||||
ret = new HttpsClient(sf, url, p, connectTimeout);
|
||||
} else {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
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.setHostnameVerifier(hv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
void setHostnameVerifier(HostnameVerifier hv) {
|
||||
this.hv = hv;
|
||||
}
|
||||
|
||||
void setSSLSocketFactory(SSLSocketFactory sf) {
|
||||
sslSocketFactory = sf;
|
||||
}
|
||||
|
||||
SSLSocketFactory getSSLSocketFactory() {
|
||||
return sslSocketFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following method, createSocket, is defined in NetworkClient
|
||||
* and overridden here so that the socket facroty is used to create
|
||||
* new sockets.
|
||||
*/
|
||||
@Override
|
||||
protected Socket createSocket() throws IOException {
|
||||
try {
|
||||
return sslSocketFactory.createSocket();
|
||||
} catch (SocketException se) {
|
||||
//
|
||||
// bug 6771432
|
||||
// javax.net.SocketFactory throws a SocketException with an
|
||||
// UnsupportedOperationException as its cause to indicate that
|
||||
// unconnected sockets have not been implemented.
|
||||
//
|
||||
Throwable t = se.getCause();
|
||||
if (t != null && t instanceof UnsupportedOperationException) {
|
||||
return super.createSocket();
|
||||
} else {
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeServer() {
|
||||
try {
|
||||
// SSLSocket.close may block up to timeout. Make sure it's short.
|
||||
serverSocket.setSoTimeout(1);
|
||||
} catch (Exception e) {}
|
||||
super.closeServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsTunneling() {
|
||||
return (proxy != null && proxy.type() != Proxy.Type.DIRECT
|
||||
&& proxy.type() != Proxy.Type.SOCKS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnect() throws IOException, UnknownHostException {
|
||||
if (!isCachedConnection()) {
|
||||
SSLSocket s = null;
|
||||
SSLSocketFactory factory = sslSocketFactory;
|
||||
try {
|
||||
if (!(serverSocket instanceof SSLSocket)) {
|
||||
s = (SSLSocket)factory.createSocket(serverSocket,
|
||||
host, port, true);
|
||||
} else {
|
||||
s = (SSLSocket)serverSocket;
|
||||
if (s instanceof SSLSocketImpl) {
|
||||
((SSLSocketImpl)s).setHost(host);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// If we fail to connect through the tunnel, try it
|
||||
// locally, as a last resort. If this doesn't work,
|
||||
// throw the original exception.
|
||||
try {
|
||||
s = (SSLSocket)factory.createSocket(host, port);
|
||||
} catch (IOException ignored) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Force handshaking, so that we get any authentication.
|
||||
// Register a handshake callback so our session state tracks any
|
||||
// later session renegotiations.
|
||||
//
|
||||
String [] protocols = getProtocols();
|
||||
String [] ciphers = getCipherSuites();
|
||||
if (protocols != null) {
|
||||
s.setEnabledProtocols(protocols);
|
||||
}
|
||||
if (ciphers != null) {
|
||||
s.setEnabledCipherSuites(ciphers);
|
||||
}
|
||||
s.addHandshakeCompletedListener(this);
|
||||
|
||||
// We have two hostname verification approaches. One is in
|
||||
// SSL/TLS socket layer, where the algorithm is configured with
|
||||
// SSLParameters.setEndpointIdentificationAlgorithm(), and the
|
||||
// hostname verification is done by X509ExtendedTrustManager when
|
||||
// the algorithm is "HTTPS". The other one is in HTTPS layer,
|
||||
// where the algorithm is customized by
|
||||
// HttpsURLConnection.setHostnameVerifier(), and the hostname
|
||||
// verification is done by HostnameVerifier when the default
|
||||
// rules for hostname verification fail.
|
||||
//
|
||||
// The relationship between two hostname verification approaches
|
||||
// likes the following:
|
||||
//
|
||||
// | EIA algorithm
|
||||
// +----------------------------------------------
|
||||
// | null | HTTPS | LDAP/other |
|
||||
// -------------------------------------------------------------
|
||||
// | |1 |2 |3 |
|
||||
// HNV | default | Set HTTPS EIA | use EIA | HTTPS |
|
||||
// |--------------------------------------------------------
|
||||
// | non - |4 |5 |6 |
|
||||
// | default | HTTPS/HNV | use EIA | HTTPS/HNV |
|
||||
// -------------------------------------------------------------
|
||||
//
|
||||
// Abbreviation:
|
||||
// EIA: the endpoint identification algorithm in SSL/TLS
|
||||
// socket layer
|
||||
// HNV: the hostname verification object in HTTPS layer
|
||||
// Notes:
|
||||
// case 1. default HNV and EIA is null
|
||||
// Set EIA as HTTPS, hostname check done in SSL/TLS
|
||||
// layer.
|
||||
// case 2. default HNV and EIA is HTTPS
|
||||
// Use existing EIA, hostname check done in SSL/TLS
|
||||
// layer.
|
||||
// case 3. default HNV and EIA is other than HTTPS
|
||||
// Use existing EIA, EIA check done in SSL/TLS
|
||||
// layer, then do HTTPS check in HTTPS layer.
|
||||
// case 4. non-default HNV and EIA is null
|
||||
// No EIA, no EIA check done in SSL/TLS layer, then do
|
||||
// HTTPS check in HTTPS layer using HNV as override.
|
||||
// case 5. non-default HNV and EIA is HTTPS
|
||||
// Use existing EIA, hostname check done in SSL/TLS
|
||||
// layer. No HNV override possible. We will review this
|
||||
// decision and may update the architecture for JDK 7.
|
||||
// case 6. non-default HNV and EIA is other than HTTPS
|
||||
// Use existing EIA, EIA check done in SSL/TLS layer,
|
||||
// then do HTTPS check in HTTPS layer as override.
|
||||
boolean needToCheckSpoofing = true;
|
||||
String identification =
|
||||
s.getSSLParameters().getEndpointIdentificationAlgorithm();
|
||||
if (identification != null && identification.length() != 0) {
|
||||
if (identification.equalsIgnoreCase("HTTPS")) {
|
||||
// Do not check server identity again out of SSLSocket,
|
||||
// the endpoint will be identified during TLS handshaking
|
||||
// in SSLSocket.
|
||||
needToCheckSpoofing = false;
|
||||
} // else, we don't understand the identification algorithm,
|
||||
// need to check URL spoofing here.
|
||||
} else {
|
||||
boolean isDefaultHostnameVerifier = false;
|
||||
|
||||
// We prefer to let the SSLSocket do the spoof checks, but if
|
||||
// the application has specified a HostnameVerifier (HNV),
|
||||
// we will always use that.
|
||||
if (hv != null) {
|
||||
String canonicalName = hv.getClass().getCanonicalName();
|
||||
if (canonicalName != null &&
|
||||
canonicalName.equalsIgnoreCase(defaultHVCanonicalName)) {
|
||||
isDefaultHostnameVerifier = true;
|
||||
}
|
||||
} else {
|
||||
// Unlikely to happen! As the behavior is the same as the
|
||||
// default hostname verifier, so we prefer to let the
|
||||
// SSLSocket do the spoof checks.
|
||||
isDefaultHostnameVerifier = true;
|
||||
}
|
||||
|
||||
if (isDefaultHostnameVerifier) {
|
||||
// If the HNV is the default from HttpsURLConnection, we
|
||||
// will do the spoof checks in SSLSocket.
|
||||
SSLParameters paramaters = s.getSSLParameters();
|
||||
paramaters.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
s.setSSLParameters(paramaters);
|
||||
|
||||
needToCheckSpoofing = false;
|
||||
}
|
||||
}
|
||||
|
||||
s.startHandshake();
|
||||
session = s.getSession();
|
||||
// change the serverSocket and serverOutput
|
||||
serverSocket = s;
|
||||
try {
|
||||
serverOutput = new PrintStream(
|
||||
new BufferedOutputStream(serverSocket.getOutputStream()),
|
||||
false, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new InternalError(encoding+" encoding not found");
|
||||
}
|
||||
|
||||
// check URL spoofing if it has not been checked under handshaking
|
||||
if (needToCheckSpoofing) {
|
||||
checkURLSpoofing(hv);
|
||||
}
|
||||
} else {
|
||||
// if we are reusing a cached https session,
|
||||
// we don't need to do handshaking etc. But we do need to
|
||||
// set the ssl session
|
||||
session = ((SSLSocket)serverSocket).getSession();
|
||||
}
|
||||
}
|
||||
|
||||
// Server identity checking is done according to RFC 2818: HTTP over TLS
|
||||
// Section 3.1 Server Identity
|
||||
private void checkURLSpoofing(HostnameVerifier hostnameVerifier)
|
||||
throws IOException {
|
||||
//
|
||||
// Get authenticated server name, if any
|
||||
//
|
||||
String host = url.getHost();
|
||||
|
||||
// if IPv6 strip off the "[]"
|
||||
if (host != null && host.startsWith("[") && host.endsWith("]")) {
|
||||
host = host.substring(1, host.length()-1);
|
||||
}
|
||||
|
||||
Certificate[] peerCerts = null;
|
||||
String cipher = session.getCipherSuite();
|
||||
try {
|
||||
HostnameChecker checker = HostnameChecker.getInstance(
|
||||
HostnameChecker.TYPE_TLS);
|
||||
|
||||
// Use ciphersuite to determine whether Kerberos is present.
|
||||
if (cipher.startsWith("TLS_KRB5")) {
|
||||
if (!HostnameChecker.match(host, getPeerPrincipal())) {
|
||||
throw new SSLPeerUnverifiedException("Hostname checker" +
|
||||
" failed for Kerberos");
|
||||
}
|
||||
} else { // X.509
|
||||
|
||||
// get the subject's certificate
|
||||
peerCerts = session.getPeerCertificates();
|
||||
|
||||
X509Certificate peerCert;
|
||||
if (peerCerts[0] instanceof
|
||||
java.security.cert.X509Certificate) {
|
||||
peerCert = (java.security.cert.X509Certificate)peerCerts[0];
|
||||
} else {
|
||||
throw new SSLPeerUnverifiedException("");
|
||||
}
|
||||
checker.match(host, peerCert);
|
||||
}
|
||||
|
||||
// if it doesn't throw an exception, we passed. Return.
|
||||
return;
|
||||
|
||||
} catch (SSLPeerUnverifiedException e) {
|
||||
|
||||
//
|
||||
// client explicitly changed default policy and enabled
|
||||
// anonymous ciphers; we can't check the standard policy
|
||||
//
|
||||
// ignore
|
||||
} catch (java.security.cert.CertificateException cpe) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) {
|
||||
return;
|
||||
} else if ((hostnameVerifier != null) &&
|
||||
(hostnameVerifier.verify(host, session))) {
|
||||
return;
|
||||
}
|
||||
|
||||
serverSocket.close();
|
||||
session.invalidate();
|
||||
|
||||
throw new IOException("HTTPS hostname wrong: should be <"
|
||||
+ url.getHost() + ">");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putInKeepAliveCache() {
|
||||
if (inCache) {
|
||||
assert false : "Duplicate put to keep alive cache";
|
||||
return;
|
||||
}
|
||||
inCache = true;
|
||||
kac.put(url, sslSocketFactory, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close an idle connection to this URL (if it exists in the cache).
|
||||
*/
|
||||
@Override
|
||||
public void closeIdleConnection() {
|
||||
HttpClient http = kac.get(url, sslSocketFactory);
|
||||
if (http != null) {
|
||||
http.closeServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cipher suite in use on this connection.
|
||||
*/
|
||||
String getCipherSuite() {
|
||||
return session.getCipherSuite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the certificate chain the client sent to the
|
||||
* server, or null if the client did not authenticate.
|
||||
*/
|
||||
public java.security.cert.Certificate [] getLocalCertificates() {
|
||||
return session.getLocalCertificates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the certificate chain with which the server
|
||||
* authenticated itself, or throw a SSLPeerUnverifiedException
|
||||
* if the server did not authenticate.
|
||||
*/
|
||||
java.security.cert.Certificate [] getServerCertificates()
|
||||
throws SSLPeerUnverifiedException
|
||||
{
|
||||
return session.getPeerCertificates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the X.509 certificate chain with which the server
|
||||
* authenticated itself, or null if the server did not authenticate.
|
||||
*/
|
||||
javax.security.cert.X509Certificate [] getServerCertificateChain()
|
||||
throws SSLPeerUnverifiedException
|
||||
{
|
||||
return session.getPeerCertificateChain();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal with which the server authenticated
|
||||
* itself, or throw a SSLPeerUnverifiedException if the
|
||||
* server did not authenticate.
|
||||
*/
|
||||
Principal getPeerPrincipal()
|
||||
throws SSLPeerUnverifiedException
|
||||
{
|
||||
Principal principal;
|
||||
try {
|
||||
principal = session.getPeerPrincipal();
|
||||
} catch (AbstractMethodError e) {
|
||||
// if the provider does not support it, fallback to peer certs.
|
||||
// return the X500Principal of the end-entity cert.
|
||||
java.security.cert.Certificate[] certs =
|
||||
session.getPeerCertificates();
|
||||
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
|
||||
}
|
||||
return principal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal the client sent to the
|
||||
* server, or null if the client did not authenticate.
|
||||
*/
|
||||
Principal getLocalPrincipal()
|
||||
{
|
||||
Principal principal;
|
||||
try {
|
||||
principal = session.getLocalPrincipal();
|
||||
} catch (AbstractMethodError e) {
|
||||
principal = null;
|
||||
// if the provider does not support it, fallback to local certs.
|
||||
// return the X500Principal of the end-entity cert.
|
||||
java.security.cert.Certificate[] certs =
|
||||
session.getLocalCertificates();
|
||||
if (certs != null) {
|
||||
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
|
||||
}
|
||||
}
|
||||
return principal;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method implements the SSL HandshakeCompleted callback,
|
||||
* remembering the resulting session so that it may be queried
|
||||
* for the current cipher suite and peer certificates. Servers
|
||||
* sometimes re-initiate handshaking, so the session in use on
|
||||
* a given connection may change. When sessions change, so may
|
||||
* peer identities and cipher suites.
|
||||
*/
|
||||
public void handshakeCompleted(HandshakeCompletedEvent event)
|
||||
{
|
||||
session = event.getSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the proxy host being used for this client, or null
|
||||
* if we're not going through a proxy
|
||||
*/
|
||||
@Override
|
||||
public String getProxyHostUsed() {
|
||||
if (!needsTunneling()) {
|
||||
return null;
|
||||
} else {
|
||||
return super.getProxyHostUsed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the proxy port being used for this client. Meaningless
|
||||
* if getProxyHostUsed() gives null.
|
||||
*/
|
||||
@Override
|
||||
public int getProxyPortUsed() {
|
||||
return (proxy == null || proxy.type() == Proxy.Type.DIRECT ||
|
||||
proxy.type() == Proxy.Type.SOCKS)? -1:
|
||||
((InetSocketAddress)proxy.address()).getPort();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This class lives in the package sun.net.www.protocol.https.
|
||||
* There is a copy in com.sun.net.ssl.internal.www.protocol.https for JSSE
|
||||
* 1.0.2 compatibility. It is 100% identical except the package and extends
|
||||
* lines. Any changes should be made to be class in sun.net.* and then copied
|
||||
* to com.sun.net.*.
|
||||
*/
|
||||
|
||||
// For both copies of the file, uncomment one line and comment the other
|
||||
package sun.net.www.protocol.https;
|
||||
// package com.sun.net.ssl.internal.www.protocol.https;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.io.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.security.Permission;
|
||||
import java.security.Principal;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.net.www.http.HttpClient;
|
||||
|
||||
/**
|
||||
* A class to represent an HTTP connection to a remote object.
|
||||
*
|
||||
* Ideally, this class should subclass and inherit the http handler
|
||||
* implementation, but it can't do so because that class have the
|
||||
* wrong Java Type. Thus it uses the delegate (aka, the
|
||||
* Adapter/Wrapper design pattern) to reuse code from the http
|
||||
* handler.
|
||||
*
|
||||
* Since it would use a delegate to access
|
||||
* sun.net.www.protocol.http.HttpURLConnection functionalities, it
|
||||
* needs to implement all public methods in it's super class and all
|
||||
* the way to Object.
|
||||
*
|
||||
*/
|
||||
|
||||
// For both copies of the file, uncomment one line and comment the
|
||||
// other. The differences between the two copies are introduced for
|
||||
// plugin, and it is marked as such.
|
||||
public class HttpsURLConnectionImpl
|
||||
extends javax.net.ssl.HttpsURLConnection {
|
||||
// public class HttpsURLConnectionOldImpl
|
||||
// extends com.sun.net.ssl.HttpsURLConnection {
|
||||
|
||||
// NOTE: made protected for plugin so that subclass can set it.
|
||||
protected DelegateHttpsURLConnection delegate;
|
||||
|
||||
// For both copies of the file, uncomment one line and comment the other
|
||||
HttpsURLConnectionImpl(URL u, Handler handler) throws IOException {
|
||||
// HttpsURLConnectionOldImpl(URL u, Handler handler) throws IOException {
|
||||
this(u, null, handler);
|
||||
}
|
||||
|
||||
static URL checkURL(URL u) throws IOException {
|
||||
if (u != null) {
|
||||
if (u.toExternalForm().indexOf('\n') > -1) {
|
||||
throw new MalformedURLException("Illegal character in URL");
|
||||
}
|
||||
}
|
||||
String s = IPAddressUtil.checkAuthority(u);
|
||||
if (s != null) {
|
||||
throw new MalformedURLException(s);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
// For both copies of the file, uncomment one line and comment the other
|
||||
HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException {
|
||||
// HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
|
||||
super(checkURL(u));
|
||||
delegate = new DelegateHttpsURLConnection(url, p, handler, this);
|
||||
}
|
||||
|
||||
// NOTE: introduced for plugin
|
||||
// subclass needs to overwrite this to set delegate to
|
||||
// the appropriate delegatee
|
||||
protected HttpsURLConnectionImpl(URL u) throws IOException {
|
||||
super(u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new HttpClient object, bypassing the cache of
|
||||
* HTTP client objects/connections.
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
*/
|
||||
protected void setNewClient(URL url) throws IOException {
|
||||
delegate.setNewClient(url, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a HttpClient object. Use the cached copy if specified.
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
* @param useCache whether the cached connection should be used
|
||||
* if present
|
||||
*/
|
||||
protected void setNewClient(URL url, boolean useCache)
|
||||
throws IOException {
|
||||
delegate.setNewClient(url, useCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new HttpClient object, set up so that it uses
|
||||
* per-instance proxying to the given HTTP proxy. This
|
||||
* bypasses the cache of HTTP client objects/connections.
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
* @param proxyHost the proxy host to use
|
||||
* @param proxyPort the proxy port to use
|
||||
*/
|
||||
protected void setProxiedClient(URL url, String proxyHost, int proxyPort)
|
||||
throws IOException {
|
||||
delegate.setProxiedClient(url, proxyHost, proxyPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a HttpClient object, set up so that it uses per-instance
|
||||
* proxying to the given HTTP proxy. Use the cached copy of HTTP
|
||||
* client objects/connections if specified.
|
||||
*
|
||||
* @param url the URL being accessed
|
||||
* @param proxyHost the proxy host to use
|
||||
* @param proxyPort the proxy port to use
|
||||
* @param useCache whether the cached connection should be used
|
||||
* if present
|
||||
*/
|
||||
protected void setProxiedClient(URL url, String proxyHost, int proxyPort,
|
||||
boolean useCache) throws IOException {
|
||||
delegate.setProxiedClient(url, proxyHost, proxyPort, useCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the HTTP protocol handler's "connect" method,
|
||||
* establishing an SSL connection to the server as necessary.
|
||||
*/
|
||||
public void connect() throws IOException {
|
||||
delegate.connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by subclass to access "connected" variable. Since we are
|
||||
* delegating the actual implementation to "delegate", we need to
|
||||
* delegate the access of "connected" as well.
|
||||
*/
|
||||
protected boolean isConnected() {
|
||||
return delegate.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by subclass to access "connected" variable. Since we are
|
||||
* delegating the actual implementation to "delegate", we need to
|
||||
* delegate the access of "connected" as well.
|
||||
*/
|
||||
protected void setConnected(boolean conn) {
|
||||
delegate.setConnected(conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cipher suite in use on this connection.
|
||||
*/
|
||||
public String getCipherSuite() {
|
||||
return delegate.getCipherSuite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the certificate chain the client sent to the
|
||||
* server, or null if the client did not authenticate.
|
||||
*/
|
||||
public java.security.cert.Certificate []
|
||||
getLocalCertificates() {
|
||||
return delegate.getLocalCertificates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's certificate chain, or throws
|
||||
* SSLPeerUnverified Exception if
|
||||
* the server did not authenticate.
|
||||
*/
|
||||
public java.security.cert.Certificate []
|
||||
getServerCertificates() throws SSLPeerUnverifiedException {
|
||||
return delegate.getServerCertificates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's X.509 certificate chain, or null if
|
||||
* the server did not authenticate.
|
||||
*
|
||||
* NOTE: This method is not necessary for the version of this class
|
||||
* implementing javax.net.ssl.HttpsURLConnection, but provided for
|
||||
* compatibility with the com.sun.net.ssl.HttpsURLConnection version.
|
||||
*/
|
||||
public javax.security.cert.X509Certificate[] getServerCertificateChain() {
|
||||
try {
|
||||
return delegate.getServerCertificateChain();
|
||||
} catch (SSLPeerUnverifiedException e) {
|
||||
// this method does not throw an exception as declared in
|
||||
// com.sun.net.ssl.HttpsURLConnection.
|
||||
// Return null for compatibility.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal with which the server authenticated itself,
|
||||
* or throw a SSLPeerUnverifiedException if the server did not authenticate.
|
||||
*/
|
||||
public Principal getPeerPrincipal()
|
||||
throws SSLPeerUnverifiedException
|
||||
{
|
||||
return delegate.getPeerPrincipal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal the client sent to the
|
||||
* server, or null if the client did not authenticate.
|
||||
*/
|
||||
public Principal getLocalPrincipal()
|
||||
{
|
||||
return delegate.getLocalPrincipal();
|
||||
}
|
||||
|
||||
/*
|
||||
* Allowable input/output sequences:
|
||||
* [interpreted as POST/PUT]
|
||||
* - get output, [write output,] get input, [read input]
|
||||
* - get output, [write output]
|
||||
* [interpreted as GET]
|
||||
* - get input, [read input]
|
||||
* Disallowed:
|
||||
* - get input, [read input,] get output, [write output]
|
||||
*/
|
||||
|
||||
public synchronized OutputStream getOutputStream() throws IOException {
|
||||
return delegate.getOutputStream();
|
||||
}
|
||||
|
||||
public synchronized InputStream getInputStream() throws IOException {
|
||||
return delegate.getInputStream();
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return delegate.getErrorStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the server.
|
||||
*/
|
||||
public void disconnect() {
|
||||
delegate.disconnect();
|
||||
}
|
||||
|
||||
public boolean usingProxy() {
|
||||
return delegate.usingProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable Map of the header fields.
|
||||
* The Map keys are Strings that represent the
|
||||
* response-header field names. Each Map value is an
|
||||
* unmodifiable List of Strings that represents
|
||||
* the corresponding field values.
|
||||
*
|
||||
* @return a Map of header fields
|
||||
* @since 1.4
|
||||
*/
|
||||
public Map<String,List<String>> getHeaderFields() {
|
||||
return delegate.getHeaderFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a header field by name. Returns null if not known.
|
||||
* @param name the name of the header field
|
||||
*/
|
||||
public String getHeaderField(String name) {
|
||||
return delegate.getHeaderField(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a header field by index. Returns null if not known.
|
||||
* @param n the index of the header field
|
||||
*/
|
||||
public String getHeaderField(int n) {
|
||||
return delegate.getHeaderField(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a header field by index. Returns null if not known.
|
||||
* @param n the index of the header field
|
||||
*/
|
||||
public String getHeaderFieldKey(int n) {
|
||||
return delegate.getHeaderFieldKey(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets request property. If a property with the key already
|
||||
* exists, overwrite its value with the new value.
|
||||
* @param value the value to be set
|
||||
*/
|
||||
public void setRequestProperty(String key, String value) {
|
||||
delegate.setRequestProperty(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a general request property specified by a
|
||||
* key-value pair. This method will not overwrite
|
||||
* existing values associated with the same key.
|
||||
*
|
||||
* @param key the keyword by which the request is known
|
||||
* (e.g., "<code>accept</code>").
|
||||
* @param value the value associated with it.
|
||||
* @see #getRequestProperty(java.lang.String)
|
||||
* @since 1.4
|
||||
*/
|
||||
public void addRequestProperty(String key, String value) {
|
||||
delegate.addRequestProperty(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite super class method
|
||||
*/
|
||||
public int getResponseCode() throws IOException {
|
||||
return delegate.getResponseCode();
|
||||
}
|
||||
|
||||
public String getRequestProperty(String key) {
|
||||
return delegate.getRequestProperty(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable Map of general request
|
||||
* properties for this connection. The Map keys
|
||||
* are Strings that represent the request-header
|
||||
* field names. Each Map value is a unmodifiable List
|
||||
* of Strings that represents the corresponding
|
||||
* field values.
|
||||
*
|
||||
* @return a Map of the general request properties for this connection.
|
||||
* @throws IllegalStateException if already connected
|
||||
* @since 1.4
|
||||
*/
|
||||
public Map<String,List<String>> getRequestProperties() {
|
||||
return delegate.getRequestProperties();
|
||||
}
|
||||
|
||||
/*
|
||||
* We support JDK 1.2.x so we can't count on these from JDK 1.3.
|
||||
* We override and supply our own version.
|
||||
*/
|
||||
public void setInstanceFollowRedirects(boolean shouldFollow) {
|
||||
delegate.setInstanceFollowRedirects(shouldFollow);
|
||||
}
|
||||
|
||||
public boolean getInstanceFollowRedirects() {
|
||||
return delegate.getInstanceFollowRedirects();
|
||||
}
|
||||
|
||||
public void setRequestMethod(String method) throws ProtocolException {
|
||||
delegate.setRequestMethod(method);
|
||||
}
|
||||
|
||||
public String getRequestMethod() {
|
||||
return delegate.getRequestMethod();
|
||||
}
|
||||
|
||||
public String getResponseMessage() throws IOException {
|
||||
return delegate.getResponseMessage();
|
||||
}
|
||||
|
||||
public long getHeaderFieldDate(String name, long Default) {
|
||||
return delegate.getHeaderFieldDate(name, Default);
|
||||
}
|
||||
|
||||
public Permission getPermission() throws IOException {
|
||||
return delegate.getPermission();
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return delegate.getURL();
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return delegate.getContentLength();
|
||||
}
|
||||
|
||||
public long getContentLengthLong() {
|
||||
return delegate.getContentLengthLong();
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return delegate.getContentType();
|
||||
}
|
||||
|
||||
public String getContentEncoding() {
|
||||
return delegate.getContentEncoding();
|
||||
}
|
||||
|
||||
public long getExpiration() {
|
||||
return delegate.getExpiration();
|
||||
}
|
||||
|
||||
public long getDate() {
|
||||
return delegate.getDate();
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return delegate.getLastModified();
|
||||
}
|
||||
|
||||
public int getHeaderFieldInt(String name, int Default) {
|
||||
return delegate.getHeaderFieldInt(name, Default);
|
||||
}
|
||||
|
||||
public long getHeaderFieldLong(String name, long Default) {
|
||||
return delegate.getHeaderFieldLong(name, Default);
|
||||
}
|
||||
|
||||
public Object getContent() throws IOException {
|
||||
return delegate.getContent();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getContent(Class[] classes) throws IOException {
|
||||
return delegate.getContent(classes);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public void setDoInput(boolean doinput) {
|
||||
delegate.setDoInput(doinput);
|
||||
}
|
||||
|
||||
public boolean getDoInput() {
|
||||
return delegate.getDoInput();
|
||||
}
|
||||
|
||||
public void setDoOutput(boolean dooutput) {
|
||||
delegate.setDoOutput(dooutput);
|
||||
}
|
||||
|
||||
public boolean getDoOutput() {
|
||||
return delegate.getDoOutput();
|
||||
}
|
||||
|
||||
public void setAllowUserInteraction(boolean allowuserinteraction) {
|
||||
delegate.setAllowUserInteraction(allowuserinteraction);
|
||||
}
|
||||
|
||||
public boolean getAllowUserInteraction() {
|
||||
return delegate.getAllowUserInteraction();
|
||||
}
|
||||
|
||||
public void setUseCaches(boolean usecaches) {
|
||||
delegate.setUseCaches(usecaches);
|
||||
}
|
||||
|
||||
public boolean getUseCaches() {
|
||||
return delegate.getUseCaches();
|
||||
}
|
||||
|
||||
public void setIfModifiedSince(long ifmodifiedsince) {
|
||||
delegate.setIfModifiedSince(ifmodifiedsince);
|
||||
}
|
||||
|
||||
public long getIfModifiedSince() {
|
||||
return delegate.getIfModifiedSince();
|
||||
}
|
||||
|
||||
public boolean getDefaultUseCaches() {
|
||||
return delegate.getDefaultUseCaches();
|
||||
}
|
||||
|
||||
public void setDefaultUseCaches(boolean defaultusecaches) {
|
||||
delegate.setDefaultUseCaches(defaultusecaches);
|
||||
}
|
||||
|
||||
/*
|
||||
* finalize (dispose) the delegated object. Otherwise
|
||||
* sun.net.www.protocol.http.HttpURLConnection's finalize()
|
||||
* would have to be made public.
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
delegate.dispose();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int timeout) {
|
||||
delegate.setConnectTimeout(timeout);
|
||||
}
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return delegate.getConnectTimeout();
|
||||
}
|
||||
|
||||
public void setReadTimeout(int timeout) {
|
||||
delegate.setReadTimeout(timeout);
|
||||
}
|
||||
|
||||
public int getReadTimeout() {
|
||||
return delegate.getReadTimeout();
|
||||
}
|
||||
|
||||
public void setFixedLengthStreamingMode (int contentLength) {
|
||||
delegate.setFixedLengthStreamingMode(contentLength);
|
||||
}
|
||||
|
||||
public void setFixedLengthStreamingMode(long contentLength) {
|
||||
delegate.setFixedLengthStreamingMode(contentLength);
|
||||
}
|
||||
|
||||
public void setChunkedStreamingMode (int chunklen) {
|
||||
delegate.setChunkedStreamingMode(chunklen);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user