Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: put new behavior for .br/.gz behind a flag
Adds --force-content-encoding flag which must be specified to enable
the behavior of including the Content-Encoding header in the response
when a .br or .gz file is directly requested in the URL.
  • Loading branch information
KernelDeimos committed Sep 26, 2025
commit 109b86a655d66b506cad7ee908dc02e6ab98f690
11 changes: 11 additions & 0 deletions bin/http-server
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ if (argv.h || argv.help) {
' -g --gzip Serve gzip files when possible [false]',
' -b --brotli Serve brotli files when possible [false]',
' If both brotli and gzip are enabled, brotli takes precedence',
'',
' --force-content-encoding',
' When using --gzip or --brotli, includes the content encoding',
' header even when the extension for the compressed file is',
' specified in the URL. "test.png.br" will be served the same',
' way as "test.png".',
'',
' -e --ext Default file extension if none supplied [none]',
' -s --silent Suppress log messages from output',
' --cors[=headers] Enable CORS via the "Access-Control-Allow-Origin" header',
Expand Down Expand Up @@ -180,6 +187,10 @@ function listen(port) {
options.corsHeaders = argv.cors;
}
}

if ( argv['force-content-encoding'] ) {
options.forceContentEncoding = true;
}

if (argv.header) {
if (Array.isArray(argv.header)) {
Expand Down
1 change: 1 addition & 0 deletions lib/core/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"cors": false,
"gzip": true,
"brotli": false,
"forceContentEncoding": false,
"defaultExt": ".html",
"handleError": true,
"contentType": "application/octet-stream",
Expand Down
9 changes: 7 additions & 2 deletions lib/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,13 @@ module.exports = function createMiddleware(_dir, _options) {
)
);
// determine compressed forms if they were to exist, make sure to handle pre-compressed files, i.e. files with .br/.gz extension. we will serve them "as-is"
gzippedFile = file.endsWith('.gz') ? file : `${file}.gz`;
brotliFile = file.endsWith('.br') ? file : `${file}.br`;
gzippedFile = `${file}.gz`;
brotliFile = `${file}.br`;

if ( opts.forceContentEncoding ) {
if ( file.endsWith('.gz') ) gzippedFile = file;
if ( file.endsWith('.br') ) brotliFile = file;
}

Object.keys(headers).forEach((key) => {
res.setHeader(key, headers[key]);
Expand Down
5 changes: 5 additions & 0 deletions lib/core/opts.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = (opts) => {
let cache = defaults.cache;
let gzip = defaults.gzip;
let brotli = defaults.brotli;
let forceContentEncoding = defaults.forceContentEncoding;
let defaultExt = defaults.defaultExt;
let handleError = defaults.handleError;
const headers = {};
Expand Down Expand Up @@ -108,6 +109,9 @@ module.exports = (opts) => {
if (typeof opts.brotli !== 'undefined' && opts.brotli !== null) {
brotli = opts.brotli;
}
if (typeof opts.forceContentEncoding !== 'undefined' && opts.forceContentEncoding !== null) {
forceContentEncoding = opts.forceContentEncoding;
}

aliases.handleError.some((k) => {
if (isDeclared(k)) {
Expand Down Expand Up @@ -192,6 +196,7 @@ module.exports = (opts) => {
baseDir: (opts && opts.baseDir) || '/',
gzip,
brotli,
forceContentEncoding,
handleError,
headers,
contentType,
Expand Down
2 changes: 2 additions & 0 deletions lib/http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ function HttpServer(options) {
this.showDotfiles = options.showDotfiles;
this.gzip = options.gzip === true;
this.brotli = options.brotli === true;
this.forceContentEncoding = options.forceContentEncoding === true;
if (options.ext) {
this.ext = options.ext === true
? 'html'
Expand Down Expand Up @@ -138,6 +139,7 @@ function HttpServer(options) {
defaultExt: this.ext,
gzip: this.gzip,
brotli: this.brotli,
forceContentEncoding: this.forceContentEncoding,
contentType: this.contentType,
mimetypes: options.mimetypes,
handleError: typeof options.proxy !== 'string'
Expand Down
Loading