Skip to content

Commit d5af101

Browse files
authored
Merge branch 'master' into qr
2 parents 49a56ad + 51204e1 commit d5af101

10 files changed

+3768
-6045
lines changed

.eslintrc.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "eslint-config-populist",
3+
"rules": {
4+
"strict": "warn",
5+
"indent": ["warn", 2],
6+
"valid-jsdoc": "warn",
7+
"no-undefined": "warn",
8+
"comma-dangle": "warn",
9+
"callback-return": ["warn", ["next"]]
10+
}
11+
}

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ Then you need to run the server with `-S` for enabling SSL and `-C` for your cer
104104
http-server -S -C cert.pem
105105
```
106106

107+
If you wish to use a passphrase with your private key you can include one in the openssl command via the -passout parameter (using password of foobar)
108+
109+
110+
e.g.
111+
`openssl req -newkey rsa:2048 -passout pass:foobar -keyout key.pem -x509 -days 365 -out cert.pem`
112+
113+
For security reasons, the passphrase will only be read from the `NODE_HTTP_SERVER_SSL_PASSPHRASE` environment variable.
114+
115+
107116
This is what should be output if successful:
108117

109118
``` sh

bin/http-server

+10-8
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,14 @@ if (argv.h || argv.help) {
6666
}
6767

6868
var port = argv.p || argv.port || parseInt(process.env.PORT, 10),
69-
host = argv.a || '0.0.0.0',
70-
tls = argv.S || argv.tls,
71-
proxy = argv.P || argv.proxy,
72-
proxyOptions = argv['proxy-options'],
73-
utc = argv.U || argv.utc,
74-
version = argv.v || argv.version,
75-
logger;
69+
host = argv.a || '0.0.0.0',
70+
tls = argv.S || argv.tls,
71+
sslPassphrase = process.env.NODE_HTTP_SERVER_SSL_PASSPHRASE,
72+
proxy = argv.P || argv.proxy,
73+
proxyOptions = argv['proxy-options'],
74+
utc = argv.U || argv.utc,
75+
version = argv.v || argv.version,
76+
logger;
7677

7778
var proxyOptionsBooleanProps = [
7879
'ws', 'xfwd', 'secure', 'toProxy', 'prependPath', 'ignorePath', 'changeOrigin',
@@ -176,7 +177,8 @@ function listen(port) {
176177
if (tls) {
177178
options.https = {
178179
cert: argv.C || argv.cert || 'cert.pem',
179-
key: argv.K || argv.key || 'key.pem'
180+
key: argv.K || argv.key || 'key.pem',
181+
passphrase: sslPassphrase,
180182
};
181183
try {
182184
fs.lstatSync(options.https.cert);

doc/http-server.1

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ If not specified, uses cert.pem.
114114
.BI \-K ", " \-\-key " " [\fIFILE\fR]
115115
Path to SSL key file.
116116
If not specified, uses key.pem.
117+
Passphrase will be read from NODE_HTTP_SERVER_SSL_PASSPHRASE (if set)
117118

118119
.TP
119120
.BI \-\-qr\-code

lib/core/index.js

-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ module.exports = function createMiddleware(_dir, _options) {
228228
// and brotli special case.
229229
const defaultType = opts.contentType || 'application/octet-stream';
230230
let contentType = mime.lookup(file, defaultType);
231-
let charSet;
232231
const range = (req.headers && req.headers.range);
233232
const lastModified = (new Date(stat.mtime)).toUTCString();
234233
const etag = generateEtag(stat, weakEtags);

lib/core/show-dir/last-modified-to-string.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
module.exports = function lastModifiedToString(stat) {
44
const t = new Date(stat.mtime);
5-
return (("0" + (t.getDate())).slice(-2) + '-' +
6-
t.toLocaleString('default', { month: 'short' }) + '-' +
5+
return (('0' + (t.getDate())).slice(-2) + '-' +
6+
t.toLocaleString('default', { month: 'short' }) + '-' +
77
t.getFullYear() + ' ' +
8-
("0" + t.getHours()).slice(-2) + ':' +
9-
("0" + t.getMinutes()).slice(-2));
8+
('0' + t.getHours()).slice(-2) + ':' +
9+
('0' + t.getMinutes()).slice(-2));
1010
};

lib/http-server.js

+18-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
'use strict';
22

33
var fs = require('fs'),
4-
union = require('union'),
5-
httpServerCore = require('./core'),
6-
auth = require('basic-auth'),
7-
httpProxy = require('http-proxy'),
8-
corser = require('corser'),
9-
path = require('path'),
10-
secureCompare = require('secure-compare');
4+
union = require('union'),
5+
httpServerCore = require('./core'),
6+
auth = require('basic-auth'),
7+
httpProxy = require('http-proxy'),
8+
corser = require('corser'),
9+
secureCompare = require('secure-compare');
1110

1211
//
1312
// Remark: backwards compatibility for previous
@@ -35,10 +34,10 @@ function HttpServer(options) {
3534
this.root = options.root;
3635
} else {
3736
try {
37+
// eslint-disable-next-line no-sync
3838
fs.lstatSync('./public');
3939
this.root = './public';
40-
}
41-
catch (err) {
40+
} catch (err) {
4241
this.root = './';
4342
}
4443
}
@@ -47,11 +46,12 @@ function HttpServer(options) {
4746
this.headers['Accept-Ranges'] = 'bytes';
4847

4948
this.cache = (
49+
// eslint-disable-next-line no-nested-ternary
5050
options.cache === undefined ? 3600 :
5151
// -1 is a special case to turn off caching.
5252
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Preventing_caching
53-
options.cache === -1 ? 'no-cache, no-store, must-revalidate' :
54-
options.cache // in seconds.
53+
options.cache === -1 ? 'no-cache, no-store, must-revalidate' :
54+
options.cache // in seconds.
5555
);
5656
this.showDir = options.showDir !== 'false';
5757
this.autoIndex = options.autoIndex !== 'false';
@@ -103,7 +103,7 @@ function HttpServer(options) {
103103
this.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Range';
104104
if (options.corsHeaders) {
105105
options.corsHeaders.split(/\s*,\s*/)
106-
.forEach(function (h) { this.headers['Access-Control-Allow-Headers'] += ', ' + h; }, this);
106+
.forEach(function (h) { this.headers['Access-Control-Allow-Headers'] += ', ' + h; }, this);
107107
}
108108
before.push(corser.create(options.corsHeaders ? {
109109
requestHeaders: this.headers['Access-Control-Allow-Headers'].split(/\s*,\s*/)
@@ -146,7 +146,7 @@ function HttpServer(options) {
146146
proxy.web(req, res, {
147147
target: options.proxy,
148148
changeOrigin: true
149-
}, function (err, req, res, target) {
149+
}, function (err, req, res) {
150150
if (options.logFn) {
151151
options.logFn(req, res, {
152152
message: err.message,
@@ -173,7 +173,11 @@ function HttpServer(options) {
173173
serverOptions.https = options.https;
174174
}
175175

176-
this.server = union.createServer(serverOptions);
176+
this.server = serverOptions.https && serverOptions.https.passphrase
177+
// if passphrase is set, shim must be used as union does not support
178+
? require('./shims/https-server-shim')(serverOptions)
179+
: union.createServer(serverOptions);
180+
177181
if (options.timeout !== undefined) {
178182
this.server.setTimeout(options.timeout);
179183
}

lib/shims/https-server-shim.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* eslint-disable no-process-env */
2+
/* eslint-disable no-sync */
3+
var https = require('https');
4+
var fs = require('fs');
5+
var core = require('union/lib/core');
6+
var RoutingStream = require('union/lib/routing-stream');
7+
8+
module.exports = function (options) {
9+
var isArray = Array.isArray(options.after);
10+
var credentials;
11+
12+
if (!options) {
13+
throw new Error('options is required to create a server');
14+
}
15+
16+
function requestHandler(req, res) {
17+
var routingStream = new RoutingStream({
18+
before: options.before,
19+
buffer: options.buffer,
20+
after:
21+
isArray &&
22+
options.after.map(function (After) {
23+
return new After();
24+
}),
25+
request: req,
26+
response: res,
27+
limit: options.limit,
28+
headers: options.headers
29+
});
30+
31+
routingStream.on('error', function (err) {
32+
var fn = options.onError || core.errorHandler;
33+
fn(err, routingStream, routingStream.target, function () {
34+
routingStream.target.emit('next');
35+
});
36+
});
37+
38+
req.pipe(routingStream);
39+
}
40+
41+
var serverOptions;
42+
43+
serverOptions = options.https;
44+
if (!serverOptions.key || !serverOptions.cert) {
45+
throw new Error(
46+
'Both options key and cert are required.'
47+
);
48+
}
49+
50+
credentials = {
51+
key: fs.readFileSync(serverOptions.key),
52+
cert: fs.readFileSync(serverOptions.cert),
53+
passphrase: process.env.NODE_HTTP_SERVER_SSL_PASSPHRASE
54+
};
55+
56+
if (serverOptions.ca) {
57+
serverOptions.ca = !Array.isArray(serverOptions.ca)
58+
? [serverOptions.ca]
59+
: serverOptions.ca;
60+
61+
credentials.ca = serverOptions.ca.map(function (ca) {
62+
return fs.readFileSync(ca);
63+
});
64+
}
65+
66+
return https.createServer(credentials, requestHandler);
67+
};

0 commit comments

Comments
 (0)