| 1 | // Copyright (C) 2024 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
| 3 | // Qt-Security score:significant reason:default |
| 4 | |
| 5 | #include "qhttpserverconfiguration.h" |
| 6 | |
| 7 | QT_BEGIN_NAMESPACE |
| 8 | |
| 9 | /*! |
| 10 | \class QHttpServerConfiguration |
| 11 | \since 6.9 |
| 12 | \inmodule QtHttpServer |
| 13 | \brief The QHttpServerConfiguration class controls server parameters. |
| 14 | */ |
| 15 | class QHttpServerConfigurationPrivate : public QSharedData |
| 16 | { |
| 17 | public: |
| 18 | bool equals(const QHttpServerConfigurationPrivate &other) const noexcept |
| 19 | { |
| 20 | return rateLimit == other.rateLimit |
| 21 | && keepAliveTimeout == other.keepAliveTimeout |
| 22 | && whitelist == other.whitelist |
| 23 | && blacklist == other.blacklist; |
| 24 | } |
| 25 | |
| 26 | quint32 rateLimit = 0; |
| 27 | std::chrono::seconds keepAliveTimeout = std::chrono::seconds(15); |
| 28 | QList<QPair<QHostAddress, int>> whitelist; |
| 29 | QList<QPair<QHostAddress, int>> blacklist; |
| 30 | }; |
| 31 | |
| 32 | QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QHttpServerConfigurationPrivate) |
| 33 | |
| 34 | /*! |
| 35 | Default constructs a QHttpServerConfiguration object. |
| 36 | |
| 37 | Such a configuration has the following values: |
| 38 | \list |
| 39 | \li Rate limit is disabled |
| 40 | \endlist |
| 41 | */ |
| 42 | QHttpServerConfiguration::QHttpServerConfiguration() |
| 43 | : d(new QHttpServerConfigurationPrivate) |
| 44 | { |
| 45 | } |
| 46 | |
| 47 | /*! |
| 48 | Copy-constructs this QHttpServerConfiguration. |
| 49 | */ |
| 50 | QHttpServerConfiguration::QHttpServerConfiguration(const QHttpServerConfiguration &) = default; |
| 51 | |
| 52 | /*! |
| 53 | \fn QHttpServerConfiguration::QHttpServerConfiguration(QHttpServerConfiguration &&other) noexcept |
| 54 | |
| 55 | Move-constructs this QHttpServerConfiguration from \a other |
| 56 | */ |
| 57 | |
| 58 | /*! |
| 59 | Copy-assigns \a other to this QHttpServerConfiguration. |
| 60 | */ |
| 61 | QHttpServerConfiguration &QHttpServerConfiguration::operator=(const QHttpServerConfiguration &) = default; |
| 62 | |
| 63 | /*! |
| 64 | \fn QHttpServerConfiguration &QHttpServerConfiguration::operator=(QHttpServerConfiguration &&other) noexcept |
| 65 | |
| 66 | Move-assigns \a other to this QHttpServerConfiguration. |
| 67 | */ |
| 68 | |
| 69 | /*! |
| 70 | Destructor. |
| 71 | */ |
| 72 | QHttpServerConfiguration::~QHttpServerConfiguration() |
| 73 | = default; |
| 74 | |
| 75 | /*! |
| 76 | Sets \a maxRequests as the maximum number of incoming requests |
| 77 | per second per IP that will be accepted by QHttpServer. |
| 78 | If the limit is exceeded, QHttpServer will respond with |
| 79 | QHttpServerResponder::StatusCode::TooManyRequests. |
| 80 | |
| 81 | \sa rateLimitPerSecond(), QHttpServerResponder::StatusCode |
| 82 | */ |
| 83 | void QHttpServerConfiguration::setRateLimitPerSecond(quint32 maxRequests) |
| 84 | { |
| 85 | d.detach(); |
| 86 | d->rateLimit = maxRequests; |
| 87 | } |
| 88 | |
| 89 | /*! |
| 90 | Returns maximum number of incoming requests per second per IP |
| 91 | accepted by the server. |
| 92 | |
| 93 | \sa setRateLimitPerSecond() |
| 94 | */ |
| 95 | quint32 QHttpServerConfiguration::rateLimitPerSecond() const |
| 96 | { |
| 97 | return d->rateLimit; |
| 98 | } |
| 99 | |
| 100 | /*! |
| 101 | \since 6.10 |
| 102 | |
| 103 | Sets \a timeout as keep-alive timeout for QHttpServer. |
| 104 | |
| 105 | The keep-alive timeout determines how long an idle connection is kept |
| 106 | open before being closed. |
| 107 | By default, the timeout is set to 15 seconds. |
| 108 | |
| 109 | \sa keepAliveTimeout() |
| 110 | */ |
| 111 | void QHttpServerConfiguration::setKeepAliveTimeout(std::chrono::seconds timeout) |
| 112 | { |
| 113 | d.detach(); |
| 114 | d->keepAliveTimeout = timeout; |
| 115 | } |
| 116 | |
| 117 | /*! |
| 118 | \since 6.10 |
| 119 | |
| 120 | Returns the keep-alive timeout used by QHttpServer. |
| 121 | |
| 122 | \sa setKeepAliveTimeout() |
| 123 | */ |
| 124 | std::chrono::seconds QHttpServerConfiguration::keepAliveTimeout() const |
| 125 | { |
| 126 | return d->keepAliveTimeout; |
| 127 | } |
| 128 | |
| 129 | /*! |
| 130 | \since 6.10 |
| 131 | |
| 132 | Sets \a subnetList as the whitelist of allowed subnets. |
| 133 | |
| 134 | When the list is not empty, only IP addresses in this list |
| 135 | will be allowed by QHttpServer. The whitelist takes priority |
| 136 | over the blacklist. |
| 137 | |
| 138 | Each subnet is represented as a pair consisting of: |
| 139 | \list |
| 140 | \li A base IP address of type QHostAddress. |
| 141 | \li A CIDR prefix length of type int, which defines the subnet mask. |
| 142 | \endlist |
| 143 | |
| 144 | To allow only a specific IP address, use a prefix length of 32 for IPv4 |
| 145 | (e.g., \c "192.168.1.100/32") or 128 for IPv6 (e.g., \c "2001:db8::1/128"). |
| 146 | |
| 147 | \sa whitelist(), setBlacklist(), QHostAddress::parseSubnet() |
| 148 | */ |
| 149 | void QHttpServerConfiguration::setWhitelist(QSpan<const std::pair<QHostAddress, int>> subnetList) |
| 150 | { |
| 151 | d.detach(); |
| 152 | d->whitelist.assign(first: subnetList.begin(), last: subnetList.end()); |
| 153 | } |
| 154 | |
| 155 | /*! |
| 156 | \since 6.10 |
| 157 | |
| 158 | Returns the whitelist of subnets allowed by QHttpServer. |
| 159 | |
| 160 | \sa setWhitelist() |
| 161 | */ |
| 162 | QSpan<const std::pair<QHostAddress, int>> QHttpServerConfiguration::whitelist() const |
| 163 | { |
| 164 | return d->whitelist; |
| 165 | } |
| 166 | |
| 167 | /*! |
| 168 | \since 6.10 |
| 169 | |
| 170 | Sets \a subnetList as the blacklist of subnets. |
| 171 | |
| 172 | IP addresses in this list will be denied access by QHttpServer. |
| 173 | The blacklist is active only when the whitelist is empty. |
| 174 | |
| 175 | \sa blacklist(), setWhitelist(), QHostAddress::parseSubnet() |
| 176 | */ |
| 177 | void QHttpServerConfiguration::setBlacklist(QSpan<const std::pair<QHostAddress, int>> subnetList) |
| 178 | { |
| 179 | d.detach(); |
| 180 | d->blacklist.assign(first: subnetList.begin(), last: subnetList.end()); |
| 181 | } |
| 182 | |
| 183 | /*! |
| 184 | \since 6.10 |
| 185 | |
| 186 | Returns the blacklist of subnets that are denied access by QHttpServer. |
| 187 | |
| 188 | \sa setBlacklist() |
| 189 | */ |
| 190 | QSpan<const std::pair<QHostAddress, int>> QHttpServerConfiguration::blacklist() const |
| 191 | { |
| 192 | return d->blacklist; |
| 193 | } |
| 194 | |
| 195 | /*! |
| 196 | \fn void QHttpServerConfiguration::swap(QHttpServerConfiguration &other) |
| 197 | \memberswap{configuration} |
| 198 | */ |
| 199 | |
| 200 | /*! |
| 201 | \fn bool QHttpServerConfiguration::operator==(const QHttpServerConfiguration &lhs, const QHttpServerConfiguration &rhs) noexcept |
| 202 | Returns \c true if \a lhs and \a rhs have the same set of configuration |
| 203 | parameters. |
| 204 | */ |
| 205 | |
| 206 | /*! |
| 207 | \fn bool QHttpServerConfiguration::operator!=(const QHttpServerConfiguration &lhs, const QHttpServerConfiguration &rhs) noexcept |
| 208 | Returns \c true if \a lhs and \a rhs do not have the same set of configuration |
| 209 | parameters. |
| 210 | */ |
| 211 | |
| 212 | /*! |
| 213 | \internal |
| 214 | */ |
| 215 | bool comparesEqual(const QHttpServerConfiguration &lhs, const QHttpServerConfiguration &rhs) noexcept |
| 216 | { |
| 217 | return lhs.d == rhs.d || lhs.d->equals(other: *rhs.d); |
| 218 | } |
| 219 | |
| 220 | QT_END_NAMESPACE |
| 221 | |