Android : SSLException: Unable to create application data + multiple HTTPS connection
Asked Answered
C

0

7

I have created one android application and two server application.

Server Details Tomcat 6 with SSL.

My both the server are on HTTPS.

In this application I read commands from Server "A" and process them.Once processing is complete I need to send them to Server "B" for verification and need to send the complete report (Along with response of Server "B") to Server "A" back.

Now when I run my application everyting seems working fine but after around some 160 to 170 server connection it gives SSLException: Unable to create application data.

At first I thought this may be related to tomcat but if i shift my server on HTTP everything works. I didn't face any single issue.

Following is my Code for Server Communication:

public final class ServerCommunicator {

private static final int TIMEOUT = 30000;

public static long counter = 0;

public static String sendToTestTool(String url, String dataToSend) {
    String encodedString = null;
    counter = counter + 1;
    System.out.println("Counter :" + counter);
    try {
        encodedString = getBase64EncodedString(dataToSend);
        return sendToServer(encodedString, url);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

public static String sendToWSCServer(String dataToSend, String url) {
    counter = counter + 1;
    System.out.println("Counter :" + counter);
    return sendToServer(dataToSend, url);
}

private static String sendToServer(String dataToSend, String url) {

    HttpURLConnection connections = null;
    try {

        URL urls = new URL(url);

        if (urls.getProtocol().equals("https")) {
            TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs,
                        String authType) {
                }

                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs,
                        String authType) {
                }
            } };

            // Install the all-trusting trust manager
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts,
                        new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc
                        .getSocketFactory());
            } catch (Exception e) {
            }
            HttpsURLConnection
                    .setDefaultHostnameVerifier(new HostnameVerifier() {
                        public boolean verify(String hostname,
                                SSLSession session) {
                            return true;
                        }
                    });
            connections = (HttpsURLConnection) urls.openConnection();
        } else {
            connections = (HttpURLConnection) urls.openConnection();
        }

        connections.setRequestMethod("POST");
        connections.setDoInput(true);
        connections.setDoOutput(true);
        connections.setConnectTimeout(TIMEOUT);

        connections.getOutputStream().write(dataToSend.getBytes());

        InputStream inputStream = connections.getInputStream();
        String responString = null;
        switch (connections.getResponseCode()) {

        case HttpURLConnection.HTTP_OK:
            long contentLength = connections.getContentLength();
            byte[] read = read(inputStream, contentLength);
            responString = new String(read);
            break;
        default:
            break;
        }

        return discardWhitespace(responString);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (connections != null) {
            connections.disconnect();
            connections = null;
        }
    }
    return null;

}

public static byte[] read(InputStream in, long length) throws IOException {

    // long length = in.available();

    if (length > Integer.MAX_VALUE) {
        throw new IOException("File is too large");
    }

    byte[] bytes = new byte[(int) length];

    int offset = 0;
    int numRead = 0;

    while (offset < bytes.length
            && (numRead = in.read(bytes, offset, bytes.length - offset)) != -1) {
        offset += numRead;

    }

    if (offset < bytes.length) {
        throw new IOException("Could not completely read file ");
    }

    in.close();
    return bytes;
}

private static String getBase64EncodedString(String sendToServer)
        throws UnsupportedEncodingException {
    byte[] data = sendToServer.getBytes("UTF-8");
    String encodedString = Base64.encodeToString(data, Base64.DEFAULT);
    return encodedString;
}

private static String discardWhitespace(String data) {
    if (data == null) {
        return null;
    }
    StringBuffer groomedData = new StringBuffer("");
    for (int i = 0; i < data.length(); i++) {
        switch (data.charAt(i)) {
        case (byte) '\n':
        case (byte) '\r':
            break;
        default:
            groomedData.append(data.charAt(i));
        }
    }
    return groomedData.toString();

}

}

All my communication are on non UI single thread and also all the communication are sequential means only one thread is performing one communication after another.

Colossus answered 12/3, 2014 at 8:29 Comment(14)
You need to implement X509Trustmanger and Keymanager to validate certificate.Multivocal
But what if I don't want to validate the certificate.Colossus
Anything in the server logs?Squad
Thats why i have added return true in HostnameVerifier.Colossus
Nop. It doesn't show any request is arrived.Colossus
I guess this is a self signed certSquad
yes..It is self signed cert.Colossus
If you use https then you need to validate your certificate or else go for http.Multivocal
@SiddharthVyas I do not think you are correct.Squad
@user2310289 : If you want to bypass this https then you can do it but it will be a hack.Multivocal
If it is working 160 times before fail then I would guess it is a resource error or multi-thread error, not because you are not validating your cert.Squad
Actually All the communication is in single thread.Also All the communication happens one after another.Colossus
having a look at developer.android.com/reference/javax/net/ssl/… it seems strange that you are using class static methods setDefaultSSLSocketFactory etc. for every send messageSquad
were you able to resolve the problem ?Bautram

© 2022 - 2024 — McMap. All rights reserved.