Commit 37a98745 authored by Aral Balkan's avatar Aral Balkan

Express doesn’t support HTTP2 yet; disable command-line functionality

parent 77ba8472
......@@ -12,15 +12,20 @@ Nothing yet.
### Added
- HTTP2 support
- HTTP2 support (API-only)
### Changed
- Command-line arguments: specify port using `--port N`
- Update `serve` method signature: `serve (pathToServe = '.', callback = null, port = 443)`
### Fixed
- Start using [semver](https://semver.org/) properly (most of the previous releases should have been minor version bumps.) This is a major bump as there is a backwards-incompatible API change to the serve() method.
## [1.0.7] - 2019-02-28
### Fixes
### Fixed
- Fix regression with automatic privileged port binding on Linux.
......
......@@ -2,11 +2,6 @@
An HTTPS server that uses [nodecert](https://source.ind.ie/hypha/tools/nodecert).
## Design goals
* ✔ Command-line app
* ✔ Easy integration with Express, etc.
* To-do: Seamless switch to using ACME/Let’s Encrypt in production
## Installation
......@@ -14,36 +9,37 @@ An HTTPS server that uses [nodecert](https://source.ind.ie/hypha/tools/nodecert)
npm i -g @ind.ie/https-server
```
## Usage
### Commandline
```sh
https-server [folder-to-serve] [port]
https-server [folder-to-serve] [--port N]
```
Both arguments are optional. Currently, if you want to specify the port manually, you must also specify the folder-to-serve.
* `[folder-to-serve]` defaults to `.` (the current directory)
* `[port]` defaults to 443 (automatically privileges Node.js to bind to it on Linux. This is not an issue on macOS & Windows.)
All arguments are optional. By default, a secure HTTP1 server will be created to serve the current folder over port 443.
If you do not already have TLS certificates, they will be created for you automatically using [nodecert](https://source.ind.ie/hypha/tools/nodecert).
All dependencies will be installed automatically for you if they do not exist if you have apt, pacman, or yum (untested) on Linux or if you have [Homebrew](https://brew.sh/) or [MacPorts](https://www.macports.org/) (untested) on macOS.
### API
http-server provides a `createServer` method that behaves like the built-in _https_ module’s createServer function so anywhere you use `https.createServer`, you can simply replace it with `httpsServer.createServer`.
__https-server__ provides a `createServer` method that behaves like the built-in _https_ module’s `createServer` function so anywhere you use `https.createServer`, you can simply replace it with `httpsServer.createServer`. Similarly, there is also a `createSecureServer` method that mirrors the function in the _http2_ module.
### createServer([options], [requestListener])
#### createServer([options], [requestListener])
* options: [(Object)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) Accepts options from [tls.createServer()](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener), [tls.createSecureContext()](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) and [http.createServer()](https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener). Populates the `cert` and `key` properties from the automatically-created [nodecert](https://source.ind.ie/hypha/tools/nodecert/) certificates and will overwrite them if they exist in the options object you pass in.
- __options__ _(object)___:__ see [https.createServer](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). Populates the `cert` and `key` properties from the automatically-created [nodecert](https://source.ind.ie/hypha/tools/nodecert/) certificates and will overwrite them if they exist in the options object you pass in.
* requestListener: [(Function)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) A listener to be added to the 'request' event.
- __requestListener__ _(function)___:__ see [https.createServer](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener).
* Returns: [https.Server](https://nodejs.org/api/https.html#https_class_https_server) instance, configured with locally-trusted certificates.
- ___Returns:___ [https.Server](https://nodejs.org/api/https.html#https_class_https_server) instance, configured with locally-trusted certificates.
#### Example
##### Example
```js
const httpsServer = require('https-server')
......@@ -58,13 +54,40 @@ const server = httpsServer.createServer(options, app).listen(443, () => {
})
```
### serve([pathToServe], [port])
* pathToServe: [(string)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string) path to serve using [Express](http://expressjs.com/).static.
#### createSecureServer([options], [requestListener])
- __options__ _(object)___:__ see [http2.createSecureServer](https://nodejs.org/api/http2.html#http2_http2_createsecureserver_options_onrequesthandler). Populates the `cert` and `key` properties from the automatically-created [nodecert](https://source.ind.ie/hypha/tools/nodecert/) certificates and will overwrite them if they exist in the options object you pass in.
- __requestListener__ _(function)___:__ see [http2.createSecureServer](https://nodejs.org/api/http2.html#http2_http2_createsecureserver_options_onrequesthandler)
- ___Returns:___ [Http2SecureServer](https://nodejs.org/api/http2.html#http2_class_http2secureserver) instance, configured with locally-trusted certificates.
##### Example
```js
const httpsServer = require('https-server')
const express = require('express')
const options = {} // (optional) customise your server
const server = httpsServer.createSecureServer(options, app).listen(443, () => {
console.log(` 🎉 Serving on https://localhost (HTTP2)\n`)
})
```
#### serve([pathToServe], [callback], [port])
* port: [(number)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) the port to serve on. Defaults to 443. (On Linux, privileges to bind to the port are automatically obtained for you.)
- __pathToServe__ _(string)___:__ the directory to serve using [Express](http://expressjs.com/).static.
#### Example
- __callback__ _(function)___:__ a function to be called when the server is ready. If you do not specify a callback, you can specify the port as the second argument.
- __port__ _(number)___:__ the port to serve on. Defaults to 443. (On Linux, privileges to bind to the port are automatically obtained for you.)
- ___Returns:___ [https.Server](https://nodejs.org/api/https.html#https_class_https_server) instance, configured with locally-trusted certificates.
##### Example
```js
const httpsServer = require('https-server')
......@@ -77,12 +100,19 @@ const server = httpsServer.serve()
I can use your help to test https-server on other the following platforms:
* Windows 64-bit (should work without requiring any dependencies)
* Linux with yum
* macOS with MacPorts
- Windows 64-bit (should work without requiring any dependencies)
- Linux with yum
- macOS with MacPorts
Please [let me know how/if it works](https://github.com/indie-mirror/https-server/issues). Thank you!
## TODO
- Command-line app. ✔
- Easy integration with Express, etc. ✔
- HTTP2 support (API only). ✔
- To-do: Seamless switch to using ACME/Let’s Encrypt in production.
## Thanks
* [thagoat](https://github.com/thagoat) for confirming that [installation works on Arch Linux with Pacman](https://github.com/indie-mirror/https-server/issues/1).
......@@ -9,17 +9,21 @@ if (arguments._.length > 1 || arguments.help === true) {
const usageFolderToServe = clr('folder-to-serve', 'green')
const usagePortOption = `${clr('--port', 'yellow')} ${clr('N', 'cyan')}`
const usageHttp2Option = clr('--http2', 'yellow')
// For when Express static gets HTTP2 support:
// ===================================================================================
// const usageHttp2Option = clr('--http2', 'yellow')
// • ${usageHttp2Option}\t\t${clr('flag', 'italic')}\tRequests an HTTP2 server (optional; defaults to HTTP1).
// ===================================================================================
const usage = `
${clr('Usage:', 'underline')}
${clr('https-server', 'bold')} [${usageFolderToServe}] [${usagePortOption}] [${usageHttp2Option}]
${clr('https-server', 'bold')} [${usageFolderToServe}] [${usagePortOption}]
${usageFolderToServe}\t${clr('string', 'italic')}\tPath to the folder to serve (optional; defaults to current folder).
${usagePortOption}\t\t${clr('number', 'italic')}\tThe port to start the server on (optional; defaults to 443).
${usageHttp2Option}\t\t${clr('flag', 'italic')}\tRequests an HTTP2 server (optional; defaults to HTTP1).
`.replace(/\n$/, '').replace(/^\n/, '')
${usageFolderToServe}\t${clr('string', 'italic')}\tPath to the folder to serve (optional; defaults to current folder).
${usagePortOption}\t\t${clr('number', 'italic')}\tThe port to start the server on (optional; defaults to 443).
`.replace(/\n$/, '').replace(/^\n/, '')
console.log(usage)
process.exit()
......@@ -43,10 +47,12 @@ if (!fs.existsSync(pathToServe)) {
process.exit(1)
}
const http2 = (arguments.http2 === true)
// For when Express static gets HTTP2 support:
// const http2 = (arguments.http2 === true)
console.log(pathToServe)
// Start the server.
httpsServer.serve(pathToServe, {port, http2})
httpsServer.serve(pathToServe, port)
// Helpers.
......
......@@ -53,17 +53,28 @@ class HttpsServer {
// Starts a static server serving the contents of the passed path at the passed port
// and returns the server.
serve(pathToServe = '.', callback = null, options = {}) {
serve(pathToServe = '.', callback = null, port = 443) {
// Can be called as serve(pathToServe, callback) also.
if (typeof callback === 'object') {
options = callback
// Can also be called as serve(pathToServe, port)
if (typeof callback === 'number') {
port = callback
callback = null
}
const port = options.port || 443
const isHTTP2 = options.http2 || false
const serverCreationMethod = isHTTP2 ? this.createSecureServer : this.createServer
// Express does not support HTTP2 yet. Disabling this until support is added.
// Once it’s ready we will replace the port argument with and options object.
// ===================================================================================
// Can be called as serve(pathToServe, callback) also.
// if (typeof callback === 'object') {
// options = callback
// callback = null
// }
// const port = options.port || 443
// const isHTTP2 = options.http2 || false
// const serverCreationMethod = isHTTP2 ? this.createSecureServer : this.createServer
// ===================================================================================
const serverCreationMethod = this.createServer
this.ensureWeCanBindToPort(port, pathToServe)
......@@ -75,11 +86,11 @@ class HttpsServer {
if (serverPort !== 443) {
portSuffix = `:${serverPort}`
}
let isHTTP2Note = ''
if (isHTTP2) {
isHTTP2Note = ' (HTTP2)'
}
console.log(` 🎉 Serving ${pathToServe} on https://localhost${portSuffix}${isHTTP2Note}\n`)
// let isHTTP2Note = ''
// if (isHTTP2) {
// isHTTP2Note = ' (HTTP2)'
// }
console.log(` 🎉 Serving ${pathToServe} on https://localhost${portSuffix}\n`) //${isHTTP2Note}\n`)
}
}
......
......@@ -39,7 +39,7 @@ test('create https server', t => {
test('create http2 server', t => {
t.plan(2)
const server = httpsServer.createSecureServer({isHTTP2: true})
const server = httpsServer.createSecureServer()
// http2 does not export the Http2SecureServer class so we cannot use instanceof to test here.
t.equal(server.constructor.name, 'Http2SecureServer', 'is Http2SecureServer')
......@@ -74,26 +74,27 @@ test('static serve https', t => {
})
test('static serve HTTP2', t => {
t.plan(3)
const server = httpsServer.serve('test/site', async () => {
// For when Express/.static gets HTTPS support.
// test('static serve HTTP2', t => {
// t.plan(3)
// const server = httpsServer.serve('test/site', async () => {
t.equal(server.constructor.name, 'Http2SecureServer', 'is Http2SecureServer')
// t.equal(server.constructor.name, 'Http2SecureServer', 'is Http2SecureServer')
let response
try {
response = await secureGet('https://localhost/index.html')
} catch (error) {
console.log(error)
process.exit(1)
}
// let response
// try {
// response = await secureGet('https://localhost/index.html')
// } catch (error) {
// console.log(error)
// process.exit(1)
// }
t.equal(response.statusCode, 200, 'request succeeds')
t.equal(response.body, indexHTML, 'index loads')
t.end()
// t.equal(response.statusCode, 200, 'request succeeds')
// t.equal(response.body, indexHTML, 'index loads')
// t.end()
server.close()
}, {
isHTTP2: true
})
})
// server.close()
// }, {
// isHTTP2: true
// })
// })
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment