forked from Qortal/qortal
/site API endpoint now tales a signature rather than a file hash
This allows it to verify that the data in a transaction, after which it will then build the complete file from its chunks if needed.
This commit is contained in:
parent
5319c5f832
commit
f2feb12708
@ -10,6 +10,7 @@ import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -38,6 +39,7 @@ import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.settings.Settings;
|
||||
import org.qortal.storage.DataFile;
|
||||
import org.qortal.storage.DataFileChunk;
|
||||
import org.qortal.transaction.ArbitraryTransaction;
|
||||
import org.qortal.transaction.Transaction;
|
||||
import org.qortal.transform.TransformationException;
|
||||
@ -263,22 +265,48 @@ public class WebsiteResource {
|
||||
|
||||
if (!Files.exists(Paths.get(unzippedPath))) {
|
||||
|
||||
// Load file
|
||||
DataFile dataFile = DataFile.fromHash58(resourceId);
|
||||
if (dataFile == null || !dataFile.exists()) {
|
||||
LOGGER.info("Unable to validate complete file hash");
|
||||
return this.get404Response();
|
||||
}
|
||||
// Load the full transaction data so we can access the file hashes
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
|
||||
if (!dataFile.digest58().equals(resourceId)) {
|
||||
LOGGER.info("Unable to validate complete file hash");
|
||||
return this.get404Response();
|
||||
}
|
||||
ArbitraryTransactionData transactionData = (ArbitraryTransactionData) repository.getTransactionRepository().fromSignature(Base58.decode(resourceId));
|
||||
if (!(transactionData instanceof ArbitraryTransactionData)) {
|
||||
return this.get404Response();
|
||||
}
|
||||
|
||||
try {
|
||||
ZipUtils.unzip(dataFile.getFilePath(), destPath);
|
||||
} catch (IOException e) {
|
||||
LOGGER.info("Unable to unzip file");
|
||||
// Load hashes
|
||||
byte[] digest = transactionData.getData();
|
||||
byte[] chunkHashes = transactionData.getChunkHashes();
|
||||
|
||||
// Load data file(s)
|
||||
DataFile dataFile = DataFile.fromDigest(digest);
|
||||
if (!dataFile.exists()) {
|
||||
if (!dataFile.allChunksExist(chunkHashes)) {
|
||||
// TODO: fetch them?
|
||||
return this.get404Response();
|
||||
}
|
||||
// We have all the chunks but not the complete file, so join them
|
||||
dataFile.addChunkHashes(chunkHashes);
|
||||
dataFile.join();
|
||||
}
|
||||
|
||||
// If the complete file still doesn't exist then something went wrong
|
||||
if (!dataFile.exists()) {
|
||||
return this.get404Response();
|
||||
}
|
||||
|
||||
if (!Arrays.equals(dataFile.digest(), digest)) {
|
||||
LOGGER.info("Unable to validate complete file hash");
|
||||
return this.get404Response();
|
||||
}
|
||||
|
||||
try {
|
||||
ZipUtils.unzip(dataFile.getFilePath(), destPath);
|
||||
} catch (IOException e) {
|
||||
LOGGER.info("Unable to unzip file");
|
||||
}
|
||||
|
||||
} catch (DataException e) {
|
||||
return this.get500Response();
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,6 +371,19 @@ public class WebsiteResource {
|
||||
return response;
|
||||
}
|
||||
|
||||
private HttpServletResponse get500Response() {
|
||||
try {
|
||||
String responseString = "500: Internal Server Error";
|
||||
byte[] responseData = responseString.getBytes();
|
||||
response.setStatus(500);
|
||||
response.setContentLength(responseData.length);
|
||||
response.getOutputStream().write(responseData);
|
||||
} catch (IOException e) {
|
||||
LOGGER.info("Error writing 500 response");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find relative links and prefix them with the resource ID, using Jsoup
|
||||
* @param path
|
||||
|
Loading…
Reference in New Issue
Block a user