cutelyst  5.0.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
tcpsslserver.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "tcpsslserver.h"
6 
7 #include "protocol.h"
8 #include "server.h"
9 #include "socket.h"
10 
11 #ifndef QT_NO_SSL
12 
13 # include <QSslError>
14 
15 using namespace Cutelyst;
16 
17 TcpSslServer::TcpSslServer(const QByteArray &serverAddress,
18  Protocol *protocol,
19  Server *server,
20  QObject *parent)
21  : TcpServer(serverAddress, protocol, server, parent)
22 {
23 }
24 
25 void TcpSslServer::incomingConnection(qintptr handle)
26 {
27  auto sock = new SslSocket(m_engine, this);
28  sock->protoData = m_protocol->createData(sock);
29  sock->setSslConfiguration(m_sslConfiguration);
30 
31  connect(sock, &QIODevice::readyRead, this, [sock]() {
32  sock->timeout = false;
33  sock->proto->parse(sock, sock);
34  });
35  connect(sock, &SslSocket::finished, this, [this, sock]() {
36  sock->deleteLater();
37  if (--m_processing == 0) {
38  m_engine->stopSocketTimeout();
39  }
40  });
41 
42  if (Q_LIKELY(sock->setSocketDescriptor(
44  sock->proto = m_protocol;
45 
46  sock->serverAddress = m_serverAddress;
47  sock->remoteAddress = sock->peerAddress();
48  sock->remotePort = sock->peerPort();
49  sock->protoData->setupNewConnection(sock);
50 
51  for (const auto &opt : m_socketOptions) {
52  sock->setSocketOption(opt.first, opt.second);
53  }
54 
55  if (++m_processing) {
56  m_engine->startSocketTimeout();
57  }
58 
59  sock->startServerEncryption();
60  if (m_http2Protocol) {
61  connect(sock, &SslSocket::encrypted, this, [this, sock]() {
62  if (sock->sslConfiguration().nextNegotiatedProtocol() == "h2") {
63  sock->proto = m_http2Protocol;
64  sock->protoData = sock->proto->createData(sock);
65  }
66  });
67  }
68  } else {
69  delete sock;
70  }
71 }
72 
73 void TcpSslServer::shutdown()
74 {
75  close();
76 
77  if (m_processing == 0) {
78  m_engine->serverShutdown();
79  } else {
80  const auto childrenL = children();
81  for (auto child : childrenL) {
82  auto socket = qobject_cast<TcpSocket *>(child);
83  if (socket) {
84  connect(socket, &TcpSocket::finished, this, [this]() {
85  if (!m_processing) {
86  m_engine->serverShutdown();
87  }
88  });
89  m_engine->handleSocketShutdown(socket);
90  }
91  }
92  }
93 }
94 
95 void TcpSslServer::timeoutConnections()
96 {
97  if (m_processing) {
98  const auto childrenL = children();
99  for (auto child : childrenL) {
100  auto socket = qobject_cast<SslSocket *>(child);
101  if (socket && !socket->processing &&
102  socket->state() == QAbstractSocket::ConnectedState) {
103  if (socket->timeout) {
104  socket->connectionClose();
105  } else {
106  socket->timeout = true;
107  }
108  }
109  }
110  }
111 }
112 
113 void TcpSslServer::setSslConfiguration(const QSslConfiguration &conf)
114 {
115  m_sslConfiguration = conf;
116  conf.allowedNextProtocols();
117 }
118 
119 void TcpSslServer::setHttp2Protocol(Protocol *protocol)
120 {
121  m_http2Protocol = protocol;
122 }
123 
124 # include "moc_tcpsslserver.cpp"
125 
126 #endif // QT_NO_SSL
QList< QByteArray > allowedNextProtocols() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
const QObjectList & children() const const
Implements a web server.
Definition: server.h:59
The Cutelyst namespace holds all public Cutelyst API.
void readyRead()
void encrypted()
T qobject_cast(QObject *object)
void close()