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