diff options
Diffstat (limited to 'Source/WebCore/platform/network')
5 files changed, 89 insertions, 33 deletions
diff --git a/Source/WebCore/platform/network/NetworkingContext.h b/Source/WebCore/platform/network/NetworkingContext.h index 3de432e42..582bca647 100644 --- a/Source/WebCore/platform/network/NetworkingContext.h +++ b/Source/WebCore/platform/network/NetworkingContext.h @@ -28,10 +28,6 @@ #include <wtf/SchedulePair.h> #endif -#if PLATFORM(QT) -#include <qglobal.h> -#endif - #if PLATFORM(COCOA) OBJC_CLASS NSOperationQueue; #endif diff --git a/Source/WebCore/platform/network/qt/CookieJarQt.cpp b/Source/WebCore/platform/network/qt/CookieJarQt.cpp index d1cf87fdd..0e05e677b 100644 --- a/Source/WebCore/platform/network/qt/CookieJarQt.cpp +++ b/Source/WebCore/platform/network/qt/CookieJarQt.cpp @@ -123,7 +123,7 @@ String cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const bool cookiesEnabled(const NetworkStorageSession& session, const URL& /*firstParty*/, const URL& /*url*/) { - return true; + return session.context() ? session.context()->networkAccessManager()->cookieJar() : SharedCookieJarQt::shared(); } bool getRawCookies(const NetworkStorageSession& session, const URL& /*firstParty*/, const URL& /*url*/, Vector<Cookie>& rawCookies) diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 1b60c5131..792459558 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -41,6 +41,29 @@ #include <QCoreApplication> +#if USE(HTTP2) && QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + +#include <private/http2protocol_p.h> +#include <cstdlib> + +// Redefine private bits which are not currenly exported from QtNetwork + +QT_BEGIN_NAMESPACE + +namespace Http2 { +const char *http2ParametersPropertyName = "QT_HTTP2_PARAMETERS_PROPERTY"; + +ProtocolParameters::ProtocolParameters() +{ + settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = qtDefaultStreamReceiveWindowSize; + settingsFrameData[Settings::ENABLE_PUSH_ID] = 0; +} +} + +QT_END_NAMESPACE + +#endif // USE(HTTP2) && QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + static const int gMaxRedirections = 10; namespace WebCore { @@ -488,12 +511,15 @@ QNetworkReply* QNetworkReplyHandler::release() static bool shouldIgnoreHttpError(QNetworkReply* reply, bool receivedData) { + int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + // Don't ignore error if we haven't received HTTP status code + if (httpStatusCode == 0) + return false; + // An HEAD XmlHTTPRequest shouldn't be marked as failure for HTTP errors. if (reply->operation() == QNetworkAccessManager::HeadOperation) return true; - int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (httpStatusCode == 401 || httpStatusCode == 407) return true; @@ -585,19 +611,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded() m_replyWrapper->reply()->header(QNetworkRequest::ContentLengthHeader).toLongLong(), m_replyWrapper->encoding()); - if (url.isLocalFile()) { - if (client->usesAsyncCallbacks()) { - setLoadingDeferred(true); - client->didReceiveResponseAsync(m_resourceHandle, response); - } else - client->didReceiveResponse(m_resourceHandle, response); - return; - } - - // The status code is equal to 0 for protocols not in the HTTP family. - int statusCode = m_replyWrapper->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (url.protocolIsInHTTPFamily()) { + // The status code is equal to 0 for protocols not in the HTTP family. + int statusCode = m_replyWrapper->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); response.setHTTPStatusCode(statusCode); response.setHTTPStatusText(m_replyWrapper->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray().constData()); @@ -606,6 +623,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() response.setHTTPHeaderField(String(pair.first.constData(), pair.first.size()), String(pair.second.constData(), pair.second.size())); } + // Note: Qt sets RedirectionTargetAttribute only for 3xx responses, so Location header in 201 responce won't affect this code QUrl redirection = m_replyWrapper->reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); if (redirection.isValid()) { redirect(response, redirection); @@ -648,8 +666,10 @@ void QNetworkReplyHandler::redirect(ResourceResponse& response, const QUrl& redi ASSERT(!m_queue.deferSignals()); QUrl currentUrl = m_replyWrapper->reply()->url(); + + // RFC7231 section 7.1.2 QUrl newUrl = currentUrl.resolved(redirection); - if (currentUrl.hasFragment()) + if (!newUrl.hasFragment() && currentUrl.hasFragment()) newUrl.setFragment(currentUrl.fragment()); ResourceHandleClient* client = m_resourceHandle->client(); @@ -777,6 +797,18 @@ QNetworkReply* QNetworkReplyHandler::sendNetworkRequest(QNetworkAccessManager* m if (!manager) return 0; +#if USE(HTTP2) && QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + static const bool alpnIsSupported = ResourceRequest::alpnIsSupported(); + if (alpnIsSupported && !manager->property(Http2::http2ParametersPropertyName).isValid()) { + Http2::ProtocolParameters params; + // QTBUG-77308 + params.maxSessionReceiveWindowSize = Http2::maxSessionReceiveWindowSize / 2; + // Enable HTTP/2 push + params.settingsFrameData[Http2::Settings::ENABLE_PUSH_ID] = 1; + manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); + } +#endif + const QUrl url = m_request.url(); // Post requests on files and data don't really make sense, but for diff --git a/Source/WebCore/platform/network/qt/ResourceRequest.h b/Source/WebCore/platform/network/qt/ResourceRequest.h index e74d9024c..1154d56a0 100644 --- a/Source/WebCore/platform/network/qt/ResourceRequest.h +++ b/Source/WebCore/platform/network/qt/ResourceRequest.h @@ -29,6 +29,13 @@ #include "ResourceRequestBase.h" +// HTTP/2 is implemented since Qt 5.8, but various QtNetwork bugs make it unusable in browser with Qt < 5.10.1 +// We also don't enable HTTP/2 for unencrypted connections because of possible compatibility issues; it can be +// enabled manually by user application via custom QNAM subclass +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 1) +#define USE_HTTP2 1 +#endif + QT_BEGIN_NAMESPACE class QNetworkRequest; QT_END_NAMESPACE @@ -63,6 +70,12 @@ class NetworkingContext; QNetworkRequest toNetworkRequest(NetworkingContext* = 0) const; +#if USE(HTTP2) + // Don't enable HTTP/2 when ALPN support status is unknown + static bool alpnIsSupported(); +#endif + + private: friend class ResourceRequestBase; diff --git a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp index c54a8115b..310738449 100644 --- a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp +++ b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp @@ -27,17 +27,12 @@ #include <QNetworkRequest> #include <QUrl> -// HTTP/2 is implemented since Qt 5.8, but QTBUG-64359 makes it unusable in browser -#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 4) -#define USE_HTTP2 1 -#endif - -// HTTP2AllowedAttribute enforces HTTP/2 instead of negotiating, see QTBUG-61397 -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) -#define HTTP2_IS_BUGGY_WITHOUT_HTTPS 1 -#else -#define HTTP2_IS_BUGGY_WITHOUT_HTTPS 0 +#if USE(HTTP2) +#include <QSslSocket> +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) +#include <QHttp2Configuration> #endif +#endif // USE(HTTP2) namespace WebCore { @@ -66,6 +61,25 @@ static inline QByteArray stringToByteArray(const String& string) return QString(string).toLatin1(); } +#if USE(HTTP2) +bool ResourceRequest::alpnIsSupported() +{ + // Before QTBUG-65903 is implemented there is no better way than to check OpenSSL version + return QSslSocket::sslLibraryVersionNumber() > 0x10002000L && + QSslSocket::sslLibraryVersionString().startsWith(QLatin1String("OpenSSL")); +} + +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) +static QHttp2Configuration createHttp2Configuration() +{ + QHttp2Configuration params; + params.setServerPushEnabled(true); + return params; +} +#endif + +#endif + QNetworkRequest ResourceRequest::toNetworkRequest(NetworkingContext *context) const { QNetworkRequest request; @@ -74,15 +88,16 @@ QNetworkRequest ResourceRequest::toNetworkRequest(NetworkingContext *context) co request.setOriginatingObject(context ? context->originatingObject() : 0); #if USE(HTTP2) -#if HTTP2_IS_BUGGY_WITHOUT_HTTPS - if (originalUrl.protocolIs("https")) + static const bool NegotiateHttp2ForHttps = alpnIsSupported(); + if (originalUrl.protocolIs("https") && NegotiateHttp2ForHttps) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + static const auto params = createHttp2Configuration(); + request.setHttp2Configuration(params); #endif - { request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); } #endif // USE(HTTP2) - const HTTPHeaderMap &headers = httpHeaderFields(); for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it) { |