summaryrefslogtreecommitdiffstats
path: root/src/network/access/qhttp2configuration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/access/qhttp2configuration.cpp')
-rw-r--r--src/network/access/qhttp2configuration.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/network/access/qhttp2configuration.cpp b/src/network/access/qhttp2configuration.cpp
new file mode 100644
index 0000000000..14c9d6dc29
--- /dev/null
+++ b/src/network/access/qhttp2configuration.cpp
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhttp2configuration.h"
+
+#include "private/http2protocol_p.h"
+#include "private/hpack_p.h"
+
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QHttp2Configuration
+ \brief The QHttp2Configuration class controls HTTP/2 parameters and settings
+ \since 5.14
+
+ \reentrant
+ \inmodule QtNetwork
+ \ingroup network
+ \ingroup shared
+
+ QHttp2Configuration controls HTTP/2 parameters and settings that
+ QNetworkAccessManager will use to send requests and process responses
+ when the HTTP/2 protocol is enabled.
+
+ The HTTP/2 parameters that QHttp2Configuration currently supports include:
+
+ \list
+ \li The session window size for connection-level flow control.
+ Will be sent to a remote peer when needed as 'WINDOW_UPDATE'
+ frames on the stream with an identifier 0.
+ \li The stream receiving window size for stream-level flow control.
+ Sent as 'SETTINGS_INITIAL_WINDOW_SIZE' parameter in the initial
+ SETTINGS frame and, when needed, 'WINDOW_UPDATE' frames will be
+ sent on streams that QNetworkAccessManager opens.
+ \li The maximum frame size. This parameter limits the maximum payload
+ a frame coming from the remote peer can have. Sent by QNetworkAccessManager
+ as 'SETTINGS_MAX_FRAME_SIZE' parameter in the initial 'SETTINGS'
+ frame.
+ \li The server push. Allows to enable or disable server push. Sent
+ as 'SETTINGS_ENABLE_PUSH' parameter in the initial 'SETTINGS'
+ frame.
+ \endlist
+
+ The QHttp2Configuration class also controls some of the parameters
+ affecting the header compression algorithm (HPACK). They include:
+
+ \list
+ \li Huffman string compression.
+ \li Indexing strings.
+ \endlist
+
+ \note The configuration must be set before the first request
+ was sent to a given host (and thus an HTTP/2 session established).
+
+ \note Details about flow control, server push and 'SETTINGS'
+ can be found in \l {https://httpwg.org/specs/rfc7540.html}{RFC 7540}.
+ Different modes and parameters of the HPACK compression algorithm
+ are described in \l {https://httpwg.org/specs/rfc7541.html}{RFC 7541}.
+
+ \sa QNetworkRequest::setHttp2Configuration(), QNetworkRequest::http2Configuration(), QNetworkAccessManager
+*/
+
+class QHttp2ConfigurationPrivate : public QSharedData
+{
+public:
+ unsigned sessionWindowSize = Http2::defaultSessionWindowSize;
+ // The size below is quite a limiting default value, QNetworkRequest
+ // by default sets a larger number, an application can change this using
+ // QNetworkRequest::setHttp2Configuration.
+ unsigned streamWindowSize = Http2::defaultSessionWindowSize;
+
+ unsigned maxFrameSize = Http2::minPayloadLimit; // Initial (default) value of 16Kb.
+
+ bool pushEnabled = false;
+ // TODO: for now those two below are noop.
+ bool huffmanCompressionEnabled = true;
+ bool indexingEnabled = true;
+};
+
+/*!
+ Default constructs a QHttp2Configuration object.
+
+ Such a configuration has the following values:
+ \list
+ \li Server push is disabled
+ \li Huffman string compression is enabled
+ \li String indexing is enabled
+ \li Window size for connection-level flow control is 65535 octets
+ \li Window size for stream-level flow control is 65535 octets
+ \li Frame size is 16384 octets
+ \endlist
+*/
+QHttp2Configuration::QHttp2Configuration()
+ : d(new QHttp2ConfigurationPrivate)
+{
+}
+
+/*!
+ Copy-constructs this QHttp2Configuration.
+*/
+QHttp2Configuration::QHttp2Configuration(const QHttp2Configuration &) = default;
+
+/*!
+ Move-constructs this QHttp2Configuration from \a other
+*/
+QHttp2Configuration::QHttp2Configuration(QHttp2Configuration &&other) noexcept
+{
+ swap(other);
+}
+
+/*!
+ Copy-assigns to this QHttp2Configuration.
+*/
+QHttp2Configuration &QHttp2Configuration::operator=(const QHttp2Configuration &) = default;
+
+/*!
+ Move-assigns to this QHttp2Configuration.
+*/
+QHttp2Configuration &QHttp2Configuration::operator=(QHttp2Configuration &&) noexcept = default;
+
+/*!
+ Destructor.
+*/
+QHttp2Configuration::~QHttp2Configuration()
+{
+}
+
+/*!
+ If \a enable is \c true, a remote server can potentially
+ use server push to send reponses in advance.
+
+ \sa serverPushEnabled
+*/
+void QHttp2Configuration::setServerPushEnabled(bool enable)
+{
+ d->pushEnabled = enable;
+}
+
+/*!
+ Returns true if server push was enabled.
+
+ \note By default, QNetworkAccessManager disables server
+ push via the 'SETTINGS' frame.
+
+ \sa setServerPushEnabled
+*/
+bool QHttp2Configuration::serverPushEnabled() const
+{
+ return d->pushEnabled;
+}
+
+/*!
+ If \a enable is \c true, HPACK compression will additionally
+ compress string using the Huffman coding. Enabled by default.
+
+ \note This parameter only affects 'HEADERS' frames that
+ QNetworkAccessManager is sending.
+
+ \sa huffmanCompressionEnabled
+*/
+void QHttp2Configuration::setHuffmanCompressionEnabled(bool enable)
+{
+ d->huffmanCompressionEnabled = enable;
+}
+
+/*!
+ Returns \c true if the Huffman coding in HPACK is enabled.
+
+ \sa setHuffmanCompressionEnabled
+*/
+bool QHttp2Configuration::huffmanCompressionEnabled() const
+{
+ return d->huffmanCompressionEnabled;
+}
+
+/*!
+ If \a enable is \c true, HPACK compression will index strings
+ in its dynamic compression table. Enabled by default.
+
+ \note This setting only has an affect on how QNetworkAccessManager
+ sending 'HEADERS' frames.
+
+ \sa stringIndexingEnabled
+*/
+void QHttp2Configuration::setStringIndexingEnabled(bool enable)
+{
+ d->indexingEnabled = enable;
+}
+
+/*!
+ Returns \true if HPACK compression is indexing strings.
+
+ \sa setStringIndexingEnabled
+*/
+bool QHttp2Configuration::stringIndexingEnabled() const
+{
+ return d->indexingEnabled;
+}
+
+/*!
+ Sets the window size for connection-level flow control.
+ \a size cannot be 0 and must not exceed 2147483647 octets.
+
+ \sa sessionReceiveWindowSize
+*/
+bool QHttp2Configuration::setSessionReceiveWindowSize(unsigned size)
+{
+ if (!size || size > Http2::maxSessionReceiveWindowSize) { // RFC-7540, 6.9
+ qCWarning(QT_HTTP2) << "Invalid session window size";
+ return false;
+ }
+
+ d->sessionWindowSize = size;
+ return true;
+}
+
+/*!
+ Returns the window size for connection-level flow control.
+ The default value QNetworkAccessManager will be using is
+ 2147483647 octets.
+*/
+unsigned QHttp2Configuration::sessionReceiveWindowSize() const
+{
+ return d->sessionWindowSize;
+}
+
+/*!
+ Sets the window size for stream-level flow control.
+ \a size cannot be 0 and must not exceed 2147483647 octets.
+
+ \sa streamReceiveWindowSize
+ */
+bool QHttp2Configuration::setStreamReceiveWindowSize(unsigned size)
+{
+ if (!size || size > Http2::maxSessionReceiveWindowSize) { // RFC-7540, 6.9
+ qCWarning(QT_HTTP2) << "Invalid stream window size";
+ return false;
+ }
+
+ d->streamWindowSize = size;
+ return true;
+}
+
+/*!
+ Returns the window size for stream-level flow control.
+ The default value QNetworkAccessManager will be using is
+ 21474836 octets.
+*/
+unsigned QHttp2Configuration::streamReceiveWindowSize() const
+{
+ return d->streamWindowSize;
+}
+
+/*!
+ Sets the maximum frame size that QNetworkAccessManager
+ will advertise to the server when sending its initial SETTINGS frame.
+ \note While this \a size is required to be within a range between
+ 16384 and 16777215 inclusive, the actual payload size in frames
+ that carry payload maybe be less than 16384.
+*/
+bool QHttp2Configuration::setMaxFrameSize(unsigned size)
+{
+ if (size < Http2::minPayloadLimit || size > Http2::maxPayloadSize) {
+ qCWarning(QT_HTTP2) << "Maximum frame size to advertise is invalid";
+ return false;
+ }
+
+ d->maxFrameSize = size;
+ return true;
+}
+
+/*!
+ The maximum payload size that HTTP/2 frames can
+ have. The default (initial) value is 16384 octets.
+*/
+unsigned QHttp2Configuration::maxFrameSize() const
+{
+ return d->maxFrameSize;
+}
+
+/*!
+ Swaps this configuration with the \a other configuration.
+*/
+void QHttp2Configuration::swap(QHttp2Configuration &other) noexcept
+{
+ d.swap(other.d);
+}
+
+/*!
+ Returns \c true if \a lhs and \a rhs have the same set of HTTP/2
+ parameters.
+*/
+bool operator==(const QHttp2Configuration &lhs, const QHttp2Configuration &rhs)
+{
+ if (lhs.d == rhs.d)
+ return true;
+
+ return lhs.d->pushEnabled == rhs.d->pushEnabled
+ && lhs.d->huffmanCompressionEnabled == rhs.d->huffmanCompressionEnabled
+ && lhs.d->indexingEnabled == rhs.d->indexingEnabled
+ && lhs.d->sessionWindowSize == rhs.d->sessionWindowSize
+ && lhs.d->streamWindowSize == rhs.d->streamWindowSize;
+}
+
+QT_END_NAMESPACE