Search code examples
c++qtcloudflarecloudflare-workers

Using QHttpMultiPart with PUT operation and form fields


I'm having quite a bit of struggle in trying to achieve a simple PUT request in QT. Frankly I am still a starter using this framework so I have much left to learn.

What I am trying to do is make a PUT request with 2 parameters this Cloudflare Workers KV API.

With that being said this is my current code snippet:

QString szUrl = "";

QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

QHttpPart valuePart;
valuePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"value\""));
valuePart.setBody(value.toByteArray());

QHttpPart metadataPart;
metadataPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"metadata\""));
metadataPart.setBody(metadata.toByteArray());

multiPart->append(valuePart);
multiPart->append(metadataPart);

QNetworkRequest request;

request.setUrl(szUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data");
request.setRawHeader("Authorization", QString("Bearer %1").arg("...").toUtf8());

QNetworkReply* reply = m_NetworkManager->put(request, multiPart);

// delete the multiPart with the reply
multiPart->setParent(reply);

// Process reply (QNetworkAccessManager::finished)
// Process errors (QNetworkAccessManager::sslErrors)

qDebug() << reply->error();
qDebug() << reply->readAll();
qDebug() << reply->errorString();

The above returns always HTTP 400 (bad request) with zero, and I mean ZERO response. I could not retrieve the error response from the API in any way. Just an empty string ("") under debug.

If I execute the example cURL cli code from the API page, it works perfectly. I get a response and it's successful.

My question would be, what on earth am I doing wrong? I read the documentation and wrote the code accordingly, I cannot understand what's happening.

I have searched quite a bit for a possible answer online but unfortunately all issues and examples are with POST requests and file uploads (mostly).

Please advise, it would be much appreciated.


Solution

  • I will answer my own question because one of the reasons the above was not working it's because of my own fault.

    Problem 1:

    Bad formatting of metadata. Looks like Cloudflare API wants the metadata "compressed".

    Problem 2:

    Unable to retrieve API error response. Now this is an interesting one because I found countless forum posts and posts even here with the same problem, yet nobody posted the actual solution.

    The readAll() function states this issue:

    This function has no way of reporting errors; returning an empty QByteArray can mean either that no data was currently available for reading, or that an error occurred. This function also has no way of indicating that more data may have been available and couldn't be read.

    The resolution is to connect QIODevice::readyRead to as per the documentation:

    connect(reply, &QIODevice::readyRead, this, [=]() {
        QByteArray response = reply->readAll();
        qDebug() << response;
    });
    

    You now have the server reply regardless of the HTTP error code.

    With that being said 2 problems solved in one go, enjoy.