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!
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());
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.
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());
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.
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.
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.
Related
I am posting some data using POST API call with the following function:
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(40000);
conn.setReadTimeout(40000);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setDefaultUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.addRequestProperty("Cache-Control", "max-age=0");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty(JsonKeys.DATE_KEY, getTimeStamp());
if (params != null) {
// Write serialized JSON data to output stream.
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(params.toString());
wr.close();
}
int status = conn.getResponseCode();
StringBuilder sb = new StringBuilder();
try {
if (status == HttpURLConnection.HTTP_OK || status == HTTP_CREATED) {
InputStream is = conn.getInputStream();
int ch;
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
is.close();
return new JSONObject(sb.toString());
} else {
throw new IOException("We encountered some problem with the request. Please try again later");
} catch (JSONException jex) {
MessageUtils.showLog(jex);
} finally {
if (conn != null) {
MessageUtils.showLog("connection disconnected");
conn.disconnect();
}
}
This POST request needs to wait for at least 40 seconds for the response from the server. This code works perfectly fine on most of the devices but on some devices the request ends abruptly after 10 seconds.I get a 502 response (like after 10 seconds). The server log has no trace of a response being sent (confirmed by my back-end developer). The error stream for 502 that I receive in my front end contains this:
<HEAD><TITLE>Server Hangup</TITLE></HEAD>
I have no idea as to why this is behaving differently for different mobile devices or different Android APIs. Can somebody help me with an insight to this problem or a solution? I have been stuck on this problem for hours and cant find an explanation/solution to it.
This is a stack trace we are receiving in the apache access log:
[Wed May 01 13:54:54.142877 2019] [proxy:error] [pid 23000:tid 140687508961231] (111)Connection refused: AH00957: HTTP: attempt to connect to 127.0.0.1:9000 (localhost) failed
[Wed May 01 13:54:54.142995 2019] [proxy:error] [pid 23000:tid 140687508961231] AH00959: ap_proxy_connect_backend disabling worker for (localhost) for 60s
[Wed May 01 13:54:54.143001 2019] [proxy_http:error] [pid 23000:tid 140687508961231] [client 160.32.32.202:256560] AH01114: HTTP: failed to make connection to backend: localhost
The proxy configuration in our server is something like this:
<Location "/v2/">
ProxyPass http://0.0.0.0:9000/ retry=0 timeout=500
ProxyPassReverse http://0.0.0.0:9000
</Location>
ProxyPreserveHost On
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
502 is actually a 'Bad Gateway'. This is definitely a server issue. You have some apache module that checks for stable connection and that module detects that your connection is not ok.
From the updated question it is visible that the property 'retry' on your proxy is 0. Here is the meaning from documentation:
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
retry
Connection pool worker retry timeout in seconds. If the connection pool worker to the backend server is in the error state, Apache httpd will not forward any requests to that server until the timeout expires. This enables to shut down the backend server for maintenance and bring it back online later. A value of 0 means always retry workers in an error state with no timeout.
So definitely the problem is in different request and not in different android. Please check your requests. The requests you send might be different and server can detect connection as dead letting you think that problem is in android. You can also play with retry parameter and set it to default retry=60.
I want to use TLS protocol with HttpsUrlConnection in Android. For this, I am overriding SSLSocketFactory class and setting TLS protocol using setEnabledProtocol() method. Then I am setting the SSLSocketFactory in HttpsUrlConnection using connection.setSSLSocketFactory() method.
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
SSLSocketFactoryEx socketFactory = new SSLSocketFactoryEx();
conn.setSSLSocketFactory(socketFactory);
conn.connect();
Here SSLSocketFactoryEx is my custom class inheriting from SSLSocketFactory class.
Inside SSLSocketFactoryEx class, I am setting setEnabledProtocol() method with TLS protocol.
Now the problem is when I use SSLSocketFactory class, the HttpsUrlConnection takes more than a sec to connect. As per the below link, there is a bug related to reverse DNS in Android due to which it takes time. I followed the approach described there to fix the issue but still it is slow.
https://code.google.com/p/android/issues/detail?id=13117
Is there a way I can improve the performance?
I would like to know if there are known issues on Android with HttpUrlConnection and POST requests. We are experiencing intermittent EOFExceptions when making POST requests from an Android client. Retrying the same request will eventually work. Here is a sample stack trace:
java.io.EOFException
at libcore.io.Streams.readAsciiLine(Streams.java:203)
at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:579)
at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:827)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
There are many similar bug reports and posts to stack overflow but I cannot understand if there really is an issue and if so, what versions of Android are affected and what the proposed fix/work around is.
Here are some of the similar reports I am referring to:
Android HttpsUrlConnection eofexception
Android HttpURLConnection throwing EOFException
EOFException and FileNotFoundException in HttpURLConnection getInputStream()
https://code.google.com/p/google-http-java-client/issues/detail?id=213
https://code.google.com/p/android/issues/detail?id=29509
https://code.google.com/p/google-http-java-client/issues/detail?id=230
https://code.google.com/p/android/issues/detail?id=41576
Here is a potential Android framework fix
https://android.googlesource.com/platform/libcore/+/19aa40c81c48ff98ccc7272f2a3c41479b806376
I do know there was an issue with poisoned connections in the connection pool in pre-Froyo but these issues are occurring on new ICS+ devices exclusively. If there were a problem on later devices I would expect some kind of official Android documentation of the issue.
Our conclusion is that there is an issue in the Android platform. Our workaround was to catch the EOFException and retry the request N number of times. Below is the pseudo code:
private static final int MAX_RETRIES = 3;
private ResponseType fetchResult(RequestType request) {
return fetchResult(request, 0);
}
private ResponseType fetchResult(RequestType request, int reentryCount) {
try {
// attempt to execute request
} catch (EOFException e) {
if (reentryCount < MAX_RETRIES) {
fetchResult(request, reentryCount + 1);
}
}
// continue processing response
}
HttpURLConnection library internally maintains a pool of Connections. So, whenever a request is send, it first checks if there is an existing connection already present in the pool, based on which it decides to create a new one.
These connections are nothing but sockets, and this library by default does not closes these sockets. It may sometimes happen that a connection (socket) which is not currently being used and is present in the pool is no longer usable as the Server may choose to terminate the connection after some time. Now, since the connection even though is closed by the server, the library does not knows about it and assumes the connection/socket to be still connected. Thus it sends the new request using this stale connection and hence we get EOFException.
The best way to handle this is to check the Response Headers after each request you send. The server always sends a "Connection: Close" before terminating a connection (HTTP 1.1). So, you can use getHeaderField() and check for "Connection" field. Another thing to note is that server ONLY sends this connection field when it is about to terminate the connection. So, you need to code around this with the possibility of getting a "null" in the normal case (when server is not closing the connection)
This workaround tends to be reliable and performant:
static final int MAX_CONNECTIONS = 5;
T send(..., int failures) throws IOException {
HttpURLConnection connection = null;
try {
// initialize connection...
if (failures > 0 && failures <= MAX_CONNECTIONS) {
connection.setRequestProperty("Connection", "close");
}
// return response (T) from connection...
} catch (EOFException e) {
if (failures <= MAX_CONNECTIONS) {
disconnect(connection);
connection = null;
return send(..., failures + 1);
}
throw e;
} finally {
disconnect(connection);
}
}
void disconnect(HttpURLConnection connection) {
if (connection != null) {
connection.disconnect();
}
}
This implementation relies on the fact that the default number of connections that can be opened with a server is 5 (Froyo - KitKat). This means that up to 5 stale connections may exist, each of which will have to be closed.
After each failed attempt, the Connection:close request property will cause the underlying HTTP engine to close the socket when connection.disconnect() is called. By retrying up to 6 times (max connections + 1), we ensure that the last attempt will always be given a new socket.
The request may experience additional latency if no connections are alive, but that is certainly better than an EOFException. In that case, the final send attempt won't immediately close the freshly opened connection. That's the only practical optimization that can be made.
Instead of relying on the magic default value of 5, you may be able to configure the system property yourself. Keep in mind that this property is accessed by a static initializer block in KitKat's ConnectionPool.java, and it works like this in older Android versions too. As a result, the property may be used before you have a chance to set it.
static final int MAX_CONNECTIONS = 5;
static {
System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS));
}
Yes. There is a problem in the Android platform, specifically, in Android libcore with version 4.1-4.3.
The problem is introduced in this commit: https://android.googlesource.com/platform/libcore/+/b2b02ac6cd42a69463fd172531aa1f9b9bb887a8
Android 4.4 switched http lib to "okhttp" which doesn't have this problem.
Problem explained as follow:
On android 4.1-4.3, when you are using URLConnection/HttpURLConnection to POST with "ChunkedStreamingMode" or "FixedLengthStreamingMode" set, URLConnection/HttpURLConnection will not do silent retry if the reused connection is stale. You should retry POST at most "http.maxConnections+1" times in your code, just as previous answers suggest.
I suspect it might be the server that is at fault here, and the HttpURLConnection is not as forgiving as other implementations. That was the cause of my EOFException. I suspect in my case this would not be intermittent (fixed it before testing the N retry workaround), so the answers above relate to other issues and be a correct solution in those cases.
My server was using python SimpleHTTPServer and I was wrongly assuming all I needed to do to indicate success was the following:
self.send_response(200)
That sends the initial response header line, a server and a date header, but leaves the stream in the state where you are able to send additional headers too. HTTP requires an additional new line after headers to indicate they are finished. It appears if this new line isn't present when you attempt to get the result body InputStream or response code etc with HttpURLConnection then it throws the EOFException (which is actually reasonable, thinking about it). Some HTTP clients did accept the short response and reported the success result code which lead to me perhaps unfairly pointing the finger at HttpURLConnection.
I changed my server to do this instead:
self.send_response(200)
self.send_header("Content-Length", "0")
self.end_headers()
No more EOFException with that code.
This worked for me.
public ResponseObject sendPOST(String urlPrefix, JSONObject payload) throws JSONException {
String line;
StringBuffer jsonString = new StringBuffer();
ResponseObject response = new ResponseObject();
try {
URL url = new URL(POST_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
OutputStream os = connection.getOutputStream();
os.write(payload.toString().getBytes("UTF-8"));
os.close();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = br.readLine()) != null) {
jsonString.append(line);
}
response.setResponseMessage(connection.getResponseMessage());
response.setResponseReturnCode(connection.getResponseCode());
br.close();
connection.disconnect();
} catch (Exception e) {
Log.w("Exception ",e);
return response;
}
String json = jsonString.toString();
response.setResponseJsonString(json);
return response;
}
connection.addRequestProperty("Accept-Encoding", "gzip");
is the answer
for study we have to develop an Android game which is location based. Currently we use OSMDroid to show the map. There are resources (like wood, stone, ...) which the player has to collect. These resources are currently stored in our backend with hardcoded long/lat and will be added with setMarker onto the current map.
To provide this game globally, we want to set the resources dynamically based on the "real" world. So we need different layers from OSM (like forest, sea, ..) to set our resources automatically without asking our backend.
After some hours searching with google I found out that the Overpass API seems to help me implementing this functionality. But I can't find any tutorial for using Overpass API in Android. I tried some things but I don't get it... So I need your help, please give me an example or explanation how to implement this :/
This is my current code, but I don't think that this is correct..
URL url = new URL("http://overpass-api.de/api/interpreter");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
inputStream.close();
Following exception will be thrown at InputStream inputStream = urlConnection.getInputStream();:
W/System.err(3958): java.io.FileNotFoundException: http://overpass-api.de/api/interpreter
W/System.err(3958): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
W/System.err(3958): at de.htw.berlin.games.based.location.gui.MapActivity$test.doInBackground(MapActivity.java:536)
W/System.err(3958): at de.htw.berlin.games.based.location.gui.MapActivity$test.doInBackground(MapActivity.java:1)
W/System.err(3958): at android.os.AsyncTask$2.call(AsyncTask.java:287)
W/System.err(3958): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
W/System.err(3958): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
W/System.err(3958): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
W/System.err(3958): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
W/System.err(3958): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
W/System.err(3958): at java.lang.Thread.run(Thread.java:856)
Thanks for all helpful replies :)
This exception you're getting is thrown because an HTTP GET call to http://overpass-api.de/api/interpreter returns a 400 Bad Request response.
What you want to do is a POST request to http://overpass-api.de/api/interpreter. An example of form-data to pass to this API is :
data='<?xml version="1.0" encoding="UTF-8"?><osm-script><!--
This is an example Overpass query.
Try it out by pressing the Run button above!
You can find more examples with the Load tool.
-->
<query type="node">
<has-kv k="amenity" v="drinking_water"/>
<bbox-query s="41.88659196260802" w="12.488558292388916" n="41.89248629819397" e="12.51119613647461"/><!--this is auto-completed with the
current map view coordinates.-->
</query>
<print/></osm-script>'
To find out how the API is working you should check, using your browser, what HTTP query is made to the API when clicking on Run in the example I pointed out.
EDIT
You can find plenty of examples like this one that shows how to post data using HTTP in Android. You'll have to add data as a key and the XML query string as a value in the used value pair container, such as :
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("data", _The_XML_Query_String_));
Stick to the linked example for the rest and you hould be fine.
Check out https://github.com/zsoltk/overpasser. It's a Java library to ease working with the Overpass API.
You don't have to write the QL string yourself
It comes with a Retrofit adapter (so you can skip the networking part)
It has an Android sample showing how to put them all together over a Google Maps to get you started in no time
For anyone in future who needs to find a solution with overpass api, here is what I did very often: Overpass API can be addressed with a GET-Request. A GET-Request comes with a HTTP-protocoll and can be used in (I think) every programming language. You have to make a GET-request to the overpass-interpreter with all the queries in the url. In Android it would look like this:
String urlOverpass = "https://overpass-api.de/api/interpreter?data=[out:json][timeout:100];(node[shop=supermarket](52.402957,13.337429,52.420730,13.379530);way[shop=supermarket](52.402957,13.337429,52.420730,13.379530););out%20body;%3E;out%20skel%20qt;";
/* here you speak to the interpreter and you can insert whatever query you need. As an example look at overpass-turbo.eu*/
StringRequest request = new StringRequest(urlOverpass, new Response.Listener<String>() {
#Override
public void onResponse(String string) {
/* Here you can do whatever you like with the data which comes from the interpreter. The "string" is the response.*/
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
/* Here you can explain what happens when an error is coming from the interpreter*/
}
});
RequestQueue rQueue = Volley.newRequestQueue(MainActivity.this);
rQueue.add(request);
Dont forget to implement the library: implementation 'com.android.volley:volley:1.1.1'
But there are multiple possibilities to fetch data from an api with a GET-request.
I've been through every related post I can find trying to get to the bottom of this and am no clearer - hoping someone can put me out of my misery…
I am trying to get Android 2.3 to POST over HTTPS via a Proxy. This code works perfectly on 2.2 through a proxy, and perfectly on both 2.2 and 2.3 using HTTPS when not going through a proxy, and in all cases (2.2 and 2.3) i can GET over HTTPS through a proxy. Its just 2.3 POST using HTTPS through a proxy that seems to be the issue. I get the dreaded "broken pipe" error. The error is thrown when I try and read the inputstream response from the connection - presumably because the TCP socket has been closed underneath my stream. I've tried everything I can think of, including using Connection and Proxy-connection headers (setting to both close and keep-alive) and setting big readTimeout numbers (30 seconds). From my relentless googling, I can see there are known issues with SSL on Android 2.3, but I can't seem to find anything that suggests why the POST might be an issue. Wireshark has yielded some results, but given this is SSL if just a little bit tricky to get to the issue.
Has anyone seem this. I'm using HttpsURLConnection as various posts suggest this is more stable that AndroidHttpClient. Here is my code…any help at all invaluable. Thanks
urlConnection.setSSLSocketFactory(factory);
urlConnection.setHostnameVerifier(new AllowAllHostnameVerifier() );
String dateText = "{\"loopParam\":\"" + String.valueOf(d.getHours()) + ":" + String.valueOf(d.getMinutes()) + ":" + String.valueOf(d.getSeconds()) + "\"}";
txtOutput.setText("Sending " + String.valueOf(dateText.length() ) + " bytes of JSON to /pulse/loop" );
urlConnection.addRequestProperty("Content-type", "application/json");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Proxy-connection", "Keep-Alive");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
urlConnection.setReadTimeout(30000);
urlConnection.setRequestMethod("POST");
DataOutputStream dataOut = new DataOutputStream(urlConnection.getOutputStream());
dataOut.writeBytes(dateText);
dataOut.flush();
BufferedReader bufIn = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String sResponse;
StringBuilder s = new StringBuilder();
//bufIn is null as error as closed urlcConnection
while ((sResponse = bufIn.readLine()) != null) {
s = s.append(sResponse);
}
Error details:
08-May-12 09:09:51 SsliferSnifferActivity Connecting through proxy INFO
08-May-12 09:09:54 SsliferSnifferActivity javax.net.ssl.SSLException: Write error: ssl=0x2d42b8: I/O error during system call, Broken pipe
at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:837)
at java.io.OutputStream.write(OutputStream.java:80)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.writeRequestHeaders(HttpURLConnectionImpl.java:799)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.retrieveResponse(HttpURLConnectionImpl.java:1028)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:726)
at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:110)
at uk.co.flurrished.sslifersniffer.SslifersnifferActivity.makeRequest(SslifersnifferActivity.java:236)
at uk.co.flurrished.sslifersniffer.SslifersnifferActivity.access$2(SslifersnifferActivity.java:148)
at uk.co.flurrished.sslifersniffer.SslifersnifferActivity$2.onClick(SslifersnifferActivity.java:76)
at android.view.View.performClick(View.java:2485)
at android.view.View$PerformClick.run(View.java:9080)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3822)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
EDIT : This looks like it is being caused by the server raising a 400 (Bad Request) and closing the pipe. What is it about ANdroid 2.3 that is adding extra content when routed through a proxy that causes the 400?
'Broken pipe' has exactly one meaning. You have written to a connection that has already been closed by the other end. Are you sure the peer is really speaking SSL?