QtWebApp
httplistener.cpp
Go to the documentation of this file.
1
6#include "httplistener.h"
8#include "httpconnectionhandlerpool.h"
9#include <QCoreApplication>
10
11using namespace stefanfrings;
12
13HttpListener::HttpListener(const QSettings* settings, HttpRequestHandler* requestHandler, QObject *parent)
14 : QTcpServer(parent)
15{
16 Q_ASSERT(settings!=nullptr);
17 Q_ASSERT(requestHandler!=nullptr);
18 pool=nullptr;
19 this->settings=settings;
20 this->requestHandler=requestHandler;
21 // Reqister type of socketDescriptor for signal/slot handling
22 qRegisterMetaType<tSocketDescriptor>("tSocketDescriptor");
23 // Start listening
24 listen();
25}
26
27
29{
30 close();
31 qDebug("HttpListener: destroyed");
32}
33
34
36{
37 if (!pool)
38 {
39 pool=new HttpConnectionHandlerPool(settings,requestHandler);
40 }
41 QString host = settings->value("host").toString();
42 quint16 port=settings->value("port").toUInt() & 0xFFFF;
43 QTcpServer::listen(host.isEmpty() ? QHostAddress::Any : QHostAddress(host), port);
44 if (!isListening())
45 {
46 qCritical("HttpListener: Cannot bind on port %i: %s",port,qPrintable(errorString()));
47 }
48 else {
49 qDebug("HttpListener: Listening on port %i",port);
50 }
51}
52
53
55 QTcpServer::close();
56 qDebug("HttpListener: closed");
57 if (pool) {
58 delete pool;
59 pool=nullptr;
60 }
61}
62
64#ifdef SUPERVERBOSE
65 qDebug("HttpListener: New connection");
66#endif
67
68 HttpConnectionHandler* freeHandler=nullptr;
69 if (pool)
70 {
71 freeHandler=pool->getConnectionHandler();
72 }
73
74 // Let the handler process the new connection.
75 if (freeHandler)
76 {
77 // The descriptor is passed via event queue because the handler lives in another thread
78 QMetaObject::invokeMethod(freeHandler, "handleConnection", Qt::QueuedConnection, Q_ARG(tSocketDescriptor, socketDescriptor));
79 }
80 else
81 {
82 // Reject the connection
83 qDebug("HttpListener: Too many incoming connections");
84 QTcpSocket* socket=new QTcpSocket(this);
85 socket->setSocketDescriptor(socketDescriptor);
86 connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
87 socket->write("HTTP/1.1 503 too many connections\r\nConnection: close\r\n\r\nToo many connections\r\n");
88 socket->disconnectFromHost();
89 }
90}
HttpConnectionHandler * getConnectionHandler()
Get a free connection handler, or 0 if not available.
Alias for QSslConfiguration if OpenSSL is not supported.
void listen()
Restart listeing after close().
void close()
Closes the listener, waits until all pending requests are processed, then closes the connection pool.
void incomingConnection(tSocketDescriptor socketDescriptor)
Serves new incoming connection requests.
virtual ~HttpListener()
Destructor.
The request handler generates a response for each HTTP request.
qintptr tSocketDescriptor
Alias type definition, for compatibility to different Qt versions.