diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-01-03 10:32:01 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2020-01-03 12:02:18 +0000 |
commit | 01bbd7e41ac8444d2282ac6ca1862c3748f685a1 (patch) | |
tree | ad46297d0f39957fd2597f19f2e5eacbeb0240d5 /src | |
parent | a4150b040e8492e070d6bfefb190ae0852644f11 (diff) |
QV4::ExecutionEngine: provide QNAM accessor
In XMLHttpRequest, we need to get the QNetworkAccessManager from the
engine. However, if the request originates from a WorkerScript, there
exists no qmlEngine. We therefore add a new indirection to access the
QNAM, and set it up accordinly in registerWorkerScript.
Fixes: QTBUG-81055
Change-Id: I8915202b6d6b7139c8386304b3d1d7a22a82045e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 11 | ||||
-rw-r--r-- | src/qml/qml/qqmlxmlhttprequest.cpp | 2 | ||||
-rw-r--r-- | src/qmlworkerscript/qquickworkerscript.cpp | 11 |
4 files changed, 27 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 885f06a3e3..23582e0ccb 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2323,4 +2323,9 @@ int ExecutionEngine::registerExtension() return registrationData()->extensionCount++; } +QNetworkAccessManager *QV4::detail::getNetworkAccessManager(ExecutionEngine *engine) +{ + return engine->qmlEngine()->networkAccessManager(); +} + QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index d233347060..081859f4cc 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -91,7 +91,14 @@ class PageAllocation; QT_BEGIN_NAMESPACE -namespace QV4 { struct QObjectMethod; } +class QNetworkAccessManager; + +namespace QV4 { +struct QObjectMethod; +namespace detail { +QNetworkAccessManager *getNetworkAccessManager(ExecutionEngine *engine); +} +} // Used to allow a QObject method take and return raw V4 handles without having to expose // 48 in the public API. @@ -348,6 +355,8 @@ public: FunctionObject *getStackFunction() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetStack_Function); } FunctionObject *thrower() const { return reinterpret_cast<FunctionObject *>(jsObjects + ThrowerObject); } + std::function<QNetworkAccessManager*(ExecutionEngine*)> networkAccessManager = detail::getNetworkAccessManager; + enum JSStrings { String_Empty, String_undefined, diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 4db0562c0e..021aa369fa 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1647,7 +1647,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject Scope scope(f->engine()); const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f); - QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->qmlEngine()->networkAccessManager(), scope.engine); + QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->networkAccessManager(scope.engine), scope.engine); Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocate<QQmlXMLHttpRequestWrapper>(r)); ScopedObject proto(scope, ctor->d()->proto); w->setPrototypeUnchecked(proto); diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index 8b236697b9..c39433c74d 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -130,6 +130,7 @@ struct WorkerScript : public QV4::ExecutionEngine { QQuickWorkerScriptEnginePrivate *p = nullptr; QUrl source; QQuickWorkerScript *owner = nullptr; + QScopedPointer<QNetworkAccessManager> scriptLocalNAM; int id = -1; }; @@ -389,6 +390,16 @@ WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent) QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(this, name, QQuickWorkerScriptEnginePrivate::method_sendMessage, 1)); api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), sendMessage); globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api); + networkAccessManager = [this](QV4::ExecutionEngine *engine){ + auto *workerScript = static_cast<WorkerScript *>(engine); + if (workerScript->scriptLocalNAM) + return workerScript->scriptLocalNAM.get(); + if (auto *namFactory = p->qmlengine->networkAccessManagerFactory()) + workerScript->scriptLocalNAM.reset(namFactory->create(p)); + else + workerScript->scriptLocalNAM.reset(new QNetworkAccessManager(p)); + return workerScript->scriptLocalNAM.get(); + }; } int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) |