UNPKG

als-send-file

Version:

file serving with advanced options for caching, headers, and error handling, compatible with Express middleware.

47 lines (43 loc) 1.79 kB
const { createReadStream } = require('fs'); const rangeParser = require('range-parser'); const {basename} = require('path') /** * Sends a file to the client with support for ranges and error handling. * @param {http.IncomingMessage} req - The request object. * @param {http.ServerResponse} res - The response object. * @param {string} filePath - The path to the file. * @param {Object} stats - The file stats object. * @param {Function} httpErrorHandler - Function to handle HTTP errors. */ async function sendFile(req, res, filePath, stats, httpErrorHandler) { const options = {} if (req.headers.range) { const ranges = rangeParser(stats.size, req.headers.range); // Parse Range header if (ranges === -1 || ranges.type !== 'bytes' || ranges.length > 1) { return httpErrorHandler(res,416, 'Range is not valid') } const { start, end } = ranges[0]; res.statusCode = 206; res.setHeader('Content-Range', `bytes ${start}-${end}/${stats.size}`); res.setHeader('Content-Length', (end - start + 1).toString()); options.start = start; options.end = end; } const fileStream = createReadStream(filePath, options); return new Promise((resolve, reject) => { let closed = false const close = (err) => { fileStream.destroy(); if (res.finished || closed) return resolve() closed = true if(err) httpErrorHandler(res,500,err) else res.end() resolve() } fileStream.on('error', () => close(`file ${basename(filePath)} error`)); fileStream.on('end', close); res.on('close', close); fileStream.pipe(res); // Passing data from a stream to a response }) } module.exports = sendFile