Add extension to atp requests

This commit is contained in:
Ryan Huffman 2015-08-27 11:51:45 -07:00
parent c6493b1720
commit a49a1eb0d6
9 changed files with 55 additions and 35 deletions

View file

@ -77,7 +77,7 @@ void AssetServer::run() {
qDebug() << "\tMoving " << filename << " to " << hash; qDebug() << "\tMoving " << filename << " to " << hash;
file.rename(_resourcesDirectory.absoluteFilePath(hash)); file.rename(_resourcesDirectory.absoluteFilePath(hash) + "." + fileInfo.suffix());
} }
} }
} }
@ -85,24 +85,28 @@ void AssetServer::run() {
void AssetServer::handleAssetGetInfo(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) { void AssetServer::handleAssetGetInfo(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) {
QByteArray assetHash; QByteArray assetHash;
MessageID messageID; MessageID messageID;
uint8_t extensionLength;
if (packet->getPayloadSize() < qint64(HASH_HEX_LENGTH + sizeof(messageID))) { if (packet->getPayloadSize() < qint64(HASH_HEX_LENGTH + sizeof(messageID) + sizeof(extensionLength))) {
qDebug() << "ERROR bad file request"; qDebug() << "ERROR bad file request";
return; return;
} }
packet->readPrimitive(&messageID); packet->readPrimitive(&messageID);
assetHash = packet->readWithoutCopy(HASH_HEX_LENGTH); assetHash = packet->readWithoutCopy(HASH_HEX_LENGTH);
packet->readPrimitive(&extensionLength);
QByteArray extension = packet->read(extensionLength);
auto replyPacket = NLPacket::create(PacketType::AssetGetInfoReply); auto replyPacket = NLPacket::create(PacketType::AssetGetInfoReply);
replyPacket->writePrimitive(messageID); replyPacket->writePrimitive(messageID);
replyPacket->write(assetHash); replyPacket->write(assetHash);
QFileInfo fileInfo { _resourcesDirectory.filePath(QString(assetHash)) }; QString fileName = QString(assetHash) + "." + extension;
qDebug() << "Opening file: " << QString(QFileInfo(assetHash).fileName()); QFileInfo fileInfo { _resourcesDirectory.filePath(fileName) };
if (fileInfo.exists() && fileInfo.isReadable()) { if (fileInfo.exists() && fileInfo.isReadable()) {
qDebug() << "Opening file: " << fileInfo.filePath();
replyPacket->writePrimitive(AssetServerError::NO_ERROR); replyPacket->writePrimitive(AssetServerError::NO_ERROR);
replyPacket->writePrimitive(fileInfo.size()); replyPacket->writePrimitive(fileInfo.size());
} else { } else {
@ -117,23 +121,27 @@ void AssetServer::handleAssetGetInfo(QSharedPointer<NLPacket> packet, SharedNode
void AssetServer::handleAssetGet(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) { void AssetServer::handleAssetGet(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) {
MessageID messageID; MessageID messageID;
QByteArray assetHash; QByteArray assetHash;
uint8_t extensionLength;
DataOffset start; DataOffset start;
DataOffset end; DataOffset end;
if (packet->getPayloadSize() < qint64(sizeof(messageID) + HASH_HEX_LENGTH + sizeof(start) + sizeof(end))) { auto minSize = qint64(sizeof(messageID) + HASH_HEX_LENGTH + sizeof(extensionLength) + sizeof(start) + sizeof(end));
if (packet->getPayloadSize() < minSize) {
qDebug() << "ERROR bad file request"; qDebug() << "ERROR bad file request";
return; return;
} }
packet->readPrimitive(&messageID); packet->readPrimitive(&messageID);
assetHash = packet->read(HASH_HEX_LENGTH); assetHash = packet->read(HASH_HEX_LENGTH);
packet->readPrimitive(&extensionLength);
QByteArray extension = packet->read(extensionLength);
packet->readPrimitive(&start); packet->readPrimitive(&start);
packet->readPrimitive(&end); packet->readPrimitive(&end);
qDebug() << "Received a request for the file: " << assetHash << " from " << start << " to " << end; qDebug() << "Received a request for the file (" << messageID << "): " << assetHash << " from " << start << " to " << end;
// Queue task // Queue task
QString filePath = _resourcesDirectory.filePath(QString(assetHash)); QString filePath = _resourcesDirectory.filePath(QString(assetHash) + "." + QString(extension));
auto task = new SendAssetTask(messageID, assetHash, filePath, start, end, senderNode); auto task = new SendAssetTask(messageID, assetHash, filePath, start, end, senderNode);
_taskPool.start(task); _taskPool.start(task);
} }
@ -170,7 +178,7 @@ void AssetServer::handleAssetUpload(QSharedPointer<NLPacketList> packetList, Sha
qDebug() << "Got data: (" << hash << ") "; qDebug() << "Got data: (" << hash << ") ";
QFile file { _resourcesDirectory.filePath(QString(hash)) }; QFile file { _resourcesDirectory.filePath(QString(hash)) + "." + QString(extension) };
if (file.exists()) { if (file.exists()) {
qDebug() << "[WARNING] This file already exists: " << hash; qDebug() << "[WARNING] This file already exists: " << hash;

View file

@ -36,7 +36,7 @@ void SendAssetTask::run() {
qDebug() << "Starting task to send asset: " << _assetHash << " for messageID " << _messageID; qDebug() << "Starting task to send asset: " << _assetHash << " for messageID " << _messageID;
auto replyPacketList = std::unique_ptr<NLPacketList>(new NLPacketList(PacketType::AssetGetReply, QByteArray(), true, true)); auto replyPacketList = std::unique_ptr<NLPacketList>(new NLPacketList(PacketType::AssetGetReply, QByteArray(), true, true));
replyPacketList->write(_assetHash, HASH_HEX_LENGTH); replyPacketList->write(_assetHash);
replyPacketList->writePrimitive(_messageID); replyPacketList->writePrimitive(_messageID);
@ -55,11 +55,11 @@ void SendAssetTask::run() {
replyPacketList->writePrimitive(AssetServerError::NO_ERROR); replyPacketList->writePrimitive(AssetServerError::NO_ERROR);
replyPacketList->writePrimitive(size); replyPacketList->writePrimitive(size);
replyPacketList->write(file.read(size)); replyPacketList->write(file.read(size));
qCDebug(networking) << "Sending asset: " << _assetHash;
} }
file.close(); file.close();
qCDebug(networking) << "Sending asset: " << _assetHash;
} else { } else {
qCDebug(networking) << "Asset not found: " << _assetHash; qCDebug(networking) << "Asset not found: " << _filePath << "(" << _assetHash << ")";
writeError(replyPacketList.get(), AssetServerError::ASSET_NOT_FOUND); writeError(replyPacketList.get(), AssetServerError::ASSET_NOT_FOUND);
} }
} }

View file

@ -28,13 +28,14 @@ AssetClient::AssetClient() {
packetReceiver.registerListener(PacketType::AssetUploadReply, this, "handleAssetUploadReply"); packetReceiver.registerListener(PacketType::AssetUploadReply, this, "handleAssetUploadReply");
} }
AssetRequest* AssetClient::create(QString hash) { AssetRequest* AssetClient::create(QString hash, QString extension) {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
AssetRequest* req; AssetRequest* req;
QMetaObject::invokeMethod(this, "create", QMetaObject::invokeMethod(this, "create",
Qt::BlockingQueuedConnection, Qt::BlockingQueuedConnection,
Q_RETURN_ARG(AssetRequest*, req), Q_RETURN_ARG(AssetRequest*, req),
Q_ARG(QString, hash)); Q_ARG(QString, hash),
Q_ARG(QString, extension));
return req; return req;
} }
@ -48,7 +49,7 @@ AssetRequest* AssetClient::create(QString hash) {
if (assetServer) { if (assetServer) {
auto assetClient = DependencyManager::get<AssetClient>(); auto assetClient = DependencyManager::get<AssetClient>();
auto request = new AssetRequest(assetClient.data(), hash); auto request = new AssetRequest(assetClient.data(), hash, extension);
return request; return request;
} }
@ -56,7 +57,7 @@ AssetRequest* AssetClient::create(QString hash) {
return nullptr; return nullptr;
} }
bool AssetClient::getAsset(QString hash, DataOffset start, DataOffset end, ReceivedAssetCallback callback) { bool AssetClient::getAsset(QString hash, QString extension, DataOffset start, DataOffset end, ReceivedAssetCallback callback) {
if (hash.length() != HASH_HEX_LENGTH) { if (hash.length() != HASH_HEX_LENGTH) {
qDebug() << "Invalid hash size"; qDebug() << "Invalid hash size";
return false; return false;
@ -70,7 +71,12 @@ bool AssetClient::getAsset(QString hash, DataOffset start, DataOffset end, Recei
auto messageID = ++_currentID; auto messageID = ++_currentID;
packet->writePrimitive(messageID); packet->writePrimitive(messageID);
packet->write(hash.toLatin1().constData(), HASH_HEX_LENGTH);
packet->write(hash.toLatin1());
packet->writePrimitive(uint8_t(extension.length()));
packet->write(extension.toLatin1());
packet->writePrimitive(start); packet->writePrimitive(start);
packet->writePrimitive(end); packet->writePrimitive(end);
@ -84,7 +90,7 @@ bool AssetClient::getAsset(QString hash, DataOffset start, DataOffset end, Recei
return false; return false;
} }
bool AssetClient::getAssetInfo(QString hash, GetInfoCallback callback) { bool AssetClient::getAssetInfo(QString hash, QString extension, GetInfoCallback callback) {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer); SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
@ -94,6 +100,8 @@ bool AssetClient::getAssetInfo(QString hash, GetInfoCallback callback) {
auto messageID = ++_currentID; auto messageID = ++_currentID;
packet->writePrimitive(messageID); packet->writePrimitive(messageID);
packet->write(hash.toLatin1().constData(), HASH_HEX_LENGTH); packet->write(hash.toLatin1().constData(), HASH_HEX_LENGTH);
packet->writePrimitive(uint8_t(extension.length()));
packet->write(extension.toLatin1());
nodeList->sendPacket(std::move(packet), *assetServer); nodeList->sendPacket(std::move(packet), *assetServer);

View file

@ -36,7 +36,7 @@ class AssetClient : public QObject, public Dependency {
public: public:
AssetClient(); AssetClient();
Q_INVOKABLE AssetRequest* create(QString hash); Q_INVOKABLE AssetRequest* create(QString hash, QString extension);
private slots: private slots:
void handleAssetGetInfoReply(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode); void handleAssetGetInfoReply(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
@ -47,8 +47,8 @@ private:
friend class AssetRequest; friend class AssetRequest;
friend class Menu; friend class Menu;
bool getAssetInfo(QString hash, GetInfoCallback callback); bool getAssetInfo(QString hash, QString extension, GetInfoCallback callback);
bool getAsset(QString hash, DataOffset start, DataOffset end, ReceivedAssetCallback callback); bool getAsset(QString hash, QString extension, DataOffset start, DataOffset end, ReceivedAssetCallback callback);
bool uploadAsset(QByteArray data, QString extension, UploadResultCallback callback); bool uploadAsset(QByteArray data, QString extension, UploadResultCallback callback);
static MessageID _currentID; static MessageID _currentID;

View file

@ -18,9 +18,10 @@
#include "NodeList.h" #include "NodeList.h"
AssetRequest::AssetRequest(QObject* parent, QString hash) : AssetRequest::AssetRequest(QObject* parent, QString hash, QString extension) :
QObject(parent), QObject(parent),
_hash(hash) _hash(hash),
_extension(extension)
{ {
} }
@ -34,7 +35,7 @@ void AssetRequest::start() {
_state = WAITING_FOR_INFO; _state = WAITING_FOR_INFO;
auto assetClient = DependencyManager::get<AssetClient>(); auto assetClient = DependencyManager::get<AssetClient>();
assetClient->getAssetInfo(_hash, [this](bool success, AssetInfo info) { assetClient->getAssetInfo(_hash, _extension, [this](bool success, AssetInfo info) {
_info = info; _info = info;
_data.resize(info.size); _data.resize(info.size);
const DataOffset CHUNK_SIZE = 1024000000; const DataOffset CHUNK_SIZE = 1024000000;
@ -48,7 +49,7 @@ void AssetRequest::start() {
++_numPendingRequests; ++_numPendingRequests;
auto start = i * CHUNK_SIZE; auto start = i * CHUNK_SIZE;
auto end = std::min((i + 1) * CHUNK_SIZE, info.size); auto end = std::min((i + 1) * CHUNK_SIZE, info.size);
assetClient->getAsset(_hash, start, end, [this, start, end](bool success, QByteArray data) { assetClient->getAsset(_hash, _extension, start, end, [this, start, end](bool success, QByteArray data) {
Q_ASSERT(data.size() == (end - start)); Q_ASSERT(data.size() == (end - start));
if (success) { if (success) {

View file

@ -20,7 +20,7 @@
#include "AssetUtils.h" #include "AssetUtils.h"
class AssetRequest : public QObject { class AssetRequest : public QObject {
Q_OBJECT Q_OBJECT
public: public:
enum State { enum State {
NOT_STARTED = 0, NOT_STARTED = 0,
@ -36,7 +36,7 @@ public:
Error, Error,
}; };
AssetRequest(QObject* parent, QString hash); AssetRequest(QObject* parent, QString hash, QString extension);
Q_INVOKABLE void start(); Q_INVOKABLE void start();
@ -44,7 +44,7 @@ public:
signals: signals:
void finished(AssetRequest*); void finished(AssetRequest*);
void progress(uint64_t totalReceived, uint64_t total); void progress(qint64 totalReceived, qint64 total);
private: private:
State _state = NOT_STARTED; State _state = NOT_STARTED;
@ -52,6 +52,7 @@ private:
AssetInfo _info; AssetInfo _info;
uint64_t _totalReceived { 0 }; uint64_t _totalReceived { 0 };
QString _hash; QString _hash;
QString _extension;
QByteArray _data; QByteArray _data;
int _numPendingRequests { 0 }; int _numPendingRequests { 0 };
}; };

View file

@ -13,18 +13,20 @@
#include "AssetClient.h" #include "AssetClient.h"
#include "AssetRequest.h" #include "AssetRequest.h"
void ATPResourceRequest::doSend() { void AssetResourceRequest::doSend() {
// Make request to atp // Make request to atp
auto assetClient = DependencyManager::get<AssetClient>(); auto assetClient = DependencyManager::get<AssetClient>();
auto hash = _url.path().split(".", QString::SkipEmptyParts)[0]; auto parts = _url.path().split(".", QString::SkipEmptyParts);
auto hash = parts[0];
auto extension = parts.length() > 1 ? parts[1] : "";
auto request = assetClient->create(hash); auto request = assetClient->create(hash, extension);
if (!request) { if (!request) {
return; return;
} }
connect(request, &AssetRequest::progress, this, &ATPResourceRequest::progress); connect(request, &AssetRequest::progress, this, &AssetResourceRequest::progress);
QObject::connect(request, &AssetRequest::finished, [this](AssetRequest* req) mutable { QObject::connect(request, &AssetRequest::finished, [this](AssetRequest* req) mutable {
if (_state != IN_PROGRESS) return; if (_state != IN_PROGRESS) return;
_state = FINISHED; _state = FINISHED;
@ -41,7 +43,7 @@ void ATPResourceRequest::doSend() {
request->start(); request->start();
} }
void ATPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { void AssetResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
qDebug() << "Got asset data: " << bytesReceived << " / " << bytesTotal; qDebug() << "Got asset data: " << bytesReceived << " / " << bytesTotal;
emit progress(bytesReceived, bytesTotal); emit progress(bytesReceived, bytesTotal);
} }

View file

@ -15,10 +15,10 @@
#include "ResourceRequest.h" #include "ResourceRequest.h"
class ATPResourceRequest : public ResourceRequest { class AssetResourceRequest : public ResourceRequest {
Q_OBJECT Q_OBJECT
public: public:
ATPResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { } AssetResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
protected: protected:
virtual void doSend() override; virtual void doSend() override;

View file

@ -29,7 +29,7 @@ ResourceRequest* ResourceManager::createResourceRequest(QObject* parent, const Q
} else if (scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP) { } else if (scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP) {
return new HTTPResourceRequest(parent, url); return new HTTPResourceRequest(parent, url);
} else if (scheme == URL_SCHEME_ATP) { } else if (scheme == URL_SCHEME_ATP) {
return new ATPResourceRequest(parent, url); return new AssetResourceRequest(parent, url);
} }
qDebug() << "Failed to load: " << url.url(); qDebug() << "Failed to load: " << url.url();