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

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • None
    • Classlib
    • 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)

      { 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

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

            Dates

              Created:
              Updated: