https://github.com/http-party/create-servers
Create an http AND/OR an https server and call the same request handler.
https://github.com/http-party/create-servers
Last synced: over 1 year ago
JSON representation
Create an http AND/OR an https server and call the same request handler.
- Host: GitHub
- URL: https://github.com/http-party/create-servers
- Owner: http-party
- License: mit
- Created: 2014-01-20T02:58:28.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2024-09-16T05:31:17.000Z (almost 2 years ago)
- Last Synced: 2024-09-16T06:48:51.933Z (almost 2 years ago)
- Language: JavaScript
- Size: 135 KB
- Stars: 45
- Watchers: 8
- Forks: 17
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# create-servers
Create an http AND/OR an https server and call the same request handler.
## 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. |
| `keepAliveTimeout` | Milliseconds of activity before sockets are destroyed. Defaults to the node default value (currently 5 seconds). |
| `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. You may also use an Array to start multiple servers. |
| `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.keepAliveTimeout` | Overrides the top-level keepAliveTimeout setting if specified. |
| `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. You may start multiple HTTPS servers by passing an array of objects |
| `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.keepAliveTimeout` | Overrides the top-level keepAliveTimeout setting if specified. |
| `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.sni` | See [SNI Support](#sni-support). |
| `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. |
| `http2` | Optional object. If present, an HTTP/2 server is started. You may start multiple HTTP/2 servers by passing an array of objects |
| `http2.allowHTTP1` | Enable [ALPN negotiation] allowing support for both HTTPS and HTTP/2 on the same socket. |
| `http2.*` | The same `https` security options are allowed, as well as any other properties supported by [http2.createSecureServer](https://nodejs.org/dist/latest-v8.x/docs/api/http2.html#http2_http2_createsecureserver_options_onrequesthandler). |
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. If creating multiple servers, this will be an Array. |
| `https` | The HTTPS server that was created, if any. If creating multiple servers, this will be an Array. |
### 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 => {
// ...
})
```
### SNI Support
[Server Name Indication](https://en.wikipedia.org/wiki/Server_Name_Indication),
or SNI, lets HTTPS clients announce which hostname they wish to connect to
before the server sends its certificate, enabling the use of the same server for
multiple hosts. Although `SNICallback` can be used to support this, you lose the
convenient certificate normalization provided by `create-servers`. The `sni`
config option provides an easier way.
The `sni` option is an object with each key being a supported hostname and each
value being a subset of the HTTPS settings listed above. HTTPS settings defined
at the top level are used as defaults for the hostname-specific settings.
```js
const createServers = require('create-servers');
createServers(
{
https: {
port: 443,
sni: {
'example1.com': {
key: '/certs/private/example1.com.key',
cert: '/certs/public/example1.com.crt'
},
'example2.com': {
key: '/certs/private/example2.com.key',
cert: '/certs/public/example2.com.crt'
}
}
},
handler: function (req, res) {
res.end('Hello');
}
},
function (errs) {
if (errs) {
return console.log(errs.https);
}
console.log('Listening on 443');
}
);
```
Use `*` in the hostname for wildcard certs. Example: `*.example.com`. The
following settings are supported in the host-specific configuration:
* key
* cert
* ca
* ciphers
* honorCipherOrder
* Anything else supported by [`tls.createSecureContext`](https://nodejs.org/dist/latest-v8.x/docs/api/tls.html#tls_tls_createsecurecontext_options)
## NOTE on Security
Inspired by [`iojs`][iojs] and a well written [article][article], we have defaulted
our [ciphers][ciphers] to support "perfect-forward-security" as well as removing insecure
cipher suites from being a possible choice. With this in mind,
be aware that we will no longer support ie6 on windows XP by default.
## Examples
### http
```js
var createServers = require('create-servers');
var servers = createServers(
{
http: 80,
handler: function (req, res) {
res.end('http only');
}
},
function (errs) {
if (errs) {
return console.log(errs.http);
}
console.log('Listening on 80');
}
);
```
### https
```js
var servers = createServers(
{
https: {
port: 443,
root: '/path/to/ssl/files',
key: 'your-key.pem',
cert: 'your-cert.pem',
ca: 'your-ca.pem' // Can be an Array of CAs
},
handler: function (req, res) {
res.end('https only');
}
},
function (errs) {
if (errs) {
return console.log(errs.https);
}
console.log('Listening on 443');
}
);
```
### http && https
```js
var servers = createServers(
{
http: 80,
https: {
port: 443,
root: '/path/to/ssl/files',
key: 'your-key.pem',
cert: 'your-cert.pem',
ca: 'your-ca.pem' // Can be an Array of CAs
},
handler: function (req, res) {
res.end('http AND https');
}
},
function (errs, servers) {
if (errs) {
return Object.keys(errs).forEach(function (key) {
console.log('Error ' + key + ': ' + errs[key]);
if (servers[key]) {
servers[key].close();
}
});
}
console.log('Listening on 80 and 443');
}
);
```
### http && https (different handlers)
```js
var servers = createServers(
{
http: {
port: 80,
handler: function (req, res) {
res.end('http');
}
},
https: {
port: 443,
root: '/path/to/ssl/files',
key: 'your-key.pem',
cert: 'your-cert.pem',
ca: 'your-ca.pem', // Can be an Array of CAs
handler: function (req, res) {
res.end('https');
}
}
},
function (errs, servers) {
if (errs) {
return Object.keys(errs).forEach(function (key) {
console.log('Error ' + key + ': ' + errs[key]);
if (servers[key]) {
servers[key].close();
}
});
}
console.log('Listening on 80 and 443');
}
);
```
## Author: [Charlie Robbins](https://github.com/indexzero)
## License: MIT
[article]: https://certsimple.com/blog/a-plus-node-js-ssl
[iojs]: https://github.com/iojs/io.js
[ciphers]: https://iojs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
[ALPN negotiation]: https://nodejs.org/api/http2.html#http2_alpn_negotiation