summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/network/qt
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/network/qt')
-rw-r--r--Source/WebCore/platform/network/qt/CookieJarQt.cpp2
-rw-r--r--Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp60
-rw-r--r--Source/WebCore/platform/network/qt/ResourceRequest.h13
-rw-r--r--Source/WebCore/platform/network/qt/ResourceRequestQt.cpp43
4 files changed, 89 insertions, 29 deletions
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) {