diff --git a/core/core.js b/core/core.js index 5d08a187..76299d8b 100644 --- a/core/core.js +++ b/core/core.js @@ -1,5 +1,6 @@ -import * as auth from './auth.js'; import * as app from './app.js'; +import * as auth from './auth.js'; +import * as form from './form.js'; import * as httpd from './httpd.js'; let gProcessIndex = 0; @@ -629,11 +630,16 @@ async function blobHandler(request, response, blobId, uri) { if (uri == "/view") { let data; let match; + let query = form.decodeForm(request.query); + let headers = {}; + if (query.filename && query.filename.match(/^[A-Za-z0-9\.-]*$/)) { + headers['Content-Disposition'] = `attachment; filename=${query.filename}`; + } if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { let id = await new Database(match[1]).get('path:' + match[2]); if (id) { if (request.headers['if-none-match'] === '"' + id + '"') { - response.writeHead(304, {}); + response.writeHead(304, headers); response.end(); } else { data = await getBlobOrContent(id); @@ -641,23 +647,23 @@ async function blobHandler(request, response, blobId, uri) { let appObject = JSON.parse(data); data = appObject.files[match[3]]; } - sendData(response, data, undefined, {etag: '"' + id + '"'}); + sendData(response, data, undefined, Object.assign({etag: '"' + id + '"'}, headers)); } } else { if (request.headers['if-none-match'] === '"' + blobId + '"') { - response.writeHead(304, {}); + response.writeHead(304, headers); response.end(); } else { - sendData(response, data, undefined, {etag: '"' + blobId + '"'}); + sendData(response, data, undefined, Object.assign({etag: '"' + blobId + '"'}, headers)); } } } else { if (request.headers['if-none-match'] === '"' + blobId + '"') { - response.writeHead(304, {}); + response.writeHead(304, headers); response.end(); } else { data = await getBlobOrContent(blobId); - sendData(response, data, undefined, {etag: '"' + blobId + '"'}); + sendData(response, data, undefined, Object.assign({etag: '"' + blobId + '"'}, headers)); } } } else if (uri == "/save") {