Small refactoring of QHttpServerRequest and QAbstractHttpServer

1. Move initialization of httpParser from QAbstractHttpServer
to QHttpServerRequest.

2. Simplify access to an upgrade header value from a request.
httpParser sets an upgrade flag only if the request has two headers
or the request is HTTP CONNECT method.

Change-Id: I39c2325558a58679e40d38e46706cd61ef36d327
Reviewed-by: Mikhail Svetkin <mikhail.svetkin@gmail.com>
This commit is contained in:
Mikhail Svetkin 2020-02-17 23:32:02 +01:00
parent a96d975ea8
commit 65ba5db9e0
2 changed files with 19 additions and 23 deletions

View File

@ -58,8 +58,6 @@ void QAbstractHttpServerPrivate::handleNewConnections()
Q_ASSERT(tcpServer);
while (auto socket = tcpServer->nextPendingConnection()) {
auto request = new QHttpServerRequest(socket->peerAddress()); // TODO own tcp server could pre-allocate it
http_parser_init(&request->d->httpParser, HTTP_REQUEST);
QObject::connect(socket, &QTcpSocket::readyRead, q_ptr,
[this, request, socket] () {
handleReadyRead(socket, request);
@ -94,30 +92,27 @@ void QAbstractHttpServerPrivate::handleReadyRead(QTcpSocket *socket,
request->d->state != QHttpServerRequestPrivate::State::OnMessageComplete)
return; // Partial read
if (request->d->httpParser.upgrade) { // Upgrade
const auto &headers = request->d->headers;
const auto upgradeHash = request->d->headerHash(QByteArrayLiteral("upgrade"));
const auto it = headers.find(upgradeHash);
if (it != headers.end()) {
if (request->d->httpParser.upgrade &&
request->d->httpParser.method != HTTP_CONNECT) { // Upgrade
const auto &upgradeValue = request->value(QByteArrayLiteral("upgrade"));
#if defined(QT_WEBSOCKETS_LIB)
if (it.value().second.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) {
static const auto signal = QMetaMethod::fromSignal(
&QAbstractHttpServer::newWebSocketConnection);
if (q->isSignalConnected(signal)) {
QObject::disconnect(socket, &QTcpSocket::readyRead, nullptr, nullptr);
socket->rollbackTransaction();
websocketServer.handleConnection(socket);
Q_EMIT socket->readyRead();
} else {
qWarning(lcHttpServer, "WebSocket received but no slots connected to "
"QWebSocketServer::newConnection");
socket->disconnectFromHost();
}
return;
if (upgradeValue.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) {
static const auto signal = QMetaMethod::fromSignal(
&QAbstractHttpServer::newWebSocketConnection);
if (q->isSignalConnected(signal)) {
QObject::disconnect(socket, &QTcpSocket::readyRead, nullptr, nullptr);
socket->rollbackTransaction();
websocketServer.handleConnection(socket);
Q_EMIT socket->readyRead();
} else {
qWarning(lcHttpServer, "WebSocket received but no slots connected to "
"QWebSocketServer::newConnection");
socket->disconnectFromHost();
}
#endif
qCWarning(lcHttpServer, "Upgrade to %s not supported", it.value().second.constData());
return;
}
#endif
qCWarning(lcHttpServer, "Upgrade to %s not supported", upgradeValue.constData());
socket->disconnectFromHost();
return;
}

View File

@ -94,6 +94,7 @@ QHttpServerRequestPrivate::QHttpServerRequestPrivate(const QHostAddress &remoteA
: remoteAddress(remoteAddress)
{
httpParser.data = this;
http_parser_init(&httpParser, HTTP_REQUEST);
}
QByteArray QHttpServerRequestPrivate::header(const QByteArray &key) const