Add static file serve for resources inside of data-directory (#19)

This commit is contained in:
Kyle Carberry 2019-01-26 13:16:06 -06:00
parent c6d35d098a
commit 9b1a635d63
No known key found for this signature in database
GPG Key ID: A0409BDB6B0B3EDB
3 changed files with 48 additions and 1 deletions

View File

@ -17,6 +17,7 @@
"@oclif/errors": "^1.2.2", "@oclif/errors": "^1.2.2",
"@oclif/plugin-help": "^2.1.4", "@oclif/plugin-help": "^2.1.4",
"express": "^4.16.4", "express": "^4.16.4",
"mime-types": "^2.1.21",
"nexe": "^2.0.0-rc.34", "nexe": "^2.0.0-rc.34",
"node-pty": "^0.8.1", "node-pty": "^0.8.1",
"spdlog": "^0.7.2", "spdlog": "^0.7.2",
@ -24,6 +25,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.16.0", "@types/express": "^4.16.0",
"@types/mime-types": "^2.1.0",
"@types/ws": "^6.0.1", "@types/ws": "^6.0.1",
"string-replace-webpack-plugin": "^0.1.3", "string-replace-webpack-plugin": "^0.1.3",
"ts-node": "^7.0.1", "ts-node": "^7.0.1",

View File

@ -4,8 +4,11 @@ import { Server, ServerOptions } from "@coder/protocol/src/node/server";
import { NewSessionMessage } from '@coder/protocol/src/proto'; import { NewSessionMessage } from '@coder/protocol/src/proto';
import { ChildProcess } from "child_process"; import { ChildProcess } from "child_process";
import * as express from "express"; import * as express from "express";
import * as fs from "fs";
import * as http from "http"; import * as http from "http";
import * as mime from "mime-types";
import * as path from "path"; import * as path from "path";
import * as util from "util";
import * as ws from "ws"; import * as ws from "ws";
import { forkModule } from "./vscode/bootstrapFork"; import { forkModule } from "./vscode/bootstrapFork";
@ -63,6 +66,43 @@ export const createApp = (registerMiddleware?: (app: express.Application) => voi
app.use(express.static(path.join(__dirname, "../build/web"))); app.use(express.static(path.join(__dirname, "../build/web")));
app.get("/resource/:url(*)", async (req, res) => {
try {
const fullPath = `/${req.params.url}`;
const relative = path.relative(options!.dataDirectory, fullPath);
if (relative.startsWith("..")) {
return res.status(403).end();
}
const exists = await util.promisify(fs.exists)(fullPath);
if (!exists) {
res.status(404).end();
return;
}
const stat = await util.promisify(fs.stat)(fullPath);
if (!stat.isFile()) {
res.write("Resource must be a file.");
res.status(422);
res.end();
return;
}
let mimeType = mime.lookup(fullPath);
if (mimeType === false) {
mimeType = "application/octet-stream";
}
const content = await util.promisify(fs.readFile)(fullPath);
res.header("Content-Type", mimeType as string);
res.write(content);
res.status(200);
res.end();
} catch (ex) {
res.write(ex.toString());
res.status(500);
res.end();
}
});
return { return {
express: app, express: app,
server, server,

View File

@ -107,6 +107,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/mime-types@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73"
integrity sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=
"@types/mime@*": "@types/mime@*":
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b"
@ -2224,7 +2229,7 @@ mime-db@^1.28.0, mime-db@~1.37.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19: mime-types@^2.1.12, mime-types@^2.1.21, mime-types@~2.1.18, mime-types@~2.1.19:
version "2.1.21" version "2.1.21"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==