mirror of
https://github.com/Jermolene/TiddlyWiki5.git
synced 2025-12-06 02:30:46 -08:00
* Update get-file.js * Update WebServer API_ Get File.tid * Update get-file.js * Update get-file.js * Update get-file.js * Update get-file.js * Update core-server/server/routes/get-file.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core-server/server/routes/get-file.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update get-file.js --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
73 lines
2.4 KiB
JavaScript
73 lines
2.4 KiB
JavaScript
/*\
|
|
title: $:/core/modules/server/routes/get-file.js
|
|
type: application/javascript
|
|
module-type: route
|
|
|
|
GET /files/:filepath
|
|
|
|
\*/
|
|
"use strict";
|
|
|
|
exports.methods = ["GET"];
|
|
|
|
exports.path = /^\/files\/(.+)$/;
|
|
|
|
exports.info = {
|
|
priority: 100
|
|
};
|
|
|
|
exports.handler = function(request,response,state) {
|
|
var path = require("path"),
|
|
fs = require("fs"),
|
|
suppliedFilename = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
|
baseFilename = path.resolve(state.boot.wikiPath,"files"),
|
|
filename = path.resolve(baseFilename,suppliedFilename),
|
|
extension = path.extname(filename);
|
|
// Check that the filename is inside the wiki files folder
|
|
if(path.relative(baseFilename,filename).indexOf("..") === 0) {
|
|
return state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
|
}
|
|
fs.stat(filename, function(err, stats) {
|
|
if(err) {
|
|
return state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
|
} else {
|
|
var type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream"),
|
|
responseHeaders = {
|
|
"Content-Type": type,
|
|
"Accept-Ranges": "bytes"
|
|
};
|
|
var rangeHeader = request.headers.range,
|
|
stream;
|
|
if(rangeHeader) {
|
|
// Handle range requests
|
|
var parts = rangeHeader.replace(/bytes=/, "").split("-"),
|
|
start = parseInt(parts[0], 10),
|
|
end = parts[1] ? parseInt(parts[1], 10) : stats.size - 1;
|
|
// Validate start and end
|
|
if(isNaN(start) || isNaN(end) || start < 0 || end < start || end >= stats.size) {
|
|
responseHeaders["Content-Range"] = "bytes */" + stats.size;
|
|
return response.writeHead(416, responseHeaders).end();
|
|
}
|
|
var chunksize = (end - start) + 1;
|
|
responseHeaders["Content-Range"] = "bytes " + start + "-" + end + "/" + stats.size;
|
|
responseHeaders["Content-Length"] = chunksize;
|
|
response.writeHead(206, responseHeaders);
|
|
stream = fs.createReadStream(filename, {start: start, end: end});
|
|
} else {
|
|
responseHeaders["Content-Length"] = stats.size;
|
|
response.writeHead(200, responseHeaders);
|
|
stream = fs.createReadStream(filename);
|
|
}
|
|
// Common stream error handling
|
|
stream.on("error", function(err) {
|
|
if(!response.headersSent) {
|
|
response.writeHead(500, {"Content-Type": "text/plain"});
|
|
response.end("Read error");
|
|
} else {
|
|
response.destroy();
|
|
}
|
|
});
|
|
stream.pipe(response);
|
|
}
|
|
});
|
|
};
|