mirror of
https://github.com/lubosz/overte.git
synced 2025-04-27 07:35:30 +02:00
cleanup invalid byte range handling
This commit is contained in:
parent
7a3219d8f9
commit
814970c4e2
3 changed files with 61 additions and 38 deletions
assignment-client/src/assets
libraries/networking/src
|
@ -60,7 +60,7 @@ void SendAssetTask::run() {
|
|||
|
||||
replyPacketList->writePrimitive(messageID);
|
||||
|
||||
if (byteRange.toExclusive < byteRange.fromInclusive || byteRange.toExclusive < 0) {
|
||||
if (!byteRange.isValid()) {
|
||||
replyPacketList->writePrimitive(AssetServerError::InvalidByteRange);
|
||||
} else {
|
||||
QString filePath = _resourcesDir.filePath(QString(hexHash));
|
||||
|
@ -74,15 +74,22 @@ void SendAssetTask::run() {
|
|||
byteRange.toExclusive = file.size();
|
||||
}
|
||||
|
||||
if (file.size() < std::abs(byteRange.fromInclusive) || file.size() < byteRange.toExclusive) {
|
||||
// check if we're being asked to read data that we just don't have
|
||||
// because of the file size
|
||||
if (file.size() < byteRange.fromInclusive || file.size() < byteRange.toExclusive) {
|
||||
replyPacketList->writePrimitive(AssetServerError::InvalidByteRange);
|
||||
qCDebug(networking) << "Bad byte range: " << hexHash << " "
|
||||
<< byteRange.fromInclusive << ":" << byteRange.toExclusive;
|
||||
} else {
|
||||
// we have a valid byte range, handle it and send the asset
|
||||
|
||||
// first fixup the range based on the now known file size
|
||||
byteRange.fixupRange(file.size());
|
||||
|
||||
auto size = byteRange.size();
|
||||
|
||||
if (byteRange.fromInclusive > 0) {
|
||||
|
||||
// this range is positive, meaning we just need to seek into the file and then read from there
|
||||
file.seek(byteRange.fromInclusive);
|
||||
replyPacketList->writePrimitive(AssetServerError::NoError);
|
||||
|
@ -98,15 +105,7 @@ void SendAssetTask::run() {
|
|||
replyPacketList->writePrimitive(size);
|
||||
|
||||
// first write everything from the negative range to the end of the file
|
||||
replyPacketList->write(file.read(-byteRange.fromInclusive));
|
||||
|
||||
if (byteRange.toExclusive != 0) {
|
||||
// this range has a portion that is at the front of the file
|
||||
|
||||
// seek to the beginning and read what is left over
|
||||
file.seek(0);
|
||||
replyPacketList->write(file.read(byteRange.toExclusive));
|
||||
}
|
||||
replyPacketList->write(file.read(size));
|
||||
}
|
||||
|
||||
qCDebug(networking) << "Sending asset: " << hexHash;
|
||||
|
|
|
@ -18,6 +18,29 @@ struct ByteRange {
|
|||
|
||||
bool isSet() { return fromInclusive < 0 || fromInclusive < toExclusive; }
|
||||
int64_t size() { return toExclusive - fromInclusive; }
|
||||
|
||||
// byte ranges are invalid if:
|
||||
// (1) the toExclusive of the range is negative
|
||||
// (2) the toExclusive of the range is less than the fromInclusive, and isn't zero
|
||||
// (3) the fromExclusive of the range is negative, and the toExclusive isn't zero
|
||||
bool isValid() {
|
||||
return toExclusive < 0
|
||||
|| (toExclusive < fromInclusive && toExclusive != 0)
|
||||
|| (fromInclusive < 0 && toExclusive != 0);
|
||||
}
|
||||
|
||||
void fixupRange(int64_t fileSize) {
|
||||
if (fromInclusive > 0 && toExclusive == 0) {
|
||||
// we have a left side of the range that is non-zero
|
||||
// if the RHS of the range is zero, set it to the end of the file now
|
||||
toExclusive = fileSize;
|
||||
} else if (-fromInclusive >= fileSize) {
|
||||
// we have a negative range that is equal or greater than the full size of the file
|
||||
// so we just set this to be a range across the entire file, from 0
|
||||
fromInclusive = 0;
|
||||
toExclusive = fileSize;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,45 +23,46 @@ void FileResourceRequest::doSend() {
|
|||
if (filename.isEmpty()) {
|
||||
filename = _url.toString();
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
if (file.exists()) {
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
|
||||
if (!_byteRange.isSet()) {
|
||||
// no byte range, read the whole file
|
||||
_data = file.readAll();
|
||||
} else {
|
||||
if (file.size() < std::abs(_byteRange.fromInclusive) || file.size() < _byteRange.toExclusive) {
|
||||
if (!_byteRange.isValid()) {
|
||||
_result = ResourceRequest::InvalidByteRange;
|
||||
} else {
|
||||
QFile file(filename);
|
||||
if (file.exists()) {
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
|
||||
if (file.size() < _byteRange.fromInclusive || file.size() < _byteRange.toExclusive) {
|
||||
_result = ResourceRequest::InvalidByteRange;
|
||||
} else {
|
||||
// we have a byte range to handle
|
||||
if (_byteRange.fromInclusive > 0) {
|
||||
// this is a positive byte range, simply skip to that part of the file and read from there
|
||||
file.seek(_byteRange.fromInclusive);
|
||||
_data = file.read(_byteRange.size());
|
||||
if (!_byteRange.isSet()) {
|
||||
// no byte range, read the whole file
|
||||
_data = file.readAll();
|
||||
} else {
|
||||
// this is a negative byte range, we'll need to grab data from the end of the file first
|
||||
file.seek(file.size() + _byteRange.fromInclusive);
|
||||
_data = file.read(-_byteRange.fromInclusive);
|
||||
// we have a byte range to handle
|
||||
|
||||
if (_byteRange.toExclusive > 0) {
|
||||
// there is additional data to read from the front of the file
|
||||
// handle that now
|
||||
file.seek(0);
|
||||
_data.append(file.read(_byteRange.toExclusive));
|
||||
// fix it up based on the known size of the file
|
||||
_byteRange.fixupRange(file.size());
|
||||
|
||||
if (_byteRange.fromInclusive > 0) {
|
||||
// this is a positive byte range, simply skip to that part of the file and read from there
|
||||
file.seek(_byteRange.fromInclusive);
|
||||
_data = file.read(_byteRange.size());
|
||||
} else {
|
||||
// this is a negative byte range, we'll need to grab data from the end of the file first
|
||||
file.seek(file.size() + _byteRange.fromInclusive);
|
||||
_data = file.read(_byteRange.size());
|
||||
}
|
||||
}
|
||||
|
||||
_result = ResourceRequest::Success;
|
||||
}
|
||||
|
||||
} else {
|
||||
_result = ResourceRequest::AccessDenied;
|
||||
}
|
||||
|
||||
_result = ResourceRequest::Success;
|
||||
} else {
|
||||
_result = ResourceRequest::AccessDenied;
|
||||
_result = ResourceRequest::NotFound;
|
||||
}
|
||||
} else {
|
||||
_result = ResourceRequest::NotFound;
|
||||
}
|
||||
|
||||
_state = Finished;
|
||||
|
|
Loading…
Reference in a new issue