mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-19 10:51:23 +00:00
allow downloads
This commit is contained in:
parent
58ab02c4f0
commit
ca88cb1f88
@ -709,14 +709,14 @@ public class ArbitraryResource {
|
|||||||
@QueryParam("encoding") String encoding,
|
@QueryParam("encoding") String encoding,
|
||||||
@QueryParam("rebuild") boolean rebuild,
|
@QueryParam("rebuild") boolean rebuild,
|
||||||
@QueryParam("async") boolean async,
|
@QueryParam("async") boolean async,
|
||||||
@QueryParam("attempts") Integer attempts) {
|
@QueryParam("attempts") Integer attempts, @QueryParam("attachment") boolean attachment, @QueryParam("attachmentFilename") String attachmentFilename) {
|
||||||
|
|
||||||
// Authentication can be bypassed in the settings, for those running public QDN nodes
|
// Authentication can be bypassed in the settings, for those running public QDN nodes
|
||||||
if (!Settings.getInstance().isQDNAuthBypassEnabled()) {
|
if (!Settings.getInstance().isQDNAuthBypassEnabled()) {
|
||||||
Security.checkApiCallAllowed(request);
|
Security.checkApiCallAllowed(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.download(service, name, null, filepath, encoding, rebuild, async, attempts);
|
this.download(service, name, null, filepath, encoding, rebuild, async, attempts, attachment, attachmentFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@ -743,14 +743,14 @@ public class ArbitraryResource {
|
|||||||
@QueryParam("encoding") String encoding,
|
@QueryParam("encoding") String encoding,
|
||||||
@QueryParam("rebuild") boolean rebuild,
|
@QueryParam("rebuild") boolean rebuild,
|
||||||
@QueryParam("async") boolean async,
|
@QueryParam("async") boolean async,
|
||||||
@QueryParam("attempts") Integer attempts) {
|
@QueryParam("attempts") Integer attempts, @QueryParam("attachment") boolean attachment, @QueryParam("attachmentFilename") String attachmentFilename) {
|
||||||
|
|
||||||
// Authentication can be bypassed in the settings, for those running public QDN nodes
|
// Authentication can be bypassed in the settings, for those running public QDN nodes
|
||||||
if (!Settings.getInstance().isQDNAuthBypassEnabled()) {
|
if (!Settings.getInstance().isQDNAuthBypassEnabled()) {
|
||||||
Security.checkApiCallAllowed(request, null);
|
Security.checkApiCallAllowed(request, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.download(service, name, identifier, filepath, encoding, rebuild, async, attempts);
|
this.download(service, name, identifier, filepath, encoding, rebuild, async, attempts, attachment, attachmentFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1900,8 +1900,9 @@ public String finalizeUpload(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void download(Service service, String name, String identifier, String filepath, String encoding, boolean rebuild, boolean async, Integer maxAttempts) {
|
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;
|
||||||
@ -1948,6 +1949,33 @@ public String finalizeUpload(
|
|||||||
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "No file exists at filepath: " + filepath);
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "No file exists at filepath: " + filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attachment) {
|
||||||
|
String rawFilename;
|
||||||
|
|
||||||
|
if (attachmentFilename != null && !attachmentFilename.isEmpty()) {
|
||||||
|
// 1. Sanitize first
|
||||||
|
String safeAttachmentFilename = attachmentFilename.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||||
|
|
||||||
|
// 2. Check for a valid extension (3–5 alphanumeric chars)
|
||||||
|
if (!safeAttachmentFilename.matches(".*\\.[a-zA-Z0-9]{2,5}$")) {
|
||||||
|
safeAttachmentFilename += ".bin";
|
||||||
|
}
|
||||||
|
|
||||||
|
rawFilename = safeAttachmentFilename;
|
||||||
|
} else {
|
||||||
|
// Fallback if no filename is provided
|
||||||
|
String baseFilename = (identifier != null && !identifier.isEmpty())
|
||||||
|
? name + "-" + identifier
|
||||||
|
: name;
|
||||||
|
rawFilename = baseFilename.replaceAll("[\\\\/:*?\"<>|]", "_") + ".bin";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: trim length
|
||||||
|
rawFilename = rawFilename.length() > 100 ? rawFilename.substring(0, 100) : rawFilename;
|
||||||
|
|
||||||
|
// 3. Set Content-Disposition header
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=\"" + rawFilename + "\"");
|
||||||
|
}
|
||||||
long fileSize = Files.size(path);
|
long fileSize = Files.size(path);
|
||||||
String mimeType = context.getMimeType(path.toString());
|
String mimeType = context.getMimeType(path.toString());
|
||||||
String range = request.getHeader("Range");
|
String range = request.getHeader("Range");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user