Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Multipart upload problem
Forum Updated to NodeBB v4.3 + New Features

Multipart upload problem

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 3 Posters 179 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AxelViennaA Offline
    AxelViennaA Offline
    AxelVienna
    wrote on last edited by
    #1

    Dear all,
    I have to replace a CURL function for multipart upload by QHttpMultipart.
    The example in the documentation does not work for my case and I just can't get it running.
    Your help is highly appreciated.
    Thanks in advance, Axel

    Original CURL based code:

        CURL *curl;
        CURLcode res;
    
        struct curl_httppost *formpost = NULL;
        struct curl_httppost *lastptr = NULL;
        struct curl_slist *headerlist = NULL;
        static const char buf[] =  "Expect:";
    
        curl_global_init(CURL_GLOBAL_ALL);
    
        // set up the header
        curl_formadd(&formpost,
            &lastptr,
            CURLFORM_COPYNAME, "cache-control:",
            CURLFORM_COPYCONTENTS, "no-cache",
            CURLFORM_END);
    
        curl_formadd(&formpost,
            &lastptr,
            CURLFORM_COPYNAME, "content-type:",
            CURLFORM_COPYCONTENTS, "multipart/form-data",
            CURLFORM_END);
    
        curl_formadd(&formpost,
            &lastptr,
            CURLFORM_COPYNAME, "part1",
            CURLFORM_COPYCONTENTS, "dummyname.csv",
            CURLFORM_END);
    
        curl_formadd(&formpost, &lastptr,
            CURLFORM_COPYNAME, "part2",
            CURLFORM_BUFFER, "data",
            CURLFORM_BUFFERPTR, contents.data(),
            CURLFORM_BUFFERLENGTH, contents.size(),
            CURLFORM_END);
    
        curl = curl_easy_init();
    
        string authkey = "apikey: " + get_apikey();
        headerlist = curl_slist_append(headerlist, authkey.c_str());
        headerlist = curl_slist_append(headerlist, buf);
        string readBuffer;
        if (curl) {
    
            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    
            curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunction);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    
            res = curl_easy_perform(curl);
    

    New code which does not work:

        const string url = URL + "upload?file=" + filekey;
    
        QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
        QHttpPart cachePart;
        cachePart.setRawHeader("cache-control:", "no-cache");
        QHttpPart contentType;
        contentType.setRawHeader("content-type:", "multipart/form-data");
        QHttpPart fileName;
        fileName.setRawHeader("part1", "dummyname.csv");
        QHttpPart data;
        data.setRawHeader("part2", "data");
        data.setBody(QByteArray(contents.c_str()));
    
        multiPart->append(cachePart);
        multiPart->append(contentType);
        multiPart->append(fileName);
        multiPart->append(data);
    
        QUrl u((URL+"upload").c_str());
        QUrlQuery q;
        q.addQueryItem("file",filekey.c_str());
        u.setQuery(q);
        QNetworkRequest request(u);
        request.setRawHeader("apikey",get_apikey().c_str());
    
        QNetworkAccessManager* nm= new QNetworkAccessManager;
        auto reply = nm->post(request, multiPart);
        multiPart->setParent(reply); // delete the multiPart with the reply
    
        QEventLoop loop;
        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
        loop.exec();
    
        bool success = (reply->error()==QNetworkReply::NoError);
        string r = reply->readAll().toStdString();
        delete reply;
        return success;
    

    C++ and Python walk into a bar. C++ reuses the first glass.

    1 Reply Last reply
    0
    • AxelViennaA AxelVienna

      Hi SGaist,
      thanks for looking into the issue. I did not get any error message. The code misbehaved and just did not upload any data.
      With some trial and error and your advice not to set raw headers, I got it working with the code attached.
      The issue is solved, I just have not gotten any wiser.
      Brgds
      Axel

       const string url = URL + "upload?file=" + filekey;
      
          QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
          QHttpPart cachePart;
          cachePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"cache-control:\""));
          cachePart.setBody("no-nache");
          QHttpPart contentType;
          contentType.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"content-type:\""));
          contentType.setBody("multipart/form-data");
          QHttpPart fileName;
          fileName.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"part1\""));
          fileName.setBody("dummyname.csv");
          QHttpPart data;
          data.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"part2\""));
          data.setBody(QByteArray(contents.c_str()));
      
          multiPart->append(cachePart);
          multiPart->append(contentType);
          multiPart->append(fileName);
          multiPart->append(data);
      
          QUrl u((URL+"upload").c_str());
          QUrlQuery q;
          q.addQueryItem("file",filekey.c_str());
          u.setQuery(q);
          QNetworkRequest request(u);
          request.setRawHeader("apikey",get_apikey().c_str());
      
          QNetworkAccessManager* nm= new QNetworkAccessManager;
          auto reply = nm->post(request, multiPart);
          multiPart->setParent(reply); // delete the multiPart with the reply
      
          QEventLoop loop;
          QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
          loop.exec();
      
      J.HilkJ Online
      J.HilkJ Online
      J.Hilk
      Moderators
      wrote on last edited by
      #4

      @AxelVienna
      please don't force synchronous behaviour on asynchronous apis

      QEventLoop loop;
          QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
          loop.exec();
      

      That's inviting all kinds of strange behaviour and hard to track down bugs.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      4
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        What exact error do you get ?

        Why are you creating one part per raw header ? That looks off.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • AxelViennaA Offline
          AxelViennaA Offline
          AxelVienna
          wrote on last edited by
          #3

          Hi SGaist,
          thanks for looking into the issue. I did not get any error message. The code misbehaved and just did not upload any data.
          With some trial and error and your advice not to set raw headers, I got it working with the code attached.
          The issue is solved, I just have not gotten any wiser.
          Brgds
          Axel

           const string url = URL + "upload?file=" + filekey;
          
              QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
              QHttpPart cachePart;
              cachePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"cache-control:\""));
              cachePart.setBody("no-nache");
              QHttpPart contentType;
              contentType.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"content-type:\""));
              contentType.setBody("multipart/form-data");
              QHttpPart fileName;
              fileName.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"part1\""));
              fileName.setBody("dummyname.csv");
              QHttpPart data;
              data.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"part2\""));
              data.setBody(QByteArray(contents.c_str()));
          
              multiPart->append(cachePart);
              multiPart->append(contentType);
              multiPart->append(fileName);
              multiPart->append(data);
          
              QUrl u((URL+"upload").c_str());
              QUrlQuery q;
              q.addQueryItem("file",filekey.c_str());
              u.setQuery(q);
              QNetworkRequest request(u);
              request.setRawHeader("apikey",get_apikey().c_str());
          
              QNetworkAccessManager* nm= new QNetworkAccessManager;
              auto reply = nm->post(request, multiPart);
              multiPart->setParent(reply); // delete the multiPart with the reply
          
              QEventLoop loop;
              QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
              loop.exec();
          

          C++ and Python walk into a bar. C++ reuses the first glass.

          J.HilkJ 1 Reply Last reply
          0
          • AxelViennaA AxelVienna

            Hi SGaist,
            thanks for looking into the issue. I did not get any error message. The code misbehaved and just did not upload any data.
            With some trial and error and your advice not to set raw headers, I got it working with the code attached.
            The issue is solved, I just have not gotten any wiser.
            Brgds
            Axel

             const string url = URL + "upload?file=" + filekey;
            
                QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
                QHttpPart cachePart;
                cachePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"cache-control:\""));
                cachePart.setBody("no-nache");
                QHttpPart contentType;
                contentType.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"content-type:\""));
                contentType.setBody("multipart/form-data");
                QHttpPart fileName;
                fileName.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"part1\""));
                fileName.setBody("dummyname.csv");
                QHttpPart data;
                data.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"part2\""));
                data.setBody(QByteArray(contents.c_str()));
            
                multiPart->append(cachePart);
                multiPart->append(contentType);
                multiPart->append(fileName);
                multiPart->append(data);
            
                QUrl u((URL+"upload").c_str());
                QUrlQuery q;
                q.addQueryItem("file",filekey.c_str());
                u.setQuery(q);
                QNetworkRequest request(u);
                request.setRawHeader("apikey",get_apikey().c_str());
            
                QNetworkAccessManager* nm= new QNetworkAccessManager;
                auto reply = nm->post(request, multiPart);
                multiPart->setParent(reply); // delete the multiPart with the reply
            
                QEventLoop loop;
                QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
                loop.exec();
            
            J.HilkJ Online
            J.HilkJ Online
            J.Hilk
            Moderators
            wrote on last edited by
            #4

            @AxelVienna
            please don't force synchronous behaviour on asynchronous apis

            QEventLoop loop;
                QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
                loop.exec();
            

            That's inviting all kinds of strange behaviour and hard to track down bugs.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            4

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved