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. Why there isn't QHttpServerRequest copy constructor?
Forum Updated to NodeBB v4.3 + New Features

Why there isn't QHttpServerRequest copy constructor?

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 381 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.
  • T Offline
    T Offline
    Tarae
    wrote on last edited by
    #1

    I'm playing with QHttpServer.

    I use asynchronous processing, so my request handler returns QFuture<QHttpServerResponse>. QFuture is created by QtConcurrent::run. But QtConcurrent::run creates a copy of its arguments. And QHttpServerRequest doesn't have copy constructor so I cannot use it as an argument.

    I came out with some workarounds to solve this, but they are not as nice as if QHttpServerRequest had copy constructor.

    Is there any reason why QHttpServerRequest isn't copy-constructible?

    There is a sample of the code to demonstrate, what I think:

    // QT += httpserver concurrent
    
    #include <QCoreApplication>
    #include <QHttpServer>
    #include <QtConcurrent>
    
    QHttpServerResponse responder1()
    {
      return "Hello";
    }
    
    QHttpServerResponse responder2(const QString & arg)
    {
      return "Hello with arg: " + arg;
    }
    
    QHttpServerResponse responder3(const QHttpServerRequest & request)
    {
      return "Hello to ip address: " + request.remoteAddress().toString();
    }
    
    int main(int argc, char *argv[])
    {
      QCoreApplication a(argc, argv);
    
      QHttpServer server;
    
      // this works
      server.route("/r1", [](){return QtConcurrent::run(responder1);});
      server.route("/r2/<arg>", [](const QString & arg){return QtConcurrent::run(responder2, arg);});
      
      //this doesn't work
      server.route("/r3", [](const QHttpServerRequest & request){return QtConcurrent::run(responder3, request);});
    
      server.listen(QHostAddress::Any, 2222);
      return a.exec();
    }
    

    This code uses simple functions to create responses but in my real code, I use QMetaObject::invokeMethod to move computation to a different thread. So I really need to use QtConcurrent::run.

    SGaistS 1 Reply Last reply
    0
    • T Tarae

      I'm playing with QHttpServer.

      I use asynchronous processing, so my request handler returns QFuture<QHttpServerResponse>. QFuture is created by QtConcurrent::run. But QtConcurrent::run creates a copy of its arguments. And QHttpServerRequest doesn't have copy constructor so I cannot use it as an argument.

      I came out with some workarounds to solve this, but they are not as nice as if QHttpServerRequest had copy constructor.

      Is there any reason why QHttpServerRequest isn't copy-constructible?

      There is a sample of the code to demonstrate, what I think:

      // QT += httpserver concurrent
      
      #include <QCoreApplication>
      #include <QHttpServer>
      #include <QtConcurrent>
      
      QHttpServerResponse responder1()
      {
        return "Hello";
      }
      
      QHttpServerResponse responder2(const QString & arg)
      {
        return "Hello with arg: " + arg;
      }
      
      QHttpServerResponse responder3(const QHttpServerRequest & request)
      {
        return "Hello to ip address: " + request.remoteAddress().toString();
      }
      
      int main(int argc, char *argv[])
      {
        QCoreApplication a(argc, argv);
      
        QHttpServer server;
      
        // this works
        server.route("/r1", [](){return QtConcurrent::run(responder1);});
        server.route("/r2/<arg>", [](const QString & arg){return QtConcurrent::run(responder2, arg);});
        
        //this doesn't work
        server.route("/r3", [](const QHttpServerRequest & request){return QtConcurrent::run(responder3, request);});
      
        server.listen(QHostAddress::Any, 2222);
        return a.exec();
      }
      

      This code uses simple functions to create responses but in my real code, I use QMetaObject::invokeMethod to move computation to a different thread. So I really need to use QtConcurrent::run.

      SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      For the why it's not copyable, that's a question you should bring to the module developers.

      That said, based on the examples of the module, it should work if you use a const reference to forward your request further.

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

      T 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        For the why it's not copyable, that's a question you should bring to the module developers.

        That said, based on the examples of the module, it should work if you use a const reference to forward your request further.

        T Offline
        T Offline
        Tarae
        wrote on last edited by
        #3

        @SGaist Thanks for your reply!

        Contacting module developers seems like a good idea. That's why I write this post. I was hoping they read it.

        How exactly should I use a const reference to forward your request further?
        My function responder3 has a const reference argument.

        SGaistS 1 Reply Last reply
        0
        • T Tarae

          @SGaist Thanks for your reply!

          Contacting module developers seems like a good idea. That's why I write this post. I was hoping they read it.

          How exactly should I use a const reference to forward your request further?
          My function responder3 has a const reference argument.

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          I somehow missed that.

          Taking a look at things again, my understanding is that when calling QtConcurrent::run as you do, there is a mandatory copy happening which is what triggers your issue.

          However, you can "cheat" the system. QtConcurrent::run can also take a lambda so you could do something like the following:

          server.route("/r3", [] (const QHttpServerRequest & request) {
              auto lambda = [&request]() -> QHttpServerResponse {
                  return responder3(request);
              };
              return QtConcurrent::run(lambda);
          });
          

          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
            Infinity
            wrote on last edited by Infinity
            #5

            Hi

            Like this you can skip the helper/workaround function:

            server.route("/r2", [] (const QHttpServerRequest & request) {
               QFuture<QHttpServerResponse> future = QtConcurrent::run([&request] () {
                   QString response = QString("Hello to ip address: %1\n").arg(request.remoteAddress().toString());
                   return QHttpServerResponse(response, QHttpServerResponder::StatusCode::Ok);
               });
               return future;
            });
            
            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