I am attempting to implement HTTP/2 on a node server using molnarg's node-http2 module. My original server.js works fine and when I implemented the HTTP/2 module I get a
ERR_CONNECTION_REFUSED
from the browser (using Chrome on a ChromeBook).
List of changes to implement HTTP/2:
hostPort
var in the config.json to 443 (tried w/80, 8000)Add to server.js:
var certs = {key: fs.readFileSync('../../key.pem'),cert: fs.readFileSync('../../cert.pem')};
Edit server.js
require('http').createServer(function (request, response) {...}
to
require('http2').createServer(certs, function (request, response) {...}
What am I missing or have wrong (I get no errors in the log)?
Below is a copy of the server.js
var environment = '../env/' + process.env.NODE_ENV;
// Process User config
var fS = require('fs')
, jsonFile = fS.readFileSync(environment + '/config.json'), jsonString, hostIp, hostPort, cacheExp, cps;
try {
jsonString = JSON.parse(jsonFile);
var SERV_HOST = jsonString['hostIp']
, SERV_PORT = jsonString['hostPort']
, CACHE_EXP = jsonString['cacheExp']
, CPS = jsonString['cps']
, xPowerBy = ''
, xFrameOptions = ''
, xXSSProtection = ''
, xContentTypeOption = ''
, cacheControl = '';
} catch (err) {
console.log('There is an error parsing the json file : ' + err);
}
// Load required modules
var web = require('node-static')
, watch = require('staticsmith-watch')
, fs = require("fs");
var certs = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
// Load security setings via config.json
var security =
[{
// Just some security stuff here
}];
if (process.env.NODE_ENV == 'production') {
var options = { host: SERV_HOST
, port: SERV_PORT
, cache: CACHE_EXP
};
var public_dir = new web.Server(environment, options);
// Serve it up!
require('http2').createServer(certs, function (request, response) {
// OLD
// require('http').createServer(function (request, response) {
// Add Content Security Rules
for(var i = 0; i < security.length; i++){
response.setHeader(security[i].name, security[i].option);
}
request.addListener('end', function () {
public_dir.serve(request, response, function (err, result) {
if (err) { // There was an error serving the file
console.error("Error serving " + request.url + " - " + err.message);
// Respond to the client
response.writeHead(err.status, err.headers);
response.end();
}
});
}).resume();
}).listen(options.port, options.host);
console.log("serving at http://" + options.host + ":" + options.port);
console.log("On Node v" + process.versions.node);
watch({
pattern: '**/*',
livereload: true,
});
}
Implementation of node-spdy was used in lieu of node-http2 because this module you can create HTTP2 / SPDY servers in node.js with natural http module interface and fallbacks to regular https (for browsers that don't support neither HTTP2, nor SPDY yet).
The above server.js now implementing the new module:
var environment = '../env/' + process.env.NODE_ENV;
// Process User config
var fS = require('fs')
, jsonFile = fS.readFileSync(environment + '/config.json'), jsonString, hostIp, hostPort, cacheExp, cps;
try {
jsonString = JSON.parse(jsonFile);
var SERV_HOST = jsonString['hostIp']
, SERV_PORT = jsonString['hostPort']
, CACHE_EXP = jsonString['cacheExp']
, CPS = jsonString['cps']
, xPowerBy = ':P'
, xFrameOptions = ''
, xXSSProtection = ''
, xContentTypeOption = ''
, cacheControl = '';
} catch (err) {
console.log('There is an error parsing the json file : ' + err);
}
// Load required modules
var fs = require('fs')
, web = require('node-static');
var public_dir = new web.Server(environment + '/_public');
var options = {
key: fs.readFileSync(environment + '/keys/key.pem')
, cert: fs.readFileSync(environment + '/keys/cert.pem')
// SPDY-specific options
, spdy: {
protocols: [ 'h2','spdy/3.1', 'spdy/3', 'spdy/2','http/1.1', 'http/1.0' ],
plain: false,
connection: {
windowSize: 1024 * 1024, // Server's window size
// **optional** if true - server will send 3.1 frames on 3.0 *plain* spdy
autoSpdy31: false
}
}
, host: SERV_HOST
, port: SERV_PORT
, cache: CACHE_EXP
};
// Load security setings via config.json
var security = [
{ name: 'X-Powered-By',
option: xPowerBy }
, { name: 'x-frame-options',
option: xFrameOptions }
, { name: 'X-XSS-Protection',
option: xXSSProtection }
, { name: 'X-Content-Type-Options',
option: xContentTypeOption }
, { name: 'Cache-Control',
option: CACHE_EXP }
, { name: 'Content-Security-Policy',
option: CPS }
, { name: 'server',
option: 'Who knows' }
];
if (process.env.NODE_ENV == 'production') {
require("spdy").createServer(options, function(req, res) {
// Add Content Security Rules
for(var i = 0; i < security.length; i++){
res.setHeader(security[i].name, security[i].option);
}
public_dir.serve(req, res, function (err, result) {
if (err) { // There was an error serving the file
console.error("Error serving " + req.url + " - " + err.message);
// Respond to the client
res.writeHead(err.status, err.headers);
res.end();
}
});
}).listen(options.port, options.host);
console.log("serving at https://" + options.host + ":" + options.port);
console.log("On Node v" + process.versions.node);
}
This worked out of the box.