generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 6
/
static-server.ts
75 lines (66 loc) · 2.71 KB
/
static-server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import http from 'http';
import { ALLOWED_HEADERS, mimeType } from './constants';
import url from 'url';
import StaticFileServerPlugin from 'main';
import { normalizePath, TFile } from 'obsidian';
function toBuffer(ab: ArrayBuffer): Buffer {
const buf = Buffer.alloc(ab.byteLength);
const view = new Uint8Array(ab);
for (let i = 0; i < buf.length; ++i) {
buf[i] = view[i];
}
return buf;
}
const exp = (folder: string, port: string, plugin: StaticFileServerPlugin) => {
const fileBufferCache = new Map<string, { mtime: number; buf: Buffer }>();
const app = plugin.app;
console.log('Creating server', folder, port);
const server = http.createServer(async function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', ALLOWED_HEADERS);
res.setHeader('Access-Control-Allow-Credentials', 'true');
try {
// parse URL
const parsedUrl = url.parse(req.url);
const fullPath = normalizePath(folder + parsedUrl.pathname);
const abstractPath = app.vault.getAbstractFileByPath(fullPath);
if (abstractPath === null || !(abstractPath instanceof TFile)) {
res.statusCode = 404;
res.end(`File ${fullPath} is not a file!`);
return;
}
let fileBuffer = null;
if (fileBufferCache.has(fullPath) && fileBufferCache.get(fullPath).mtime == abstractPath.stat.mtime) {
fileBuffer = fileBufferCache.get(fullPath).buf;
} else {
const file = await app.vault.readBinary(abstractPath);
if (!file) {
// if the file is not found, return 404
res.statusCode = 404;
res.end(`File ${fullPath} not found!`);
return;
}
fileBuffer = toBuffer(file);
fileBufferCache.set(fullPath, { mtime: abstractPath.stat.mtime, buf: fileBuffer });
}
const ext = '.' + abstractPath.extension;
// if the file is found, set Content-type and send data
res.setHeader('Content-type', mimeType[ext as keyof typeof mimeType] || 'text/plain');
res.end(fileBuffer);
} catch (e) {
res.statusCode = 500;
res.end(`Error getting the file: ${e}.`);
}
});
return {
listen() {
server.listen(port);
},
close() {
server.close();
}
};
};
export default exp;
export type StaticServer = ReturnType<typeof exp>;