Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-49896

[QtQuick] XmlHttpRequest status is "lost" (becomes 0) in readyState 3->4 transition for PUT requests yielding response with custom HTTP status

    XMLWordPrintable

Details

    Description

      Hi.

      For some {HTTP request method / HTTP response status} combinations, QML's XmlHttpRequest implementation loses the contents of its status attribute, which becomes 0 at readyState == 4, after containing the correct, non-zero integer HTTP status returned by the server during readyState 2 and 3.

      I hit the problem with a PUT request to an Apache CouchDB server, which responds a (CouchDB-specific) status 409 in cases of conflict (see CouchDB documentation :: PUT)

      The attached minimal reproduction QML app demonstrates the problem. Below is the gist of it. As you can see from my logging, HTTP status 409 is here at readyState 2 and 3, but is "lost" between readyState 3 and readyState 4.

      Am I doing anything wrong? Is this indeed a bug? Thanks for your support. Remarks:

      • HTTP status 409 is indeed a custom, CouchDB-specific status code, but this is totally legitimate, and client HTTP code should leave it alone.
      • I don't know if this readyState 3→4 loss happens for other {HTTP request method / HTTP response status} combinations.
      • Short-term I'm going to iron over that and patch my client code to "catch" the 409 at readyState 3, but it's a hack. Would be great to see this fixed
      var xhr = new XMLHttpRequest(),
          method = 'PUT',
          baseUrl = 'http://localhost:5984/data/', // REST entry point to a CouchDB database
          newCouchDocumentId = '331ed149-af1a-4979-bd2e-0186b8738c5f', // random client-generated UUID
          url = baseUrl + newCouchDocumentId,
          async = true,
          couchDocumentPayload = '{"description":"Hello World"}'; // The body of the document to be created
      
      xhr.open(method, url, async);
      xhr.onreadystatechange = function() {
          console.log('readyState:', xhr.readyState, 'status:', xhr.status);
      }
      xhr.send(couchDocumentPayload)
      
      // Below is the QML console log after clicking the button twice.
      
      // On first click, CouchDB successfully creates the requested resource,
      // and returns HTTP status code 201 ("Created"):
      // qml: readyState: 2 status: 201
      // qml: readyState: 3 status: 201
      // qml: readyState: 4 status: 201
      
      // On second click, as expected, CouchDB refuses creation, because
      // our previously-created resource is already there at the same URI,
      // and returns a CouchDB-specific error code 409 ("Conflict").
      // But rather than ending up at {readyState=4, status=409},
      // here is what we see:
      // qml: readyState: 2 status: 409
      // qml: readyState: 3 status: 409
      // qml: readyState: 4 status: 0
      

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              qtqmlteam Qt Qml Team User
              ronjouch Ronan Jouchet
              Votes:
              5 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes