create-servers
Advanced tools
Comparing version 2.4.0 to 2.5.0
52
index.js
@@ -152,5 +152,5 @@ 'use strict'; | ||
// | ||
key: normalizeCertFile(ssl.root, ssl.key), | ||
cert: normalizeCertFile(ssl.root, ssl.cert), | ||
ca: ca && ca.map(normalizeCertFile.bind(null, ssl.root)), | ||
key: normalizePEMContent(ssl.root, ssl.key), | ||
cert: normalizeCertContent(ssl.root, ssl.cert, ssl.key), | ||
ca: ca && ca.map(normalizePEMContent.bind(null, ssl.root)), | ||
// | ||
@@ -175,4 +175,4 @@ // Properly expose ciphers for an A+ SSL rating: | ||
args = [server, port]; | ||
if (options.https.host) { | ||
args.push(options.https.host); | ||
if (ssl.host) { | ||
args.push(ssl.host); | ||
} | ||
@@ -188,4 +188,40 @@ | ||
function normalizeCertContent(root, cert, key) { | ||
// Node accepts an array of certs, which must match up with an array of keys. | ||
// The user may instead intend for an array passed into cert to represent | ||
// a cert chain they want to concatenate. Therefore, if key is not an array, | ||
// we'll assume the latter. | ||
if (Array.isArray(cert)) { | ||
if (Array.isArray(key)) { | ||
// This is an array of certs/chains with corresponding keys | ||
return normalizeCertChainList(root, cert); | ||
} else { | ||
// This is a single cert chain | ||
return normalizeCertChain(root, cert); | ||
} | ||
} | ||
return normalizePEMContent(root, cert); | ||
} | ||
function normalizeCertChainList(root, data) { | ||
// If this is an array, treat like an array of bundles, otherwise a single | ||
// bundle | ||
return Array.isArray(data) | ||
? data.map(function (item) { | ||
return normalizeCertChain(root, item); | ||
}) | ||
: normalizePEMContent(root, data); | ||
} | ||
function normalizeCertChain(root, data) { | ||
// A chain can be an array, which we concatenate together into one PEM, | ||
// an already-concatenated chain, or a single PEM | ||
const content = normalizePEMContent(root, data); | ||
return Array.isArray(content) ? content.join('\n') : content; | ||
} | ||
/** | ||
* function normalizeCertFile(root, file) | ||
* function normalizePEMContent(root, file) | ||
* Returns the contents of `file` verbatim if it is determined to be | ||
@@ -195,5 +231,5 @@ * certificate material and not a file path. Otherwise, returns the | ||
*/ | ||
function normalizeCertFile(root, file) { | ||
function normalizePEMContent(root, file) { | ||
if (Array.isArray(file)) return file.map(function map(item) { | ||
return normalizeCertFile(root, item) | ||
return normalizePEMContent(root, item) | ||
}); | ||
@@ -200,0 +236,0 @@ |
{ | ||
"name": "create-servers", | ||
"version": "2.4.0", | ||
"version": "2.5.0", | ||
"description": "Create an http AND/OR an https server and call the same request handler.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
116
README.md
@@ -1,7 +0,103 @@ | ||
create-servers | ||
============== | ||
# create-servers | ||
Create an http AND/OR an https server and call the same request handler. | ||
*NOTE on Security* | ||
## Usage | ||
The `create-servers` module exports a function that takes a config object and | ||
a node-style callback. The config object must have at minimum an `http` or | ||
`https` property (or both). The following config properties are supported: | ||
| Property | Description | | ||
|---------------------------|-------------| | ||
| `handler` | Request handler to be used for any server, unless overridden specifically with `http.handler` or `https.handler`. | | ||
| `timeout` | Socket timeout in milliseconds for any server, unless overridden with `http.timeout` or `https.timeout`. Defaults to the node default of 2 minutes. | | ||
| `http` | Optional. If present, an HTTP server is started. This can be an object or a number. If it's a number, it's used as the TCP port for an HTTP server. | | ||
| `http.port` | TCP port for the HTTP server. Defaults to `80`. | | ||
| `http.host` | The address the HTTP server is bound to. Defaults to `::` or `0.0.0.0`. | | ||
| `http.timeout` | Socket timeout in milliseconds for the server. If unspecified, the top-level `timeout` configuration is used. | | ||
| `http.handler` | Handler for HTTP requests. If you want to share a handler with all servers, use a top-level `handler` config property instead. | | ||
| `https` | Optional object. If present, an HTTPS server is started. | | ||
| `https.port` | TCP port for the HTTPS server. Defaults to `443`. | | ||
| `https.host` | The address the HTTPS server is bound to. Defaults to `::` or `0.0.0.0`. | | ||
| `https.timeout` | Socket timeout in milliseconds for the server. If unspecified, the top-level `timeout` configuration is used. | | ||
| `https.ciphers` | Defaults to a [default cipher suite](#note-on-security). To customize, either supply a colon-separated string or array of strings for the ciphers you want the server to support. | | ||
| `https.honorCipherOrder` | If true, prefer the server's specified cipher order instead of the client's. Defaults to `false`. | | ||
| `https.root` | Root directory for certificate/key files. See [Certificate normalization](#certificate-normalization) for more details. | | ||
| `https.key` | PEM/file path for the server's private key. See [Certificate normalization](#certificate-normalization) for more details. | | ||
| `https.cert` | PEM/file path(s) for the server's certificate. See [Certificate normalization](#certificate-normalization) for more details. | | ||
| `https.ca` | Cert or array of certs specifying trusted authorities for peer certificates. Only required if your server accepts client certificate connections signed by authorities that are not trusted by default. See [Certificate normalization](#certificate-normalization) for more details. | | ||
| `https.handler` | Handler for HTTPS requests. If you want to share a handler with all servers, use a top-level `handler` config property instead. | | ||
| `https.*` | Any other properties supported by [https.createServer](https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_createserver_options_requestlistener) can be added to the https object, except `secureProtocol` and `secureOptions` which are set to recommended values. | | ||
If successful, the `create-servers` callback is passed an object with the | ||
following properties: | ||
| Property | Description | | ||
|----------|-------------| | ||
| `http` | The HTTP server that was created, if any | | ||
| `https` | The HTTPS server that was created, if any | | ||
### Certificate normalization | ||
`create-servers` provides some conveniences for `https.ca`, `https.key`, and | ||
`https.cert` config properties. You may use PEM data directly (inside a `Buffer` | ||
or string) or a file name. When using a file name, you must also set an | ||
`https.root` config property if using relative paths to cert/key files. | ||
`https.ca`, `https.cert`, and `https.key` also support specifying an Array. | ||
Given an array for `cert`, you must have a matching array for `key` so each cert | ||
can be matched with its private key. | ||
```js | ||
const createServers = require('create-servers'); | ||
createServers({ | ||
https: { | ||
root: '/cert/path', | ||
cert: ['cert1.crt', 'cert2.crt'], | ||
key: ['cert1.key', 'cert2.key'] | ||
} | ||
}, err => { | ||
// ... | ||
}) | ||
``` | ||
If you have a cert that is signed by an intermediate CA, your server will need | ||
to append the untrusted parts of the CA chain with your cert. To make this more | ||
convenient, `create-servers` lets you use an array to automatically create a | ||
chain. | ||
```js | ||
const createServers = require('create-servers'); | ||
createServers({ | ||
https: { | ||
root: '/cert/path', | ||
cert: ['cert.crt', 'intermediate.crt'], | ||
key: 'cert.key' | ||
} | ||
}, err => { | ||
// ... | ||
}) | ||
``` | ||
If you are specifying multiple certs _and_ you want to create chains for each, | ||
use an array of arrays. | ||
```js | ||
const createServers = require('create-servers'); | ||
createServers({ | ||
https: { | ||
root: '/cert/path', | ||
cert: [['cert1.crt', 'intermediate.crt'], 'cert2.crt'], | ||
key: ['cert1.key', 'cert2.key'] | ||
} | ||
}, err => { | ||
// ... | ||
}) | ||
``` | ||
## NOTE on Security | ||
Inspired by [`iojs`][iojs] and a well written [article][article], we have defaulted | ||
@@ -12,3 +108,5 @@ our [ciphers][ciphers] to support "perfect-forward-security" as well as removing insecure | ||
**http** | ||
## Examples | ||
### http | ||
``` js | ||
@@ -34,3 +132,3 @@ var createServers = require('create-servers'); | ||
**https** | ||
### https | ||
``` js | ||
@@ -60,3 +158,3 @@ var servers = createServers( | ||
**http && https** | ||
### http && https | ||
``` js | ||
@@ -92,3 +190,3 @@ var servers = createServers( | ||
**http && https (different handlers)** | ||
### http && https (different handlers) | ||
``` js | ||
@@ -129,4 +227,4 @@ var servers = createServers( | ||
### Author: [Charlie Robbins](https://github.com/indexzero) | ||
### License: MIT | ||
## Author: [Charlie Robbins](https://github.com/indexzero) | ||
## License: MIT | ||
@@ -133,0 +231,0 @@ [article]: https://certsimple.com/blog/a-plus-node-js-ssl |
@@ -277,2 +277,29 @@ /* | ||
test('supports creating certificate chains', function (t) { | ||
t.plan(2); | ||
var root = path.join(__dirname, 'fixtures'); | ||
var agent3Cert = fs.readFileSync(path.resolve(root, 'agent3-cert.pem')); | ||
var intermediate = fs.readFileSync(path.resolve(root, 'intermediate-cert.pem')); | ||
var spy = sinon.spy(https, 'createServer'); | ||
createServers({ | ||
log: console.log, | ||
https: { | ||
port: 3456, | ||
root: root, | ||
cert: ['agent3-cert.pem', 'intermediate-cert.pem'], | ||
key: 'agent3-key.pem' | ||
}, | ||
handler: fend | ||
}, function (err, servers) { | ||
t.error(err); | ||
const expectedBundle = [agent3Cert, intermediate].join('\n'); | ||
const cert = spy.lastCall.args[0].cert; | ||
t.equals(cert, expectedBundle, 'should create a cert chain'); | ||
servers.https.close(); | ||
spy.restore(); | ||
}); | ||
}); | ||
test('supports requestCert https option', function (t) { | ||
@@ -279,0 +306,0 @@ t.plan(2); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
32735
15
511
229