summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-21 10:23:06 +0000
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-01-30 15:55:00 +0000
commit94d2cba36b8a1c3e02ca2abf16b11963fd1801d5 (patch)
treefda30bf876ed68e1eefa0c5560835c5d945e6f85
parentec4a94c5d872824d20a70bd45e6c53ab72dd2194 (diff)
Add HTTP request headers to custom URL schemes (reland)
Makes it possible to read extra headers added to the request. This reverts commit 9cbe64c54dee8451794e29f4357ccfac6d883e6b. Task-number: QTBUG-69844 Change-Id: I5c5e0c06655d5f764227fdc97fdb0c2a189f532d Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp9
-rw-r--r--src/core/api/qwebengineurlrequestjob.h1
-rw-r--r--src/core/net/url_request_custom_job.cpp16
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp11
-rw-r--r--src/core/net/url_request_custom_job_delegate.h6
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp10
-rw-r--r--src/core/net/url_request_custom_job_proxy.h2
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp61
8 files changed, 109 insertions, 7 deletions
diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index c3541598b..41b43d42c 100644
--- a/src/core/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -140,6 +140,15 @@ QUrl QWebEngineUrlRequestJob::initiator() const
}
/*!
+ \since 5.13
+ Returns any HTTP headers added to the request.
+*/
+const QMap<QByteArray, QByteArray> &QWebEngineUrlRequestJob::requestHeaders() const
+{
+ return d_ptr->requestHeaders();
+}
+
+/*!
Replies to the request with \a device and the MIME type \a contentType.
The user has to be aware that \a device will be used on another thread
diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h
index 7ce8be7ec..55ec7c6d2 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -73,6 +73,7 @@ public:
QUrl requestUrl() const;
QByteArray requestMethod() const;
QUrl initiator() const;
+ const QMap<QByteArray, QByteArray> &requestHeaders() const;
void reply(const QByteArray &contentType, QIODevice *device);
void fail(Error error);
diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp
index edea155a1..cba9b4dc5 100644
--- a/src/core/net/url_request_custom_job.cpp
+++ b/src/core/net/url_request_custom_job.cpp
@@ -78,9 +78,23 @@ URLRequestCustomJob::~URLRequestCustomJob()
void URLRequestCustomJob::Start()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ HttpRequestHeaders requestHeaders = request()->extra_request_headers();
+ std::map<std::string, std::string> headers;
+ net::HttpRequestHeaders::Iterator it(requestHeaders);
+ while (it.GetNext())
+ headers.emplace(it.name(), it.value());
+ if (!request()->referrer().empty())
+ headers.emplace("Referer", request()->referrer());
+
+ // TODO: handle UploadDataStream, for instance using a QIODevice wrapper.
+
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&URLRequestCustomJobProxy::initialize,
- m_proxy, request()->url(), request()->method(), request()->initiator()));
+ m_proxy,
+ request()->url(),
+ request()->method(),
+ request()->initiator(),
+ std::move(headers)));
}
void URLRequestCustomJob::Kill()
diff --git a/src/core/net/url_request_custom_job_delegate.cpp b/src/core/net/url_request_custom_job_delegate.cpp
index d968dd341..83d47e291 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -54,11 +54,13 @@ namespace QtWebEngineCore {
URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
const QUrl &url,
const QByteArray &method,
- const QUrl &initiatorOrigin)
+ const QUrl &initiatorOrigin,
+ const QMap<QByteArray, QByteArray> &headers)
: m_proxy(proxy),
m_request(url),
m_method(method),
- m_initiatorOrigin(initiatorOrigin)
+ m_initiatorOrigin(initiatorOrigin),
+ m_requestHeaders(headers)
{
}
@@ -81,6 +83,11 @@ QUrl URLRequestCustomJobDelegate::initiator() const
return m_initiatorOrigin;
}
+const QMap<QByteArray, QByteArray> &URLRequestCustomJobDelegate::requestHeaders() const
+{
+ return m_requestHeaders;
+}
+
void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device)
{
if (device)
diff --git a/src/core/net/url_request_custom_job_delegate.h b/src/core/net/url_request_custom_job_delegate.h
index caabfcf99..9de0224f9 100644
--- a/src/core/net/url_request_custom_job_delegate.h
+++ b/src/core/net/url_request_custom_job_delegate.h
@@ -54,6 +54,7 @@
#include "base/memory/ref_counted.h"
#include "qtwebenginecoreglobal_p.h"
+#include <QMap>
#include <QObject>
#include <QUrl>
@@ -80,6 +81,7 @@ public:
QUrl url() const;
QByteArray method() const;
QUrl initiator() const;
+ const QMap<QByteArray, QByteArray> &requestHeaders() const;
void reply(const QByteArray &contentType, QIODevice *device);
void redirect(const QUrl& url);
@@ -93,13 +95,15 @@ private:
URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
const QUrl &url,
const QByteArray &method,
- const QUrl &initiatorOrigin);
+ const QUrl &initiatorOrigin,
+ const QMap<QByteArray, QByteArray> &requestHeaders);
friend class URLRequestCustomJobProxy;
scoped_refptr<URLRequestCustomJobProxy> m_proxy;
QUrl m_request;
QByteArray m_method;
QUrl m_initiatorOrigin;
+ const QMap<QByteArray, QByteArray> m_requestHeaders;
};
} // namespace
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index a80ef8060..72d14450e 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -152,7 +152,9 @@ void URLRequestCustomJobProxy::readyRead()
m_job->notifyReadyRead();
}
-void URLRequestCustomJobProxy::initialize(GURL url, std::string method, base::Optional<url::Origin> initiator)
+void URLRequestCustomJobProxy::initialize(GURL url, std::string method,
+ base::Optional<url::Origin> initiator,
+ std::map<std::string, std::string> headers)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Q_ASSERT(!m_delegate);
@@ -165,11 +167,15 @@ void URLRequestCustomJobProxy::initialize(GURL url, std::string method, base::Op
if (m_profileAdapter)
schemeHandler = m_profileAdapter->urlSchemeHandler(toQByteArray(m_scheme));
+ QMap<QByteArray, QByteArray> qHeaders;
+ for (auto it = headers.cbegin(); it != headers.cend(); ++it)
+ qHeaders.insert(toQByteArray(it->first), toQByteArray(it->second));
if (schemeHandler) {
m_delegate = new URLRequestCustomJobDelegate(this, toQt(url),
QByteArray::fromStdString(method),
- initiatorOrigin);
+ initiatorOrigin,
+ qHeaders);
QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
schemeHandler->requestStarted(requestJob);
}
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
index 3986fe119..aa55db07c 100644
--- a/src/core/net/url_request_custom_job_proxy.h
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -72,7 +72,7 @@ public:
void abort();
void fail(int error);
void release();
- void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin);
+ void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin, std::map<std::string, std::string> headers);
void readyRead();
// IO thread owned:
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 1fe0f0304..bf5d320b7 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -29,6 +29,7 @@
#include "../util.h"
#include <QtCore/qbuffer.h>
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineCore/qwebengineurlrequestjob.h>
#include <QtWebEngineCore/qwebengineurlschemehandler.h>
#include <QtWebEngineWidgets/qwebengineprofile.h>
@@ -52,6 +53,7 @@ private Q_SLOTS:
void urlSchemeHandlerFailRequest();
void urlSchemeHandlerFailOnRead();
void urlSchemeHandlerStreaming();
+ void urlSchemeHandlerRequestHeaders();
void customUserAgent();
void httpAcceptLanguage();
void downloadItem();
@@ -444,6 +446,65 @@ void tst_QWebEngineProfile::urlSchemeHandlerStreaming()
QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result));
}
+class ExtraHeaderInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ ExtraHeaderInterceptor() { }
+
+ void setExtraHeader(const QByteArray &key, const QByteArray &value)
+ {
+ m_extraKey = key;
+ m_extraValue = value;
+ }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ if (info.requestUrl().scheme() == QLatin1String("myscheme"))
+ info.setHttpHeader(m_extraKey, m_extraValue);
+ }
+
+ QByteArray m_extraKey;
+ QByteArray m_extraValue;
+};
+
+class RequestHeadersUrlSchemeHandler : public ReplyingUrlSchemeHandler
+{
+public:
+ void setExpectedHeader(const QByteArray &key, const QByteArray &value)
+ {
+ m_expectedKey = key;
+ m_expectedValue = value;
+ }
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ const auto requestHeaders = job->requestHeaders();
+ QVERIFY(requestHeaders.contains(m_expectedKey));
+ QCOMPARE(requestHeaders.value(m_expectedKey), m_expectedValue);
+ ReplyingUrlSchemeHandler::requestStarted(job);
+ }
+ QByteArray m_expectedKey;
+ QByteArray m_expectedValue;
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders()
+{
+ RequestHeadersUrlSchemeHandler handler;
+ ExtraHeaderInterceptor interceptor;
+
+ handler.setExpectedHeader("Hello", "World");
+ interceptor.setExtraHeader("Hello", "World");
+
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("myscheme", &handler);
+ profile.setRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl(QStringLiteral("myscheme://whatever")));
+ QVERIFY(loadFinishedSpy.wait());
+}
+
+
void tst_QWebEngineProfile::customUserAgent()
{
QString defaultUserAgent = QWebEngineProfile::defaultProfile()->httpUserAgent();