SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
httpconnectionhandlerpool.cpp
Go to the documentation of this file.
1 #ifndef QT_NO_OPENSSL
2  #include <QSslSocket>
3  #include <QSslKey>
4  #include <QSslCertificate>
5  #include <QSslConfiguration>
6 #endif
7 #include <QDir>
9 
10 using namespace qtwebapp;
11 
13  : QObject(), useQtSettings(true)
14 {
15  Q_ASSERT(settings != 0);
16  this->settings = settings;
17  this->listenerSettings = 0;
18  this->requestHandler = requestHandler;
19  this->sslConfiguration = 0;
20  loadSslConfig();
21  cleanupTimer.start(settings->value("cleanupInterval",1000).toInt());
22  connect(&cleanupTimer, SIGNAL(timeout()), SLOT(cleanup()));
23 }
24 
26  : QObject(), useQtSettings(false)
27 {
28  Q_ASSERT(settings != 0);
29  this->settings = 0;
30  this->listenerSettings = settings;
31  this->requestHandler = requestHandler;
32  this->sslConfiguration = 0;
33  loadSslConfig();
34  cleanupTimer.start(settings->cleanupInterval);
35  connect(&cleanupTimer, SIGNAL(timeout()), SLOT(cleanup()));
36 }
37 
39 {
40  // delete all connection handlers and wait until their threads are closed
42  {
43  delete handler;
44  }
45  delete sslConfiguration;
46  qDebug("HttpConnectionHandlerPool (%p): destroyed", this);
47 }
48 
49 
51 {
52  HttpConnectionHandler* freeHandler=0;
53  mutex.lock();
54  // find a free handler in pool
56  {
57  if (!handler->isBusy())
58  {
59  freeHandler=handler;
60  freeHandler->setBusy();
61  break;
62  }
63  }
64  // create a new handler, if necessary
65  if (!freeHandler)
66  {
67  int maxConnectionHandlers = useQtSettings ? settings->value("maxThreads",100).toInt() : listenerSettings->maxThreads;
68  if (pool.count()<maxConnectionHandlers)
69  {
70  if (useQtSettings) {
72  } else {
74  }
75 
76  freeHandler->setBusy();
77  pool.append(freeHandler);
78  }
79  }
80  mutex.unlock();
81  return freeHandler;
82 }
83 
84 
86 {
87  int maxIdleHandlers = useQtSettings ? settings->value("minThreads",1).toInt() : listenerSettings->minThreads;
88  int idleCounter=0;
89  mutex.lock();
91  {
92  if (!handler->isBusy())
93  {
94  if (++idleCounter > maxIdleHandlers)
95  {
96  pool.removeOne(handler);
97  qDebug("HttpConnectionHandlerPool: Removed connection handler (%p), pool size is now %i",handler,pool.size());
98  delete handler;
99  break; // remove only one handler in each interval
100  }
101  }
102  }
103  mutex.unlock();
104 }
105 
106 
108 {
109  // If certificate and key files are configured, then load them
110  QString sslKeyFileName = useQtSettings ? settings->value("sslKeyFile","").toString() : listenerSettings->sslKeyFile;
111  QString sslCertFileName = useQtSettings ? settings->value("sslCertFile","").toString() : listenerSettings->sslCertFile;
112  if (!sslKeyFileName.isEmpty() && !sslCertFileName.isEmpty())
113  {
114  #ifdef QT_NO_OPENSSL
115  qWarning("HttpConnectionHandlerPool::loadSslConfig: SSL is not supported");
116  #else
117  // Convert relative fileNames to absolute, based on the directory of the config file.
118  QFileInfo configFile(settings->fileName());
119  #ifdef Q_OS_WIN32
120  if (QDir::isRelativePath(sslKeyFileName) && settings->format()!=QSettings::NativeFormat)
121  #else
122  if (QDir::isRelativePath(sslKeyFileName))
123  #endif
124  {
125  sslKeyFileName=QFileInfo(configFile.absolutePath(),sslKeyFileName).absoluteFilePath();
126  }
127  #ifdef Q_OS_WIN32
128  if (QDir::isRelativePath(sslCertFileName) && settings->format()!=QSettings::NativeFormat)
129  #else
130  if (QDir::isRelativePath(sslCertFileName))
131  #endif
132  {
133  sslCertFileName=QFileInfo(configFile.absolutePath(),sslCertFileName).absoluteFilePath();
134  }
135 
136  // Load the SSL certificate
137  QFile certFile(sslCertFileName);
138  if (!certFile.open(QIODevice::ReadOnly))
139  {
140  qCritical("HttpConnectionHandlerPool: cannot open sslCertFile %s", qPrintable(sslCertFileName));
141  return;
142  }
143  QSslCertificate certificate(&certFile, QSsl::Pem);
144  certFile.close();
145 
146  // Load the key file
147  QFile keyFile(sslKeyFileName);
148  if (!keyFile.open(QIODevice::ReadOnly))
149  {
150  qCritical("HttpConnectionHandlerPool: cannot open sslKeyFile %s", qPrintable(sslKeyFileName));
151  return;
152  }
153  QSslKey sslKey(&keyFile, QSsl::Rsa, QSsl::Pem);
154  keyFile.close();
155 
156  // Create the SSL configuration
157  sslConfiguration=new QSslConfiguration();
158  sslConfiguration->setLocalCertificate(certificate);
159  sslConfiguration->setPrivateKey(sslKey);
160  sslConfiguration->setPeerVerifyMode(QSslSocket::VerifyNone);
161  sslConfiguration->setProtocol(QSsl::TlsV1SslV3);
162 
163  qDebug("HttpConnectionHandlerPool: SSL settings loaded");
164  #endif
165  }
166 }
HttpConnectionHandlerPool(QSettings *settings, HttpRequestHandler *requestHandler)
QList< HttpConnectionHandler * > pool
const HttpListenerSettings * listenerSettings
void handler(int sig)
Definition: main.cpp:32