From 277a32f74b5757e3a7e5a1fe57d592206a1817fa Mon Sep 17 00:00:00 2001 From: Frazer Smith Date: Fri, 22 Nov 2024 10:19:46 +0000 Subject: [PATCH] feat: add `contentType` option (#93) * feat: add `contentType` option * test: add type tests * Update README.md Signed-off-by: Frazer Smith --------- Signed-off-by: Frazer Smith --- README.md | 8 ++++++++ lib/send.js | 21 ++++++++++++++------- test/send.1.test.js | 15 ++++++++++++++- types/index.d.ts | 5 +++++ types/index.test-d.ts | 10 +++++++++- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a6a87df..f5b11e5 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,14 @@ of the `Range` request header. Enable or disable setting `Cache-Control` response header, defaults to true. Disabling this will ignore the `immutable` and `maxAge` options. +##### contentType + +By default, this library uses the `mime` module to set the `Content-Type` +of the response based on the file extension of the requested file. + +To disable this functionality, set `contentType` to `false`. +The `Content-Type` header will need to be set manually if disabled. + ##### dotfiles Set how "dotfiles" are treated when encountered. A dotfile is a file diff --git a/lib/send.js b/lib/send.js index d9b05e0..f8df6ec 100644 --- a/lib/send.js +++ b/lib/send.js @@ -101,6 +101,10 @@ function normalizeOptions (options) { ? Boolean(options.cacheControl) : true + const contentType = options.contentType !== undefined + ? Boolean(options.contentType) + : true + const etag = options.etag !== undefined ? Boolean(options.etag) : true @@ -137,6 +141,7 @@ function normalizeOptions (options) { return { acceptRanges, cacheControl, + contentType, etag, dotfiles, extensions, @@ -489,13 +494,15 @@ function sendFileDirectly (request, path, stat, options) { } // set content-type - let type = mime.getType(path) || mime.default_type - debug('content-type %s', type) - if (type && isUtf8MimeType(type)) { - type += '; charset=utf-8' - } - if (type) { - headers['Content-Type'] = type + if (options.contentType) { + let type = mime.getType(path) || mime.default_type + debug('content-type %s', type) + if (type && isUtf8MimeType(type)) { + type += '; charset=utf-8' + } + if (type) { + headers['Content-Type'] = type + } } // conditional GET support diff --git a/test/send.1.test.js b/test/send.1.test.js index 672face..a744346 100644 --- a/test/send.1.test.js +++ b/test/send.1.test.js @@ -13,7 +13,7 @@ const { shouldNotHaveHeader, createServer } = require('./utils') const fixtures = path.join(__dirname, 'fixtures') test('send(file, options)', function (t) { - t.plan(10) + t.plan(11) t.test('acceptRanges', function (t) { t.plan(2) @@ -60,6 +60,19 @@ test('send(file, options)', function (t) { }) }) + t.test('contentType', function (t) { + t.plan(1) + + t.test('should support disabling content-type', function (t) { + t.plan(2) + + request(createServer({ contentType: false, root: fixtures })) + .get('/name.txt') + .expect(shouldNotHaveHeader('Content-Type', t)) + .expect(200, err => t.error(err)) + }) + }) + t.test('etag', function (t) { t.plan(1) diff --git a/types/index.d.ts b/types/index.d.ts index 31cd91d..b2a0f11 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -44,6 +44,11 @@ declare namespace send { */ cacheControl?: boolean | undefined; + /** + * Enable or disable setting Content-Type response header, defaults to true. + */ + contentType?: boolean | undefined; + /** * Set how "dotfiles" are treated when encountered. * A dotfile is a file or directory that begins with a dot ("."). diff --git a/types/index.test-d.ts b/types/index.test-d.ts index 783ceba..7a50808 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -26,7 +26,7 @@ const req: any = {} } { - const result = await send(req, '/test.html', { maxAge: 0, root: __dirname + '/wwwroot' }) + const result = await send(req, '/test.html', { contentType: true, maxAge: 0, root: __dirname + '/wwwroot' }) expectType(result) expectType(result.statusCode) @@ -34,6 +34,14 @@ const req: any = {} expectType(result.stream) } +{ + const result = await send(req, '/test.html', { contentType: false, root: __dirname + '/wwwroot' }) + + expectType(result) + expectType(result.statusCode) + expectType>(result.headers) + expectType(result.stream) +} const result = await send(req, '/test.html') switch (result.type) {