fix: 416 status code handling

This commit is contained in:
Bobby Wibowo 2022-07-31 16:46:35 +07:00
parent 0598a63989
commit 21ec4a7479
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
3 changed files with 23 additions and 16 deletions

View File

@ -180,26 +180,29 @@ class ServeStatic {
} }
// ReadStream options with Content-Range support if required // ReadStream options with Content-Range support if required
const { options, length } = serveUtils.buildReadStreamOptions(req, res, stat, this.#options.acceptRanges) const result = serveUtils.buildReadStreamOptions(req, res, stat, this.#options.acceptRanges)
if (!result) {
return res.end()
}
// HEAD support // HEAD support
if (req.method === 'HEAD') { if (req.method === 'HEAD') {
// If HEAD, also set Content-Length (must be string) // If HEAD, also set Content-Length (must be string)
res.header('Content-Length', String(length)) res.header('Content-Length', String(result.length))
return res.end() return res.end()
} }
// Only set Content-Disposition on initial GET request // Only set Content-Disposition on initial GET request
// Skip for subsequent requests on non-zero start byte (e.g. streaming) // Skip for subsequent requests on non-zero start byte (e.g. streaming)
if (options.start === 0 && this.setContentDisposition) { if (result.options.start === 0 && this.setContentDisposition) {
await this.setContentDisposition(req, res) await this.setContentDisposition(req, res)
} }
if (length === 0) { if (result.length === 0) {
res.end() res.end()
} }
return this.#stream(req, res, fullPath, options, length) return this.#stream(req, res, fullPath, result)
} }
async #setHeaders (req, res, stat) { async #setHeaders (req, res, stat) {
@ -229,8 +232,8 @@ class ServeStatic {
} }
} }
async #stream (req, res, fullPath, options, length) { async #stream (req, res, fullPath, result) {
const readStream = fs.createReadStream(fullPath, options) const readStream = fs.createReadStream(fullPath, result.options)
readStream.on('error', error => { readStream.on('error', error => {
readStream.destroy() readStream.destroy()
@ -238,7 +241,7 @@ class ServeStatic {
}) })
// 2nd param will be set as Content-Length header (must be number) // 2nd param will be set as Content-Length header (must be number)
return res.stream(readStream, length) return res.stream(readStream, result.length)
} }
get handler () { get handler () {

View File

@ -90,20 +90,23 @@ class ServeStaticQuick {
} }
// ReadStream options with Content-Range support if required // ReadStream options with Content-Range support if required
const { options, length } = serveUtils.buildReadStreamOptions(req, res, stat, this.#options.acceptRanges) const result = serveUtils.buildReadStreamOptions(req, res, stat, this.#options.acceptRanges)
if (!result) {
return res.end()
}
// HEAD support // HEAD support
if (req.method === 'HEAD') { if (req.method === 'HEAD') {
// If HEAD, also set Content-Length (must be string) // If HEAD, also set Content-Length (must be string)
res.header('Content-Length', String(length)) res.header('Content-Length', String(result.length))
return res.end() return res.end()
} }
if (length === 0) { if (result.length === 0) {
res.end() res.end()
} }
return this.#stream(req, res, stat, options, length) return this.#stream(req, res, stat, result)
} }
// Returns a promise which resolves to true once ServeStaticQuick is ready // Returns a promise which resolves to true once ServeStaticQuick is ready
@ -195,9 +198,9 @@ class ServeStaticQuick {
} }
} }
#stream (req, res, stat, options, length) { #stream (req, res, stat, result) {
const fullPath = this.directory + req.path const fullPath = this.directory + req.path
const readStream = fs.createReadStream(fullPath, options) const readStream = fs.createReadStream(fullPath, result.options)
readStream.on('error', error => { readStream.on('error', error => {
readStream.destroy() readStream.destroy()
@ -205,7 +208,7 @@ class ServeStaticQuick {
}) })
// 2nd param will be set as Content-Length header (must be number) // 2nd param will be set as Content-Length header (must be number)
return res.stream(readStream, length) return res.stream(readStream, result.length)
} }
get middleware () { get middleware () {

View File

@ -166,7 +166,8 @@ self.buildReadStreamOptions = (req, res, stat, acceptRanges) => {
res.header('Content-Range', self.contentRange('bytes', length)) res.header('Content-Range', self.contentRange('bytes', length))
// 416 Requested Range Not Satisfiable // 416 Requested Range Not Satisfiable
return res.status(416).end() res.status(416)
return false
} }
// Valid (syntactically invalid/multiple ranges are treated as a regular response) // Valid (syntactically invalid/multiple ranges are treated as a regular response)