Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
-
Android 2.2 as well as trunk code inspection
Description
The following code will force 2 HTTP requests being sent to the server
<snip>
URL url = new URL("http://server/that/sends/401");
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
int rc = cn.getResponseCode(); // This will cause the first request/response cycle
// now cn.connected will be false
Map<String, List<String>> map = m_cn.getRequestProperties(); // This will cause ANOTHER request/response cycle
Map<String, List<String>> map = m_cn.getRequestProperties(); // This will cause ANOTHER request/response cycle
Map<String, List<String>> map = m_cn.getRequestProperties(); // This will cause ANOTHER request/response cycle
...
</snip>
The cause of the problem seems to be that doRequestInternal sets its "connected" variable back to false.
<snip>
doRequestInternal() {
...
// HTTP authorization failed ?
1415 if (responseCode == HTTP_UNAUTHORIZED) {
1416 // keep asking for username/password until authorized
1417 String challenge = resHeader.get("WWW-Authenticate"); //$NON-NLS-1$
1418 if (challenge == null)
1421 // drop everything and reconnect, might not be required for
1422 // HTTP/1.1
1423 endRequest();
1424 disconnect();
=> 1425 connected = false;
</snip>
however, getHeaderFieldXXX methods call getInputStream() which will itself call connect() and doRequest().
<snip>
@Override
854 public Map<String, List<String>> getHeaderFields() {
855 try {
856 // ensure that resHeader exists
857 getInputStream();
</snip>
<snip>
75 @Override
876 public InputStream getInputStream() throws IOException {
877 if (!doInput)
880
881 // connect before sending requests
=> 882 connect();
883 doRequest();
</snip>
Since connected=false and the connection is already considered "reset" every of these methods will again force a complete request/response cycle.
Therefore if a user would like to see both the return code as well as all the headers for a request that resultet in a 401, harmony will send AT LEAST 2 requests out. It actually gets even worse when trying to iterate over the response headers.