package org.ksoap2.transport; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocketFactory; import org.ksoap2.HeaderProperty; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.List; import java.util.Set; /** * HttpsServiceConnectionSE is a service connection that uses a https url connection and requires explicit setting of * host, port and file. * * The explicit setting is necessary since pure url passing and letting the Java URL class parse the string does not * work properly on Android. * * Links for reference: * @see "http://stackoverflow.com/questions/2820284/ssl-on-android-strange-issue" * @see "http://stackoverflow.com/questions/2899079/custom-ssl-handling-stopped-working-on-android-2-2-froyo" * @see "http://code.google.com/p/android/issues/detail?id=2690" * @see "http://code.google.com/p/android/issues/detail?id=2764" * * @see "https://gist.github.com/908048" There can be problems with the * certificate of theof the server on older android versions. You can disable * SSL for the versions only e.g. with an approach like this. * * @author Manfred Moser <manfred@simpligility.com> */ public class HttpsServiceConnectionSE implements ServiceConnection { private HttpsURLConnection connection; /** * Create the transport with the supplied parameters. * @param host the name of the host e.g. webservices.somewhere.com * @param port the http port to connect on * @param file the path to the file on the webserver that represents the * webservice e.g. /api/services/myservice.jsp * @param timeout the timeout for the connection in milliseconds * @throws IOException */ public HttpsServiceConnectionSE(String host, int port, String file, int timeout) throws IOException { connection = (HttpsURLConnection) new URL(HttpsTransportSE.PROTOCOL, host, port, file).openConnection(); updateConnectionParameters(timeout); } private void updateConnectionParameters(int timeout) { connection.setConnectTimeout(timeout); connection.setReadTimeout(timeout); // even if we connect fine we want to time out if we cant read anything.. connection.setUseCaches(false); connection.setDoOutput(true); connection.setDoInput(true); } public void connect() throws IOException { connection.connect(); } public void disconnect() { connection.disconnect(); } public List getResponseProperties() { Map properties = connection.getHeaderFields(); Set keys = properties.keySet(); List retList = new LinkedList(); for (Iterator i = keys.iterator(); i.hasNext();) { String key = (String) i.next(); List values = (List) properties.get(key); for (int j = 0; j < values.size(); j++) { retList.add(new HeaderProperty(key, (String) values.get(j))); } } return retList; } public void setRequestProperty(String key, String value) { connection.setRequestProperty(key, value); } public void setRequestMethod(String requestMethod) throws IOException { connection.setRequestMethod(requestMethod); } public void setFixedLengthStreamingMode(int contentLength) { connection.setFixedLengthStreamingMode(contentLength); } public OutputStream openOutputStream() throws IOException { return connection.getOutputStream(); } public InputStream openInputStream() throws IOException { return connection.getInputStream(); } public InputStream getErrorStream() { return connection.getErrorStream(); } public String getHost() { return connection.getURL().getHost(); } public int getPort() { return connection.getURL().getPort(); } public String getPath() { return connection.getURL().getPath(); } public void setSSLSocketFactory(SSLSocketFactory sf) { connection.setSSLSocketFactory(sf); } }