QtWebApp
httplistener.cpp
Go to the documentation of this file.
1 
6 #include "httplistener.h"
8 #include "httpconnectionhandlerpool.h"
9 #include <QCoreApplication>
10 
11 using namespace stefanfrings;
12 
13 HttpListener::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().
HttpListener(const QSettings *settings, HttpRequestHandler *requestHandler, QObject *parent=nullptr)
Constructor.
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.