From d43e4f44cd9393d048b883c282aee49b7b68be85 Mon Sep 17 00:00:00 2001 From: Nadav Ivgi Date: Mon, 6 Aug 2018 04:36:57 +0300 Subject: [PATCH] Work-in-progress HTTP2 support via "spdy" module This works, but it looks like the "spdy" module (which, despite its name, also supports http2) is not compatible with newer nodejs versions and should be avoided: https://github.com/spdy-http2/node-spdy/issues/333 https://github.com/webpack/webpack-dev-server/pull/1451 Should eventually use nodejs's native http2 module, but it is currently incompatible with express: https://github.com/expressjs/express/issues/3388 Committing the changes to a branch and setting aside for now. --- npm-shrinkwrap.json | 84 +++++++++++++++++++++++++++++++++++++++++--- package.json | 1 + src/cli.js | 1 + src/transport/tls.js | 10 ++++-- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index bbe571e9..0cae9b25 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1256,6 +1256,11 @@ "repeating": "2.0.1" } }, + "detect-node": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", + "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=" + }, "dijkstrajs": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", @@ -2315,6 +2320,11 @@ "rsa-compat": "1.5.1" } }, + "handle-thing": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", + "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=" + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -2380,6 +2390,17 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "requires": { + "inherits": "2.0.3", + "obuf": "1.1.2", + "readable-stream": "2.3.3", + "wbuf": "1.7.3" + } + }, "hpkp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", @@ -2415,6 +2436,11 @@ "readable-stream": "2.3.3" } }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -2912,6 +2938,11 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2991,7 +3022,8 @@ "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "optional": true }, "node.extend": { "version": "1.1.6", @@ -3060,6 +3092,11 @@ "is-extendable": "0.1.1" } }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -3242,8 +3279,7 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "optional": true + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "proxy-addr": { "version": "2.0.3", @@ -3387,7 +3423,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "optional": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -3559,6 +3594,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, "selfsigned": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.2.tgz", @@ -3695,6 +3735,33 @@ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" }, + "spdy": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", + "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "requires": { + "debug": "2.6.9", + "handle-thing": "1.2.5", + "http-deceiver": "1.2.7", + "safe-buffer": "5.1.1", + "select-hose": "2.0.0", + "spdy-transport": "2.1.0" + } + }, + "spdy-transport": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", + "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", + "requires": { + "debug": "2.6.9", + "detect-node": "2.0.3", + "hpack.js": "2.1.6", + "obuf": "1.1.2", + "readable-stream": "2.3.3", + "safe-buffer": "5.1.1", + "wbuf": "1.7.3" + } + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -3738,7 +3805,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "optional": true, "requires": { "safe-buffer": "5.1.1" } @@ -3911,6 +3977,14 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "1.0.1" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index e53aaaca..9e0d0f19 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "morgan": "^1.9.0", "nanoid": "^1.1.0", "qrcode": "^1.2.2", + "spdy": "^3.4.7", "superagent": "^3.8.3" }, "devDependencies": { diff --git a/src/cli.js b/src/cli.js index 46414254..b50e9392 100755 --- a/src/cli.js +++ b/src/cli.js @@ -24,6 +24,7 @@ const args = require('meow')(` -q, --print-qr print QR code with the server URL [default: false] -Q, --pairing-qr print QR code with embedded access key [default: false] --no-webui run API server without serving client assets [default: false] + --no-http2 disable HTTP/2.0 support [default: enabled when TLS is] -C, --config-path path to config file [default: ~/.spark-wallet/config] -V, --verbose display debugging information [default: false] diff --git a/src/transport/tls.js b/src/transport/tls.js index d80d9ce0..ff3e9655 100644 --- a/src/transport/tls.js +++ b/src/transport/tls.js @@ -1,6 +1,5 @@ import forge from 'node-forge' import path from 'path' -import https from 'https' import http from 'http' import isIp from 'is-ip' import fs from 'fs' @@ -8,9 +7,16 @@ import mkdirp from 'mkdirp' const defaultDir = path.join(require('os').homedir(), '.spark-wallet', 'tls') +// the "spdy" module in fact supports http/2.0 despite its confusing name. +// we're using it (with spdy support turned off) because the native "http2" module +// is not currently compatible with Express. https://github.com/expressjs/express/issues/3388 + +const https = process.env.NO_HTTP2 ? require('https') : require('spdy') + , srvOpt = process.env.NO_HTTP2 ? {} : { protocols: [ 'h2', 'http/1.1', 'http/1.0' ] } + module.exports = (app, name=app.settings.host, dir=defaultDir, leEmail) => { const tlsOpt = leEmail ? letsencrypt(name, dir, leEmail) : selfsigned(name, dir) - , server = https.createServer(tlsOpt, app) + , server = https.createServer( { ...tlsOpt, ...srvOpt }, app) tlsOpt.cert && app.get('/cert.pem', (req, res) => res.type('pem').send(tlsOpt.cert)) // @TODO allow downloading letsencrypt's cert