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. Slow POST upload using QtNetworkAccessManager
Forum Update on Monday, May 27th 2025

Slow POST upload using QtNetworkAccessManager

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

    I'm writing a Qt5 program to upload files to a server using HTTP and POST. It works fine to send the files, but the speed is really slow. When I upload files using SCP from my development machine to the server, I get ~200Mbps (measured from Windows task manager). When I use an HTML form on the server's website and POST to the same PHP page that my Qt program is posting to, I get ~140Mbps. But when I upload from my Qt application, I get ~10Mbps. The files I'm trying to upload are around 400MB.

    I understand there is a difference between SCP and HTTP, but in theory POSTing a file through the browser and through Qt to the same PHP page should be same speed, not 14x slower.

    Below is the code that does the uploading

    QUrl url(connServer + "/api.php");
    QNetworkRequest request(url);
    
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    
    QHttpPart loginPart;
    /* username */
    loginPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"u\""));
    loginPart.setBody(connUsername.toLatin1());
    multiPart->append(loginPart);
    /* password */
    loginPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"p\""));
    loginPart.setBody(connPassword.toLatin1());
    multiPart->append(loginPart);
    
    QStringList md5stringlist;
    /* loop through the list of files */
    ui->progUpload->setRange(0,100);
    for (int i=0;i<list.size();i++) {
        qDebug("UploadFileList [%d] [%s]", i, list[i].toStdString().c_str());
        QFile *file = new QFile(list[i]);
        QHttpPart filePart;
        filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"files[]\"; filename=\""+ file->fileName() + "\""));
        file->open(QIODevice::ReadOnly);
        filePart.setBodyDevice(file);
        file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
        multiPart->append(filePart);
        /* create the MD5 list [file|md5,file2|md5,etc] */
        QFileInfo fileInfo(file->fileName());
        QString filename(fileInfo.fileName());
        md5stringlist << md5list[i];
    }
    
    /* check if there was a previous upload still going on */
    while (isUploading) {
        ui->lblStatus->setText("Waiting for previous upload to complete...");
        QTest::qWait(1000);
    }
    
    /* do the POST and setup the event handlers for it */
    QNetworkReply* reply = networkManager->post(request, multiPart);
    multiPart->setParent(reply); // delete the multiPart with the reply
    numNetConn++;
    isUploading = true;
    connect(reply, SIGNAL(finished()), this, SLOT(onGetReplyUpload()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onNetworkError(QNetworkReply::NetworkError)));
    connect(reply, SIGNAL(uploadProgress(qint64, qint64)), SLOT(progressChanged(qint64, qint64)));
    

    What is going on? Am I missing a setting in QtNetworkAccessManager?

    raven-worxR 1 Reply Last reply
    0
    • G GregB

      I'm writing a Qt5 program to upload files to a server using HTTP and POST. It works fine to send the files, but the speed is really slow. When I upload files using SCP from my development machine to the server, I get ~200Mbps (measured from Windows task manager). When I use an HTML form on the server's website and POST to the same PHP page that my Qt program is posting to, I get ~140Mbps. But when I upload from my Qt application, I get ~10Mbps. The files I'm trying to upload are around 400MB.

      I understand there is a difference between SCP and HTTP, but in theory POSTing a file through the browser and through Qt to the same PHP page should be same speed, not 14x slower.

      Below is the code that does the uploading

      QUrl url(connServer + "/api.php");
      QNetworkRequest request(url);
      
      QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
      
      QHttpPart loginPart;
      /* username */
      loginPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"u\""));
      loginPart.setBody(connUsername.toLatin1());
      multiPart->append(loginPart);
      /* password */
      loginPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"p\""));
      loginPart.setBody(connPassword.toLatin1());
      multiPart->append(loginPart);
      
      QStringList md5stringlist;
      /* loop through the list of files */
      ui->progUpload->setRange(0,100);
      for (int i=0;i<list.size();i++) {
          qDebug("UploadFileList [%d] [%s]", i, list[i].toStdString().c_str());
          QFile *file = new QFile(list[i]);
          QHttpPart filePart;
          filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"files[]\"; filename=\""+ file->fileName() + "\""));
          file->open(QIODevice::ReadOnly);
          filePart.setBodyDevice(file);
          file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
          multiPart->append(filePart);
          /* create the MD5 list [file|md5,file2|md5,etc] */
          QFileInfo fileInfo(file->fileName());
          QString filename(fileInfo.fileName());
          md5stringlist << md5list[i];
      }
      
      /* check if there was a previous upload still going on */
      while (isUploading) {
          ui->lblStatus->setText("Waiting for previous upload to complete...");
          QTest::qWait(1000);
      }
      
      /* do the POST and setup the event handlers for it */
      QNetworkReply* reply = networkManager->post(request, multiPart);
      multiPart->setParent(reply); // delete the multiPart with the reply
      numNetConn++;
      isUploading = true;
      connect(reply, SIGNAL(finished()), this, SLOT(onGetReplyUpload()));
      connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onNetworkError(QNetworkReply::NetworkError)));
      connect(reply, SIGNAL(uploadProgress(qint64, qint64)), SLOT(progressChanged(qint64, qint64)));
      

      What is going on? Am I missing a setting in QtNetworkAccessManager?

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @GregB
      are you testing a release build and without a debugger attached?

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      G 1 Reply Last reply
      0
      • G Offline
        G Offline
        GregB
        wrote on last edited by
        #3

        Yes. Release build on Windows 10. No debugging.

        1 Reply Last reply
        0
        • raven-worxR raven-worx

          @GregB
          are you testing a release build and without a debugger attached?

          G Offline
          G Offline
          GregB
          wrote on last edited by
          #4

          @raven-worx Yes. Release build on Windows 10. No debugging.

          A 1 Reply Last reply
          0
          • G GregB

            @raven-worx Yes. Release build on Windows 10. No debugging.

            A Offline
            A Offline
            ambershark
            wrote on last edited by
            #5

            @GregB In a way you are comparing 2 different things. I've never seen an HTTP POST upload be anywhere near as fast as my scps.

            What I would do is check your apache (or whatever webserver you use) and make sure there isn't a limitation on upload speeds. That is usually a setting to help throttle connections.

            Secondly if you really want to narrow things down I would compare a Qt POST upload with a non-Qt POST upload and see if there is a difference. Normally when you see performance stuff like this in files and network traffic it has to do with the buffers being used. It is possible Qt's network buffer is too small for those files.

            Or you can go the other route and try an scp upload to your server using Qt's Networking and see if it reaches the same speeds. It should. I wouldn't necessarily do this though as you are not concerned with scp speed but with POST speed.

            To limit variables in your testing I would have 2 functions in your app, 1 that uses Qt's HTTP stuff, and one that uses the network directly. This should let you figure out if it's Qt or not. Then you can look at why it's happening with the Qt Http stuff and file a bug if necessary or adjust your code if it's a user error.

            Wish I could give more insight but I haven't used Qt's HTTP stuff enough to notice any glaring issues with your code.

            My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

            G 1 Reply Last reply
            0
            • A ambershark

              @GregB In a way you are comparing 2 different things. I've never seen an HTTP POST upload be anywhere near as fast as my scps.

              What I would do is check your apache (or whatever webserver you use) and make sure there isn't a limitation on upload speeds. That is usually a setting to help throttle connections.

              Secondly if you really want to narrow things down I would compare a Qt POST upload with a non-Qt POST upload and see if there is a difference. Normally when you see performance stuff like this in files and network traffic it has to do with the buffers being used. It is possible Qt's network buffer is too small for those files.

              Or you can go the other route and try an scp upload to your server using Qt's Networking and see if it reaches the same speeds. It should. I wouldn't necessarily do this though as you are not concerned with scp speed but with POST speed.

              To limit variables in your testing I would have 2 functions in your app, 1 that uses Qt's HTTP stuff, and one that uses the network directly. This should let you figure out if it's Qt or not. Then you can look at why it's happening with the Qt Http stuff and file a bug if necessary or adjust your code if it's a user error.

              Wish I could give more insight but I haven't used Qt's HTTP stuff enough to notice any glaring issues with your code.

              G Offline
              G Offline
              GregB
              wrote on last edited by
              #6

              @ambershark Thanks for the suggestions!

              I have tried a Qt POST and non-Qt POST to the same PHP page on the same server. Qt is slow, POST through the browser is fast. I can't use scp for this application though because the only port open on the production server is 80, and only httpd is running on it.

              The Qt network buffer sounds like a possibility, since the files are so large. How can I change the buffer size?

              A raven-worxR 2 Replies Last reply
              0
              • G GregB

                @ambershark Thanks for the suggestions!

                I have tried a Qt POST and non-Qt POST to the same PHP page on the same server. Qt is slow, POST through the browser is fast. I can't use scp for this application though because the only port open on the production server is 80, and only httpd is running on it.

                The Qt network buffer sounds like a possibility, since the files are so large. How can I change the buffer size?

                A Offline
                A Offline
                ambershark
                wrote on last edited by
                #7

                @GregB The part that handles the buffering would be QNetworkReply* reply = networkManager->post(request, multiPart);.

                I'd look into your networkManager object first. If that's Qt and assuming it is, check the docs on that and see if there is a way to change it.

                If not what I usually do when I run into things like this is actually go look at Qt's code and see if they are doing something stupid like a small buffer or worse yet byte by byte. :) If they are you can of course modify it and rebuild Qt or submit a bug for a larger buffer or buffer size control.

                My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                1 Reply Last reply
                0
                • G GregB

                  @ambershark Thanks for the suggestions!

                  I have tried a Qt POST and non-Qt POST to the same PHP page on the same server. Qt is slow, POST through the browser is fast. I can't use scp for this application though because the only port open on the production server is 80, and only httpd is running on it.

                  The Qt network buffer sounds like a possibility, since the files are so large. How can I change the buffer size?

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  @GregB
                  just for testing purposes: can you try to upload the file by using a QByteArray (loading the whole file into memory before uploading) instead of the QIODevice-Multipart stuff?

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  G 1 Reply Last reply
                  2
                  • raven-worxR raven-worx

                    @GregB
                    just for testing purposes: can you try to upload the file by using a QByteArray (loading the whole file into memory before uploading) instead of the QIODevice-Multipart stuff?

                    G Offline
                    G Offline
                    GregB
                    wrote on last edited by
                    #9

                    @raven-worx How do I POST using the QByteArray instead?

                    This is what I have now

                    QFile *file = new QFile(list[i]);
                    QHttpPart filePart;
                    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"files[]\"; filename=\""+ file->fileName() + "\""));
                    file->open(QIODevice::ReadOnly);
                    filePart.setBodyDevice(file);
                    file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
                    multiPart->append(filePart);
                    

                    Would this be correct?

                    QFile *file = new QFile(list[i]);
                    QHttpPart filePart;
                    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"files[]\"; filename=\""+ file->fileName() + "\""));
                    filePart.setBody(file->readAll());
                    multiPart->append(filePart);
                    
                    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