Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(http-server):Add a configuration file to store frequently used configuration values #770 #769

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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` |
Expand Down Expand Up @@ -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:
Expand Down
36 changes: 28 additions & 8 deletions bin/http-server
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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',
Expand All @@ -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,
Expand All @@ -88,6 +106,7 @@ if (proxyOptions) {
});
}


if (!argv.s && !argv.silent) {
logger = {
info: console.log,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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:'));
Expand Down
2 changes: 1 addition & 1 deletion lib/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
5 changes: 2 additions & 3 deletions lib/http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down