5

I am trying to send a "PATCH" request to my firebase application.As far as I read QNetworkManager doesn't support "Patch" request.

How can I send "PATCH" request ?

Aykut Celik
  • 511
  • 2
  • 7
  • 18

3 Answers3

9

So we are clear that there is no method in QNetworkAccessManager named "patch" Therefore I have used "sendCustomRequest" but with QBuffer. Because QNetworkManager requires a QIODevice object.

QString destination="";
currentNode.replace(QString("/").append(latestNode),"");
destination
        .append(host)
        .append(currentNode)
        .append(".json");
QString jsonString=QString(QString("{").append("\"").append(latestNode).append("\"").append(":").append("\"").append(str).append("\"").append(QString("}")));
QNetworkRequest request(destination);
request.setHeader(QNetworkRequest::ContentTypeHeader,
    "application/x-www-form-urlencoded");
qDebug()<<jsonString;
QBuffer *buffer=new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(jsonString.toUtf8());
buffer->seek(0);
manager->sendCustomRequest(request,"PATCH",buffer);
qDebug()<<"posted";
Aykut Celik
  • 511
  • 2
  • 7
  • 18
  • 1
    Aside: using operator `+` instead of all those `append`s results in clearer and more maintainable code. – owacoder Dec 03 '15 at 15:34
  • Note that the `QBuffer` needs to be created as a pointer (as Aykut rightly did) and not on the stack, otherwise it might be garbage collected before the request has time to be executed, leading to very hard to debug issues. – laurent Jan 03 '17 at 10:00
  • If you want to use `QBuffer`, you can make the code simpler (as per Qt source code for `QNetworkAccessManager`) and replace the calls to `write` & `seek` with `setData()`. However `QNetworkAccessManager::sendCustomRequest()` has a variant that takes a `QByteArray`, so you could bypass `QBuffer` and simply put `manager->sendCustomRequest(request,"PATCH",jsonString.toUtf8());` – Paul Masri-Stone Feb 07 '20 at 11:45
2

try:

QNetworkAccessManager* manager = new QNetworkAccessManager();
QNetworkRequest request("http://<domain>/<path>/");
QHttpMultiPart* multipart = new QHttpMultiPart();
//... Add your data in multipart
manager->sendCustomRequest(request, "PATCH", multipart);
Ráfagan
  • 2,165
  • 2
  • 15
  • 22
2

As QNetworkAccessManager does not support PATCH implicitly, I've created the following class QNetworkAccessManagerWithPatch that does. Use it in place of QNetworkAccessManager and you'll have the same 3 variants for patch() as there are for post(), put(), etc.

Get the Github gist here: https://gist.github.com/paulmasri/efafb8ee350a8ce84a6657a30eb4eb8a

Or take the code directly from here: (save as QNetworkAccessManagerWithPatch.h)

#pragma once

#include <QNetworkAccessManager>

class QNetworkAccessManagerWithPatch : public QNetworkAccessManager
{
    Q_OBJECT

public:
    explicit QNetworkAccessManagerWithPatch(QObject *parent = Q_NULLPTR)
        : QNetworkAccessManager(parent) {}

    QNetworkReply* patch(const QNetworkRequest &request, QIODevice *data)
    { return sendCustomRequest(request, "PATCH", data); }
    QNetworkReply* patch(const QNetworkRequest &request, const QByteArray &data)
    { return sendCustomRequest(request, "PATCH", data); }

#if QT_CONFIG(http)
    QNetworkReply *patch(const QNetworkRequest &request, QHttpMultiPart *multiPart)
    { return sendCustomRequest(request, "PATCH", multiPart); }
#endif
};
Paul Masri-Stone
  • 2,843
  • 3
  • 29
  • 51
  • 2
    While the point of stack overflow is not to get free code, I like it when you are in the middle of building a solution and is blocked by an distracting issue with the framework (or whatever), and then... suddenly a heavenly developer shares you some code that allows you to focus on the actual solution you were working on.... Thanks mate. – C-- Mar 01 '20 at 10:17