UNPKG

ziron-server

Version:
1 lines 3.13 kB
"use strict";var __awaiter=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(s,o){function i(e){try{d(n.next(e))}catch(e){o(e)}}function a(e){try{d(n.throw(e))}catch(e){o(e)}}function d(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,a)}d((n=n.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=enhanceHttpResponse,exports.writeResponseHeaders=writeResponseHeaders,exports.writeResponseRedirection=writeResponseRedirection,exports.sendFileToRes=sendFileToRes;const fs_1=require("fs"),MimeLockup_1=require("./MimeLockup");function enhanceHttpResponse(e){const t=e.end.bind(e),r=e.tryEnd.bind(e);return e.state=0,e.end=(...r)=>(t(...r),e.state=3,e),e.tryEnd=(...t)=>{const[n,s]=r(...t);return s&&(e.state=3),[n,s]},e.onAborted(()=>{e.state=2}),Object.defineProperty(e,"available",{get:()=>0===e.state}),Object.defineProperty(e,"closed",{get:()=>3===e.state||2===e.state}),e.reserve=()=>{if(0!==e.state)throw new Error("An unavailable response can not be reserved.");e.state=1},e.headers={},e.writeHeaders=t=>(t&&Object.assign(e.headers,t),writeResponseHeaders(e,e.headers),e),e.writeFile=(t,r,n)=>sendFileToRes(e,t,r,n),e.redirect=t=>writeResponseRedirection(e,t),e}function writeResponseHeaders(e,t={}){e.cork(()=>{for(const r in t)e.writeHeader(r,t[r].toString())})}function writeResponseRedirection(e,t){e.cork(()=>{e.writeStatus("302 Found"),e.headers.Location=t,e.writeHeaders(),e.end()})}const BYTES_PREFIX="bytes=";function sendFileToRes(e,t){return __awaiter(this,arguments,void 0,(function*(e,t,r={},n=!0){if(!e.available)throw new Error("A file can not be sent to an unavailable response.");e.reserve();let{mtime:s,size:o}=(0,fs_1.statSync)(t);s.setMilliseconds(0);const i=s.toUTCString();if(n){if(r["if-modified-since"]&&new Date(r["if-modified-since"])>=s)return void e.cork(()=>{e.writeStatus("304 Not Modified"),e.end()});e.headers["last-modified"]=i}if(!e.headers["content-type"]){const r=(0,MimeLockup_1.lockupMimeType)(t);null!=r&&(e.headers["content-type"]=r)}return new Promise((n,s)=>{let i=0,a=o-1;if(r.range){const t=r.range.replace("bytes=","").split("-");i=parseInt(t[0],10),a=t[1]?parseInt(t[1],10):a,e.headers["accept-ranges"]="bytes",e.headers["content-range"]=`bytes ${i}-${a}/${o}`,o=a-i+1,e.writeStatus("206 Partial Content")}a<0&&(a=0);const d=(0,fs_1.createReadStream)(t,{start:i,end:a});e.writeHeaders(),e.onAborted(()=>{d.destroy(),s(new Error("The request was aborted in the meantime."))}),d.on("data",t=>{if(e.closed)return s(new Error("The request was aborted in the meantime."));const r=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength),i=e.getWriteOffset(),[a,c]=e.tryEnd(r,o);if(c)d.destroy(),n();else if(!a){if(e.closed)return s(new Error("The request was aborted in the meantime."));d.pause(),e.ab=r,e.abOffset=i,e.onWritable(t=>{const[r,s]=e.tryEnd(e.ab.slice(t-e.abOffset),o);return s?(d.destroy(),n()):r&&d.resume(),r})}}).on("error",t=>{s(new Error(`Stream error: ${t}.`)),e.closed||e.cork(()=>{e.writeStatus("500 Internal server error"),e.end()}),d.destroy()})})}))}