diff --git a/src/libsync/accessmanager.cpp b/src/libsync/accessmanager.cpp index 4c19c20a196..fb131b02c21 100644 --- a/src/libsync/accessmanager.cpp +++ b/src/libsync/accessmanager.cpp @@ -93,6 +93,14 @@ QNetworkReply *AccessManager::createRequest(QNetworkAccessManager::Operation op, qInfo(lcAccessManager) << op << verb << newRequest.url().toString() << "has X-Request-ID" << requestId; newRequest.setRawHeader("X-Request-ID", requestId); +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + // only enable HTTP2 with Qt 5.9 because Qt 5.8.0 has too many bugs + // (only use one connection if the server does not support HTTP2) + if (newRequest.url().scheme() == "https") { // Not for "http": QTBUG-61397 + newRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); + } +#endif + return QNetworkAccessManager::createRequest(op, newRequest, outgoingData); } diff --git a/src/libsync/account.h b/src/libsync/account.h index b34342d4525..de1cd0293c9 100644 --- a/src/libsync/account.h +++ b/src/libsync/account.h @@ -189,6 +189,10 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject /** Detects a specific bug in older server versions */ bool rootEtagChangesNotOnlySubFolderEtags(); + /** True when the server supports HTTP2 */ + bool isHttp2Supported() { return _http2Supported; } + void setHttp2Supported(bool value) { _http2Supported = value; }; + void clearCookieJar(); void lendCookieJarTo(QNetworkAccessManager *guest); QString cookieJarPath(); @@ -247,6 +251,7 @@ protected Q_SLOTS: QuotaInfo *_quotaInfo; QSharedPointer _am; QScopedPointer _credentials; + bool _http2Supported = false; /// Certificates that were explicitly rejected by the user QList _rejectedCertificates; diff --git a/src/libsync/connectionvalidator.cpp b/src/libsync/connectionvalidator.cpp index 0b5897f1ff6..9eff065dee5 100644 --- a/src/libsync/connectionvalidator.cpp +++ b/src/libsync/connectionvalidator.cpp @@ -282,10 +282,18 @@ bool ConnectionValidator::setAndCheckServerVersion(const QString &version) reportResult(ServerVersionMismatch); return false; } - // We attempt to work with servers >= 5.0.0 but warn users. // Check usages of Account::serverVersionUnsupported() for details. +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + // Record that the server supports HTTP/2 + if (auto job = qobject_cast(sender())) { + if (auto reply = job->reply()) { + _account->setHttp2Supported( + reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute).toBool()); + } + } +#endif return true; } diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index 016f0cdc84d..e76e00e8e15 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -84,18 +84,18 @@ int OwncloudPropagator::maximumActiveTransferJob() // disable parallelism when there is a network limit. return 1; } - return qCeil(hardMaximumActiveJob() / 2.); + return qMax(3, qCeil(hardMaximumActiveJob() / 2.)); } /* The maximum number of active jobs in parallel */ int OwncloudPropagator::hardMaximumActiveJob() { static int max = qgetenv("OWNCLOUD_MAX_PARALLEL").toUInt(); - if (!max) { - max = 6; //default (Qt cannot do more anyway) - // TODO: increase this number when using HTTP2 - } - return max; + if (max) + return max; + if (_account->isHttp2Supported()) + return 20; + return 6; // (Qt cannot do more anyway) } PropagateItemJob::~PropagateItemJob() diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index b5d6ac00406..2a6ca14394d 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -118,6 +118,8 @@ void GETFileJob::start() req.setRawHeader(it.key(), it.value()); } + req.setPriority(QNetworkRequest::LowPriority); // Long downloads must not block non-propagation jobs. + if (_directDownloadUrl.isEmpty()) { sendRequest("GET", makeDavUrl(path()), req); } else { diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 757aee1c448..1cd0266277e 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -79,6 +79,8 @@ void PUTFileJob::start() req.setRawHeader(it.key(), it.value()); } + req.setPriority(QNetworkRequest::LowPriority); // Long uploads must not block non-propagation jobs. + if (_url.isValid()) { sendRequest("PUT", _url, req, _device); } else { diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 8fa6eb7b726..967f5ca6a00 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -852,7 +852,7 @@ void SyncEngine::startSync() _discoveryMainThread->setParent(this); connect(this, SIGNAL(finished(bool)), _discoveryMainThread, SLOT(deleteLater())); qCInfo(lcEngine) << "Server" << account()->serverVersion() - << QString("rootEtagChangesNotOnlySubFolderEtags=%1").arg(account()->rootEtagChangesNotOnlySubFolderEtags()); + << (account()->isHttp2Supported() ? "Using HTTP/2" : ""); if (account()->rootEtagChangesNotOnlySubFolderEtags()) { connect(_discoveryMainThread, SIGNAL(etag(QString)), this, SLOT(slotRootEtagReceived(QString))); } else {