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,44 @@ 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/" )) {
45+ path = this ->configRoot .filePath (path.sliced (5 ));
46+ } else if (!path.startsWith (" /" )) {
47+ qCDebug (logQsIntercept) << " Blackholed import URL" << url;
48+ return QUrl (" qrc:/qs-blackhole" );
49+ }
50+
51+ // Some types such as Image take into account where they are loading from, and force
52+ // asynchronous loading over a network. qs: is considered to be over a network.
53+ // In those cases we want to return a file:// url so asynchronous loading is not forced.
54+ if (type == QQmlAbstractUrlInterceptor::DataType::UrlString) {
55+ // Qt.resolvedUrl and context->resolvedUrl can use this on qml files, in which
56+ // case we want to keep the intercept, otherwise objects created from those paths
57+ // will not be able to use singletons.
58+ if (path.endsWith (" .qml" )) return url;
59+
60+ auto newUrl = url;
61+ newUrl.setScheme (" file" );
62+ // above check asserts path starts with /qs/
63+ newUrl.setPath (path);
64+ qCDebug (logQsIntercept) << " Rewrote intercept" << url << " to" << newUrl;
65+ return newUrl;
66+ }
4967 }
5068
5169 return url;
@@ -67,10 +85,12 @@ qint64 QsInterceptDataReply::readData(char* data, qint64 maxSize) {
6785}
6886
6987QsInterceptNetworkAccessManager::QsInterceptNetworkAccessManager (
88+ const QDir& configRoot,
7089 const QHash<QString, QString>& fileIntercepts,
7190 QObject* parent
7291)
7392 : QNetworkAccessManager(parent)
93+ , configRoot(configRoot)
7494 , fileIntercepts(fileIntercepts) {}
7595
7696QNetworkReply* QsInterceptNetworkAccessManager::createRequest (
@@ -79,19 +99,26 @@ QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
7999 QIODevice* outgoingData
80100) {
81101 auto url = req.url ();
82- if (url.scheme () == " qsintercept" ) {
102+
103+ if (url.scheme () == " qs" ) {
83104 auto path = url.path ();
105+
106+ if (path.startsWith (" @/qs/" )) path = this ->configRoot .filePath (path.sliced (5 ));
107+ // otherwise pass through to fs
108+
84109 qCDebug (logQsIntercept) << " Got intercept for" << path << " contains"
85110 << this ->fileIntercepts .value (path);
86- auto data = this -> fileIntercepts . value (path);
87- if (data != nullptr ) {
111+
112+ if (auto data = this -> fileIntercepts . value (path); !data. isEmpty () ) {
88113 return new QsInterceptDataReply (data, this );
89114 }
90115
91116 auto fileReq = req;
92117 auto fileUrl = req.url ();
93118 fileUrl.setScheme (" file" );
119+ fileUrl.setPath (path);
94120 qCDebug (logQsIntercept) << " Passing through intercept" << url << " to" << fileUrl;
121+
95122 fileReq.setUrl (fileUrl);
96123 return this ->QNetworkAccessManager ::createRequest (op, fileReq, outgoingData);
97124 }
@@ -100,5 +127,5 @@ QNetworkReply* QsInterceptNetworkAccessManager::createRequest(
100127}
101128
102129QNetworkAccessManager* QsInterceptNetworkAccessManagerFactory::create (QObject* parent) {
103- return new QsInterceptNetworkAccessManager (this ->fileIntercepts , parent);
130+ return new QsInterceptNetworkAccessManager (this ->configRoot , this -> fileIntercepts , parent);
104131}
0 commit comments