HttpsURLConnection on localhost


    The following example is given for debugging of programs functioning with HTTPS on local computer.

    As a first step it is necessary to install Apache server. Adjust it for the functioning with https. Information on Apache installation can be found in Internet.

    Place test cases on the server. For instance we can use simple test case in programming language C:

// script.c file
#include <stdio.h>
#include <stdlib.h>

int main(void) {
     char *remote_addr = getenv("REMOTE_ADDR");
     char *content_length = getenv("CONTENT_LENGTH");
     int num_bytes = atoi(content_length);
     char *data = (char *)malloc(num_bytes + 1);
     fread(data, 1, num_bytes, stdin);
     data[num_bytes] = 0;
     printf("Content-type: text/html\n\n");
     printf("Hello. We know about you all!\n");
     printf("Your IP-address: %s\n", remote_addr);
     printf("Count of data bytes: %d\n", num_bytes);
     printf("There are parameters you have entered:\n%s", data);
     return 0;
}

    Compile it on any compilator (VC, MinGW, etc.). Rename extension exe into cgi and place it in the cgi folder of local host server. As a result I have file script.cgi.

    Further we create an application Android in Eclipse. In the file AndroidMainifest.xml enable Internet access:

    <uses-permission android:name="android.permission.INTERNET" ></uses-permission>


    Code of the file Activity:


import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Scanner;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private TextView tv;
	private static SSLSocketFactory socketFactory;
	private static final HostnameVerifier verifier;
	
	static {
		//For access of any certificate we create base class TrustManager		
		final TrustManager[] tm = new TrustManager[] { 
			new X509TrustManager() {
				@Override
				public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
		} };
		
		//For access of any host name we create base class HostnameVerifier
		verifier = new HostnameVerifier() {
			@Override
			public boolean verify(String arg0, SSLSession arg1) {
				
				return true;
			}
		};
		
		try {
			//Cryptographic protocol TLS, analogue SSLv3, is used on Android
			
			SSLContext sc = SSLContext.getInstance("TLS");
			
			sc.init(null, tm, null);
			
			socketFactory = sc.getSocketFactory();
		} catch (GeneralSecurityException e) {
    		Log.v("GeneralSecurityException", e.toString());
    	}
	}

    @Override
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tv = (TextView)findViewById(R.id.text);
	//Emulator addresses to local host 127.0.0.1
	//through IP address 10.0.2.2
        String srv = "https://10.0.2.2/cgi-bin/script.cgi"; 
        
        connectToServer(srv);
    }
    
    private void connectToServer(String srv) {
    	URL url;
    	HttpsURLConnection conn;  
    	
    	try {
    		url = new URL(srv);
    		String param = "param1=" + URLEncoder.encode("value 1", "UTF-8") +
					"&param2=" + URLEncoder.encode("value2", "UTF-8") +
					"&param3=" + URLEncoder.encode("value3", "UTF-8") ;
					
    		//The connection is not always possible on the first try,
			//so give permission for a second attempt
			int counter = 0;
			while(true)
			{
				HttpsURLConnection.setDefaultHostnameVerifier( verifier);
				conn = (HttpsURLConnection)url.openConnection();
				
				HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
				conn.setDoOutput(true);
				conn.setDoInput(true);
				conn.setRequestMethod("POST"); 
				conn.addRequestProperty("Content-Type", 
					"application/xml; charset=utf-8");
				
				//Attempt to connect to the server
				try {
					conn.connect();
					break;
				} catch(IOException ex){
					counter++;
					
					conn.disconnect();
					conn = null;
					if (counter == 2)
						break;
					else
						continue;
				}
			}
			if (conn == null) return;

			//Transmit parameters request to server
			PrintWriter out = new PrintWriter(conn.getOutputStream());
			
			out.print(param); 
			
			out.close();
			
			//Receive response from server
			
			Scanner scanner = new Scanner(conn.getInputStream()); 
			StringBuilder sb = new StringBuilder();
			while(scanner.hasNextLine())
				sb.append(URLDecoder.decode(scanner.nextLine(), "UTF-8") + "\n");
			scanner.close();

			//Response is depicted on the display
			tv.setText(sb.toString());
			
			//Disconnect from server
			conn.disconnect();
			
    		
    	} catch(IOException ex){
    		Log.v("IOException", ex.toString());
    		
    	}
    }
}


    Startup the program and receive:




    Contributor: Dmitry I.