Skip to content

https SNICallback hangs if optional callback isn't provided on ARM6 (and possibly others) #869

@coolaj86

Description

@coolaj86

Originally I found this bug #867 on ARM6 and while testing further on OS X I found a workaround.

I took my band-aided test case back to my Rapsberry Pi to test and found that the https request still just hangs forever.

I commented out the SNICallback entirely and found that the certificates I'm loading are working by themselves, but the SNICallback is broken.

'use strict';

var https           = require('https');
var fs              = require('fs');
var path            = require('path');
var crypto          = require('crypto');
var connect         = require('connect');

module.exports.create = function (_securePort, _insecurePort) {
    // connect / express app
  var app             = connect();

    // SSL Server
  var secureContexts  = {};
  var dummyCerts;
  var secureOpts;
  var secureServer;
  var securePort      = _securePort || 443;

    // force SSL upgrade server
  var insecureServer;
  var insecurePort    = _insecurePort || 80;

  function loadDummyCerts() {
    var certsPath = path.join(__dirname, 'certs');
    var certs = {
      key:          fs.readFileSync(path.join(certsPath, 'server', 'dummy-server.key.pem'))
    , cert:         fs.readFileSync(path.join(certsPath, 'server', 'dummy-server.crt.pem'))
    , ca:           fs.readdirSync(path.join(certsPath, 'ca')).filter(function (node) {
                       return /crt\.pem$/.test(node);
                     }).map(function (node) {
                       console.log('[Add CA]', node);
                      return fs.readFileSync(path.join(certsPath, 'ca', node));
                    })
    };
    secureContexts.dummy = crypto.createCredentials(certs).context;
    dummyCerts = certs;
  }
  loadDummyCerts();

  app.use(function (req, res, next) {
    console.log('[log] request for ' + req.headers.host + req.url);
    next();
  });

  function runServer() {
    //provide a SNICallback when you create the options for the https server
    secureOpts = {
                    // fallback / default dummy certs
      key:          dummyCerts.key
    , cert:         dummyCerts.cert
    , ca:           dummyCerts.ca
      //SNICallback is passed the domain name, see NodeJS docs on TLS
  /*
    , SNICallback:  function (domainname) {
                      console.log('[log] SNI:', domainname);
                      console.log('[log] SNI:', secureContexts[domainname]);
                      var secureContext = secureContexts[domainname] || secureContexts.dummy;
                      console.log('[log]', secureContext);
                      return secureContext;
                    }
  */
    };

    secureServer = https.createServer(secureOpts);
    secureServer.on('request', function (req, res) {
      console.log('[log] request');
      app(req, res);
    });
    secureServer.listen(securePort, function () {
      console.log("Listening on https://localhost:" + secureServer.address().port);
    });
  }

  runServer();
}
module.exports.create(65443, 65080);

To experience the hang, simply uncomment the SNICallback block.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions