11#include " qsintercept.hpp"
22#include < cstring>
33
4+ #include < qdir.h>
45#include < qhash.h>
56#include < qiodevice.h>
67#include < qlogging.h>
@@ -25,27 +26,42 @@ QUrl QsUrlInterceptor::intercept(
2526 auto url = originalUrl;
2627
2728 if (url.scheme () == " root" ) {
28- url.setScheme (" qsintercept " );
29+ url.setScheme (" qs " );
2930
3031 auto path = url.path ();
3132 if (path.startsWith (' /' )) path = path.sliced (1 );
32- url.setPath (this -> configRoot . filePath ( path) );
33+ url.setPath (" @/qs/ " % path);
3334
3435 qCDebug (logQsIntercept) << " Rewrote root intercept" << originalUrl << " to" << url;
3536 }
3637
37- // Some types such as Image take into account where they are loading from, and force
38- // asynchronous loading over a network. qsintercept is considered to be over a network.
39- if (type == QQmlAbstractUrlInterceptor::DataType::UrlString && url.scheme () == " qsintercept" ) {
40- // Qt.resolvedUrl and context->resolvedUrl can use this on qml files, in which
41- // case we want to keep the intercept, otherwise objects created from those paths
42- // will not be able to use singletons.
43- if (url.path ().endsWith (" .qml" )) return url;
44-
45- auto newUrl = url;
46- newUrl.setScheme (" file" );
47- qCDebug (logQsIntercept) << " Rewrote intercept" << url << " to" << newUrl;
48- return newUrl;
38+ if (url.scheme () == " qs" ) {
39+ auto path = url.path ();
40+
41+ // Our import path is on "qs:@/".
42+ // We want to blackhole any import resolution outside of the config folder as it breaks Qt
43+ // but NOT file lookups that might be on "qs:/" due to a missing "file:/" prefix.
44+ if (!path.startsWith (" @/qs/" ) && !path.startsWith (" /" )) {
45+ qCDebug (logQsIntercept) << " Blackholed import URL" << url;
46+ return QUrl (" qrc:/qs-blackhole" );
47+ }
48+
49+ // Some types such as Image take into account where they are loading from, and force
50+ // asynchronous loading over a network. qs: is considered to be over a network.
51+ // In those cases we want to return a file:// url so asynchronous loading is not forced.
52+ if (type == QQmlAbstractUrlInterceptor::DataType::UrlString) {
53+ // Qt.resolvedUrl and context->resolvedUrl can use this on qml files, in which
54+ // case we want to keep the intercept, otherwise objects created from those paths
55+ // will not be able to use singletons.
56+ if (path.endsWith (" .qml" )) return url;
57+
58+ auto newUrl = url;
59+ newUrl.setScheme (" file" );
60+ // above check asserts path starts with /qs/
61+ newUrl.setPath (this ->configRoot .filePath (path.sliced (5 )));
62+ qCDebug (logQsIntercept) << " Rewrote intercept" << url << " to" << newUrl;
63+ return newUrl;
64+ }
4965 }
5066
5167 return url;
@@ -67,10 +83,12 @@ qint64 QsInterceptDataReply::readData(char* data, qint64 maxSize) {
6783}
6884
6985QsInterceptNetworkAccessManager::QsInterceptNetworkAccessManager (
86+ const QDir& configRoot,
7087 const QHash<QString, QString>& fileIntercepts,
7188 QObject* parent
7289)
7390 : QNetworkAccessManager(parent)
91+ , configRoot(configRoot)
7492 , fileIntercepts(fileIntercepts) {}
7593
7694QNetworkReply* QsInterceptNetworkAccessManager::createRequest (
@@ -79,19 +97,26 @@ QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
7997 QIODevice* outgoingData
8098) {
8199 auto url = req.url ();
82- if (url.scheme () == " qsintercept" ) {
100+
101+ if (url.scheme () == " qs" ) {
83102 auto path = url.path ();
103+
104+ if (path.startsWith (" @/qs/" )) path = this ->configRoot .filePath (path.sliced (5 ));
105+ // otherwise pass through to fs
106+
84107 qCDebug (logQsIntercept) << " Got intercept for" << path << " contains"
85108 << this ->fileIntercepts .value (path);
86- auto data = this -> fileIntercepts . value (path);
87- if (data != nullptr ) {
109+
110+ if (auto data = this -> fileIntercepts . value (path); !data. isEmpty () ) {
88111 return new QsInterceptDataReply (data, this );
89112 }
90113
91114 auto fileReq = req;
92115 auto fileUrl = req.url ();
93116 fileUrl.setScheme (" file" );
117+ fileUrl.setPath (path);
94118 qCDebug (logQsIntercept) << " Passing through intercept" << url << " to" << fileUrl;
119+
95120 fileReq.setUrl (fileUrl);
96121 return this ->QNetworkAccessManager ::createRequest (op, fileReq, outgoingData);
97122 }
@@ -100,5 +125,5 @@ QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
100125}
101126
102127QNetworkAccessManager* QsInterceptNetworkAccessManagerFactory::create (QObject* parent) {
103- return new QsInterceptNetworkAccessManager (this ->fileIntercepts , parent);
128+ return new QsInterceptNetworkAccessManager (this ->configRoot , this -> fileIntercepts , parent);
104129}
0 commit comments