diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2019-05-27 13:11:26 +0200 |
---|---|---|
committer | Jüri Valdmann <juri.valdmann@qt.io> | 2019-07-18 10:47:05 +0200 |
commit | 1b319cab5c5a049093bf165f2909273005fc625c (patch) | |
tree | f3ad2e3c5b3eaf64bfeee040a72002b49a00714a /src/core | |
parent | 0872bcd6a0a423d7aa904f597f83cd991b53112b (diff) |
Add QWebEngineUrlScheme::CorsEnabled flag
Add support for enabling CORS for custom schemes. Headers for CORS are generated
automatically by UrlRequestCustomJob for all CorsEnabled schemes.
[ChangeLog][Custom Schemes] Added the QWebEngineUrlScheme::CorsEnabled flag for
enabling cross-origin resource sharing with custom schemes.
Fixes: QTBUG-75651
Change-Id: Ia17acf25ae8488f23c6b4609777a3bdbf72149ee
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/api/qwebengineurlscheme.cpp | 8 | ||||
-rw-r--r-- | src/core/api/qwebengineurlscheme.h | 1 | ||||
-rw-r--r-- | src/core/net/url_request_custom_job.cpp | 26 | ||||
-rw-r--r-- | src/core/net/url_request_custom_job.h | 3 | ||||
-rw-r--r-- | src/core/net/url_request_custom_job_proxy.cpp | 3 |
5 files changed, 41 insertions, 0 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) |