support http urls as source
Massimo Melina committed
Dec 15, 2021 at 15:23 UTC
bb16f7010cd8231bd2c4d6f55a589ba2003a290f
3 files changed
+19
-9
src/apis.ts
+4
-3
@@ -30,9 +30,10 @@ export const frontEndApis: ApiHandlers = {
30
return
31
const list = await Promise.all((node.children ||[]).map(async (node:VfsNode) =>
32
node.hidden ? null
33
- : node.source ? stat(node.source).then(res => statToFile(node.name, res), () => null)
34
- : node.name ? { n: node.name + '/' }
35
- : null
33
+ : node.source?.includes('//') ? { n:node.name }
34
+ : node.source ? stat(node.source).then(res => statToFile(node.name, res), () => null)
35
+ : node.name ? { n: node.name + '/' }
36
+ : null
37
))
38
_.remove(list, x => !x)
39
let path = node.source
src/index.ts
+8
-6
@@ -6,7 +6,8 @@ import { serveFrontend } from './frontend'
6
import { API_URI, argv, DEV, FRONTEND_URI } from './const'
7
import { createReadStream } from 'fs'
8
import { vfs } from './vfs'
9
-import { stat } from 'fs/promises'
9
+import { isDirectory } from './misc'
10
+import proxy from 'koa-better-http-proxy'
11
12
const PORT = argv.port || 80
13
@@ -26,18 +27,19 @@ srv.use(async (ctx, next) => {
27
const { path } = ctx
28
if (ctx.method !== 'GET' || ctx.body)
29
return await next()
29
- if (path.endsWith('/'))
30
- return await serveFrontend(ctx,next)
30
if (path.startsWith(FRONTEND_URI))
31
return await serveFrontendPrefixed(ctx,next)
32
const node = vfs.urlToNode(decodeURI(path))
33
if (!node)
34
return await next()
35
const { source } = node
37
- if (!source || (await stat(source)).isDirectory()) // this folder was requested without the trailing /
38
- return ctx.redirect(ctx.path+'/')
36
+ if (!source || await isDirectory(source)) // this folder was requested without the trailing /
37
+ return path.endsWith('/') ? await serveFrontend(ctx,next)
38
+ : ctx.redirect(ctx.path+'/')
39
if (source)
40
- ctx.body = createReadStream(source as string)
40
+ return ctx.body = source.includes('//') ? mount(path,proxy(source,{}))(ctx,next)
41
+ : createReadStream(source)
42
+ await next()
43
})
44
45
srv.on('error', err => {
src/misc.ts
+7
@@ -1,7 +1,14 @@
1
+import { stat } from 'fs/promises'
2
+
3
export function enforceFinal(sub:string, s:string) {
4
return s.endsWith(sub) ? s : s+sub
5
}
6
7
export function wantArray(x:any) {
8
return x == null ? [] : Array.isArray(x) ? x : [x]
9
+}
10
+
11
+export async function isDirectory(path: string) {
12
+ try { return (await stat(path)).isDirectory() }
13
+ catch(e) { return false }
14
}
\ No newline at end of file