Beispiel #1
0
void AssetUpload::start() {
    if (QThread::currentThread() != thread()) {
        QMetaObject::invokeMethod(this, "start");
        return;
    }
    
    if (_data.isEmpty() && !_filename.isEmpty()) {
        // try to open the file at the given filename
        QFile file { _filename };
        
        if (file.open(QIODevice::ReadOnly)) {            
            _data = file.readAll();
        } else {
            // we couldn't open the file - set the error result
            _error = FileOpenError;
            
            // emit that we are done
            emit finished(this, QString());

            return;
        }
    }
    
    // ask the AssetClient to upload the asset and emit the proper signals from the passed callback
    auto assetClient = DependencyManager::get<AssetClient>();
   
    if (!_filename.isEmpty()) {
        qCDebug(asset_client) << "Attempting to upload" << _filename << "to asset-server.";
    }
    
    assetClient->uploadAsset(_data, [this](bool responseReceived, AssetServerError error, const QString& hash){
        if (!responseReceived) {
            _error = NetworkError;
        } else {
            switch (error) {
                case AssetServerError::NoError:
                    _error = NoError;
                    break;
                case AssetServerError::AssetTooLarge:
                    _error = TooLarge;
                    break;
                case AssetServerError::PermissionDenied:
                    _error = PermissionDenied;
                    break;
                case AssetServerError::FileOperationFailed:
                    _error = ServerFileError;
                    break;
                default:
                    _error = FileOpenError;
                    break;
            }
        }
        
        if (_error == NoError && hash == hashData(_data).toHex()) {
            saveToCache(getATPUrl(hash), _data);
        }
        
        emit finished(this, hash);
    });
}
Beispiel #2
0
QString ContentDisplay::generateFileMD5(QString fileName)
{
    QFile contentFile(fileName);
    if(!contentFile.open(QFile::ReadOnly)) {
        displayErrorMessage("Could not open content file: \n" + fileName);
        return QString("");
    }
    QString hashData(QCryptographicHash::hash(contentFile.readAll(), QCryptographicHash::Md5).toHex().constData());
    contentFile.close();

    return hashData;
}
Beispiel #3
0
static int processSNI( INOUT SSL_HANDSHAKE_INFO *handshakeInfo,
					   INOUT STREAM *stream, 
					   IN_LENGTH_SHORT_Z const int extLength,
					   const BOOLEAN isServer )
	{
	BYTE nameBuffer[ MAX_DNS_SIZE + 8 ];
	int listLen, nameLen, status;

	assert( isWritePtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	REQUIRES( extLength >= 0 && extLength < MAX_INTLENGTH_SHORT );

	/* If we're the client then the server should have sent us an empty
	   extension */
	if( !isServer )
		return( ( extLength != 0 ) ? CRYPT_ERROR_BADDATA : CRYPT_OK );

	/* Remember that we've seen the server-name extension so that we can 
	   send a zero-length reply to the client */
	handshakeInfo->needSNIResponse = TRUE;

	/* Read the extension wrapper */
	status = listLen = readUint16( stream );
	if( cryptStatusError( status ) )
		return( status );
	if( listLen != extLength - UINT16_SIZE || \
		listLen < 1 + UINT16_SIZE || \
		listLen >= MAX_INTLENGTH_SHORT )
		return( CRYPT_ERROR_BADDATA );

	/* Read the name type and length */
	if( sgetc( stream ) != 0 )	/* Name type 0 = hostname */
		return( CRYPT_ERROR_BADDATA );
	status = nameLen = readUint16( stream );
	if( cryptStatusError( status ) )
		return( status );
	if( nameLen != listLen - ( 1 + UINT16_SIZE ) || \
		nameLen < MIN_DNS_SIZE || nameLen > MAX_DNS_SIZE )
		return( CRYPT_ERROR_BADDATA );

	/* Read the SNI and hash it */
	status = sread( stream, nameBuffer, nameLen );
	if( cryptStatusError( status ) )
		return( status );
	hashData( handshakeInfo->hashedSNI, KEYID_SIZE, nameBuffer, nameLen );
	handshakeInfo->hashedSNIpresent = TRUE;

	return( CRYPT_OK );
	}
Beispiel #4
0
void AssetServer::run() {
    ThreadedAssignment::commonInit(ASSET_SERVER_LOGGING_TARGET_NAME, NodeType::AssetServer);

    auto nodeList = DependencyManager::get<NodeList>();
    nodeList->addNodeTypeToInterestSet(NodeType::Agent);

    _resourcesDirectory = QDir(QCoreApplication::applicationDirPath()).filePath("resources/assets");
    if (!_resourcesDirectory.exists()) {
        qDebug() << "Creating resources directory";
        _resourcesDirectory.mkpath(".");
    }
    qDebug() << "Serving files from: " << _resourcesDirectory.path();

    // Scan for new files
    qDebug() << "Looking for new files in asset directory";
    auto files = _resourcesDirectory.entryInfoList(QDir::Files);
    QRegExp filenameRegex { "^[a-f0-9]{" + QString::number(SHA256_HASH_HEX_LENGTH) + "}(\\..+)?$" };
    for (const auto& fileInfo : files) {
        auto filename = fileInfo.fileName();
        if (!filenameRegex.exactMatch(filename)) {
            qDebug() << "Found file: " << filename;
            if (!fileInfo.isReadable()) {
                qDebug() << "\tCan't open file for reading: " << filename;
                continue;
            }

            // Read file
            QFile file { fileInfo.absoluteFilePath() };
            file.open(QFile::ReadOnly);
            QByteArray data = file.readAll();

            auto hash = hashData(data);
            auto hexHash = hash.toHex();

            qDebug() << "\tMoving " << filename << " to " << hexHash;

            file.rename(_resourcesDirectory.absoluteFilePath(hexHash) + "." + fileInfo.suffix());
        }
    }
}
Beispiel #5
0
void UploadAssetTask::run() {
    auto data = _receivedMessage->getMessage();
    
    QBuffer buffer { &data };
    buffer.open(QIODevice::ReadOnly);
    
    MessageID messageID;
    buffer.read(reinterpret_cast<char*>(&messageID), sizeof(messageID));
    
    uint64_t fileSize;
    buffer.read(reinterpret_cast<char*>(&fileSize), sizeof(fileSize));
    
    qDebug() << "UploadAssetTask reading a file of " << fileSize << "bytes from"
        << uuidStringWithoutCurlyBraces(_senderNode->getUUID());
    
    auto replyPacket = NLPacket::create(PacketType::AssetUploadReply);
    replyPacket->writePrimitive(messageID);
    
    if (fileSize > MAX_UPLOAD_SIZE) {
        replyPacket->writePrimitive(AssetServerError::AssetTooLarge);
    } else {
        QByteArray fileData = buffer.read(fileSize);
        
        auto hash = hashData(fileData);
        auto hexHash = hash.toHex();
        
        qDebug() << "Hash for uploaded file from" << uuidStringWithoutCurlyBraces(_senderNode->getUUID())
            << "is: (" << hexHash << ") ";
        
        QFile file { _resourcesDir.filePath(QString(hexHash)) };

        bool existingCorrectFile = false;
        
        if (file.exists()) {
            // check if the local file has the correct contents, otherwise we overwrite
            if (file.open(QIODevice::ReadOnly) && hashData(file.readAll()) == hash) {
                qDebug() << "Not overwriting existing verified file: " << hexHash;

                existingCorrectFile = true;

                replyPacket->writePrimitive(AssetServerError::NoError);
                replyPacket->write(hash);
            } else {
                qDebug() << "Overwriting an existing file whose contents did not match the expected hash: " << hexHash;
                file.close();
            }
        }

        if (!existingCorrectFile) {
            if (file.open(QIODevice::WriteOnly) && file.write(fileData) == qint64(fileSize)) {
                qDebug() << "Wrote file" << hexHash << "to disk. Upload complete";
                file.close();

                replyPacket->writePrimitive(AssetServerError::NoError);
                replyPacket->write(hash);
            } else {
                qWarning() << "Failed to upload or write to file" << hexHash << " - upload failed.";

                // upload has failed - remove the file and return an error
                auto removed = file.remove();

                if (!removed) {
                    qWarning() << "Removal of failed upload file" << hexHash << "failed.";
                }
                
                replyPacket->writePrimitive(AssetServerError::FileOperationFailed);
            }
        }


    }
    
    auto nodeList = DependencyManager::get<NodeList>();
    nodeList->sendPacket(std::move(replyPacket), *_senderNode);
}
Beispiel #6
0
void AssetRequest::start() {
    if (QThread::currentThread() != thread()) {
        QMetaObject::invokeMethod(this, "start", Qt::AutoConnection);
        return;
    }

    if (_state != NotStarted) {
        qCWarning(asset_client) << "AssetRequest already started.";
        return;
    }

    // in case we haven't parsed a valid hash, return an error now
    if (!isValidHash(_hash)) {
        _error = InvalidHash;
        _state = Finished;

        emit finished(this);
        return;
    }
    
    // Try to load from cache
    _data = loadFromCache(getUrl());
    if (!_data.isNull()) {
        _error = NoError;

        _loadedFromCache = true;

        _state = Finished;
        emit finished(this);

        return;
    }

    _state = WaitingForData;

    auto assetClient = DependencyManager::get<AssetClient>();
    auto that = QPointer<AssetRequest>(this); // Used to track the request's lifetime
    auto hash = _hash;

    _assetRequestID = assetClient->getAsset(_hash, _byteRange.fromInclusive, _byteRange.toExclusive,
        [this, that, hash](bool responseReceived, AssetServerError serverError, const QByteArray& data) {

        if (!that) {
            qCWarning(asset_client) << "Got reply for dead asset request " << hash << "- error code" << _error;
            // If the request is dead, return
            return;
        }
        _assetRequestID = INVALID_MESSAGE_ID;

        if (!responseReceived) {
            _error = NetworkError;
        } else if (serverError != AssetServerError::NoError) {
            switch (serverError) {
                case AssetServerError::AssetNotFound:
                    _error = NotFound;
                    break;
                case AssetServerError::InvalidByteRange:
                    _error = InvalidByteRange;
                    break;
                default:
                    _error = UnknownError;
                    break;
            }
        } else {
            if (!_byteRange.isSet() && hashData(data).toHex() != _hash) {
                // the hash of the received data does not match what we expect, so we return an error
                _error = HashVerificationFailed;
            }

            if (_error == NoError) {
                _data = data;
                _totalReceived += data.size();
                emit progress(_totalReceived, data.size());

                if (!_byteRange.isSet()) {
                    saveToCache(getUrl(), data);
                }
            }
        }
        
        if (_error != NoError) {
            qCWarning(asset_client) << "Got error retrieving asset" << _hash << "- error code" << _error;
        }
        
        _state = Finished;
        emit finished(this);
    }, [this, that](qint64 totalReceived, qint64 total) {
        if (!that) {
            // If the request is dead, return
            return;
        }
        emit progress(totalReceived, total);
    });
}
Beispiel #7
0
void AssetServer::run() {
    ThreadedAssignment::commonInit(ASSET_SERVER_LOGGING_TARGET_NAME, NodeType::AssetServer);

    auto nodeList = DependencyManager::get<NodeList>();
    nodeList->addNodeTypeToInterestSet(NodeType::Agent);

    const QString RESOURCES_PATH = "assets";

    _resourcesDirectory = QDir(ServerPathUtils::getDataDirectory()).filePath(RESOURCES_PATH);

    qDebug() << "Creating resources directory";
    _resourcesDirectory.mkpath(".");

    bool noExistingAssets = !_resourcesDirectory.exists() \
        || _resourcesDirectory.entryList(QDir::Files).size() == 0;

    if (noExistingAssets) {
        qDebug() << "Asset resources directory not found, searching for existing asset resources";
        QString oldDataDirectory = QCoreApplication::applicationDirPath();
        auto oldResourcesDirectory = QDir(oldDataDirectory).filePath("resources/" + RESOURCES_PATH);


        if (QDir(oldResourcesDirectory).exists()) {
            qDebug() << "Existing assets found in " << oldResourcesDirectory << ", copying to " << _resourcesDirectory;


            QDir resourcesParentDirectory = _resourcesDirectory.filePath("..");
            if (!resourcesParentDirectory.exists()) {
                qDebug() << "Creating data directory " << resourcesParentDirectory.absolutePath();
                resourcesParentDirectory.mkpath(".");
            }

            auto files = QDir(oldResourcesDirectory).entryList(QDir::Files);

            for (auto& file : files) {
                auto from = oldResourcesDirectory + QDir::separator() + file;
                auto to = _resourcesDirectory.absoluteFilePath(file);
                qDebug() << "\tCopying from " << from << " to " << to;
                QFile::copy(from, to);
            }

        }
    }
    qDebug() << "Serving files from: " << _resourcesDirectory.path();

    // Scan for new files
    qDebug() << "Looking for new files in asset directory";
    auto files = _resourcesDirectory.entryInfoList(QDir::Files);
    QRegExp filenameRegex { "^[a-f0-9]{" + QString::number(SHA256_HASH_HEX_LENGTH) + "}(\\..+)?$" };
    for (const auto& fileInfo : files) {
        auto filename = fileInfo.fileName();
        if (!filenameRegex.exactMatch(filename)) {
            qDebug() << "Found file: " << filename;
            if (!fileInfo.isReadable()) {
                qDebug() << "\tCan't open file for reading: " << filename;
                continue;
            }

            // Read file
            QFile file { fileInfo.absoluteFilePath() };
            file.open(QFile::ReadOnly);
            QByteArray data = file.readAll();

            auto hash = hashData(data);
            auto hexHash = hash.toHex();

            qDebug() << "\tMoving " << filename << " to " << hexHash;

            file.rename(_resourcesDirectory.absoluteFilePath(hexHash) + "." + fileInfo.suffix());
        }
    }
}