@@ -66,6 +66,28 @@ function escapeHtml(string) {
6666/** @typedef {import("fs").Stats } Stats */
6767/** @typedef {import("fs").ReadStream } ReadStream */
6868
69+ /**
70+ * Parse an HTTP Date into a number.
71+ * @param {string } date date
72+ * @returns {number } timestamp
73+ */
74+ function parseHttpDate ( date ) {
75+ const timestamp = date && Date . parse ( date ) ;
76+
77+ // istanbul ignore next: guard against date.js Date.parse patching
78+ return typeof timestamp === "number" ? timestamp : Number . NaN ;
79+ }
80+
81+ /**
82+ * @param {"bytes" } type type
83+ * @param {number } size size
84+ * @param {import("range-parser").Range= } range range
85+ * @returns {string } value of content range header
86+ */
87+ function getValueContentRangeHeader ( type , size , range ) {
88+ return `${ type } ${ range ? `${ range . start } -${ range . end } ` : "*" } /${ size } ` ;
89+ }
90+
6991/**
7092 * Generate a tag for a stat.
7193 * @param {Stats } stats stats
@@ -447,14 +469,9 @@ function finish(res, data) {
447469 * @param {OutputFileSystem } outputFileSystem output file system
448470 * @param {number } start start
449471 * @param {number } end end
450- * @returns {Promise< { bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number }> } result with buffer or stream and byte length
472+ * @returns {{ bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number } } result with buffer or stream and byte length
451473 */
452- async function createReadStreamOrReadFile (
453- filename ,
454- outputFileSystem ,
455- start ,
456- end ,
457- ) {
474+ function createReadStreamOrReadFile ( filename , outputFileSystem , start , end ) {
458475 /** @type {string | Buffer | import("fs").ReadStream } */
459476 let bufferOrStream ;
460477 /** @type {number } */
@@ -474,29 +491,33 @@ async function createReadStreamOrReadFile(
474491
475492 byteLength = end === 0 ? 0 : end - start + 1 ;
476493 } else {
477- bufferOrStream = await new Promise (
478- /**
479- * @param {(value: Buffer) => void } resolve resolve
480- * @param {(reason: Error) => void } reject reject
481- */
482- ( resolve , reject ) => {
483- outputFileSystem . readFile ( filename , ( err , data ) => {
484- if ( err ) {
485- reject ( err ) ;
486- return ;
487- }
488-
489- resolve ( /** @type {Buffer } */ ( data ) ) ;
490- } ) ;
491- } ,
492- ) ;
494+ bufferOrStream = outputFileSystem . readFileSync ( filename ) ;
495+ ( { byteLength } = bufferOrStream ) ;
493496
494497 byteLength = bufferOrStream . byteLength ;
495498 }
496499
497500 return { bufferOrStream, byteLength } ;
498501}
499502
503+ /**
504+ * @param {import("fs").ReadStream } stream stream
505+ * @param {boolean } suppress do need suppress?
506+ * @returns {void }
507+ */
508+ function destroyStream ( stream , suppress ) {
509+ if ( stream . destroyed ) {
510+ return ;
511+ }
512+
513+ stream . destroy ( ) ;
514+
515+ if ( typeof stream . addListener === "function" && suppress ) {
516+ stream . removeAllListeners ( "error" ) ;
517+ stream . addListener ( "error" , ( ) => { } ) ;
518+ }
519+ }
520+
500521/**
501522 * @template {ServerResponse & ExpectedServerResponse} Response
502523 * @param {Response } res res
@@ -544,6 +565,7 @@ function setState(res, name, value) {
544565
545566module . exports = {
546567 createReadStreamOrReadFile,
568+ destroyStream,
547569 escapeHtml,
548570 etag,
549571 finish,
@@ -555,8 +577,10 @@ module.exports = {
555577 getResponseHeader,
556578 getResponseHeaders,
557579 getStatusCode,
580+ getValueContentRangeHeader,
558581 initState,
559582 memorize,
583+ parseHttpDate,
560584 parseTokenList,
561585 pipe,
562586 removeResponseHeader,
0 commit comments