doocus improvemnts
This commit is contained in:
@@ -80,7 +80,7 @@ export function doocusApi(opts: Options): Plugin {
|
||||
server.middlewares.use('/api', (req, res, next) => {
|
||||
const url = new URL(req.url ?? '/', 'http://localhost')
|
||||
const parts = url.pathname.split('/').filter(Boolean)
|
||||
handle(res, parts, url.searchParams).catch((err) => {
|
||||
handle(res, parts, url.searchParams, req.headers.range).catch((err) => {
|
||||
server.config.logger.error(`[doocus-api] ${String(err)}`)
|
||||
sendJson(res, 500, { error: String(err) })
|
||||
}).then((handled) => { if (!handled) next() })
|
||||
@@ -88,7 +88,7 @@ export function doocusApi(opts: Options): Plugin {
|
||||
},
|
||||
}
|
||||
|
||||
async function handle(res: ServerResponse, parts: string[], q: URLSearchParams): Promise<boolean> {
|
||||
async function handle(res: ServerResponse, parts: string[], q: URLSearchParams, range?: string): Promise<boolean> {
|
||||
if (parts[0] === 'tree') {
|
||||
const index = readIndex()
|
||||
if (!index) { sendJson(res, 404, { error: `index.json not found in ${outputDir}` }); return true }
|
||||
@@ -102,7 +102,7 @@ export function doocusApi(opts: Options): Plugin {
|
||||
}
|
||||
|
||||
if (parts[0] === 'original') {
|
||||
await serveOriginal(res, q.get('path') ?? '')
|
||||
await serveOriginal(res, q.get('path') ?? '', range)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -137,13 +137,34 @@ export function doocusApi(opts: Options): Plugin {
|
||||
})
|
||||
}
|
||||
|
||||
async function serveOriginal(res: ServerResponse, rel: string): Promise<void> {
|
||||
async function serveOriginal(res: ServerResponse, rel: string, range?: string): Promise<void> {
|
||||
const index = readIndex()
|
||||
if (!index) { sendJson(res, 404, { error: 'no index' }); return }
|
||||
const abs = originalAbs(index, rel)
|
||||
if (!abs || !isFile(abs)) { sendJson(res, 404, { error: 'original not reachable' }); return }
|
||||
res.setHeader('Content-Type', MIME[path.extname(abs).toLowerCase()] ?? 'application/octet-stream')
|
||||
res.setHeader('Cache-Control', 'no-cache')
|
||||
const mime = MIME[path.extname(abs).toLowerCase()] ?? 'application/octet-stream'
|
||||
const size = fs.statSync(abs).size
|
||||
res.setHeader('Content-Type', mime)
|
||||
res.setHeader('Accept-Ranges', 'bytes')
|
||||
|
||||
// Range support — needed so large meeting videos can seek/stream.
|
||||
const m = range?.match(/bytes=(\d*)-(\d*)/)
|
||||
if (m) {
|
||||
const start = m[1] ? parseInt(m[1], 10) : 0
|
||||
const end = m[2] ? parseInt(m[2], 10) : size - 1
|
||||
if (start >= size || end >= size || start > end) {
|
||||
res.statusCode = 416
|
||||
res.setHeader('Content-Range', `bytes */${size}`)
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
res.statusCode = 206
|
||||
res.setHeader('Content-Range', `bytes ${start}-${end}/${size}`)
|
||||
res.setHeader('Content-Length', String(end - start + 1))
|
||||
fs.createReadStream(abs, { start, end }).pipe(res)
|
||||
return
|
||||
}
|
||||
res.setHeader('Content-Length', String(size))
|
||||
fs.createReadStream(abs).pipe(res)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user