diff --git a/server/middleware/ResponseUtils.js b/server/middleware/ResponseUtils.js deleted file mode 100644 index 146e28d..0000000 --- a/server/middleware/ResponseUtils.js +++ /dev/null @@ -1,88 +0,0 @@ -const fs = require('fs') -const etag = require('etag') -const { getContentType } = require('./FileUtils') - -const sendText = (res, statusCode, text) => { - res.writeHead(statusCode, { - 'Content-Type': 'text/plain', - 'Content-Length': Buffer.byteLength(text) - }) - - res.end(text) -} - -const sendJSON = (res, json, maxAge = 0, statusCode = 200) => { - const text = JSON.stringify(json) - - res.writeHead(statusCode, { - 'Content-Type': 'application/json', - 'Content-Length': Buffer.byteLength(text), - 'Cache-Control': `public, max-age=${maxAge}` - }) - - res.end(text) -} - -const sendInvalidURLError = (res, url) => - sendText(res, 403, `Invalid URL: ${url}`) - -const sendNotFoundError = (res, what) => - sendText(res, 404, `Not found: ${what}`) - -const sendServerError = (res, error) => - sendText(res, 500, `Server error: ${error.message || error}`) - -const sendHTML = (res, html, statusCode = 200) => { - res.writeHead(statusCode, { - 'Content-Type': 'text/html', - 'Content-Length': Buffer.byteLength(html) - }) - - res.end(html) -} - -const sendRedirect = (res, relativeLocation, statusCode = 302) => { - const location = res.req && res.req.baseUrl ? res.req.baseUrl + relativeLocation : relativeLocation - const html = `

You are being redirected to ${location}` - - res.writeHead(statusCode, { - 'Content-Type': 'text/html', - 'Content-Length': Buffer.byteLength(html), - 'Location': encodeURI(location) - }) - - res.end(html) -} - -const sendFile = (res, file, stats, maxAge = 0) => { - let contentType = getContentType(file) - - if (contentType === 'text/html') - contentType = 'text/plain' // We can't serve HTML because bad people :( - - res.writeHead(200, { - 'Content-Type': contentType, - 'Content-Length': stats.size, - 'Cache-Control': `public, max-age=${maxAge}`, - 'ETag': etag(stats) - }) - - const stream = fs.createReadStream(file) - - stream.on('error', (error) => { - sendServerError(res, error) - }) - - stream.pipe(res) -} - -module.exports = { - sendText, - sendJSON, - sendInvalidURLError, - sendNotFoundError, - sendServerError, - sendHTML, - sendRedirect, - sendFile -} diff --git a/server/middleware/findFile.js b/server/middleware/findFile.js index b67ae90..86318bc 100644 --- a/server/middleware/findFile.js +++ b/server/middleware/findFile.js @@ -71,7 +71,7 @@ function findFile(req, res, next) { if (queryMain) { if (!(queryMain in packageConfig)) - return res.status(404).send(`Cannot find field "${queryMain}" in ${req.packageSpec}/package.json`) + return res.status(404).send(`Cannot find field "${queryMain}" in ${req.packageSpec} package config`) mainFilename = packageConfig[queryMain] } else { diff --git a/server/middleware/serveFile.js b/server/middleware/serveFile.js index 38d23ea..59f12ca 100644 --- a/server/middleware/serveFile.js +++ b/server/middleware/serveFile.js @@ -1,7 +1,32 @@ +const fs = require('fs') const path = require('path') +const etag = require('etag') const { generateMetadata } = require('./MetadataUtils') const { generateDirectoryIndexHTML } = require('./IndexUtils') -const { sendFile } = require('./ResponseUtils') +const { getContentType } = require('./FileUtils') + +function sendFile(res, file, stats, maxAge = 0) { + let contentType = getContentType(file) + + if (contentType === 'text/html') + contentType = 'text/plain' // We can't serve HTML because bad people :( + + res.writeHead(200, { + 'Content-Type': contentType, + 'Content-Length': stats.size, + 'Cache-Control': `public, max-age=${maxAge}`, + 'ETag': etag(stats) + }) + + const stream = fs.createReadStream(file) + + stream.on('error', (error) => { + console.error(error) + res.status(500).send('There was an error serving this file') + }) + + stream.pipe(res) +} /** * Send the file, JSON metadata, or HTML directory listing. @@ -18,7 +43,7 @@ function serveFile(autoIndex, maximumDepth) { } }) } else if (req.stats.isFile()) { - // TODO: use res.sendFile instead of our own custom function? + // TODO: use res.sendFile instead of our own sendFile? sendFile(res, path.join(req.packageDir, req.file), req.stats, 31536000) } else if (autoIndex && req.stats.isDirectory()) { generateDirectoryIndexHTML(req.packageInfo, req.packageVersion, req.packageDir, req.file, function (error, html) {