mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-07 09:51:37 +00:00
Fix keep-alive timeout and remove fs.stat() overhead from downloads
This commit is contained in:
parent
cf0a432027
commit
e74dbf5f40
2 changed files with 13 additions and 13 deletions
|
|
@ -301,6 +301,11 @@ class Server {
|
||||||
app.disable('x-powered-by')
|
app.disable('x-powered-by')
|
||||||
|
|
||||||
this.server = http.createServer(app)
|
this.server = http.createServer(app)
|
||||||
|
// Keep connections alive for 120s so multi-file downloads don't pay a new
|
||||||
|
// TCP handshake per file. Default Node.js keepAliveTimeout is only 5s,
|
||||||
|
// which causes connections to drop mid-download for files > 5s.
|
||||||
|
this.server.keepAliveTimeout = 120000
|
||||||
|
this.server.headersTimeout = 125000
|
||||||
|
|
||||||
router.use(
|
router.use(
|
||||||
fileUpload({
|
fileUpload({
|
||||||
|
|
|
||||||
|
|
@ -184,12 +184,10 @@ class LibraryItemController {
|
||||||
if (audioMimeType) {
|
if (audioMimeType) {
|
||||||
res.setHeader('Content-Type', audioMimeType)
|
res.setHeader('Content-Type', audioMimeType)
|
||||||
}
|
}
|
||||||
// Set Content-Length so clients can show accurate progress bars.
|
// Use sendFile so the `send` module sets Content-Length, Accept-Ranges,
|
||||||
const fileStat = await fs.stat(libraryItemPath).catch(() => null)
|
// and handles range requests natively — no extra stat() call needed.
|
||||||
if (fileStat) {
|
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(Path.basename(req.libraryItem.relPath))}"`)
|
||||||
res.setHeader('Content-Length', fileStat.size)
|
await new Promise((resolve, reject) => res.sendFile(libraryItemPath, { dotfiles: 'allow' }, (error) => (error ? reject(error) : resolve())))
|
||||||
}
|
|
||||||
await new Promise((resolve, reject) => res.download(libraryItemPath, req.libraryItem.relPath, (error) => (error ? reject(error) : resolve())))
|
|
||||||
} else {
|
} else {
|
||||||
const filename = `${itemTitle}.zip`
|
const filename = `${itemTitle}.zip`
|
||||||
await zipHelpers.zipDirectoryPipe(libraryItemPath, filename, res)
|
await zipHelpers.zipDirectoryPipe(libraryItemPath, filename, res)
|
||||||
|
|
@ -1102,13 +1100,10 @@ class LibraryItemController {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Set Content-Length so clients (including the Android app) can show accurate
|
// Use sendFile so the `send` module sets Content-Length, Accept-Ranges,
|
||||||
// download progress and avoid chunked-transfer encoding when the file size is known.
|
// and handles range requests natively — no extra stat() call needed.
|
||||||
const fileStat = await fs.stat(libraryFile.metadata.path).catch(() => null)
|
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(libraryFile.metadata.filename)}"`)
|
||||||
if (fileStat) {
|
await new Promise((resolve, reject) => res.sendFile(libraryFile.metadata.path, { dotfiles: 'allow' }, (error) => (error ? reject(error) : resolve())))
|
||||||
res.setHeader('Content-Length', fileStat.size)
|
|
||||||
}
|
|
||||||
await new Promise((resolve, reject) => res.download(libraryFile.metadata.path, libraryFile.metadata.filename, (error) => (error ? reject(error) : resolve())))
|
|
||||||
Logger.info(`[LibraryItemController] Downloaded file "${libraryFile.metadata.path}"`)
|
Logger.info(`[LibraryItemController] Downloaded file "${libraryFile.metadata.path}"`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(`[LibraryItemController] Failed to download file "${libraryFile.metadata.path}"`, error)
|
Logger.error(`[LibraryItemController] Failed to download file "${libraryFile.metadata.path}"`, error)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue