| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.harmony.luni.internal.net.www.protocol.https; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.ProtocolException; |
| import java.net.Proxy; |
| import java.net.URL; |
| import java.security.Permission; |
| import java.security.Principal; |
| import java.security.cert.Certificate; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.net.ssl.SSLPeerUnverifiedException; |
| import javax.net.ssl.SSLSocket; |
| |
| import org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection; |
| import org.apache.harmony.luni.internal.nls.Messages; |
| |
| /** |
| * HttpsURLConnection implementation. |
| */ |
| public class HttpsURLConnection extends javax.net.ssl.HttpsURLConnection { |
| |
| // Https engine to be wrapped |
| private final HttpsEngine httpsEngine; |
| |
| // SSLSocket to be used for connection |
| private SSLSocket sslSocket; |
| |
| protected HttpsURLConnection(URL url, int port) { |
| super(url); |
| httpsEngine = new HttpsEngine(url, port); |
| } |
| |
| protected HttpsURLConnection(URL url, int port, Proxy proxy) { |
| super(url); |
| httpsEngine = new HttpsEngine(url, port, proxy); |
| } |
| |
| @Override |
| public String getCipherSuite() { |
| if (sslSocket == null) { |
| throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$ |
| } |
| return sslSocket.getSession().getCipherSuite(); |
| } |
| |
| @Override |
| public Certificate[] getLocalCertificates() { |
| if (sslSocket == null) { |
| throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$ |
| } |
| return sslSocket.getSession().getLocalCertificates(); |
| } |
| |
| @Override |
| public Certificate[] getServerCertificates() |
| throws SSLPeerUnverifiedException { |
| if (sslSocket == null) { |
| throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$ |
| } |
| return sslSocket.getSession().getPeerCertificates(); |
| } |
| |
| @Override |
| public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { |
| if (sslSocket == null) { |
| throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$ |
| } |
| return sslSocket.getSession().getPeerPrincipal(); |
| } |
| |
| @Override |
| public Principal getLocalPrincipal() { |
| if (sslSocket == null) { |
| throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$ |
| } |
| return sslSocket.getSession().getLocalPrincipal(); |
| } |
| |
| @Override |
| public void disconnect() { |
| httpsEngine.disconnect(); |
| } |
| |
| @Override |
| public InputStream getErrorStream() { |
| return httpsEngine.getErrorStream(); |
| } |
| |
| @Override |
| public String getRequestMethod() { |
| return httpsEngine.getRequestMethod(); |
| } |
| |
| @Override |
| public int getResponseCode() throws IOException { |
| return httpsEngine.getResponseCode(); |
| } |
| |
| @Override |
| public String getResponseMessage() throws IOException { |
| return httpsEngine.getResponseMessage(); |
| } |
| |
| @Override |
| public void setRequestMethod(String method) throws ProtocolException { |
| httpsEngine.setRequestMethod(method); |
| } |
| |
| @Override |
| public boolean usingProxy() { |
| return httpsEngine.usingProxy(); |
| } |
| |
| @Override |
| public boolean getInstanceFollowRedirects() { |
| return httpsEngine.getInstanceFollowRedirects(); |
| } |
| |
| @Override |
| public void setInstanceFollowRedirects(boolean followRedirects) { |
| httpsEngine.setInstanceFollowRedirects(followRedirects); |
| } |
| |
| @Override |
| public void connect() throws IOException { |
| httpsEngine.connect(); |
| } |
| |
| @Override |
| public boolean getAllowUserInteraction() { |
| return httpsEngine.getAllowUserInteraction(); |
| } |
| |
| @Override |
| public Object getContent() throws IOException { |
| return httpsEngine.getContent(); |
| } |
| |
| @SuppressWarnings("unchecked") // Spec does not generify |
| @Override |
| public Object getContent(Class[] types) throws IOException { |
| return httpsEngine.getContent(types); |
| } |
| |
| @Override |
| public String getContentEncoding() { |
| return httpsEngine.getContentEncoding(); |
| } |
| |
| @Override |
| public int getContentLength() { |
| return httpsEngine.getContentLength(); |
| } |
| |
| @Override |
| public String getContentType() { |
| return httpsEngine.getContentType(); |
| } |
| |
| @Override |
| public long getDate() { |
| return httpsEngine.getDate(); |
| } |
| |
| @Override |
| public boolean getDefaultUseCaches() { |
| return httpsEngine.getDefaultUseCaches(); |
| } |
| |
| @Override |
| public boolean getDoInput() { |
| return httpsEngine.getDoInput(); |
| } |
| |
| @Override |
| public boolean getDoOutput() { |
| return httpsEngine.getDoOutput(); |
| } |
| |
| @Override |
| public long getExpiration() { |
| return httpsEngine.getExpiration(); |
| } |
| |
| @Override |
| public String getHeaderField(int pos) { |
| return httpsEngine.getHeaderField(pos); |
| } |
| |
| @Override |
| public Map<String, List<String>> getHeaderFields() { |
| return httpsEngine.getHeaderFields(); |
| } |
| |
| @Override |
| public Map<String, List<String>> getRequestProperties() { |
| return httpsEngine.getRequestProperties(); |
| } |
| |
| @Override |
| public void addRequestProperty(String field, String newValue) { |
| httpsEngine.addRequestProperty(field, newValue); |
| } |
| |
| @Override |
| public String getHeaderField(String key) { |
| return httpsEngine.getHeaderField(key); |
| } |
| |
| @Override |
| public long getHeaderFieldDate(String field, long defaultValue) { |
| return httpsEngine.getHeaderFieldDate(field, defaultValue); |
| } |
| |
| @Override |
| public int getHeaderFieldInt(String field, int defaultValue) { |
| return httpsEngine.getHeaderFieldInt(field, defaultValue); |
| } |
| |
| @Override |
| public String getHeaderFieldKey(int posn) { |
| return httpsEngine.getHeaderFieldKey(posn); |
| } |
| |
| @Override |
| public long getIfModifiedSince() { |
| return httpsEngine.getIfModifiedSince(); |
| } |
| |
| @Override |
| public InputStream getInputStream() throws IOException { |
| return httpsEngine.getInputStream(); |
| } |
| |
| @Override |
| public long getLastModified() { |
| return httpsEngine.getLastModified(); |
| } |
| |
| @Override |
| public OutputStream getOutputStream() throws IOException { |
| return httpsEngine.getOutputStream(); |
| } |
| |
| @Override |
| public Permission getPermission() throws IOException { |
| return httpsEngine.getPermission(); |
| } |
| |
| @Override |
| public String getRequestProperty(String field) { |
| return httpsEngine.getRequestProperty(field); |
| } |
| |
| @Override |
| public URL getURL() { |
| return httpsEngine.getURL(); |
| } |
| |
| @Override |
| public boolean getUseCaches() { |
| return httpsEngine.getUseCaches(); |
| } |
| |
| @Override |
| public void setAllowUserInteraction(boolean newValue) { |
| httpsEngine.setAllowUserInteraction(newValue); |
| } |
| |
| @Override |
| public void setDefaultUseCaches(boolean newValue) { |
| httpsEngine.setDefaultUseCaches(newValue); |
| } |
| |
| @Override |
| public void setDoInput(boolean newValue) { |
| httpsEngine.setDoInput(newValue); |
| } |
| |
| @Override |
| public void setDoOutput(boolean newValue) { |
| httpsEngine.setDoOutput(newValue); |
| } |
| |
| @Override |
| public void setIfModifiedSince(long newValue) { |
| httpsEngine.setIfModifiedSince(newValue); |
| } |
| |
| @Override |
| public void setRequestProperty(String field, String newValue) { |
| httpsEngine.setRequestProperty(field, newValue); |
| } |
| |
| @Override |
| public void setUseCaches(boolean newValue) { |
| httpsEngine.setUseCaches(newValue); |
| } |
| |
| @Override |
| public void setConnectTimeout(int timeout) { |
| httpsEngine.setConnectTimeout(timeout); |
| } |
| |
| @Override |
| public int getConnectTimeout() { |
| return httpsEngine.getConnectTimeout(); |
| } |
| |
| @Override |
| public void setReadTimeout(int timeout) { |
| httpsEngine.setReadTimeout(timeout); |
| } |
| |
| @Override |
| public int getReadTimeout() { |
| return httpsEngine.getReadTimeout(); |
| } |
| |
| @Override |
| public String toString() { |
| return httpsEngine.toString(); |
| } |
| |
| /** |
| * HttpsEngine |
| */ |
| private class HttpsEngine extends HttpURLConnection { |
| |
| // In case of using proxy this field indicates |
| // if it is a SSL Tunnel establishing stage |
| private boolean makingSSLTunnel; |
| |
| protected HttpsEngine(URL url, int port) { |
| super(url, port); |
| } |
| |
| protected HttpsEngine(URL url, int port, Proxy proxy) { |
| super(url, port, proxy); |
| } |
| |
| @Override |
| public void connect() throws IOException { |
| if (connected) { |
| return; |
| } |
| if (usingProxy() && !makingSSLTunnel) { |
| // SSL Tunnel through the proxy was not established yet, do so |
| makingSSLTunnel = true; |
| // first - make the connection |
| super.connect(); |
| // keep request method |
| String save_meth = method; |
| // make SSL Tunnel |
| method = "CONNECT"; //$NON-NLS-1$ |
| try { |
| doRequest(); |
| endRequest(); |
| } finally { |
| // restore initial request method |
| method = save_meth; |
| } |
| if (!connected) { |
| throw new IOException(Messages.getString("luni.01", //$NON-NLS-1$ |
| responseMessage, responseCode)); |
| } |
| // if there are some remaining data in the stream - read it out |
| InputStream is = connection.getInputStream(); |
| while (is.available() != 0) { |
| is.read(); |
| } |
| makingSSLTunnel = false; |
| } else { |
| // no need in SSL tunnel |
| super.connect(); |
| } |
| if (!makingSSLTunnel) { |
| sslSocket = connection.getSecureSocket(getSSLSocketFactory(), getHostnameVerifier()); |
| setUpTransportIO(connection); |
| } |
| } |
| |
| @Override |
| protected String requestString() { |
| if (usingProxy()) { |
| if (makingSSLTunnel) { |
| // we are making the SSL Tunneling, return remotehost:port |
| int port = url.getPort(); |
| return (port > 0) ? url.getHost() + ":" + port //$NON-NLS-1$ |
| : url.getHost(); |
| } |
| // we has made SSL Tunneling, return /requested.data |
| String file = url.getFile(); |
| if (file == null || file.length() == 0) { |
| file = "/"; //$NON-NLS-1$ |
| } |
| return file; |
| } |
| return super.requestString(); |
| } |
| |
| } |
| } |