Source code

Revision control

Copy as Markdown

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qhttpserverconfiguration.h"
QT_BEGIN_NAMESPACE
/*!
\class QHttpServerConfiguration
\since 6.9
\inmodule QtHttpServer
\brief The QHttpServerConfiguration class controls server parameters.
*/
class QHttpServerConfigurationPrivate : public QSharedData
{
public:
bool equals(const QHttpServerConfigurationPrivate &other) const noexcept
{
return rateLimit == other.rateLimit
&& maxConnectionsPerHost == other.maxConnectionsPerHost
&& maxConnections == other.maxConnections
&& keepAliveTimeout == other.keepAliveTimeout
&& whitelist == other.whitelist
&& blacklist == other.blacklist
&& maxUrlSize == other.maxUrlSize
&& maxTotalHeaderSize == other.maxTotalHeaderSize
&& maxHeaderFieldSize == other.maxHeaderFieldSize
&& maxNumberOfHeaderFields == other.maxNumberOfHeaderFields
&& maxBodySize == other.maxBodySize;
}
quint32 rateLimit = 0;
quint32 maxConnectionsPerHost = 0;
quint32 maxConnections = 0;
std::chrono::seconds keepAliveTimeout = std::chrono::seconds(15);
QList<std::pair<QHostAddress, int>> whitelist;
QList<std::pair<QHostAddress, int>> blacklist;
qint64 maxUrlSize = 64 * 1024;
qint64 maxTotalHeaderSize = 64 * 1024;
qint64 maxHeaderFieldSize = 48 * 1024;
qint64 maxNumberOfHeaderFields = 128;
qint64 maxBodySize = 32 * 1024 * 1024;
};
QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QHttpServerConfigurationPrivate)
/*!
Default constructs a QHttpServerConfiguration object.
Such a configuration has the following values:
\list
\li Rate limit is disabled.
\li Maximum connections is disabled.
\li Maximum connections per host is disabled.
\li Keep-alive timeout is set to 15 seconds.
\li Whitelist is empty.
\li Blacklist is empty.
\li Maximum Url size is 64 KiB.
\li Maximum total header size is 64 KiB.
\li Maximum header field size is 48 KiB.
\li Maximum number of header fields is 128.
\li Maximum body size is 32 MiB.
\endlist
*/
QHttpServerConfiguration::QHttpServerConfiguration()
: d(new QHttpServerConfigurationPrivate)
{
}
/*!
Copy-constructs this QHttpServerConfiguration.
*/
QHttpServerConfiguration::QHttpServerConfiguration(const QHttpServerConfiguration &) = default;
/*!
\fn QHttpServerConfiguration::QHttpServerConfiguration(QHttpServerConfiguration &&other) noexcept
Move-constructs this QHttpServerConfiguration from \a other
*/
/*!
Copy-assigns \a other to this QHttpServerConfiguration.
*/
QHttpServerConfiguration &QHttpServerConfiguration::operator=(const QHttpServerConfiguration &) = default;
/*!
\fn QHttpServerConfiguration &QHttpServerConfiguration::operator=(QHttpServerConfiguration &&other) noexcept
Move-assigns \a other to this QHttpServerConfiguration.
*/
/*!
Destructor.
*/
QHttpServerConfiguration::~QHttpServerConfiguration()
= default;
/*!
Sets \a maxRequests as the maximum number of incoming requests
per second per IP that will be accepted by QHttpServer.
If the limit is exceeded, QHttpServer will respond with
QHttpServerResponder::StatusCode::TooManyRequests.
This limit is applied separately to each client IP address.
A value of 0 disables rate limiting.
By default, rate limiting is disabled.
\sa rateLimitPerSecond(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setRateLimitPerSecond(quint32 maxRequests)
{
d.detach();
d->rateLimit = maxRequests;
}
/*!
Returns maximum number of incoming requests per second per IP
accepted by the server.
This limit is applied separately to each client IP address.
Returns 0 if rate limiting is disabled.
\sa setRateLimitPerSecond()
*/
quint32 QHttpServerConfiguration::rateLimitPerSecond() const
{
return d->rateLimit;
}
/*!
\since 6.12
Sets limit on \a maxPerHost simultaneous connections
per host that will be accepted by QHttpServer.
If the limit is exceeded, QHttpServer will respond with
QHttpServerResponder::StatusCode::TooManyRequests.
If \a maxPerHost is set to 0, the per-host
connection limit is disabled. This should be done when
running behind a reverse proxy, as all incoming
sockets will appear to originate from the reverse proxy.
When the per-host connection limit is reached, HTTP/1
connections are closed with a 429 (Too Many Requests) response.
For SSL connections the connection is closed when the limit is exceeded.
By default this is disabled.
\sa maximumConnectionsPerHost(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumConnectionsPerHost(quint32 maxPerHost)
{
d.detach();
d->maxConnectionsPerHost = maxPerHost;
}
/*!
\since 6.12
Returns maximum number of simultaneous connections
per host that will be accepted by the server.
The host is identified by the IP address of the incoming TCP
connection.
Returns 0 if the per-host connection limit is disabled.
\sa setMaximumConnectionsPerHost()
*/
quint32 QHttpServerConfiguration::maximumConnectionsPerHost() const
{
return d->maxConnectionsPerHost;
}
/*!
\since 6.12
Sets limit of \a maxConnections on the total simultaneous
connections that will be accepted by the server.
If the limit is reached, the server rejects new connections. For
HTTP/1 connections, QHttpServer responds with
QHttpServerResponder::StatusCode::TooManyRequests and closes the connection.
If \a maxConnections is set to 0, the total connection
limit is disabled.
By default this limit is disabled.
\sa maximumConnections(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumConnections(quint32 maxConnections)
{
d.detach();
d->maxConnections = maxConnections;
}
/*!
\since 6.12
Returns the maximum number of simultaneous connections
accepted by the server in total.
Returns 0 if the total connection limit is disabled.
\sa setMaximumConnections()
*/
quint32 QHttpServerConfiguration::maximumConnections() const
{
return d->maxConnections;
}
/*!
\since 6.10
Sets \a timeout as keep-alive timeout for QHttpServer.
The keep-alive timeout determines how long an idle connection is kept
open before being closed.
By default, the timeout is set to 15 seconds.
\sa keepAliveTimeout()
*/
void QHttpServerConfiguration::setKeepAliveTimeout(std::chrono::seconds timeout)
{
d.detach();
d->keepAliveTimeout = timeout;
}
/*!
\since 6.10
Returns the keep-alive timeout used by QHttpServer.
This is the amount of time an idle connections may remain open
before it is timed out.
\sa setKeepAliveTimeout()
*/
std::chrono::seconds QHttpServerConfiguration::keepAliveTimeout() const
{
return d->keepAliveTimeout;
}
/*!
\since 6.10
Sets \a subnetList as the whitelist of allowed subnets.
When the list is not empty, only IP addresses in this list
will be allowed by QHttpServer. The whitelist takes priority
over the blacklist.
Each subnet is represented as a pair consisting of:
\list
\li A base IP address of type QHostAddress.
\li A CIDR prefix length of type int, which defines the subnet mask.
\endlist
To allow only a specific IP address, use a prefix length of 32 for IPv4
(e.g., \c "192.168.1.100/32") or 128 for IPv6 (e.g., \c "2001:db8::1/128").
By default, the whitelist is empty.
\sa whitelist(), setBlacklist(), QHostAddress::parseSubnet()
*/
void QHttpServerConfiguration::setWhitelist(QSpan<const std::pair<QHostAddress, int>> subnetList)
{
d.detach();
d->whitelist.assign(subnetList.begin(), subnetList.end());
}
/*!
\since 6.10
Returns the whitelist of subnets allowed by QHttpServer.
When the whitelist is not empty, only addresses in the returned subnets
are allowed. The whitelist takes priority over blacklist.
By default, the whitelist is empty.
\sa setWhitelist()
*/
QSpan<const std::pair<QHostAddress, int>> QHttpServerConfiguration::whitelist() const
{
return d->whitelist;
}
/*!
\since 6.10
Sets \a subnetList as the blacklist of subnets.
IP addresses in this list will be denied access by QHttpServer.
The blacklist is active only when the whitelist is empty.
By default, the blacklist is empty.
\sa blacklist(), setWhitelist(), QHostAddress::parseSubnet()
*/
void QHttpServerConfiguration::setBlacklist(QSpan<const std::pair<QHostAddress, int>> subnetList)
{
d.detach();
d->blacklist.assign(subnetList.begin(), subnetList.end());
}
/*!
\since 6.10
Returns the blacklist of subnets that are denied access by QHttpServer.
\sa setBlacklist()
*/
QSpan<const std::pair<QHostAddress, int>> QHttpServerConfiguration::blacklist() const
{
return d->blacklist;
}
/*!
\since 6.11
Sets \a maxSize as the maximum size of the request URL
that the server will accept. If the limit is exceeded,
QHttpServer will respond with status 414 Request-URI
Too Long. If \a maxSize is -1 there is no limit.
The default is 64 KiB.
\sa maximumUrlSize(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumUrlSize(qint64 maxSize)
{
d.detach();
d->maxUrlSize = maxSize;
}
/*!
\since 6.11
Returns the maximum size of the URL accepted by the
server.
\sa setMaximumUrlSize()
*/
qint64 QHttpServerConfiguration::maximumUrlSize() const
{
return d->maxUrlSize;
}
/*!
\since 6.11
Sets \a maxSize as the maximum total size of the header fields
that the server will accept in a request. If the limit
is exceeded, QHttpServer will respond with
status 431 Request Header Fields Too Large.
If \a maxSize is -1 there is no limit.
The default is 64 KiB.
\sa maximumTotalHeaderSize(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumTotalHeaderSize(qint64 maxSize)
{
d.detach();
d->maxTotalHeaderSize = maxSize;
}
/*!
\since 6.11
Returns the maximum size of the total incoming headers accepted
by the server.
\sa setMaximumTotalHeaderSize()
*/
qint64 QHttpServerConfiguration::maximumTotalHeaderSize() const
{
return d->maxTotalHeaderSize;
}
/*!
\since 6.11
Sets \a maxSize as the maximum size of any single header
field that the server will accept in a request. If the limit
is exceeded, QHttpServer will respond with status
431 Request Header Fields Too Large. If \a maxSize is -1
there is no limit.
The default is 48 KiB.
\sa maximumHeaderFieldSize(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumHeaderFieldSize(qint64 maxSize)
{
d.detach();
d->maxHeaderFieldSize = maxSize;
}
/*!
\since 6.11
Returns the maximum size of each incoming header field accepted
by the server.
\sa setMaximumHeaderFieldSize()
*/
qint64 QHttpServerConfiguration::maximumHeaderFieldSize() const
{
return d->maxHeaderFieldSize;
}
/*!
\since 6.11
Sets \a maxSize as the maximum number of header fields
that the server will accept in a request.
If the limit is exceeded, QHttpServer will respond with
status 431 Request Header Fields Too Large.
If \a maxSize is -1 there is no limit.
The default is 128.
\sa maximumHeaderFieldCount(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumHeaderFieldCount(qint64 maxSize)
{
d.detach();
d->maxNumberOfHeaderFields = maxSize;
}
/*!
\since 6.11
Returns the maximum number of incoming header fields accepted
by the server.
\sa setMaximumHeaderFieldCount()
*/
qint64 QHttpServerConfiguration::maximumHeaderFieldCount() const
{
return d->maxNumberOfHeaderFields;
}
/*!
\since 6.11
Sets \a maxSize as the maximum size of the request body
that the server will accept. If the limit is exceeded,
QHttpServer will respond with status 413 Content Too Large.
If \a maxSize is -1 there is no limit.
The default is 32 MiB.
\sa maximumBodySize(), QHttpServerResponder::StatusCode
*/
void QHttpServerConfiguration::setMaximumBodySize(qint64 maxSize)
{
d.detach();
d->maxBodySize = maxSize;
}
/*!
\since 6.11
Returns the maximum size of the incoming body accepted
by the server.
\sa setMaximumBodySize()
*/
qint64 QHttpServerConfiguration::maximumBodySize() const
{
return d->maxBodySize;
}
/*!
\fn void QHttpServerConfiguration::swap(QHttpServerConfiguration &other)
\memberswap{configuration}
*/
/*!
\fn bool QHttpServerConfiguration::operator==(const QHttpServerConfiguration &lhs, const QHttpServerConfiguration &rhs) noexcept
Returns \c true if \a lhs and \a rhs have the same set of configuration
parameters.
*/
/*!
\fn bool QHttpServerConfiguration::operator!=(const QHttpServerConfiguration &lhs, const QHttpServerConfiguration &rhs) noexcept
Returns \c true if \a lhs and \a rhs do not have the same set of configuration
parameters.
*/
/*!
\internal
*/
bool comparesEqual(const QHttpServerConfiguration &lhs, const QHttpServerConfiguration &rhs) noexcept
{
return lhs.d == rhs.d || lhs.d->equals(*rhs.d);
}
QT_END_NAMESPACE