Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpUrlConnection.openConnection fails second time

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!

like image 921
ggomeze Avatar asked Jul 28 '10 11:07

ggomeze


People also ask

Can I reuse HttpURLConnection?

You don't. You close this one and create a new one.

What is the difference between URLConnection and HttpURLConnection?

URLConnection is the base class. HttpURLConnection is a derived class which you can use when you need the extra API and you are dealing with HTTP or HTTPS only. HttpsURLConnection is a 'more derived' class which you can use when you need the 'more extra' API and you are dealing with HTTPS only.

Can I use HttpURLConnection for https?

HttpsURLConnection extends HttpURLConnection , and your connection is an instance of both. When you call openConnection() the function actually returns an HttpsURLConnection . However, because the https object extends the http one, your connection is still an instance of an HttpURLConnection .

Which is the following used in HttpURLConnection?

HttpURLConnection uses the GET method by default. It will use POST if setDoOutput(true) has been called. Other HTTP methods ( OPTIONS , HEAD , PUT , DELETE and TRACE ) can be used with setRequestMethod(String) .


2 Answers

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()); 
like image 98
barrycburton Avatar answered Sep 20 '22 20:09

barrycburton


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.

like image 23
RaB Avatar answered Sep 18 '22 20:09

RaB