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

Dynamic response headers #460

Closed
wants to merge 5 commits into from
Closed
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,42 @@ This will install `http-server` globally so that it may be run from the command

`-h` or `--help` Print this list and exit.

## Headers

An optional file called `headers.json` may be placed in the root path (as specified by the [path] argument) being
served. If this file is present, the contents are used to add headers to the server response. Request paths can be
added to the json file with an array of objects that contain information about the headers to add.

The `headers.json` file follows this format:
```
{
"Path to Match": [
{"header": "Name of the header to add", "value": "value of header", "append": true/false},
{"header": "Second header on same path", "value": "value of header", "append": true/false}
],
"Second Path to match": [
{"header": "Name of the header to add", "value": "value of header", "append": true/false}
]
}
```

Notes about the `headers.json` file:
- "Path to match" uses [minimatch](https://www.npmjs.com/package/minimatch) to match to the request. For example,
an entry for `/**` would match all requests.
- The headers are added in the order they appear in the file. Unless `append` is set to true, previous values will
be overwritten
- `append` is optional. If not present, or set to false, a matched header will be overwritten. If set to true,
the value specified will be appended to the existing header value separated by a comma (,) and a space as
specified [here](https://tools.ietf.org/html/rfc7230#section-3.2).
- Headers added with this file will be added/set AFTER headers set by command line arguments. This will allow you
to selectively override/change headers set at http-server startup.


## Magic Files

- `index.html` will be served as the default file to any directory requests.
- `404.html` will be served if a file is not found. This can be used for Single-Page App (SPA) hosting to serve the entry page.
- `headers.json` will be read (if present) and used to add headers to the response.

# Development

Expand Down
24 changes: 23 additions & 1 deletion lib/http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ var fs = require('fs'),
union = require('union'),
ecstatic = require('ecstatic'),
httpProxy = require('http-proxy'),
corser = require('corser');
corser = require('corser'),
minimatch = require('minimatch');

var HEADERS_FILE_NAME = 'headers.json';
//
// Remark: backwards compatibility for previous
// case convention of HTTP
Expand Down Expand Up @@ -93,6 +95,26 @@ function HttpServer(options) {
});
}

if (fs.existsSync(this.root + '/' + HEADERS_FILE_NAME)) {
console.log('Loading Headers file:', this.root + '/' + HEADERS_FILE_NAME);
var headers = JSON.parse(fs.readFileSync(this.root + '/' + HEADERS_FILE_NAME)) || {};
var paths = Object.keys(headers);
before.push(function (req, res) {
paths.forEach(function (p) {
if (minimatch(req.url, p, {})) {
headers[p].forEach(function (h) {
var value = h.value.trim();
if (h.hasOwnProperty('append') && h.append) {
value = res.getHeader(h.header).trim() + ', ' + value; // Trim .getHeader() as we may not have set it
}
res.setHeader(h.header, value);
});
}
});
res.emit('next');
});
}

before.push(ecstatic({
root: this.root,
cache: this.cache,
Expand Down
Loading