Uploaded image for project: 'Harmony'
  1. Harmony
  2. HARMONY-6643

HTTP 401 status code closes HttpUrlConnectionImpl and causes retries when calling getHeaderField() methods

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Classlib
    • Labels:
      None
    • Environment:
      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)

      { 1419 break; 1420 }

      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)

      { 878 throw new ProtocolException(Messages.getString("luni.28")); //$NON-NLS-1$ 879 }

      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.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              rburgst Rainer Burgstaller
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: