diff --git a/libraries/networking/src/ResourceManager.cpp b/libraries/networking/src/ResourceManager.cpp index 6492e9171e..e2c1cf2431 100644 --- a/libraries/networking/src/ResourceManager.cpp +++ b/libraries/networking/src/ResourceManager.cpp @@ -116,3 +116,51 @@ ResourceRequest* ResourceManager::createResourceRequest(QObject* parent, const Q request->moveToThread(&_thread); return request; } + + +bool ResourceManager::resourceExists(const QUrl& url) { + auto scheme = url.scheme(); + if (scheme == URL_SCHEME_FILE) { + QFileInfo file { url.toString() }; + return file.exists(); + } else if (scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP) { + auto& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest request { url }; + + request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + request.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); + + auto reply = networkAccessManager.head(request); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + + reply->deleteLater(); + + return reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200; + } else if (scheme == URL_SCHEME_ATP) { + auto request = new AssetResourceRequest(url); + ByteRange range; + range.fromInclusive = 1; + range.toExclusive = 1; + request->setByteRange(range); + request->setCacheEnabled(false); + + QEventLoop loop; + + QObject::connect(request, &AssetResourceRequest::finished, &loop, &QEventLoop::quit); + + request->send(); + + loop.exec(); + + request->deleteLater(); + + return request->getResult() == ResourceRequest::Success; + } + + qCDebug(networking) << "Unknown scheme (" << scheme << ") for URL: " << url.url(); + return false; +} + diff --git a/libraries/networking/src/ResourceManager.h b/libraries/networking/src/ResourceManager.h index d193c39cae..41da892701 100644 --- a/libraries/networking/src/ResourceManager.h +++ b/libraries/networking/src/ResourceManager.h @@ -36,6 +36,10 @@ public: static void init(); static void cleanup(); + // Blocking call to check if a resource exists. This function uses a QEventLoop internally + // to return to the calling thread so that events can still be processed. + static bool resourceExists(const QUrl& url); + private: static QThread _thread;