mirror of
https://github.com/Jermolene/TiddlyWiki5.git
synced 2025-12-05 18:20:38 -08:00
Get-file web server route now support streaming (#9078)
* 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>
This commit is contained in:
parent
8be83cf01b
commit
b061f90f87
2 changed files with 59 additions and 21 deletions
|
|
@ -19,28 +19,55 @@ exports.info = {
|
|||
exports.handler = function(request,response,state) {
|
||||
var path = require("path"),
|
||||
fs = require("fs"),
|
||||
util = require("util"),
|
||||
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) {
|
||||
// Send the file
|
||||
fs.readFile(filename,function(err,content) {
|
||||
var status,content,type = "text/plain";
|
||||
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) {
|
||||
console.log("Error accessing file " + filename + ": " + err.toString());
|
||||
status = 404;
|
||||
content = "File '" + suppliedFilename + "' not found";
|
||||
return state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
||||
} else {
|
||||
status = 200;
|
||||
content = content;
|
||||
type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream");
|
||||
}
|
||||
state.sendResponse(status,{"Content-Type": type},content);
|
||||
});
|
||||
} else {
|
||||
state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
created: 20181002123907518
|
||||
modified: 20181002124345482
|
||||
modified: 20250605000000000
|
||||
tags: [[WebServer API]]
|
||||
title: WebServer API: Get File
|
||||
type: text/vnd.tiddlywiki
|
||||
|
|
@ -15,11 +15,22 @@ Parameters:
|
|||
|
||||
* ''pathname'' - URI encoded path to the file
|
||||
|
||||
Headers:
|
||||
|
||||
* ''Range'' - <<.from-version "5.3.7">> (optional) Request specific byte ranges using the format `bytes=start-end`. Supports partial content delivery for media streaming.
|
||||
|
||||
Response:
|
||||
|
||||
* 200 OK
|
||||
*> `Content-Type: <content-type>` (determined from file extension)
|
||||
*> Body: data retrieved from file
|
||||
*> `Content-Length: <file-size>`
|
||||
*> `Accept-Ranges: bytes`
|
||||
*> Body: complete file data
|
||||
* 206 Partial Content (when Range header is provided)
|
||||
*> `Content-Type: <content-type>` (determined from file extension)
|
||||
*> `Content-Length: <range-size>`
|
||||
*> `Content-Range: bytes <start>-<end>/<total-size>`
|
||||
*> `Accept-Ranges: bytes`
|
||||
*> Body: requested byte range data
|
||||
* 403 Forbidden
|
||||
* 404 Not Found
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue