mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-19 19:01:22 +00:00
Merge pull request #8 from Philreact/fix/load-data
fix issue of not breaking when file is complete
This commit is contained in:
commit
fa8b9f2cee
@ -1902,7 +1902,6 @@ public String finalizeUpload(
|
|||||||
|
|
||||||
private void download(Service service, String name, String identifier, String filepath, String encoding, boolean rebuild, boolean async, Integer maxAttempts, boolean attachment, String attachmentFilename) {
|
private void download(Service service, String name, String identifier, String filepath, String encoding, boolean rebuild, boolean async, Integer maxAttempts, boolean attachment, String attachmentFilename) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier);
|
ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier);
|
||||||
|
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
@ -1928,7 +1927,6 @@ public String finalizeUpload(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Thread.sleep(3000L);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1981,6 +1979,7 @@ public String finalizeUpload(
|
|||||||
// 3. Set Content-Disposition header
|
// 3. Set Content-Disposition header
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + rawFilename + "\"");
|
response.setHeader("Content-Disposition", "attachment; filename=\"" + rawFilename + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the total size of the requested file
|
// Determine the total size of the requested file
|
||||||
long fileSize = Files.size(path);
|
long fileSize = Files.size(path);
|
||||||
String mimeType = context.getMimeType(path.toString());
|
String mimeType = context.getMimeType(path.toString());
|
||||||
@ -2026,10 +2025,13 @@ public String finalizeUpload(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize output streams for writing the file to the response
|
// Initialize output streams for writing the file to the response
|
||||||
OutputStream rawOut = response.getOutputStream();
|
OutputStream rawOut = null;
|
||||||
OutputStream base64Out = null;
|
OutputStream base64Out = null;
|
||||||
OutputStream gzipOut = null;
|
OutputStream gzipOut = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
rawOut = response.getOutputStream();
|
||||||
|
|
||||||
if (encoding != null && "base64".equalsIgnoreCase(encoding)) {
|
if (encoding != null && "base64".equalsIgnoreCase(encoding)) {
|
||||||
// If base64 encoding is requested, override content type
|
// If base64 encoding is requested, override content type
|
||||||
response.setContentType("text/plain");
|
response.setContentType("text/plain");
|
||||||
@ -2054,6 +2056,7 @@ public String finalizeUpload(
|
|||||||
response.setContentType(mimeType != null ? mimeType : "application/octet-stream");
|
response.setContentType(mimeType != null ? mimeType : "application/octet-stream");
|
||||||
response.setContentLength((int) contentLength);
|
response.setContentLength((int) contentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream file content
|
// Stream file content
|
||||||
try (InputStream inputStream = Files.newInputStream(path)) {
|
try (InputStream inputStream = Files.newInputStream(path)) {
|
||||||
if (rangeStart > 0) {
|
if (rangeStart > 0) {
|
||||||
@ -2069,28 +2072,39 @@ public String finalizeUpload(
|
|||||||
bytesRemaining -= bytesRead;
|
bytesRemaining -= bytesRead;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Stream finished
|
|
||||||
if (base64Out != null) {
|
// Stream finished
|
||||||
|
if (base64Out != null) {
|
||||||
base64Out.close(); // Also flushes and closes the wrapped gzipOut
|
base64Out.close(); // Also flushes and closes the wrapped gzipOut
|
||||||
} else if (gzipOut != null) {
|
} else if (gzipOut != null) {
|
||||||
gzipOut.close(); // Only close gzipOut if it wasn't wrapped by base64Out
|
gzipOut.close(); // Only close gzipOut if it wasn't wrapped by base64Out
|
||||||
} else {
|
} else {
|
||||||
rawOut.flush(); // Flush only the base output stream if nothing was wrapped
|
rawOut.flush(); // Flush only the base output stream if nothing was wrapped
|
||||||
}
|
}
|
||||||
if (!response.isCommitted()) {
|
|
||||||
|
if (!response.isCommitted()) {
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
response.getWriter().write(" ");
|
response.getWriter().write(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | InterruptedException | ApiException | DataException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error(String.format("Unable to load %s %s: %s", service, name, e.getMessage()), e);
|
// Streaming errors should not rethrow — just log
|
||||||
|
LOGGER.warn(String.format("Streaming error for %s %s: %s", service, name, e.getMessage()), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | ApiException | DataException e) {
|
||||||
|
LOGGER.warn(String.format("Unable to load %s %s: %s", service, name, e.getMessage()), e);
|
||||||
|
if (!response.isCommitted()) {
|
||||||
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FILE_NOT_FOUND, e.getMessage());
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FILE_NOT_FOUND, e.getMessage());
|
||||||
}
|
}
|
||||||
catch ( NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
LOGGER.error(String.format("Unable to load %s %s: %s", service, name, e.getMessage()), e);
|
LOGGER.warn(String.format("Invalid range for %s %s: %s", service, name, e.getMessage()), e);
|
||||||
|
if (!response.isCommitted()) {
|
||||||
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_DATA, e.getMessage());
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_DATA, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private FileProperties getFileProperties(Service service, String name, String identifier) {
|
private FileProperties getFileProperties(Service service, String name, String identifier) {
|
||||||
|
@ -400,7 +400,7 @@ public class ArbitraryDataFileListManager {
|
|||||||
String signature58 = Base58.encode(signature);
|
String signature58 = Base58.encode(signature);
|
||||||
for (Iterator<Map.Entry<Integer, Triple<String, Peer, Long>>> it = arbitraryDataFileListRequests.entrySet().iterator(); it.hasNext();) {
|
for (Iterator<Map.Entry<Integer, Triple<String, Peer, Long>>> it = arbitraryDataFileListRequests.entrySet().iterator(); it.hasNext();) {
|
||||||
Map.Entry<Integer, Triple<String, Peer, Long>> entry = it.next();
|
Map.Entry<Integer, Triple<String, Peer, Long>> entry = it.next();
|
||||||
if (entry == null || entry.getKey() == null || entry.getValue() != null) {
|
if (entry == null || entry.getKey() == null || entry.getValue() == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Objects.equals(entry.getValue().getA(), signature58)) {
|
if (Objects.equals(entry.getValue().getA(), signature58)) {
|
||||||
|
@ -212,8 +212,7 @@ public class ArbitraryDataFileManager extends Thread {
|
|||||||
arbitraryDataFileRequests.remove(hash58);
|
arbitraryDataFileRequests.remove(hash58);
|
||||||
LOGGER.trace(String.format("Removed hash %.8s from arbitraryDataFileRequests", hash58));
|
LOGGER.trace(String.format("Removed hash %.8s from arbitraryDataFileRequests", hash58));
|
||||||
|
|
||||||
// We may need to remove the file list request, if we have all the files for this transaction
|
|
||||||
this.handleFileListRequests(signature);
|
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
LOGGER.debug("Received null response from peer {}", peer);
|
LOGGER.debug("Received null response from peer {}", peer);
|
||||||
@ -258,6 +257,9 @@ public class ArbitraryDataFileManager extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We may need to remove the file list request, if we have all the files for this transaction
|
||||||
|
this.handleFileListRequests(signature);
|
||||||
|
|
||||||
return arbitraryDataFile;
|
return arbitraryDataFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,10 +272,12 @@ public class ArbitraryDataFileManager extends Thread {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allChunksExist = ArbitraryTransactionUtils.allChunksExist(arbitraryTransactionData);
|
boolean completeFileExists = ArbitraryTransactionUtils.completeFileExists(arbitraryTransactionData);
|
||||||
|
|
||||||
|
if (completeFileExists) {
|
||||||
|
String signature58 = Base58.encode(arbitraryTransactionData.getSignature());
|
||||||
|
LOGGER.info("All chunks or complete file exist for transaction {}", signature58);
|
||||||
|
|
||||||
if (allChunksExist) {
|
|
||||||
// Update requests map to reflect that we've received all chunks
|
|
||||||
ArbitraryDataFileListManager.getInstance().deleteFileListRequestsForSignature(signature);
|
ArbitraryDataFileListManager.getInstance().deleteFileListRequestsForSignature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user