mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 05:17:34 +02:00
Add generalized ResourceRequest
This commit is contained in:
parent
260404f1fb
commit
86c82a2b2d
2 changed files with 235 additions and 0 deletions
138
libraries/networking/src/ResourceManager.cpp
Normal file
138
libraries/networking/src/ResourceManager.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
//
|
||||
// ResourceManager.cpp
|
||||
//
|
||||
// Created by Ryan Huffman on 2015/07/23
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "AssetClient.h"
|
||||
#include "AssetRequest.h"
|
||||
#include "NetworkAccessManager.h"
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
const QString URL_SCHEME_FILE = "file";
|
||||
const QString URL_SCHEME_HTTP = "http";
|
||||
const QString URL_SCHEME_HTTPS = "https";
|
||||
const QString URL_SCHEME_FTP = "ftp";
|
||||
const QString URL_SCHEME_ATP = "atp";
|
||||
|
||||
ResourceRequest::ResourceRequest(QObject* parent, const QUrl& url) :
|
||||
QObject(parent),
|
||||
_url(url) {
|
||||
}
|
||||
|
||||
void HTTPResourceRequest::doSend() {
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest networkRequest = QNetworkRequest(_url);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
|
||||
if (!_cacheEnabled) {
|
||||
networkRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
|
||||
}
|
||||
|
||||
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=]() {
|
||||
if (_state != IN_PROGRESS) return;
|
||||
|
||||
_state = FINISHED;
|
||||
auto error = reply->error();
|
||||
qDebug() << "Loaded " << _url;
|
||||
if (error == QNetworkReply::NoError) {
|
||||
_data = reply->readAll();
|
||||
_result = ResourceRequest::SUCCESS;
|
||||
emit finished();
|
||||
} else if (error == QNetworkReply::TimeoutError) {
|
||||
_result = ResourceRequest::TIMEOUT;
|
||||
emit finished();
|
||||
} else {
|
||||
_result = ResourceRequest::ERROR;
|
||||
emit finished();
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void FileResourceRequest::doSend() {
|
||||
QString filename = _url.toLocalFile();
|
||||
QFile file(filename);
|
||||
_state = FINISHED;
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
_data = file.readAll();
|
||||
_result = ResourceRequest::SUCCESS;
|
||||
emit finished();
|
||||
} else {
|
||||
_result = ResourceRequest::ERROR;
|
||||
emit finished();
|
||||
}
|
||||
}
|
||||
|
||||
void ATPResourceRequest::doSend() {
|
||||
// Make request to atp
|
||||
auto assetClient = DependencyManager::get<AssetClient>();
|
||||
auto hash = _url.path();
|
||||
|
||||
auto request = assetClient->create(hash);
|
||||
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
QObject::connect(request, &AssetRequest::finished, [this](AssetRequest* req) mutable {
|
||||
if (_state != IN_PROGRESS) return;
|
||||
_state = FINISHED;
|
||||
if (true) {
|
||||
_data = req->getData();
|
||||
_result = ResourceRequest::SUCCESS;
|
||||
emit finished();
|
||||
} else {
|
||||
_result = ResourceRequest::ERROR;
|
||||
emit finished();
|
||||
}
|
||||
});
|
||||
|
||||
request->start();
|
||||
}
|
||||
|
||||
const int TIMEOUT_MS = 2000;
|
||||
void ResourceRequest::send() {
|
||||
connect(&_sendTimer, &QTimer::timeout, this, &ResourceRequest::timeout);
|
||||
_sendTimer.setSingleShot(true);
|
||||
_sendTimer.start(TIMEOUT_MS);
|
||||
_state = IN_PROGRESS;
|
||||
doSend();
|
||||
}
|
||||
|
||||
void ResourceRequest::timeout() {
|
||||
// TIMEOUT!!
|
||||
if (_state == UNSENT) {
|
||||
qDebug() << "TImed out loading " << _url;
|
||||
_state = FINISHED;
|
||||
_result = TIMEOUT;
|
||||
emit finished();
|
||||
}
|
||||
}
|
||||
|
||||
ResourceRequest* ResourceManager::createResourceRequest(QObject* parent, const QUrl& url) {
|
||||
auto scheme = url.scheme();
|
||||
if (scheme == URL_SCHEME_FILE) {
|
||||
return new FileResourceRequest(parent, url);
|
||||
} else if (scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP) {
|
||||
return new HTTPResourceRequest(parent, url);
|
||||
} else if (scheme == URL_SCHEME_ATP) {
|
||||
return new ATPResourceRequest(parent, url);
|
||||
}
|
||||
|
||||
qDebug() << "Failed to load: " << url.url();
|
||||
|
||||
return nullptr;
|
||||
}
|
97
libraries/networking/src/ResourceManager.h
Normal file
97
libraries/networking/src/ResourceManager.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// ResourceManager.h
|
||||
//
|
||||
// Created by Ryan Huffman on 2015/07/23
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#ifndef hifi_ResourceManager_h
|
||||
#define hifi_ResourceManager_h
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QUrl>
|
||||
|
||||
class ResourceRequest : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResourceRequest(QObject* parent, const QUrl& url);
|
||||
|
||||
enum State {
|
||||
UNSENT = 0,
|
||||
IN_PROGRESS,
|
||||
FINISHED
|
||||
};
|
||||
|
||||
enum Result {
|
||||
SUCCESS,
|
||||
ERROR,
|
||||
TIMEOUT,
|
||||
NOT_FOUND
|
||||
};
|
||||
|
||||
void send();
|
||||
QByteArray moveData() { return _data; }
|
||||
State getState() const { return _state; }
|
||||
Result getResult() const { return _result; }
|
||||
QUrl getUrl() const { return _url; }
|
||||
|
||||
void setCacheEnabled(bool value) { _cacheEnabled = value; }
|
||||
|
||||
signals:
|
||||
void progress(uint64_t bytesReceived, uint64_t bytesTotal);
|
||||
void finished();
|
||||
|
||||
protected:
|
||||
virtual void doSend() = 0;
|
||||
|
||||
QUrl _url;
|
||||
State _state = UNSENT;
|
||||
Result _result;
|
||||
QTimer _sendTimer;
|
||||
QByteArray _data;
|
||||
bool _cacheEnabled { true };
|
||||
|
||||
private slots:
|
||||
void timeout();
|
||||
};
|
||||
|
||||
class HTTPResourceRequest : public ResourceRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HTTPResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
|
||||
|
||||
protected:
|
||||
virtual void doSend() override;
|
||||
};
|
||||
|
||||
class FileResourceRequest : public ResourceRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FileResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
|
||||
|
||||
protected:
|
||||
virtual void doSend() override;
|
||||
};
|
||||
|
||||
class ATPResourceRequest : public ResourceRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ATPResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
|
||||
|
||||
protected:
|
||||
virtual void doSend() override;
|
||||
};
|
||||
|
||||
class ResourceManager {
|
||||
public:
|
||||
static ResourceRequest* createResourceRequest(QObject* parent, const QUrl& url);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue