32

I know this issue should be fixed with System.setProperty("http.keepAlive", "false"); before openConnection, but that didn't work to me. First try on this code works, second one fails. Even if i try this request after less than 5 seconds, it also works. If i wait more than that, it fails again

This is my code:

    System.setProperty("http.keepAlive", "false");
  HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
  conn.setUseCaches(false); 
  conn.setRequestProperty("Connection","Keep-Alive"); 
  conn.setRequestProperty("User-Agent", useragent);
  conn.setConnectTimeout (30000) ; 
  conn.setDoOutput(true); 
        conn.setDoInput(true); 

  consumer.sign(conn);
  InputSource is = new InputSource(conn.getInputStream());

I get the exception on last line:

java.io.IOException: Write error: I/O error during system call, Broken pipe
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativewrite(Native Method)
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.access$600(OpenSSLSocketImpl.java:55)
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:583)
W/System.err( 2164):  at java.io.OutputStream.write(OutputStream.java:82)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.sendRequest(HttpURLConnectionImpl.java:1332)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1656)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1153)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:253)

Does someone have an idea about what's wrong here?. Thanks!

Yasir Khan
  • 2,413
  • 4
  • 20
  • 26
ggomeze
  • 5,711
  • 6
  • 29
  • 32

6 Answers6

29

The connection pool used by HttpURLConnection when it is keeping connections alive is broken such that it tries to use connections that have been closed by the server. By default Android sets KeepAlive on all connections.

System.setProperty("http.keepAlive", "false"); is a workaround that disables KeepAlive for all connections so then you avoid the bug in the connection pool.

conn.setRequestProperty("Connection","Keep-Alive"); turns KeepAlive on for this particular connection, essentially reversing what System.setProperty("http.keepAlive", "false"); does.

Also I always explicitly call connect() as it makes it clear where you are ending your connection setup. I'm not sure if calling this method is optional or not.

System.setProperty("http.keepAlive", "false");
HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
conn.setUseCaches(false); 
conn.setRequestProperty("User-Agent", useragent);
conn.setConnectTimeout(30000);
conn.setDoOutput(true); 
conn.setDoInput(true); 
consumer.sign(conn);

conn.connect();

InputSource is = new InputSource(conn.getInputStream());
barry
  • 769
  • 6
  • 12
  • Thanks @fonetik for the answer and explanation!! I cannot test it now as i moved to HttpClient, but i'm sure this can help other people. Thanks again! – ggomeze Sep 14 '10 at 11:11
  • @user464773 `System.setProperty("http.keepAlive", "false");` disables _Keep Alive_ on all of the app's connections. This is what we want because _Keep Alive_ will always cause bugs. Using `conn.setRequestProperty("connection", "close");` only disables _Keep Alive_ for `conn`, leaving the door open for a bug when we forget to add it to any one connection. I don't know if the bug made it back to Harmony but the Android team is aware of it: http://code.google.com/p/android/issues/detail?id=7786 – barry Oct 25 '10 at 22:13
  • 1
    I wonder if this is still acceptable/best answer or there is better advice to solve occurencies of "javax.net.ssl.SSLException: Write error: ssl=0x130f4a0: I/O error during system call, Broken pipe"? 10q – Ewoks Jun 07 '13 at 13:15
  • Disabling the keepalive with setRequestProperty doesn't even seem to work when the connection is hanging . – Alkanshel May 02 '19 at 02:32
24

You dont need the System.setProperty("http.keepAlive", "false");

All you need is conn.setRequestProperty("connection", "close");

this fixes the issue but effectively kills keep alives and therefore potentially makes multiple connections slower (which is a shame). I was looking through the harmony bug tracker but could not really find anything.

@fonetik, do you know whether this is already raised with harmony? I mean not that it helps much since another http related luni defect is still unassigned after more than a month.

Sotiris
  • 38,986
  • 11
  • 53
  • 85
RaB
  • 1,545
  • 13
  • 16
3

I solved the problem. Here I leave you the code, in case it might be helpful for someone. Basically I see a trend on Google for using HttpClient/HttpGet instead of HttpUrlConnection. So I tried with those classes, and everything worked:

final HttpClient client = new DefaultHttpClient();
final HttpGet conn = new HttpGet(mURL.toString());

OAuthConsumer consumer = mOAuthManager.getPostConsumer();
consumer.sign(conn);
HttpResponse response = client.execute(conn);
InputSource is = new InputSource(response.getEntity().getContent());
Aditi Parikh
  • 1,522
  • 3
  • 13
  • 34
ggomeze
  • 5,711
  • 6
  • 29
  • 32
  • 10
    google now recommends to use HttpUrlConnection (starting from Gingerbread) since a few of those bugs have been fixed: http://android-developers.blogspot.com/2011/09/androids-http-clients.html – Jan Berkel Nov 07 '11 at 23:20
  • Sooner or later, especially with Android M growing, HttpClient is becoming effectively deprecated. URLConnection is recommended for apps with a long life ahead. – Josh Dec 16 '15 at 12:52
1

this bug had beed fixed in Android2.3 version,as we know System.setProperty("http.keepAlive", "false"); is not a very good solution ,because on mobile device ,create each connection is every time is high cost.

Sotiris
  • 38,986
  • 11
  • 53
  • 85
allen
  • 19
  • 1
0

When i am trying to open https connection it is working fine but second time it fails because i have set the system property value instead of HttpsURLConnection connection. I have got the java.io.IOException: Write error: I/O issue while opening the https connection second time. I have used following code in my applicaiton.

System.setProperty("http.proxyHost", proxy);
System.setProperty("http.proxyPort", port);

But when i changed the same to below it works fine.

javax.net.ssl.HttpsURLConnection ucon = (javax.net.ssl.HttpsURLConnection) urlWPF.openConnection(proxyserver);

ucon.setRequestProperty("http.proxyHost", proxy);
ucon.setRequestProperty("http.proxyPort", port);

If you set the system property, it will applicable for entire application. If you want reset the same, you can follow two ways. One is you have to take server refresh and second one is you have to change the HttpsURLConnection.setRequestProperty which is mentioned above where required.

Ali Lotfi
  • 856
  • 3
  • 18
  • 40
0

I believe your problem lies in the order of your code. Check those methods in the URLConnection JavaDocs - setRequestProperty should not be called after the connection is made on mUrl.openConnection(). It may be working the first time because the connection is made, then you are changing settings that are not affecting anything until the next time you try to make a connection. Try using the HttpURLConnection constructor instead so you can call connect() after you have set the properties.

ZachM
  • 893
  • 2
  • 8
  • 22
  • 1
    Thank for your answer, but i'm afraid that will not work. This is what API doc says: A URLConnection can only be set up after the instantiation but before connecting to the remote resource. In my case the actual connection happens in: conn.getInputStream() and that's after the headers setup – ggomeze Jul 29 '10 at 06:08