summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/api/qwebengineurlscheme.cpp8
-rw-r--r--src/core/api/qwebengineurlscheme.h1
-rw-r--r--src/core/net/url_request_custom_job.cpp26
-rw-r--r--src/core/net/url_request_custom_job.h3
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp3
-rw-r--r--tests/auto/widgets/origins/resources/redirect.css8
-rw-r--r--tests/auto/widgets/origins/resources/redirect.html10
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp55
8 files changed, 113 insertions, 1 deletions
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index f4efad717..6c7d1780c 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -59,6 +59,7 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::NoAccessAllowed, url::CustomScheme::NoAc
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ServiceWorkersAllowed, url::CustomScheme::ServiceWorkersAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ViewSourceAllowed, url::CustomScheme::ViewSourceAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ContentSecurityPolicyIgnored, url::CustomScheme::ContentSecurityPolicyIgnored)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::CorsEnabled, url::CustomScheme::CorsEnabled)
static bool g_schemesLocked = false;
@@ -190,6 +191,13 @@ public:
\value ContentSecurityPolicyIgnored
Indicates that accesses to this scheme should bypass all
Content-Security-Policy checks.
+
+ \value CorsEnabled
+ Enables cross-origin resource sharing (CORS) for this scheme. This flag is
+ required in order to, for example, use the scheme with the \l
+ {https://fetch.spec.whatwg.org/}{Fetch API}, or to deliver CSS fonts to a
+ different origin. The appropriate CORS headers are generated automatically by
+ the QWebEngineUrlRequestJob class. (Added in Qt 5.14)
*/
QWebEngineUrlScheme::QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d) : d(d) {}
diff --git a/src/core/api/qwebengineurlscheme.h b/src/core/api/qwebengineurlscheme.h
index 095b47320..ecac44184 100644
--- a/src/core/api/qwebengineurlscheme.h
+++ b/src/core/api/qwebengineurlscheme.h
@@ -76,6 +76,7 @@ public:
ServiceWorkersAllowed = 0x10,
ViewSourceAllowed = 0x20,
ContentSecurityPolicyIgnored = 0x40,
+ CorsEnabled = 0x80,
};
Q_DECLARE_FLAGS(Flags, Flag)
Q_FLAG(Flags)
diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp
index cba9b4dc5..dd213d4f8 100644
--- a/src/core/net/url_request_custom_job.cpp
+++ b/src/core/net/url_request_custom_job.cpp
@@ -40,10 +40,13 @@
#include "url_request_custom_job.h"
#include "url_request_custom_job_proxy.h"
+#include "api/qwebengineurlscheme.h"
+#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
+#include "net/http/http_util.h"
#include <QIODevice>
@@ -62,6 +65,9 @@ URLRequestCustomJob::URLRequestCustomJob(URLRequest *request,
, m_pendingReadSize(0)
, m_pendingReadPos(0)
, m_pendingReadBuffer(nullptr)
+ , m_corsEnabled(QWebEngineUrlScheme::schemeByName(QByteArray::fromStdString(scheme))
+ .flags().testFlag(QWebEngineUrlScheme::CorsEnabled))
+ , m_httpStatusCode(500)
{
}
@@ -136,6 +142,26 @@ bool URLRequestCustomJob::GetCharset(std::string* charset)
return false;
}
+void URLRequestCustomJob::GetResponseInfo(HttpResponseInfo* info)
+{
+ // Based on net::URLRequestRedirectJob::StartAsync()
+
+ if (!m_corsEnabled)
+ return;
+
+ std::string headers;
+ headers += base::StringPrintf("HTTP/1.1 %i OK\n", m_httpStatusCode);
+ if (m_redirect.is_valid())
+ headers += base::StringPrintf("Location: %s\n", m_redirect.spec().c_str());
+ std::string origin;
+ if (request_->extra_request_headers().GetHeader("Origin", &origin)) {
+ headers += base::StringPrintf("Access-Control-Allow-Origin: %s\n", origin.c_str());
+ headers += "Access-Control-Allow-Credentials: true\n";
+ }
+
+ info->headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+}
+
bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code, bool* /*insecure_scheme_was_upgraded*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/src/core/net/url_request_custom_job.h b/src/core/net/url_request_custom_job.h
index 16be76f29..e1e8e9fba 100644
--- a/src/core/net/url_request_custom_job.h
+++ b/src/core/net/url_request_custom_job.h
@@ -64,6 +64,7 @@ public:
int ReadRawData(net::IOBuffer *buf, int buf_size) override;
bool GetMimeType(std::string *mimeType) const override;
bool GetCharset(std::string *charset) override;
+ void GetResponseInfo(net::HttpResponseInfo* info) override;
bool IsRedirectResponse(GURL* location, int* http_status_code, bool* insecure_scheme_was_upgraded) override;
protected:
@@ -80,6 +81,8 @@ private:
int m_pendingReadSize;
int m_pendingReadPos;
net::IOBuffer *m_pendingReadBuffer;
+ const bool m_corsEnabled;
+ int m_httpStatusCode;
friend class URLRequestCustomJobProxy;
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 72d14450e..b9ccf7ea4 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -100,6 +100,7 @@ void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device)
m_job->set_expected_content_size(size);
if (m_job->m_device && m_job->m_device->isReadable()) {
m_started = true;
+ m_job->m_httpStatusCode = 200;
m_job->NotifyHeadersComplete();
} else {
fail(ERR_INVALID_URL);
@@ -114,6 +115,7 @@ void URLRequestCustomJobProxy::redirect(GURL url)
if (m_job->m_device || m_job->m_error)
return;
m_job->m_redirect = url;
+ m_job->m_httpStatusCode = 303;
m_started = true;
m_job->NotifyHeadersComplete();
}
@@ -138,6 +140,7 @@ void URLRequestCustomJobProxy::fail(int error)
if (!m_job)
return;
m_job->m_error = error;
+ m_job->m_httpStatusCode = 500;
if (m_job->m_device)
m_job->m_device->close();
if (!m_started)
diff --git a/tests/auto/widgets/origins/resources/redirect.css b/tests/auto/widgets/origins/resources/redirect.css
new file mode 100644
index 000000000..41d7560cc
--- /dev/null
+++ b/tests/auto/widgets/origins/resources/redirect.css
@@ -0,0 +1,8 @@
+@font-face {
+ font-family: 'MyWebFont';
+ src: url('redirect1:/resources/Akronim-Regular.woff2') format('woff2');
+}
+
+body {
+ font-family: 'MyWebFont', Fallback, sans-serif;
+}
diff --git a/tests/auto/widgets/origins/resources/redirect.html b/tests/auto/widgets/origins/resources/redirect.html
new file mode 100644
index 000000000..04948e14b
--- /dev/null
+++ b/tests/auto/widgets/origins/resources/redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>redirect</title>
+ <link rel="stylesheet" href="redirect1:/resources/redirect.css">
+ </head>
+ <body>
+ Text
+ </body>
+</html>
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index 8fed79975..02d5bfba3 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -122,6 +122,18 @@ void registerSchemes()
scheme.setDefaultPort(42);
QWebEngineUrlScheme::registerScheme(scheme);
}
+
+ {
+ QWebEngineUrlScheme scheme(QBAL("redirect1"));
+ scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+
+ {
+ QWebEngineUrlScheme scheme(QBAL("redirect2"));
+ scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
}
Q_CONSTRUCTOR_FUNCTION(registerSchemes)
@@ -145,13 +157,26 @@ public:
profile->installUrlSchemeHandler(QBAL("HostSyntax-ContentSecurityPolicyIgnored"), this);
profile->installUrlSchemeHandler(QBAL("HostAndPortSyntax"), this);
profile->installUrlSchemeHandler(QBAL("HostPortAndUserInformationSyntax"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect1"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect2"), this);
}
+ QVector<QUrl> &requests() { return m_requests; }
+
private:
void requestStarted(QWebEngineUrlRequestJob *job) override
{
+ QUrl url = job->requestUrl();
+ m_requests << url;
+
+ if (url.scheme() == QBAL("redirect1")) {
+ url.setScheme(QBAL("redirect2"));
+ job->redirect(url);
+ return;
+ }
+
QString pathPrefix = QSL(THIS_DIR);
- QString pathSuffix = job->requestUrl().path();
+ QString pathSuffix = url.path();
QFile *file = new QFile(pathPrefix + pathSuffix, job);
if (!file->open(QIODevice::ReadOnly)) {
job->fail(QWebEngineUrlRequestJob::RequestFailed);
@@ -160,8 +185,12 @@ private:
QByteArray mimeType = QBAL("text/html");
if (pathSuffix.endsWith(QSL(".js")))
mimeType = QBAL("application/javascript");
+ else if (pathSuffix.endsWith(QSL(".css")))
+ mimeType = QBAL("text/css");
job->reply(mimeType, file);
}
+
+ QVector<QUrl> m_requests;
};
class tst_Origins final : public QObject {
@@ -169,6 +198,7 @@ class tst_Origins final : public QObject {
private Q_SLOTS:
void initTestCase();
+ void cleanup();
void cleanupTestCase();
void jsUrlCanon();
@@ -187,6 +217,7 @@ private Q_SLOTS:
void serviceWorker();
void viewSource();
void createObjectURL();
+ void redirect();
private:
bool load(const QUrl &url)
@@ -209,10 +240,19 @@ private:
void tst_Origins::initTestCase()
{
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ QRegularExpression("Please register the custom scheme 'tst'.*"));
+
m_page = new QWebEnginePage(&m_profile, nullptr);
m_handler = new TstUrlSchemeHandler(&m_profile);
}
+void tst_Origins::cleanup()
+{
+ m_handler->requests().clear();
+}
+
void tst_Origins::cleanupTestCase()
{
delete m_handler;
@@ -772,5 +812,18 @@ void tst_Origins::createObjectURL()
QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:")));
}
+void tst_Origins::redirect()
+{
+ QVERIFY(load(QSL("redirect1:/resources/redirect.html")));
+ QTRY_COMPARE(m_handler->requests().size(), 7);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect1:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("redirect2:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect1:/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("redirect2:/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[4], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2")));
+ QCOMPARE(m_handler->requests()[5], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2")));
+ QCOMPARE(m_handler->requests()[6], QUrl(QStringLiteral("redirect2:/resources/Akronim-Regular.woff2")));
+}
+
QTEST_MAIN(tst_Origins)
#include "tst_origins.moc"