Tubo roto SSL

I make POST requests in my application and somtimes (if i have a huge amount of Post data), the following error occured:

avax.net.ssl.SSLException: Write error: ssl=0x2f0610: I/O error during system call, Broken pipe

while executing http.execute(httpost) in the code below. Does anybody know how to avoid this?

I tryed to use AndroidHttpClient, but can't find a valid way for basic auth And i tryed a HttpsUrlConnection, but get the same error.

    public static String makePOSTRequest(String s, List<NameValuePair> nvps,
        String encoding) {
        String ret = "";
        UsernamePasswordCredentials c = new UsernamePasswordCredentials("XXX", "YYY");
        BasicCredentialsProvider cP = new BasicCredentialsProvider();
        cP.setCredentials(AuthScope.ANY, c);

        HttpParams httpParams = new BasicHttpParams();
        int connection_Timeout = 5000;
        HttpConnectionParams.setConnectionTimeout(httpParams,
                connection_Timeout);
        HttpConnectionParams.setSoTimeout(httpParams, connection_Timeout);
        DefaultHttpClient http = new DefaultHttpClient(httpParams);
        http.setCredentialsProvider(cP);
        HttpResponse res;
        try {
            HttpPost httpost = new HttpPost(s);
            httpost.setEntity(new UrlEncodedFormEntity(nvps,
                    HTTP.DEFAULT_CONTENT_CHARSET));
            res = http.execute(httpost);
            InputStream is = res.getEntity().getContent();
            BufferedInputStream bis = new BufferedInputStream(is);
            ByteArrayBuffer baf = new ByteArrayBuffer(50);
            int current = 0;
            while ((current = bis.read()) != -1) {
                baf.append((byte) current);
            }
            res = null;
            httpost = null;
            ret = new String(baf.toByteArray(), encoding);
            break;
        } catch (ClientProtocolException e) {
            ret = e.getMessage();

        } catch (IOException e) {
            ret = e.getMessage();
        }
    return ret;
}

edit: The following code is used for uploading files, if I try to upload small files, the code works, but if the files get bigger, i receive the broken pipe error. Using a faster Internetconnection will increase the filesize, it seemed to be a problem withe the time until the server is resetting the connection.

public static boolean upload_image2(String url,
        List<NameValuePair> nameValuePairs, File file, String encoding) {
    boolean erg = false;

                    HttpParams httpParams = new BasicHttpParams();
            int connection_Timeout = 120000;

     HttpConnectionParams.setConnectionTimeout(httpParams,connection_Timeout);
       HttpConnectionParams.setSoTimeout(httpParams, connection_Timeout);
       http = new DefaultHttpClient(httpParams);
        HttpResponse res;
        UsernamePasswordCredentials c = new UsernamePasswordCredentials(username, password);
        BasicCredentialsProvider cP = new BasicCredentialsProvider();
        cP.setCredentials(AuthScope.ANY, c);


        try {
            HttpPost httpost = new HttpPost(url);

            MultipartEntity entity = new MultipartEntity(
                    HttpMultipartMode.STRICT);

            FileBody isb = new FileBody(file, "application/*");
            entity.addPart("File", isb);
            for (int index = 0; index < nameValuePairs.size(); index++) {
                ContentBody cb;
                // Normal string data
                cb = new StringBody(nameValuePairs.get(index).getValue(),
                        "", null);
                entity.addPart(nameValuePairs.get(index).getName(), cb);
            }

            httpost.setEntity(entity);

            res = http.execute(httpost);
            InputStream is = res.getEntity().getContent();
            BufferedInputStream bis = new BufferedInputStream(is);
            ByteArrayBuffer baf = new ByteArrayBuffer(50);
            int current = 0;
            while ((current = bis.read()) != -1) {
                baf.append((byte) current);
            }
            res = null;
            httpost = null;
            String ret = new String(baf.toByteArray(), encoding);
            LastError = ret;
            erg = true;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            LastError = e.getMessage();
            erg = false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            LastError = e.getMessage();
            erg = false;
        }
    return erg;
}

preguntado el 08 de noviembre de 11 a las 16:11

Consulte nuestra página stackoverflow.com/questions/2899079/… -

thx, but already tryed, same error. I use a proxy for the request, but in my WM app it't running without errors, must depend to the android system -

Sometimes it occurs due to the internet connectivity problem. I am facing it as well. -

3 Respuestas

I've had the same problem using the DefaultHttpClient, well, using my own implementation of the httpclient to support https. Small files it was working fine and big files were failing time after time.

After reading this response I've changed to the HttpsURLConnection like the accepted answer suggests and also because it is recommended by android (http://android-developers.blogspot.pt/2011/09/androids-http-clients.html).

The problem stood. Turns out the issue was on the server, I've changed the configs from the PHP server before to accept bigger sizes, but I totally forgot to change the client_max_body_size of the nginx. After making that small change sending big files was working. Through both HttpsUrlConnections and DefaultHttpClient.

contestado el 15 de mayo de 18 a las 11:05

I had got the same error. The problem is in the Android library where is use DefaultHttpClient has been around since Android API level 1 and AndroidHttpClient has been available since Android API level 8. This is bug in android https://code.google.com/p/android/issues/detail?id=8625

My problem was: The default tiempo de espera is 60 seconds. When I ran the connection in the Wireshark. It was created handshake and he has been waiting on the ApplicationData, but he didn't get it so after timeout send FIN and I have got :javax.net.ssl.SSLException: Write error: ssl=0x2f0610: I/O error during system call, Broken pipe.

I resolved my problem problem setting timeout the http connection on the 5 minutes or something value is longer than 60second. If I can recommended how resolve your problem run on the server Wireshark and listening the comunication with mobile device.

contestado el 15 de mayo de 14 a las 18:05

I wasn't able to fix the problem with DefaultHttpClient, AndroidHttpClient or Abstract, but finally found a solution with HttpsUrlRequest ant Authentication via header instead of CredentielsService:

public static boolean upload_image5(String urls,File file, String encoding){
    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    DataInputStream inputStream = null;
    String myfilename = file.getName();
    String urlServer = urls;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary =  "*****";
    boolean erg = false;
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1*1024*1024;

    try
    {
    FileInputStream fileInputStream = new FileInputStream(file);

    URL url = new URL(urlServer);
    connection = (HttpsURLConnection) url.openConnection();

    // Allow Inputs & Outputs
    connection.setDoInput(true);
    connection.setDoOutput(true);
    connection.setUseCaches(false);

    // Enable POST method
    connection.setRequestMethod("POST");

    connection.setRequestProperty("Connection", "Keep-Alive");
    connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
    connection.addRequestProperty("Authorization","Basic [YOUR MD5 LOGIN VALUE]");
    outputStream = new DataOutputStream( connection.getOutputStream() );
    outputStream.writeBytes(twoHyphens + boundary + lineEnd);

    outputStream.writeBytes("Content-Disposition: form-data; name=\"DestFileName\"");
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(myfilename);
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(twoHyphens + boundary + lineEnd);
    outputStream.writeBytes("Content-Disposition: form-data; name=\"Target\"" );
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes("DOC");
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(twoHyphens + boundary + lineEnd);
    outputStream.writeBytes("Content-Disposition: form-data; name=\"filename\"");
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(myfilename);
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(twoHyphens + boundary + lineEnd);
    outputStream.writeBytes("Content-Disposition: form-data; name=\"File\"; filename=\"" + myfilename + "\"");
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes("Content-Type: application/*");
    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(lineEnd);
    //hier File schreiben
    bytesAvailable = fileInputStream.available();
    bufferSize = Math.min(bytesAvailable, maxBufferSize);
    buffer = new byte[bufferSize];
    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

    while (bytesRead > 0)
    {
    outputStream.write(buffer, 0, bufferSize);
    bytesAvailable = fileInputStream.available();
    bufferSize = Math.min(bytesAvailable, maxBufferSize);
    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
    }

    outputStream.writeBytes(lineEnd);
    outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);


    fileInputStream.close();


    try {
        inputStream = new DataInputStream(connection.getInputStream()); 
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = inputStream.readLine()) != null) {
            response.append(line).append('\n');
        }
        LastError =response.toString();
        erg = true;
    } catch (IOException e) { 
        LastError = e.getMessage();
        erg = false;
    } finally { 
        if (inputStream != null){
            try { 
                inputStream.close(); 
            } catch (IOException e) { 
                e.printStackTrace();
            } 
        }
    }

    outputStream.flush();
    outputStream.close();
    }
    catch (Exception ex)
    {
        LastError = ex.getMessage();
        erg = false;
    }
    return erg;
}

respondido 10 nov., 11:16

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.