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. http Multi part file upload via post request doesn't work in Windows
Forum Updated to NodeBB v4.3 + New Features

http Multi part file upload via post request doesn't work in Windows

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 3.0k Views 3 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.
  • F Offline
    F Offline
    fastcoder
    wrote on last edited by fastcoder
    #1

    I am trying to upload a file (~3Mb) to a server via http multipart post request in QT.The same code uploads successfully on MacOSx without any problems,however in windows 10 (didnt try with 7 or 8) QNetworkReply never emits finish signal and doesn't update upload progress at all. If I remove the file part from post request or choose a file which is 1kb then it also works with windows 10. If i wait long enough then I receive QNetworkReply::RemoteHostClosedError
    Here is my function to upload a file.

    QErrorMessage msg;
    QString filename="some_file_name.zip";
    QFile *file=new QFile(filename);
        if(!file->open(QIODevice::ReadOnly))
    {
        msg.showMessage("File couldnt be found, upload failed");
        msg.exec();
        return false;
    }
    
    uploadProgressBar = new QProgressDialog("Uploading...", "cancel", 0, 100);
        QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    
        QHttpPart productIDpart;
        productIDpart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"ProductId\""));
        productIDpart.setBody("123");
        multiPart->append(productIDpart);
    
        QHttpPart filePart;
        filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/zip"));
        filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                           QVariant("form-data; name=\"File\";filename=\"some_file_name.zip\" "));
    
        filePart.setBodyDevice(file);
        file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
        multiPart->append(filePart);
        QNetworkAccessManager manager;
        QUrl serviceUrl = QUrl("http://someserver.com/");
        QNetworkRequest request(serviceUrl);
        request.setRawHeader( "AuthenticationKey",authenticationKey.toUtf8());
        QEventLoop eventLoop;
        QNetworkReply *reply = manager.post(request, multiPart);
        connect(uploadProgressBar, SIGNAL(canceled()),reply,SLOT(abort()));
        connect(reply, SIGNAL(metaDataChanged()), reply, SLOT(abort()));
        connect(reply, SIGNAL(uploadProgress(qint64, qint64)),this,SLOT(uploadProgress(qint64, qint64)));
        connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));       
        multiPart->setParent(reply);
        //When uploading a file larger than 3-4Kb the code stucks at below line.
        //however the same code uploads on Mac OSx without any problems
         eventLoop.exec();  
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You should add additional error checks as well as connect the error related signals, you might be hitting something on Windows that doesn't occur on macOS.

      On a side note, you have memory leak with your file object. Since you're "blocking" the function until the upload is done. You should keep that variable on the stack.

      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
      • F Offline
        F Offline
        fastcoder
        wrote on last edited by
        #3

        Thank you very much for your reply, I was already printing the error code returned by QNetworkReply::error() function when the eventLoop quits as a result of finished() signal emitted by the reply. After 1-2 minutes the error code returned was QNetworkReply::RemoteHostClosedError. What other error checks should I be doing?

        1 Reply Last reply
        0
        • F Offline
          F Offline
          fastcoder
          wrote on last edited by
          #4

          Here is the communication log from from wireshark during the file upload if it helps. Last line arrived exactly when QT networkreply gave QNetworkReply::RemoteHostClosedError
          0_1485051950363_Capture.PNG

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

            The upload functionality of the forum is currently broken. Please use an image sharing site and post the link.

            You shouldn't wait for the loop to end to gather the information. You should connect the QNetworkReply::error signal.

            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
            • F Offline
              F Offline
              fastcoder
              wrote on last edited by fastcoder
              #6

              after your suggestion I complemented with the below lines however still not catching any errors before the server really kills the connection. Here is the screenshot from wireshark just before the communication ends with QNetworkReply::RemoteHostClosedError http://www.imageno.com/rxgfgmc2bt2tpic.html

              as an additional information right after the uploadprogress callback is called with 0%, I see a lot of thread exited information at the console
              Uploading 16384 / 2634392 % 0
              The thread 0x1ac4 has exited with code 0 (0x0).
              The thread 0x698 has exited with code 0 (0x0).
              The thread 0x2448 has exited with code 0 (0x0).

              interesting point is during the upload even if I close my wifi connection, still it doesnt come to the error callback. It comes to the error call back only if I press cancel button of upload dialog or wait 2-3 minutes.

                      QNetworkReply *reply = manager.post(request, multiPart);
                      connect(uploadProgressBar, SIGNAL(canceled()),reply,SLOT(abort()));
                      connect(reply, SIGNAL(uploadProgress(qint64, qint64)),this,SLOT(uploadProgress(qint64, qint64)));
                      connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
              	connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
              	connect(reply, SIGNAL(sslErrors(const QList<QSslError>)), this, SLOT(error(const QList<QSslError>)));
                      multiPart->setParent(reply); // delete the multiPart with the reply
                   //When uploading a file larger than 3-4Kb the code stucks at below line.
                  //however the same code uploads on Mac OSx without any problems
                      eventLoop.exec();
                      if (reply->error() == QNetworkReply::NoError)
                      {
                          
                          QString strReply = (QString)reply->readAll();
                          
                          //parse json
                          qDebug() << "Response:" << strReply;
                          QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
                          QJsonObject jsonObj = jsonResponse.object();
                          QJsonObject result=jsonObj["result"].toObject();
                          
                          if(jsonObj["error"].toBool()==false)
                          {
                              QJsonObject data=result["data"].toObject();
                              QrLink=data["QrLink"].toString();
                              QMessageBox msgBox;
                              msgBox.setText("model is uploaded");
                              msgBox.exec();
                          }
                          else
                          {
                              QErrorMessage msg;
                              msg.showMessage("Error during upload proces");
                              msg.exec();
                          }
                          delete reply;
                          
                      }
                      else
                      {
                          QErrorMessage msg;
              			int code= reply->error();
                          msg.showMessage("Upload couldn't start"+ QString::number(code));
                          msg.exec();
                      }
                  delete file;
                  }
              	return true;
              }
              void error(const QList<QSslError> &errors)
              {
              	qDebug() << errors;
              }
              void error(QNetworkReply::NetworkError error)
              {
              	qDebug() << error;
              }
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                You should also connect the error signal to the quit slot, that way you don't have to "influence" the system to make it go further and thus maybe modify its outcome.

                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
                • I Offline
                  I Offline
                  iLya84a
                  wrote on last edited by
                  #8

                  @fastcoder I have the same issue but in the opposite direction. Everything works in Windows but not in MacOS.

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    fastcoder
                    wrote on last edited by
                    #9

                    In my case I had processEvents() function called in uploadProgress function. When I get rid of it the problem was solved.

                    1 Reply Last reply
                    0

                    • Login

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