Skip to content

engine.io-client 3.5.x is broken on node.js 15 due to changes in the way null SSL options are treated #654

@calzoneman

Description

@calzoneman

Describe the bug
Attempting to use [email protected] (depends on [email protected]) with node.js 15.x fails to connect to SSL servers with the following error:

engine.io-client:socket socket error {"type":"TransportError","description":{"code":"ERR_CRYPTO_OPERATION_FAILED"}} 

The internal error that leads to the above is:

Error: Unable to load PFX certificate
    at Object.createSecureContext (node:_tls_common:333:17)
    at Object.connect (node:_tls_wrap:1601:48)
    at Agent.createConnection (node:https:130:22)
    at Agent.createSocket (node:_http_agent:323:26)
    at Agent.addRequest (node:_http_agent:274:10)
    at new ClientRequest (node:_http_client:314:16)
    at request (node:https:326:10)
    at XMLHttpRequest.send (/home/calvin/tmp/n15err/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js:495:17)
    at Request.create (/home/calvin/tmp/n15err/node_modules/engine.io-client/lib/transports/polling-xhr.js:268:9)
    at new Request (/home/calvin/tmp/n15err/node_modules/engine.io-client/lib/transports/polling-xhr.js:170:8)

I've narrowed this down to the fact that engine.io-client assigns this.pfx = opts.pfx || null here -- it seems as if node.js 15.x treats null differently from previous versions of node. Changing this to undefined mitigates the problem.

It looks like the option handling was changed to an Object.assign call in 4.x -- would you accept a pull request to backport that to 3.5.x to avoid this kind of issue?

To Reproduce

Please fill the following code example:

Engine.IO server version: 3.5.0

Server

const fs = require('fs');
const https = require('https');
const engine = require('engine.io');

let httpsServer = https.createServer({
    // You will need to provide your own cert / set the passphrase accordingly
    key: fs.readFileSync('key.pem'),
    cert: fs.readFileSync('cert.pem'),
    passphrase: '1234'
});
httpsServer.listen(8443);

let server = engine.attach(httpsServer);
server.on('connection', socket => {
    console.log('Got a connection!');
});

Engine.IO client version: 3.5.0

Client

const engine = require('engine.io-client');

let socket = engine('wss://localhost:8443', {
    secure: true,
    rejectUnauthorized: false // I'm using a self-signed local cert
});

socket.on('open', () => {
    console.log('open');
});
socket.on('error', error => {
    console.error(error.stack);
});
$ node -v
v15.5.0
$ DEBUG=* node client.js
  engine.io-client:socket creating transport "polling" +0ms
  engine.io-client:polling polling +0ms
  engine.io-client:polling-xhr xhr poll +0ms
  engine.io-client:polling-xhr xhr open GET: https://localhost:8443/engine.io/?EIO=3&transport=polling&t=NVgA3uJ&b64=1 +0ms
  engine.io-client:polling-xhr xhr data null +1ms
  engine.io-client:socket setting transport polling +10ms
  engine.io-client:socket socket error {"type":"TransportError","description":{"code":"ERR_CRYPTO_OPERATION_FAILED"}} +2ms
Error: xhr poll error
    at XHR.Transport.onError (/home/calvin/tmp/n15err/node_modules/engine.io-client/lib/transport.js:68:13)
    at Request.<anonymous> (/home/calvin/tmp/n15err/node_modules/engine.io-client/lib/transports/polling-xhr.js:132:10)
    at Request.Emitter.emit (/home/calvin/tmp/n15err/node_modules/component-emitter/index.js:145:20)
    at Request.onError (/home/calvin/tmp/n15err/node_modules/engine.io-client/lib/transports/polling-xhr.js:314:8)
    at Timeout._onTimeout (/home/calvin/tmp/n15err/node_modules/engine.io-client/lib/transports/polling-xhr.js:274:12)
    at listOnTimeout (node:internal/timers:556:17)
    at processTimers (node:internal/timers:499:7)
  engine.io-client:socket socket close with reason: "transport error" +0ms
  engine.io-client:polling transport not open - deferring close +12ms

Expected behavior
The engine.io connection should be established.

Platform:

  • Device: Desktop computer
  • OS: Linux

Additional context
Details provided above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions