From af94f7b9a19de71026ccbc192a6f4eb8dc430799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Thu, 5 Mar 2020 17:37:06 +0000 Subject: [PATCH] Use mime-types for file to content type mapping closes #192 --- HISTORY.md | 1 + README.md | 27 ++++++++++----------------- index.js | 15 ++++----------- package.json | 2 +- test/send.js | 45 +++++++++------------------------------------ 5 files changed, 25 insertions(+), 65 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 66d3ced..82e1ff2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,7 @@ * Remove `send.index()` -- use `index` in `options` * Remove `send.maxage()` -- use `maxAge` in `options` * Remove `send.root()` -- use `root` in `options` + * Use `mime-types` for file to content type mapping -- removed `send.mime` 0.17.2 / 2021-12-11 =================== diff --git a/README.md b/README.md index fc1d3a1..984a952 100644 --- a/README.md +++ b/README.md @@ -133,15 +133,6 @@ The `SendStream` is an event emitter and will emit the following events: The `pipe` method is used to pipe the response into the Node.js HTTP response object, typically `send(req, path, options).pipe(res)`. -### .mime - -The `mime` export is the global instance of of the -[`mime` npm module](https://www.npmjs.com/package/mime). - -This is used to configure the MIME types that are associated with file extensions -as well as other options for how to resolve the MIME type of a file (like the -default type to use for an unknown file extension). - ## Error-handling By default when no `error` listeners are present an automatic response will be @@ -210,20 +201,22 @@ server.listen(3000) ### Custom file types ```js +var extname = require('path').extname var http = require('http') var parseUrl = require('parseurl') var send = require('send') -// Default unknown types to text/plain -send.mime.default_type = 'text/plain' - -// Add a custom type -send.mime.define({ - 'application/x-my-type': ['x-mt', 'x-mtt'] -}) - var server = http.createServer(function onRequest (req, res) { send(req, parseUrl(req).pathname, { root: '/www/public' }) + .on('headers', function (res, path) { + switch (extname(path)) { + case '.x-mt': + case '.x-mtt': + // custom type for these extensions + res.setHeader('Content-Type', 'application/x-my-type') + break + } + }) .pipe(res) }) diff --git a/index.js b/index.js index 74bceb1..2c6a789 100644 --- a/index.js +++ b/index.js @@ -21,7 +21,7 @@ var escapeHtml = require('escape-html') var etag = require('etag') var fresh = require('fresh') var fs = require('fs') -var mime = require('mime') +var mime = require('mime-types') var ms = require('ms') var onFinished = require('on-finished') var parseRange = require('range-parser') @@ -68,7 +68,6 @@ var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/ */ module.exports = send -module.exports.mime = mime /** * Return a `SendStream` for `req` and `path`. @@ -762,17 +761,11 @@ SendStream.prototype.type = function type (path) { if (res.getHeader('Content-Type')) return - var type = mime.lookup(path) - - if (!type) { - debug('no content-type') - return - } - - var charset = mime.charsets.lookup(type) + var ext = extname(path) + var type = mime.contentType(ext) || 'application/octet-stream' debug('content-type %s', type) - res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')) + res.setHeader('Content-Type', type) } /** diff --git a/package.json b/package.json index 2bbce46..0288573 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "1.8.1", - "mime": "1.6.0", + "mime-types": "~2.1.34", "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", diff --git a/test/send.js b/test/send.js index d74890d..0be4282 100644 --- a/test/send.js +++ b/test/send.js @@ -147,16 +147,23 @@ describe('send(file).pipe(res)', function () { it('should set Content-Type via mime map', function (done) { request(app) .get('/name.txt') - .expect('Content-Type', 'text/plain; charset=UTF-8') + .expect('Content-Type', 'text/plain; charset=utf-8') .expect(200, function (err) { if (err) return done(err) request(app) .get('/tobi.html') - .expect('Content-Type', 'text/html; charset=UTF-8') + .expect('Content-Type', 'text/html; charset=utf-8') .expect(200, done) }) }) + it('should default Content-Type to octet-stream', function (done) { + request(app) + .get('/no_ext') + .expect('Content-Type', 'application/octet-stream') + .expect(200, done) + }) + it('should 404 if file disappears after stat, before open', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, { root: 'test/fixtures' }) @@ -1281,40 +1288,6 @@ describe('send(file, options)', function () { }) }) -describe('send.mime', function () { - it('should be exposed', function () { - assert.ok(send.mime) - }) - - describe('.default_type', function () { - before(function () { - this.default_type = send.mime.default_type - }) - - afterEach(function () { - send.mime.default_type = this.default_type - }) - - it('should change the default type', function (done) { - send.mime.default_type = 'text/plain' - - request(createServer({ root: fixtures })) - .get('/no_ext') - .expect('Content-Type', 'text/plain; charset=UTF-8') - .expect(200, done) - }) - - it('should not add Content-Type for undefined default', function (done) { - send.mime.default_type = undefined - - request(createServer({ root: fixtures })) - .get('/no_ext') - .expect(shouldNotHaveHeader('Content-Type')) - .expect(200, done) - }) - }) -}) - function createServer (opts, fn) { return http.createServer(function onRequest (req, res) { try {