diff --git a/README.md b/README.md index 0ffbbc1f..7da2faca 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Using `npx` you can run the script without installing it first: npx http-server [path] [options] +Optionally you can create a JavaScript module file 'http-server-config.js' that exports any of the configuration options you want to include. This can be used to create redirects, apply custom content types etc. + #### Globally via `npm` npm install --global http-server @@ -44,6 +46,7 @@ This will install `http-server` globally so that it may be run from the command | Command | Description | Defaults | | ------------- |-------------|-------------| +| --config | Configuration file to read. Defaults to http-server-config.js | |`-p` or `--port` |Port to use. Use `-p 0` to look for an open port, starting at 8080. It will also read from `process.env.PORT`. |8080 | |`-a` |Address to use |0.0.0.0| |`-d` |Show directory listings |`true` | @@ -134,6 +137,24 @@ Available on: Hit CTRL-C to stop the server ``` +# configuration file +You can configure http-server automatically with a file named http-server-config.js, located in the directory +you run the command from, or as specified by the --config option. + +An example configuration: +```js +module.exports = { + gzip: true, + before: [ + (req,res) => { + console.log('Hello req', req); + console.log('Hello res', res); + res.emit('next'); + }, + ], +}; +``` + # Development Checkout this repository locally, then: diff --git a/bin/http-server b/bin/http-server index 3b9e59d2..3acc8ae1 100755 --- a/bin/http-server +++ b/bin/http-server @@ -10,6 +10,7 @@ var colors = require('colors/safe'), fs = require('fs'), url = require('url'); +const path = require('path'); var argv = require('minimist')(process.argv.slice(2), { alias: { tls: 'ssl' @@ -56,6 +57,7 @@ if (argv.h || argv.help) { ' -C --cert Path to TLS cert file (default: cert.pem)', ' -K --key Path to TLS key file (default: key.pem)', '', + ' --config Read the JavaScript file for initial options (http-server-config.js if it exists)', ' -r --robots Respond to /robots.txt [User-agent: *\\nDisallow: /]', ' --no-dotfiles Do not show dotfiles', ' --mimetypes Path to a .types file for custom mimetype definition', @@ -65,7 +67,23 @@ if (argv.h || argv.help) { process.exit(); } -var port = argv.p || argv.port || parseInt(process.env.PORT, 10), +const configFile = (typeof argv.config) == 'string' && argv.config || 'http-server-config.js'; +const isRootConfig = configFile.length && (configFile[0] == '/' || configFile[0] == '\\') || + configFile.length > 1 && configFile[1] == ':'; +const configPath = isRootConfig && configFile || path.join(process.cwd(), configFile); +let defaultOptions = {}; +try { + defaultOptions = require(configPath); + console.log('Read config', configPath); +} catch(e) { + if( argv.config ) { + console.log(e); + throw new Error(`Couldn't load ${configPath}`); + } +} + + +var port = argv.p || argv.port || parseInt(process.env.PORT, 10) || defaultOptions.port, host = argv.a || '0.0.0.0', tls = argv.S || argv.tls, sslPassphrase = process.env.NODE_HTTP_SERVER_SSL_PASSPHRASE, @@ -88,6 +106,7 @@ if (proxyOptions) { }); } + if (!argv.s && !argv.silent) { logger = { info: console.log, @@ -153,7 +172,8 @@ function listen(port) { showDotfiles: argv.dotfiles, mimetypes: argv.mimetypes, username: argv.username || process.env.NODE_HTTP_SERVER_USERNAME, - password: argv.password || process.env.NODE_HTTP_SERVER_PASSWORD + password: argv.password || process.env.NODE_HTTP_SERVER_PASSWORD, + ...defaultOptions, }; if (argv.cors) { @@ -209,14 +229,14 @@ function listen(port) { logger.info([ colors.yellow('\nhttp-server settings: '), - ([colors.yellow('CORS: '), argv.cors ? colors.cyan(argv.cors) : colors.red('disabled')].join('')), - ([colors.yellow('Cache: '), argv.c ? (argv.c === '-1' ? colors.red('disabled') : colors.cyan(argv.c + ' seconds')) : colors.cyan('3600 seconds')].join('')), + ([colors.yellow('CORS: '), options.cors ? colors.cyan(options.cors) : colors.red('disabled')].join('')), + ([colors.yellow('Cache: '), options.cache ? (options.cache === '-1' ? colors.red('disabled') : colors.cyan(options.cache + ' seconds')) : colors.cyan('3600 seconds')].join('')), ([colors.yellow('Connection Timeout: '), argv.t === '0' ? colors.red('disabled') : (argv.t ? colors.cyan(argv.t + ' seconds') : colors.cyan('120 seconds'))].join('')), - ([colors.yellow('Directory Listings: '), argv.d ? colors.red('not visible') : colors.cyan('visible')].join('')), + ([colors.yellow('Directory Listings: '), options.showDir ? colors.red('not visible') : colors.cyan('visible')].join('')), ([colors.yellow('AutoIndex: '), argv.i ? colors.red('not visible') : colors.cyan('visible')].join('')), - ([colors.yellow('Serve GZIP Files: '), argv.g || argv.gzip ? colors.cyan('true') : colors.red('false')].join('')), - ([colors.yellow('Serve Brotli Files: '), argv.b || argv.brotli ? colors.cyan('true') : colors.red('false')].join('')), - ([colors.yellow('Default File Extension: '), argv.e ? colors.cyan(argv.e) : (argv.ext ? colors.cyan(argv.ext) : colors.red('none'))].join('')) + ([colors.yellow('Serve GZIP Files: '), options.gzip ? colors.cyan('true') : colors.red('false')].join('')), + ([colors.yellow('Serve Brotli Files: '), options.brotli ? colors.cyan('true') : colors.red('false')].join('')), + ([colors.yellow('Default File Extension: '), options.ext ? colors.cyan(options.ext) : colors.red('none')].join('')) ].join('\n')); logger.info(colors.yellow('\nAvailable on:')); diff --git a/lib/core/index.js b/lib/core/index.js index 920e55b9..68593198 100644 --- a/lib/core/index.js +++ b/lib/core/index.js @@ -320,7 +320,7 @@ module.exports = function createMiddleware(_dir, _options) { res.setHeader('content-type', contentType); // set the response statusCode if we have a request statusCode. - // This only can happen if we have a 404 with some kind of 404.html + // This only can happen if we have a 404 with some kind of 404.html // In all other cases where we have a file we serve the 200 res.statusCode = req.statusCode || 200; diff --git a/lib/http-server.js b/lib/http-server.js index dfe4c474..aa3aa407 100644 --- a/lib/http-server.js +++ b/lib/http-server.js @@ -46,11 +46,10 @@ function HttpServer(options) { this.headers['Accept-Ranges'] = 'bytes'; this.cache = ( - // eslint-disable-next-line no-nested-ternary - options.cache === undefined ? 3600 : + options.cache === undefined && 3600 || // -1 is a special case to turn off caching. // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Preventing_caching - options.cache === -1 ? 'no-cache, no-store, must-revalidate' : + options.cache === -1 && 'no-cache, no-store, must-revalidate' || options.cache // in seconds. ); this.showDir = options.showDir !== 'false';