| /**************************************************************************** |
| ** |
| ** Copyright (C) 2018 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtWebEngine module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qwebengineurlscheme.h" |
| |
| #include "url/url_util_qt.h" |
| |
| #include <QtDebug> |
| |
| QT_BEGIN_NAMESPACE |
| |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::Path, url::SCHEME_WITHOUT_AUTHORITY) |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::Host, url::SCHEME_WITH_HOST) |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostAndPort, url::SCHEME_WITH_HOST_AND_PORT) |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION) |
| |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::PortUnspecified, url::PORT_UNSPECIFIED) |
| |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::SecureScheme, url::CustomScheme::Secure) |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::LocalScheme, url::CustomScheme::Local) |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::LocalAccessAllowed, url::CustomScheme::LocalAccessAllowed) |
| ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::NoAccessAllowed, url::CustomScheme::NoAccessAllowed) |
| 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; |
| |
| class QWebEngineUrlSchemePrivate : public QSharedData |
| , public url::CustomScheme |
| { |
| public: |
| QWebEngineUrlSchemePrivate() {} |
| QWebEngineUrlSchemePrivate(const url::CustomScheme &cs) : url::CustomScheme(cs) {} |
| static QSharedDataPointer<QWebEngineUrlSchemePrivate> defaultConstructed() |
| { |
| static QSharedDataPointer<QWebEngineUrlSchemePrivate> instance(new QWebEngineUrlSchemePrivate); |
| return instance; |
| } |
| }; |
| |
| /*! |
| \class QWebEngineUrlScheme |
| \inmodule QtWebEngineCore |
| \since 5.12 |
| \brief The QWebEngineUrlScheme class configures a custom URL scheme. |
| |
| A web engine URL scheme describes a URL scheme from the web engine's |
| perspective, specifying how URLs of this scheme should be parsed, and which |
| security restrictions should be placed on resources originating from such |
| URLs. |
| |
| Custom URL schemes must be configured early at application startup, before |
| creating any \QWE classes. In general this means the schemes need to be configured before |
| a QGuiApplication or QApplication instance is created. |
| |
| Every registered scheme configuration applies globally to all profiles. |
| |
| \code |
| int main(int argc, char **argv) |
| { |
| QWebEngineUrlScheme scheme("myscheme"); |
| scheme.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort); |
| scheme.setDefaultPort(2345); |
| scheme.setFlags(QWebEngineUrlScheme::SecureScheme); |
| QWebEngineUrlScheme::registerScheme(scheme); |
| ... |
| } |
| \endcode |
| |
| To actually make use of the custom URL scheme, a \l QWebEngineUrlSchemeHandler |
| must be created and registered in a profile. |
| |
| \sa QWebEngineUrlSchemeHandler |
| */ |
| |
| /*! |
| \enum QWebEngineUrlScheme::Syntax |
| |
| This enum type lists types of URL syntax. |
| |
| To apply the same-origin policy to a custom URL scheme, WebEngine must be able |
| to compute the origin (host and port combination) of a URL. The \c {Host...} |
| options indicate that the URL scheme conforms to the standard URL syntax (like |
| \c http) and automatically enable the same-origin policy. The \c {Path} |
| option indicates that the URL scheme uses a non-standard syntax and that the |
| same-origin policy cannot be applied. |
| |
| \value HostPortAndUserInformation |
| The authority component of a URL of this type has all of the standard |
| elements: host, port, user name, and password. A URL without a port will use |
| the \l defaultPort (which \e must not be \l PortUnspecified). |
| |
| \value HostAndPort |
| The authority component of a URL of this type has only the host and port |
| elements. A URL without a port will use the \l defaultPort (which \e must not |
| be \l PortUnspecified). |
| |
| \value Host |
| The authority component of a URL of this type has only the host part and no |
| port. The \l defaultPort \e must be set to \l PortUnspecified. |
| |
| \value Path |
| A URL of this type has no authority component at all. Everything after scheme |
| name and separator character (:) will be preserved as is without validation |
| or canonicalization. All URLs of such a scheme will be considered as having |
| the same origin (unless the \c NoAccessAllowed flag is used). |
| */ |
| |
| /*! |
| \enum QWebEngineUrlScheme::SpecialPort |
| |
| This enum type defines special values for \l defaultPort. |
| |
| \value PortUnspecified |
| Indicates that the URL scheme does not have a port element. |
| */ |
| |
| /*! |
| \enum QWebEngineUrlScheme::Flag |
| |
| This enum type specifies security options that should apply to a URL scheme. |
| |
| \value SecureScheme |
| Indicates that the URL scheme is |
| \l{https://www.w3.org/TR/powerful-features/#is-origin-trustworthy}{potentially |
| trustworthy}. This flag should only be applied to URL schemes which ensure |
| data authenticity, confidentiality, and integrity, either through encryption |
| or other means. Examples of secure builtin schemes include \c https |
| (authenticated and encrypted) and \c qrc (local resources only), whereas \c |
| http is an example of an insecure scheme. |
| |
| \value LocalScheme |
| Indicates that the URL scheme provides access to local resources. The purpose |
| of this flag is to prevent network content from accessing local resources. |
| Only schemes with the \c LocalAccessAllowed flag may load resources from a |
| scheme with the \c Local flag. The only builtin schemes with this flag are \c |
| file and \c qrc. |
| |
| \value LocalAccessAllowed |
| Indicates that content from this scheme should be allowed to load resources |
| from schemes with the \c Local flag. |
| |
| \value NoAccessAllowed |
| Indicates that all content from this scheme should be forced to have unique |
| opaque origins: no two resources will have the same origin. |
| |
| \value ServiceWorkersAllowed |
| Indicates that the Service Workers API should be enabled. |
| |
| \value ViewSourceAllowed |
| Indicates that the View Source feature should be enabled. |
| |
| \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) {} |
| |
| /*! |
| Constructs a web engine URL scheme with default values. |
| */ |
| QWebEngineUrlScheme::QWebEngineUrlScheme() |
| : QWebEngineUrlScheme(QWebEngineUrlSchemePrivate::defaultConstructed()) |
| { |
| } |
| |
| /*! |
| Constructs a web engine URL scheme with given \a name. |
| */ |
| QWebEngineUrlScheme::QWebEngineUrlScheme(const QByteArray &name) |
| : QWebEngineUrlScheme() |
| { |
| setName(name); |
| } |
| |
| /*! |
| Copies \a that. |
| */ |
| QWebEngineUrlScheme::QWebEngineUrlScheme(const QWebEngineUrlScheme &that) = default; |
| |
| /*! |
| Copies \a that. |
| */ |
| QWebEngineUrlScheme &QWebEngineUrlScheme::operator=(const QWebEngineUrlScheme &that) = default; |
| |
| /*! |
| Moves \a that. |
| */ |
| QWebEngineUrlScheme::QWebEngineUrlScheme(QWebEngineUrlScheme &&that) = default; |
| |
| /*! |
| Moves \a that. |
| */ |
| QWebEngineUrlScheme &QWebEngineUrlScheme::operator=(QWebEngineUrlScheme &&that) = default; |
| |
| /*! |
| Destructs this object. |
| */ |
| QWebEngineUrlScheme::~QWebEngineUrlScheme() = default; |
| |
| /*! |
| Returns \c true if this and \a that object are equal. |
| */ |
| bool QWebEngineUrlScheme::operator==(const QWebEngineUrlScheme &that) const |
| { |
| return (d == that.d) |
| || (d->name == that.d->name |
| && d->type == that.d->type |
| && d->default_port == that.d->default_port |
| && d->flags == that.d->flags); |
| } |
| |
| /*! |
| \fn bool QWebEngineUrlScheme::operator!=(const QWebEngineUrlScheme &that) const |
| |
| Returns \c true if this and \a that object are not equal. |
| */ |
| |
| /*! |
| Returns the name of this URL scheme. |
| |
| The default value is an empty string. |
| |
| \sa setName() |
| */ |
| QByteArray QWebEngineUrlScheme::name() const |
| { |
| return QByteArray::fromStdString(d->name); |
| } |
| |
| /*! |
| Sets the name of this URL scheme to \a newValue. |
| |
| \note The name is automatically converted to lower case. |
| |
| \sa name() |
| */ |
| void QWebEngineUrlScheme::setName(const QByteArray &newValue) |
| { |
| d->name = newValue.toLower().toStdString(); |
| } |
| |
| /*! |
| Returns the syntax type of this URL scheme. |
| |
| The default value is \c Path. |
| |
| \sa Syntax, setSyntax() |
| */ |
| QWebEngineUrlScheme::Syntax QWebEngineUrlScheme::syntax() const |
| { |
| return static_cast<Syntax>(d->type); |
| } |
| |
| /*! |
| Sets the syntax type of this URL scheme to \a newValue. |
| |
| \sa Syntax, syntax() |
| */ |
| void QWebEngineUrlScheme::setSyntax(Syntax newValue) |
| { |
| d->type = static_cast<url::SchemeType>(newValue); |
| } |
| |
| /*! |
| Returns the default port of this URL scheme. |
| |
| The default value is \c PortUnspecified. |
| |
| \sa setDefaultPort() |
| */ |
| int QWebEngineUrlScheme::defaultPort() const |
| { |
| return d->default_port; |
| } |
| |
| /*! |
| Sets the default port of this URL scheme to \a newValue. |
| |
| \sa defaultPort() |
| */ |
| void QWebEngineUrlScheme::setDefaultPort(int newValue) |
| { |
| d->default_port = newValue; |
| } |
| |
| /*! |
| Returns the flags for this URL scheme. |
| |
| The default value is an empty set of flags. |
| |
| \sa Flags, setFlags() |
| */ |
| QWebEngineUrlScheme::Flags QWebEngineUrlScheme::flags() const |
| { |
| return Flags(d->flags); |
| } |
| |
| /*! |
| Sets the flags for this URL scheme to \a newValue. |
| |
| \sa Flags, flags() |
| */ |
| void QWebEngineUrlScheme::setFlags(Flags newValue) |
| { |
| d->flags = newValue; |
| } |
| |
| /*! |
| Registers \a scheme with the web engine's URL parser and security model. |
| |
| It is recommended that all custom URL schemes are first registered with this |
| function at application startup, even if the default options are to be used. |
| |
| \warning This function must be called early at application startup, before |
| creating any WebEngine classes. Late calls will be ignored. |
| |
| \sa schemeByName() |
| */ |
| void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme) |
| { |
| if (scheme.d->name.empty()) { |
| qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme name cannot be empty"; |
| return; |
| } |
| |
| bool needsPort = scheme.d->has_port_component(); |
| bool hasPort = scheme.d->default_port != url::PORT_UNSPECIFIED; |
| if (needsPort && !hasPort) { |
| qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "needs a default port"; |
| return; |
| } |
| |
| if (url::CustomScheme::FindScheme(scheme.d->name)) { |
| qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "already registered"; |
| return; |
| } |
| |
| if (url::IsStandard(scheme.d->name.data(), url::Component(0, static_cast<int>(scheme.d->name.size())))) { |
| qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "is a standard scheme"; |
| return; |
| } |
| |
| if (g_schemesLocked) { |
| qWarning() << "QWebEngineUrlScheme::registerScheme: Too late to register scheme" << scheme.name(); |
| return; |
| } |
| |
| url::CustomScheme::AddScheme(*scheme.d); |
| } |
| |
| /*! |
| Returns the web engine URL scheme with the given \a name or the |
| default-constructed scheme. |
| |
| \sa registerScheme() |
| */ |
| QWebEngineUrlScheme QWebEngineUrlScheme::schemeByName(const QByteArray &name) |
| { |
| base::StringPiece namePiece{ name.data(), static_cast<size_t>(name.size()) }; |
| if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(namePiece)) |
| return QWebEngineUrlScheme(new QWebEngineUrlSchemePrivate(*cs)); |
| return QWebEngineUrlScheme(); |
| } |
| |
| void QWebEngineUrlScheme::lockSchemes() |
| { |
| g_schemesLocked = true; |
| } |
| |
| QT_END_NAMESPACE |