QNetworkAccessManager: Configurable number of HTTP1 TCP connections
Introduces new class QHttp1Configuration. [ChangeLog][QtNetwork][QHttp1Configuration] New class. Fixes: QTBUG-25280 Fixes: QTBUG-108215 Change-Id: Ide6cee23946e5001befb8fab34edf10b8a66e02b Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
a09c33e1f7
commit
be05bb749e
@ -121,6 +121,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_http
|
|||||||
access/http2/huffman.cpp access/http2/huffman_p.h
|
access/http2/huffman.cpp access/http2/huffman_p.h
|
||||||
access/qabstractprotocolhandler.cpp access/qabstractprotocolhandler_p.h
|
access/qabstractprotocolhandler.cpp access/qabstractprotocolhandler_p.h
|
||||||
access/qdecompresshelper.cpp access/qdecompresshelper_p.h
|
access/qdecompresshelper.cpp access/qdecompresshelper_p.h
|
||||||
|
access/qhttp1configuration.cpp access/qhttp1configuration.h
|
||||||
access/qhttp2configuration.cpp access/qhttp2configuration.h
|
access/qhttp2configuration.cpp access/qhttp2configuration.h
|
||||||
access/qhttp2protocolhandler.cpp access/qhttp2protocolhandler_p.h
|
access/qhttp2protocolhandler.cpp access/qhttp2protocolhandler_p.h
|
||||||
access/qhttpmultipart.cpp access/qhttpmultipart.h access/qhttpmultipart_p.h
|
access/qhttpmultipart.cpp access/qhttpmultipart.h access/qhttpmultipart_p.h
|
||||||
|
125
src/network/access/qhttp1configuration.cpp
Normal file
125
src/network/access/qhttp1configuration.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
#include "qhttp1configuration.h"
|
||||||
|
|
||||||
|
#include "qdebug.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QHttp1Configuration
|
||||||
|
\brief The QHttp1Configuration class controls HTTP/1 parameters and settings.
|
||||||
|
\since 6.5
|
||||||
|
|
||||||
|
\reentrant
|
||||||
|
\inmodule QtNetwork
|
||||||
|
\ingroup network
|
||||||
|
\ingroup shared
|
||||||
|
|
||||||
|
QHttp1Configuration controls HTTP/1 parameters and settings that
|
||||||
|
QNetworkAccessManager will use to send requests and process responses.
|
||||||
|
|
||||||
|
\note The configuration must be set before the first request
|
||||||
|
was sent to a given host (and thus an HTTP/1 session established).
|
||||||
|
|
||||||
|
\sa QNetworkRequest::setHttp1Configuration(), QNetworkRequest::http1Configuration(), QNetworkAccessManager
|
||||||
|
*/
|
||||||
|
|
||||||
|
class QHttp1ConfigurationPrivate : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned numberOfConnectionsPerHost = 6; // QHttpNetworkConnectionPrivate::defaultHttpChannelCount
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Default constructs a QHttp1Configuration object.
|
||||||
|
*/
|
||||||
|
QHttp1Configuration::QHttp1Configuration()
|
||||||
|
: d(new QHttp1ConfigurationPrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Copy-constructs this QHttp1Configuration.
|
||||||
|
*/
|
||||||
|
QHttp1Configuration::QHttp1Configuration(const QHttp1Configuration &) = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Move-constructs this QHttp1Configuration from \a other
|
||||||
|
*/
|
||||||
|
QHttp1Configuration::QHttp1Configuration(QHttp1Configuration &&other) noexcept
|
||||||
|
{
|
||||||
|
swap(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Copy-assigns \a other to this QHttp1Configuration.
|
||||||
|
*/
|
||||||
|
QHttp1Configuration &QHttp1Configuration::operator=(const QHttp1Configuration &) = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Move-assigns \a other to this QHttp1Configuration.
|
||||||
|
*/
|
||||||
|
QHttp1Configuration &QHttp1Configuration::operator=(QHttp1Configuration &&) noexcept = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destructor.
|
||||||
|
*/
|
||||||
|
QHttp1Configuration::~QHttp1Configuration()
|
||||||
|
= default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets number of connections (default 6) to a http(s)://host:port
|
||||||
|
\sa numberOfConnectionsPerHost
|
||||||
|
*/
|
||||||
|
void QHttp1Configuration::setNumberOfConnectionsPerHost(unsigned number)
|
||||||
|
{
|
||||||
|
if (number == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d->numberOfConnectionsPerHost = number;
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
Returns the number of connections (default 6) to a http(s)://host:port
|
||||||
|
\sa setNumberOfConnectionsPerHost
|
||||||
|
*/
|
||||||
|
unsigned QHttp1Configuration::numberOfConnectionsPerHost() const
|
||||||
|
{
|
||||||
|
return d->numberOfConnectionsPerHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Swaps this configuration with the \a other configuration.
|
||||||
|
*/
|
||||||
|
void QHttp1Configuration::swap(QHttp1Configuration &other) noexcept
|
||||||
|
{
|
||||||
|
d.swap(other.d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QHttp1Configuration::operator==(const QHttp1Configuration &lhs, const QHttp1Configuration &rhs) noexcept
|
||||||
|
|
||||||
|
Returns \c true if \a lhs and \a rhs represent the same set of HTTP/1
|
||||||
|
parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QHttp1Configuration::operator!=(const QHttp1Configuration &lhs, const QHttp1Configuration &rhs) noexcept
|
||||||
|
|
||||||
|
Returns \c true if \a lhs and \a rhs do not represent the same set of
|
||||||
|
HTTP/1 parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
*/
|
||||||
|
bool QHttp1Configuration::isEqual(const QHttp1Configuration &other) const noexcept
|
||||||
|
{
|
||||||
|
if (d == other.d)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return d->numberOfConnectionsPerHost == other.d->numberOfConnectionsPerHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
51
src/network/access/qhttp1configuration.h
Normal file
51
src/network/access/qhttp1configuration.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
#ifndef QHTTP1CONFIGURATION_H
|
||||||
|
#define QHTTP1CONFIGURATION_H
|
||||||
|
|
||||||
|
#include <QtNetwork/qtnetworkglobal.h>
|
||||||
|
|
||||||
|
#include <QtCore/qshareddata.h>
|
||||||
|
|
||||||
|
#ifndef Q_CLANG_QDOC
|
||||||
|
QT_REQUIRE_CONFIG(http);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QHttp1ConfigurationPrivate;
|
||||||
|
class Q_NETWORK_EXPORT QHttp1Configuration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QHttp1Configuration();
|
||||||
|
QHttp1Configuration(const QHttp1Configuration &other);
|
||||||
|
QHttp1Configuration(QHttp1Configuration &&other) noexcept;
|
||||||
|
|
||||||
|
QHttp1Configuration &operator=(const QHttp1Configuration &other);
|
||||||
|
QHttp1Configuration &operator=(QHttp1Configuration &&other) noexcept;
|
||||||
|
|
||||||
|
~QHttp1Configuration();
|
||||||
|
|
||||||
|
void setNumberOfConnectionsPerHost(unsigned amount);
|
||||||
|
unsigned numberOfConnectionsPerHost() const;
|
||||||
|
|
||||||
|
void swap(QHttp1Configuration &other) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedDataPointer<QHttp1ConfigurationPrivate> d;
|
||||||
|
|
||||||
|
bool isEqual(const QHttp1Configuration &other) const noexcept;
|
||||||
|
|
||||||
|
friend bool operator==(const QHttp1Configuration &lhs, const QHttp1Configuration &rhs) noexcept
|
||||||
|
{ return lhs.isEqual(rhs); }
|
||||||
|
friend bool operator!=(const QHttp1Configuration &lhs, const QHttp1Configuration &rhs) noexcept
|
||||||
|
{ return !lhs.isEqual(rhs); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_SHARED(QHttp1Configuration)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QHTTP1CONFIGURATION_H
|
@ -32,6 +32,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
// Note: Only used from auto tests, normal usage is via QHttp1Configuration
|
||||||
const int QHttpNetworkConnectionPrivate::defaultHttpChannelCount = 6;
|
const int QHttpNetworkConnectionPrivate::defaultHttpChannelCount = 6;
|
||||||
|
|
||||||
// The pipeline length. So there will be 4 requests in flight.
|
// The pipeline length. So there will be 4 requests in flight.
|
||||||
@ -69,7 +70,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 connectionC
|
|||||||
QHttpNetworkConnection::ConnectionType type)
|
QHttpNetworkConnection::ConnectionType type)
|
||||||
: state(RunningState), networkLayerState(Unknown),
|
: state(RunningState), networkLayerState(Unknown),
|
||||||
hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true),
|
hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true),
|
||||||
activeChannelCount(connectionCount), channelCount(connectionCount)
|
channelCount(connectionCount)
|
||||||
#ifndef QT_NO_NETWORKPROXY
|
#ifndef QT_NO_NETWORKPROXY
|
||||||
, networkProxy(QNetworkProxy::NoProxy)
|
, networkProxy(QNetworkProxy::NoProxy)
|
||||||
#endif
|
#endif
|
||||||
@ -77,6 +78,14 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 connectionC
|
|||||||
, connectionType(type)
|
, connectionType(type)
|
||||||
{
|
{
|
||||||
channels = new QHttpNetworkConnectionChannel[channelCount];
|
channels = new QHttpNetworkConnectionChannel[channelCount];
|
||||||
|
|
||||||
|
activeChannelCount = (type == QHttpNetworkConnection::ConnectionTypeHTTP2 ||
|
||||||
|
type == QHttpNetworkConnection::ConnectionTypeHTTP2Direct)
|
||||||
|
? 1 : connectionCount;
|
||||||
|
// We allocate all 6 channels even if it's an HTTP/2-enabled
|
||||||
|
// connection: in case the protocol negotiation via NPN/ALPN fails,
|
||||||
|
// we will have normally working HTTP/1.1.
|
||||||
|
Q_ASSERT(channelCount >= activeChannelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,9 +145,9 @@ class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection,
|
|||||||
{
|
{
|
||||||
// Q_OBJECT
|
// Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt,
|
QNetworkAccessCachedHttpConnection(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt,
|
||||||
QHttpNetworkConnection::ConnectionType connectionType)
|
QHttpNetworkConnection::ConnectionType connectionType)
|
||||||
: QHttpNetworkConnection(hostName, port, encrypt, connectionType)
|
: QHttpNetworkConnection(connectionCount, hostName, port, encrypt, /*parent=*/nullptr, connectionType)
|
||||||
{
|
{
|
||||||
setExpires(true);
|
setExpires(true);
|
||||||
setShareable(true);
|
setShareable(true);
|
||||||
@ -297,7 +297,7 @@ void QHttpThreadDelegate::startRequest()
|
|||||||
if (!httpConnection) {
|
if (!httpConnection) {
|
||||||
// no entry in cache; create an object
|
// no entry in cache; create an object
|
||||||
// the http object is actually a QHttpNetworkConnection
|
// the http object is actually a QHttpNetworkConnection
|
||||||
httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl,
|
httpConnection = new QNetworkAccessCachedHttpConnection(http1Parameters.numberOfConnectionsPerHost(), urlCopy.host(), urlCopy.port(), ssl,
|
||||||
connectionType);
|
connectionType);
|
||||||
if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
|
if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
|
||||||
|| connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
|
|| connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include "qhttpnetworkrequest_p.h"
|
#include "qhttpnetworkrequest_p.h"
|
||||||
#include "qhttpnetworkconnection_p.h"
|
#include "qhttpnetworkconnection_p.h"
|
||||||
|
#include "qhttp1configuration.h"
|
||||||
#include "qhttp2configuration.h"
|
#include "qhttp2configuration.h"
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
@ -82,6 +83,7 @@ public:
|
|||||||
qint64 removedContentLength;
|
qint64 removedContentLength;
|
||||||
QNetworkReply::NetworkError incomingErrorCode;
|
QNetworkReply::NetworkError incomingErrorCode;
|
||||||
QString incomingErrorDetail;
|
QString incomingErrorDetail;
|
||||||
|
QHttp1Configuration http1Parameters;
|
||||||
QHttp2Configuration http2Parameters;
|
QHttp2Configuration http2Parameters;
|
||||||
|
|
||||||
bool isCompressed;
|
bool isCompressed;
|
||||||
|
@ -784,6 +784,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
|
|||||||
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
|
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
|
||||||
// Propagate Http/2 settings:
|
// Propagate Http/2 settings:
|
||||||
delegate->http2Parameters = request.http2Configuration();
|
delegate->http2Parameters = request.http2Configuration();
|
||||||
|
delegate->http1Parameters = request.http1Configuration();
|
||||||
|
|
||||||
if (request.attribute(QNetworkRequest::ConnectionCacheExpiryTimeoutSecondsAttribute).isValid())
|
if (request.attribute(QNetworkRequest::ConnectionCacheExpiryTimeoutSecondsAttribute).isValid())
|
||||||
delegate->connectionCacheExpiryTimeoutSeconds = request.attribute(QNetworkRequest::ConnectionCacheExpiryTimeoutSecondsAttribute).toInt();
|
delegate->connectionCacheExpiryTimeoutSeconds = request.attribute(QNetworkRequest::ConnectionCacheExpiryTimeoutSecondsAttribute).toInt();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "qnetworkcookie.h"
|
#include "qnetworkcookie.h"
|
||||||
#include "qsslconfiguration.h"
|
#include "qsslconfiguration.h"
|
||||||
#if QT_CONFIG(http) || defined(Q_QDOC)
|
#if QT_CONFIG(http) || defined(Q_QDOC)
|
||||||
|
#include "qhttp1configuration.h"
|
||||||
#include "qhttp2configuration.h"
|
#include "qhttp2configuration.h"
|
||||||
#include "private/http2protocol_p.h"
|
#include "private/http2protocol_p.h"
|
||||||
#endif
|
#endif
|
||||||
@ -439,6 +440,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
peerVerifyName = other.peerVerifyName;
|
peerVerifyName = other.peerVerifyName;
|
||||||
#if QT_CONFIG(http)
|
#if QT_CONFIG(http)
|
||||||
|
h1Configuration = other.h1Configuration;
|
||||||
h2Configuration = other.h2Configuration;
|
h2Configuration = other.h2Configuration;
|
||||||
decompressedSafetyCheckThreshold = other.decompressedSafetyCheckThreshold;
|
decompressedSafetyCheckThreshold = other.decompressedSafetyCheckThreshold;
|
||||||
#endif
|
#endif
|
||||||
@ -454,6 +456,7 @@ public:
|
|||||||
maxRedirectsAllowed == other.maxRedirectsAllowed &&
|
maxRedirectsAllowed == other.maxRedirectsAllowed &&
|
||||||
peerVerifyName == other.peerVerifyName
|
peerVerifyName == other.peerVerifyName
|
||||||
#if QT_CONFIG(http)
|
#if QT_CONFIG(http)
|
||||||
|
&& h1Configuration == other.h1Configuration
|
||||||
&& h2Configuration == other.h2Configuration
|
&& h2Configuration == other.h2Configuration
|
||||||
&& decompressedSafetyCheckThreshold == other.decompressedSafetyCheckThreshold
|
&& decompressedSafetyCheckThreshold == other.decompressedSafetyCheckThreshold
|
||||||
#endif
|
#endif
|
||||||
@ -470,6 +473,7 @@ public:
|
|||||||
int maxRedirectsAllowed;
|
int maxRedirectsAllowed;
|
||||||
QString peerVerifyName;
|
QString peerVerifyName;
|
||||||
#if QT_CONFIG(http)
|
#if QT_CONFIG(http)
|
||||||
|
QHttp1Configuration h1Configuration;
|
||||||
QHttp2Configuration h2Configuration;
|
QHttp2Configuration h2Configuration;
|
||||||
qint64 decompressedSafetyCheckThreshold = 10ll * 1024ll * 1024ll;
|
qint64 decompressedSafetyCheckThreshold = 10ll * 1024ll * 1024ll;
|
||||||
#endif
|
#endif
|
||||||
@ -854,6 +858,30 @@ void QNetworkRequest::setPeerVerifyName(const QString &peerName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(http) || defined(Q_QDOC)
|
#if QT_CONFIG(http) || defined(Q_QDOC)
|
||||||
|
/*!
|
||||||
|
\since 6.5
|
||||||
|
|
||||||
|
Returns the current parameters that QNetworkAccessManager is
|
||||||
|
using for the underlying HTTP/1 connection of this request.
|
||||||
|
|
||||||
|
\sa setHttp1Configuration
|
||||||
|
*/
|
||||||
|
QHttp1Configuration QNetworkRequest::http1Configuration() const
|
||||||
|
{
|
||||||
|
return d->h1Configuration;
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
\since 6.5
|
||||||
|
|
||||||
|
Sets request's HTTP/1 parameters from \a configuration.
|
||||||
|
|
||||||
|
\sa http1Configuration, QNetworkAccessManager, QHttp1Configuration
|
||||||
|
*/
|
||||||
|
void QNetworkRequest::setHttp1Configuration(const QHttp1Configuration &configuration)
|
||||||
|
{
|
||||||
|
d->h1Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\since 5.14
|
\since 5.14
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QSslConfiguration;
|
class QSslConfiguration;
|
||||||
class QHttp2Configuration;
|
class QHttp2Configuration;
|
||||||
|
class QHttp1Configuration;
|
||||||
|
|
||||||
class QNetworkRequestPrivate;
|
class QNetworkRequestPrivate;
|
||||||
class Q_NETWORK_EXPORT QNetworkRequest
|
class Q_NETWORK_EXPORT QNetworkRequest
|
||||||
@ -144,6 +145,9 @@ public:
|
|||||||
QString peerVerifyName() const;
|
QString peerVerifyName() const;
|
||||||
void setPeerVerifyName(const QString &peerName);
|
void setPeerVerifyName(const QString &peerName);
|
||||||
#if QT_CONFIG(http) || defined(Q_QDOC)
|
#if QT_CONFIG(http) || defined(Q_QDOC)
|
||||||
|
QHttp1Configuration http1Configuration() const;
|
||||||
|
void setHttp1Configuration(const QHttp1Configuration &configuration);
|
||||||
|
|
||||||
QHttp2Configuration http2Configuration() const;
|
QHttp2Configuration http2Configuration() const;
|
||||||
void setHttp2Configuration(const QHttp2Configuration &configuration);
|
void setHttp2Configuration(const QHttp2Configuration &configuration);
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <QtNetwork/qnetworkdiskcache.h>
|
#include <QtNetwork/qnetworkdiskcache.h>
|
||||||
#include <QtNetwork/qnetworkrequest.h>
|
#include <QtNetwork/qnetworkrequest.h>
|
||||||
#include <QtNetwork/qnetworkreply.h>
|
#include <QtNetwork/qnetworkreply.h>
|
||||||
|
#include <QtNetwork/QHttp1Configuration>
|
||||||
#include <QtNetwork/qnetworkcookie.h>
|
#include <QtNetwork/qnetworkcookie.h>
|
||||||
#include <QtNetwork/QNetworkCookieJar>
|
#include <QtNetwork/QNetworkCookieJar>
|
||||||
#include <QtNetwork/QHttpPart>
|
#include <QtNetwork/QHttpPart>
|
||||||
@ -65,6 +66,7 @@ Q_DECLARE_METATYPE(QSharedPointer<char>)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
@ -445,6 +447,7 @@ private Q_SLOTS:
|
|||||||
void varyingCacheExpiry_data();
|
void varyingCacheExpiry_data();
|
||||||
void varyingCacheExpiry();
|
void varyingCacheExpiry();
|
||||||
|
|
||||||
|
void amountOfHttp1ConnectionsQtbug25280_data();
|
||||||
void amountOfHttp1ConnectionsQtbug25280();
|
void amountOfHttp1ConnectionsQtbug25280();
|
||||||
|
|
||||||
void dontInsertPartialContentIntoTheCache();
|
void dontInsertPartialContentIntoTheCache();
|
||||||
@ -8120,10 +8123,18 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void tst_QNetworkReply::amountOfHttp1ConnectionsQtbug25280_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<int>("amount");
|
||||||
|
QTest::addRow("default") << 6;
|
||||||
|
QTest::addRow("minimize") << 1;
|
||||||
|
QTest::addRow("increase") << 12;
|
||||||
|
}
|
||||||
|
|
||||||
// Also kind of QTBUG-8468
|
// Also kind of QTBUG-8468
|
||||||
void tst_QNetworkReply::amountOfHttp1ConnectionsQtbug25280()
|
void tst_QNetworkReply::amountOfHttp1ConnectionsQtbug25280()
|
||||||
{
|
{
|
||||||
const int amount = 6;
|
QFETCH(const int, amount);
|
||||||
QNetworkAccessManager manager; // function local instance
|
QNetworkAccessManager manager; // function local instance
|
||||||
Qtbug25280Server server(tst_QNetworkReply::httpEmpty200Response);
|
Qtbug25280Server server(tst_QNetworkReply::httpEmpty200Response);
|
||||||
server.doClose = false;
|
server.doClose = false;
|
||||||
@ -8131,11 +8142,16 @@ void tst_QNetworkReply::amountOfHttp1ConnectionsQtbug25280()
|
|||||||
QUrl url(QLatin1String("http://127.0.0.1")); // not "localhost" to prevent "Happy Eyeballs"
|
QUrl url(QLatin1String("http://127.0.0.1")); // not "localhost" to prevent "Happy Eyeballs"
|
||||||
// from skewing the counting
|
// from skewing the counting
|
||||||
url.setPort(server.serverPort());
|
url.setPort(server.serverPort());
|
||||||
|
std::optional<QHttp1Configuration> http1Configuration;
|
||||||
|
if (amount != 6) // don't set if it's the default
|
||||||
|
http1Configuration.emplace().setNumberOfConnectionsPerHost(amount);
|
||||||
constexpr int NumRequests = 200; // send a lot more than we have sockets
|
constexpr int NumRequests = 200; // send a lot more than we have sockets
|
||||||
int finished = 0;
|
int finished = 0;
|
||||||
std::array<std::unique_ptr<QNetworkReply>, NumRequests> replies;
|
std::array<std::unique_ptr<QNetworkReply>, NumRequests> replies;
|
||||||
for (auto &reply : replies) {
|
for (auto &reply : replies) {
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
|
if (http1Configuration)
|
||||||
|
request.setHttp1Configuration(*http1Configuration);
|
||||||
reply.reset(manager.get(request));
|
reply.reset(manager.get(request));
|
||||||
QObject::connect(reply.get(), &QNetworkReply::finished,
|
QObject::connect(reply.get(), &QNetworkReply::finished,
|
||||||
[&finished] { ++finished; });
|
[&finished] { ++finished; });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user