httplistener.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /**
  2. @file
  3. @author Stefan Frings
  4. */
  5. #include "httplistener.h"
  6. #include "httpconnectionhandler.h"
  7. #include "httpconnectionhandlerpool.h"
  8. #include <QCoreApplication>
  9. using namespace stefanfrings;
  10. HttpListener::HttpListener(const QSettings* settings, HttpRequestHandler* requestHandler, QObject *parent)
  11. : QTcpServer(parent)
  12. {
  13. Q_ASSERT(settings!=nullptr);
  14. Q_ASSERT(requestHandler!=nullptr);
  15. pool=nullptr;
  16. this->settings=settings;
  17. this->requestHandler=requestHandler;
  18. // Reqister type of socketDescriptor for signal/slot handling
  19. qRegisterMetaType<tSocketDescriptor>("tSocketDescriptor");
  20. // Start listening
  21. listen();
  22. }
  23. HttpListener::~HttpListener()
  24. {
  25. close();
  26. qDebug("HttpListener: destroyed");
  27. }
  28. void HttpListener::listen()
  29. {
  30. if (!pool)
  31. {
  32. pool=new HttpConnectionHandlerPool(settings,requestHandler);
  33. }
  34. QString host = settings->value("host").toString();
  35. quint16 port=settings->value("port").toUInt() & 0xFFFF;
  36. QTcpServer::listen(host.isEmpty() ? QHostAddress::Any : QHostAddress(host), port);
  37. if (!isListening())
  38. {
  39. qCritical("HttpListener: Cannot bind on port %i: %s",port,qPrintable(errorString()));
  40. }
  41. else {
  42. qDebug("HttpListener: Listening on port %i",port);
  43. }
  44. }
  45. void HttpListener::close() {
  46. QTcpServer::close();
  47. qDebug("HttpListener: closed");
  48. if (pool) {
  49. delete pool;
  50. pool=nullptr;
  51. }
  52. }
  53. void HttpListener::incomingConnection(tSocketDescriptor socketDescriptor) {
  54. #ifdef SUPERVERBOSE
  55. qDebug("HttpListener: New connection");
  56. #endif
  57. HttpConnectionHandler* freeHandler=nullptr;
  58. if (pool)
  59. {
  60. freeHandler=pool->getConnectionHandler();
  61. }
  62. // Let the handler process the new connection.
  63. if (freeHandler)
  64. {
  65. // The descriptor is passed via event queue because the handler lives in another thread
  66. QMetaObject::invokeMethod(freeHandler, "handleConnection", Qt::QueuedConnection, Q_ARG(tSocketDescriptor, socketDescriptor));
  67. }
  68. else
  69. {
  70. // Reject the connection
  71. qDebug("HttpListener: Too many incoming connections");
  72. QTcpSocket* socket=new QTcpSocket(this);
  73. socket->setSocketDescriptor(socketDescriptor);
  74. connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
  75. socket->write("HTTP/1.1 503 too many connections\r\nConnection: close\r\n\r\nToo many connections\r\n");
  76. socket->disconnectFromHost();
  77. }
  78. }