Added support of simple Range headers when requesting QDN data.

This commit is contained in:
CalDescent 2023-04-28 20:36:06 +01:00
parent 6dfaaf0054
commit aed1823afb

View File

@ -65,10 +65,7 @@ import org.qortal.transaction.Transaction.ValidationResult;
import org.qortal.transform.TransformationException; import org.qortal.transform.TransformationException;
import org.qortal.transform.transaction.ArbitraryTransactionTransformer; import org.qortal.transform.transaction.ArbitraryTransactionTransformer;
import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer;
import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.*;
import org.qortal.utils.Base58;
import org.qortal.utils.NTP;
import org.qortal.utils.ZipUtils;
@Path("/arbitrary") @Path("/arbitrary")
@Tag(name = "Arbitrary") @Tag(name = "Arbitrary")
@ -1324,14 +1321,43 @@ public class ArbitraryResource {
} }
} }
// TODO: limit file size that can be read into memory
java.nio.file.Path path = Paths.get(outputPath.toString(), filepath); java.nio.file.Path path = Paths.get(outputPath.toString(), filepath);
if (!Files.exists(path)) { if (!Files.exists(path)) {
String message = String.format("No file exists at filepath: %s", filepath); String message = String.format("No file exists at filepath: %s", filepath);
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, message); throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, message);
} }
byte[] data = Files.readAllBytes(path); byte[] data;
int fileSize = (int)path.toFile().length();
int length = fileSize;
// Parse "Range" header
Integer rangeStart = null;
Integer rangeEnd = null;
String range = request.getHeader("Range");
if (range != null) {
range = range.replace("bytes=", "");
String[] parts = range.split("-");
rangeStart = (parts != null && parts.length > 0) ? Integer.parseInt(parts[0]) : null;
rangeEnd = (parts != null && parts.length > 1) ? Integer.parseInt(parts[1]) : fileSize;
}
if (rangeStart != null && rangeEnd != null) {
// We have a range, so update the requested length
length = rangeEnd - rangeStart;
}
if (length < fileSize && encoding == null) {
// Partial content requested, and not encoding the data
response.setStatus(206);
response.addHeader("Content-Range", String.format("bytes %d-%d/%d", rangeStart, rangeEnd-1, fileSize));
data = FilesystemUtils.readFromFile(path.toString(), rangeStart, length);
}
else {
// Full content requested (or encoded data)
response.setStatus(200);
data = Files.readAllBytes(path); // TODO: limit file size that can be read into memory
}
// Encode the data if requested // Encode the data if requested
if (encoding != null && Objects.equals(encoding.toLowerCase(), "base64")) { if (encoding != null && Objects.equals(encoding.toLowerCase(), "base64")) {