UNPKG

send-stream

Version:

Streaming file serving library with Range and conditional-GET support from file system or any streaming sources.

110 lines 3.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StreamResponse = void 0; const node_http_1 = require("node:http"); const node_http2_1 = require("node:http2"); const node_stream_1 = require("node:stream"); const node_util_1 = require("node:util"); const promisifiedStreamPipeline = (0, node_util_1.promisify)(node_stream_1.pipeline); async function pipeline(readStream, res, ignorePrematureClose) { try { await promisifiedStreamPipeline(readStream, res); } catch (err) { if (ignorePrematureClose) { return; } throw err; } } /** * Stream response * @template AttachedData - attached data type */ class StreamResponse { /** * Create stream response * @param statusCode - the status code matching the required resource * @param headers - the response headers to be sent for the required resource * @param stream - the response stream to be sent for the required resource * @param storageInfo - the storage information for the required resource (if existing) * @param error - the error if the resource can not be found or openned for any reason */ constructor(statusCode, headers, stream, storageInfo, error) { Object.defineProperty(this, "statusCode", { enumerable: true, configurable: true, writable: true, value: statusCode }); Object.defineProperty(this, "headers", { enumerable: true, configurable: true, writable: true, value: headers }); Object.defineProperty(this, "stream", { enumerable: true, configurable: true, writable: true, value: stream }); Object.defineProperty(this, "storageInfo", { enumerable: true, configurable: true, writable: true, value: storageInfo }); Object.defineProperty(this, "error", { enumerable: true, configurable: true, writable: true, value: error }); } /** * Send response to http response * @param res - http response * @param opts - options * @param opts.ignorePrematureClose - ignore premature close errors * @throws error when response is already closed */ async send(res, { ignorePrematureClose = true } = {}) { const { statusCode } = this; const { headers: responseHeaders, stream: readStream } = this; if (res.headersSent) { readStream.destroy(); throw new Error('response headers already sent'); } if (res instanceof node_http_1.ServerResponse) { const { socket, destroyed } = res; if (destroyed || !socket || socket.destroyed) { readStream.destroy(); return; } res.writeHead(statusCode, responseHeaders); await pipeline(readStream, res, ignorePrematureClose); } else { const resStream = res instanceof node_http2_1.Http2ServerResponse ? res.stream : res; if (resStream.destroyed || resStream.closed) { readStream.destroy(); return; } resStream.respond({ // eslint-disable-next-line @typescript-eslint/naming-convention ':status': statusCode, ...responseHeaders, }); await pipeline(readStream, resStream, ignorePrematureClose); } } /** * Disposes of resources within the stream response object */ dispose() { this.stream.destroy(); } } exports.StreamResponse = StreamResponse; //# sourceMappingURL=response.js.map