package kidozen.client.internal; import org.apache.http.HttpStatus; import java.io.BufferedInputStream; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import kidozen.client.KZHttpMethod; /** * Created with IntelliJ IDEA. * User: christian * Date: 5/20/13 * Time: 10:29 AM * To change this template use File | Settings | File Templates. */ public class SNIConnectionManager { public boolean ProcessAsStream = false; public int LastResponseCode; public String LastResponseMessage; public String LastResponseBody; String mUrlAsString; Hashtable<String, String> mRequestHeaders; HashMap<String,String> mParameters; boolean mDeveloperMode; String mBodyAsString; InputStream mBodyAsStream; public SNIConnectionManager (String urlAsString, String message, Hashtable<String, String> requestProperties, HashMap<String,String> params, boolean developerMode) { mUrlAsString = urlAsString; mRequestHeaders = requestProperties; mParameters = params; mDeveloperMode = developerMode; mBodyAsString = message; } public SNIConnectionManager (String urlAsString, InputStream message, Hashtable<String, String> requestProperties, HashMap<String,String> params, boolean developerMode) { mUrlAsString = urlAsString; mRequestHeaders = requestProperties; mParameters = params; mDeveloperMode = developerMode; mBodyAsString = null; mBodyAsStream = message; } public OutputStream ExecuteHttpAsStream(KZHttpMethod method) throws Exception { HttpURLConnection con = CreateConnectionThatHandlesRedirects(method); if (method ==KZHttpMethod.POST || method ==KZHttpMethod.PUT && mBodyAsStream !=null) { con.setDoOutput(true); int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1*1024*1024; DataOutputStream dos = new DataOutputStream( con.getOutputStream() ); bytesAvailable = mBodyAsStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; bytesRead = mBodyAsStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { dos.write(buffer, 0, bufferSize); bytesAvailable = mBodyAsStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = mBodyAsStream.read(buffer, 0, bufferSize); } mBodyAsStream.close(); dos.flush(); dos.close(); } LastResponseCode = con.getResponseCode(); LastResponseMessage = con.getResponseMessage(); if (LastResponseCode>= HttpStatus.SC_BAD_REQUEST) { LastResponseBody = Utilities.convertStreamToString(con.getErrorStream()); return null; } else { int dataRead = 0; int CHUNK_SIZE = 8192; // TCP/IP packet size byte[] dataChunk = new byte[CHUNK_SIZE]; // byte array for storing temporary data. OutputStream fos = new ByteArrayOutputStream(); BufferedInputStream bis = new BufferedInputStream(con.getInputStream()); InputStreamReader isr = new InputStreamReader( bis ); while (dataRead >= 0) { dataRead = bis.read(dataChunk,0,CHUNK_SIZE); // only write out if there is data to be read if ( dataRead > 0 ) { fos.write(dataChunk, 0, dataRead); } } bis.close(); fos.close(); return fos; } } public Hashtable<String, String> ExecuteHttp(KZHttpMethod method) throws Exception { HttpURLConnection con = CreateConnectionThatHandlesRedirects(method); //System.out.println("ExecuteHttp"); if (method ==KZHttpMethod.POST || method ==KZHttpMethod.PUT && mBodyAsString !=null) { con.setDoOutput(true); OutputStream os = con.getOutputStream(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); writer.write(mBodyAsString); writer.close(); os.close(); } return getExecutionResponse(con); } protected HttpURLConnection CreateConnectionThatHandlesRedirects(KZHttpMethod method) throws IOException, NoSuchAlgorithmException, KeyManagementException { if(mParameters !=null) { if (mParameters.keySet().size() > 0) mUrlAsString = mUrlAsString + "?" + Utilities.getQuery(mParameters); } URL url = new URL(mUrlAsString); //just in case services doesnt have configured redirection if (url.getProtocol().toLowerCase().equals("https")) { return CreateSNIConnection(mUrlAsString, method); } HttpURLConnection con = (HttpURLConnection) url.openConnection(); if (con.getResponseCode()==302) { con = CreateSNIConnection(con.getHeaderField("Location"), method); } return con; } protected HttpURLConnection CreateSNIConnection(String url, KZHttpMethod method) throws IOException, NoSuchAlgorithmException, KeyManagementException { if (mDeveloperMode) { trustAllHosts(); } URL connectionUrl = new URL(url); HttpsURLConnection secureConnection = (HttpsURLConnection) connectionUrl.openConnection(); secureConnection.setRequestMethod(method.toString()); if (mRequestHeaders !=null) { for (Map.Entry<String, String> entry : mRequestHeaders.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); secureConnection.setRequestProperty(key, value); } } secureConnection.setRequestProperty(Constants.X_KIDO_SDK_HEADER,Constants.X_KIDO_SDK_HEADER_VALUE); secureConnection.setRequestProperty(Constants.X_KIDO_SDK_VERSION_HEADER,Constants.X_KIDO_SDK_VERSION_HEADER_VALUE); return secureConnection; } protected void trustAllHosts() throws NoSuchAlgorithmException, KeyManagementException{ TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[] {}; } public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException { } } }; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }); } protected Hashtable<String, String> getExecutionResponse( HttpURLConnection con) throws IOException { Hashtable<String, String> retVal = new Hashtable<String, String>(); //System.out.println("SNIConnectionManager, getExecutionResponse," + mUrlAsString); int responseCode = con.getResponseCode(); //System.out.println("SNIConnectionManager, getExecutionResponse, Status Code:" + String.valueOf(responseCode)); String responseBody = con.getResponseMessage(); //System.out.println("SNIConnectionManager, getExecutionResponse, Response Body:" + responseBody); String contentType = con.getHeaderField("content-type"); //System.out.println("SNIConnectionManager, getExecutionResponse, Response contentType:" + contentType); retVal.put("statusCode", String.valueOf(responseCode)); retVal.put("responseMessage", responseBody); retVal.put("contentType", (contentType == null ? "" : contentType) ); /* Map<String, List<String>> selects = con.getHeaderFields(); for(Map.Entry<String, List<String>> entry : selects.entrySet()) { String key = entry.getKey(); List<String> value = entry.getValue(); System.out.println("SNIConnectionManager, getExecutionResponse, ** HEADER KEY *******->" + key); System.out.println("SNIConnectionManager, getExecutionResponse, ** HEADER VALUE *****->" + value.toString()); } */ if (responseCode>= HttpStatus.SC_BAD_REQUEST) retVal.put("responseBody", Utilities.convertStreamToString(con.getErrorStream())); else retVal.put("responseBody", Utilities.convertStreamToString(con.getInputStream())); return retVal; } }