#include #include #include #include #include #include struct MyRequestContext { QTcpSocket* socket; //Asuming, that path is enough to process a request. QString path; MyRequestContext(const QHttpServerRequest& request, QTcpSocket* const socket); MyRequestContext(); }; class MyServer : public QAbstractHttpServer { Q_OBJECT public: explicit MyServer(QObject* const parent = Q_NULLPTR); signals: void signal_deferred(QTcpSocket* socket); private slots: void slot_deferred(QTcpSocket* socket); void slot_missingHandler(const QHttpServerRequest& request, QTcpSocket* socket); void slot_disconnected(); protected: bool handleRequest(const QHttpServerRequest& request, QTcpSocket* socket); private: void handleRequests(QTcpSocket* const socket); private: QMap > requests; }; int main(int argc, char* argv[]) { QCoreApplication a(argc, argv); MyServer httpServer; httpServer.listen(QHostAddress::Any, 10111); return a.exec(); } MyRequestContext::MyRequestContext(const QHttpServerRequest& request, QTcpSocket* const socket) : socket(socket), path(request.url().path()) { } MyRequestContext::MyRequestContext() : socket(Q_NULLPTR) { } MyServer::MyServer(QObject* const parent) : QAbstractHttpServer(parent) { connect( this, &MyServer::missingHandler, this, &MyServer::slot_missingHandler ); connect( this, &MyServer::signal_deferred, this, &MyServer::slot_deferred, Qt::QueuedConnection ); } void MyServer::slot_deferred(QTcpSocket* const socket) { if(requests.contains(socket)) { requests[socket].dequeue(); makeResponder(socket).write("Deferred!", QByteArray()); handleRequests(socket); } } void MyServer::slot_missingHandler(const QHttpServerRequest& request, QTcpSocket* const socket) { Q_UNUSED(request); makeResponder(socket).write(QHttpServerResponder::StatusCode::NotFound); } void MyServer::slot_disconnected() { QTcpSocket* const socket(reinterpret_cast(sender())); if(requests.contains(socket)) requests.remove(socket); } bool MyServer::handleRequest(const QHttpServerRequest& request, QTcpSocket* const socket) { if(request.url().path() == "/hello" || request.url().path() == "/deferred") { //Might get called after signal_deferred, but before slot_deferred. QQueue& requests_(requests[socket]); requests_.enqueue(MyRequestContext(request, socket)); if(requests_.size() == 1) handleRequests(socket); } else return false; return true; } void MyServer::handleRequests(QTcpSocket* const socket) { QQueue& requests_(requests[socket]); while(!requests_.isEmpty()) { const MyRequestContext& request(requests_.head()); if(request.path == "/hello") { makeResponder(socket).write("Hello, world!", QByteArray()); requests_.dequeue(); } else if(request.path == "/deferred") { requests[socket].append(MyRequestContext(socket)); emit signal_deferred(socket); return; } } requests.remove(socket); } #include "main.moc"