3
0
Fork 0
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:
Stephen Birarda 2017-04-18 12:36:38 -07:00 committed by Atlante45
parent 7a3219d8f9
commit 814970c4e2
3 changed files with 61 additions and 38 deletions
assignment-client/src/assets
libraries/networking/src

View file

@ -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;

View file

@ -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;
}
}
};

View file

@ -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;