This code is giving me socket hang up error:
const https = require("https");
var req = https.request({
host: 'www.tisknulevne.cz',
port: 443,
path:'/',
method:'GET'
}, (res) => console.log("done", res));
req.end();
$ NODE_DEBUG="tls https http" node test.js
HTTP 13990: call onSocket 0 0
HTTP 13990: createConnection www.tisknulevne.cz:443:::::::: { servername: 'www.tisknulevne.cz',
_defaultAgent:
Agent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: { 'www.tisknulevne.cz:443::::::::': [] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
host: 'www.tisknulevne.cz',
port: 443,
path: null,
method: 'GET',
_agentKey: 'www.tisknulevne.cz:443::::::::' }
HTTPS 13990: createConnection { servername: 'www.tisknulevne.cz',
_defaultAgent:
Agent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: { 'www.tisknulevne.cz:443::::::::': [] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
host: 'www.tisknulevne.cz',
port: 443,
path: null,
method: 'GET',
_agentKey: 'www.tisknulevne.cz:443::::::::',
encoding: null }
HTTP 13990: sockets www.tisknulevne.cz:443:::::::: 1
HTTP 13990: outgoing message end.
TLS 13990: start
HTTP 13990: SOCKET ERROR: socket hang up Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1094:19)
at TLSSocket.g (events.js:291:16)
at emitNone (events.js:91:20)
at TLSSocket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
events.js:160
throw er; // Unhandled 'error' event
^
Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1094:19)
at TLSSocket.g (events.js:291:16)
at emitNone (events.js:91:20)
at TLSSocket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
I traced it down to the tls module, this code still throws socket hang up error:
```const tls = require("tls");
var socket = tls.connect({
host: "www.tisknulevne.cz",
port: 443
});
socket.end();
Ending the socket or not doesn't make difference. Opening the site in browser works fine, even wget and curl does.
$ curl -svvv https://www.tisknulevne.cz > /dev/null
GET / HTTP/1.1
Host: www.tisknulevne.cz
User-Agent: curl/7.47.0
Accept: /< HTTP/1.1 200 OK
< Date: Tue, 29 Nov 2016 19:56:34 GMT
< Server: Microsoft-IIS/6.0
< X-Powered-By: ASP.NET
< Content-Type: text/html
< Expires: Tue, 29 Nov 2016 19:56:34 GMT
< Set-Cookie: ASPSESSIONIDQSBDRCDC=AAMFDOOCNMAMFBGAKGCNMBIP; path=/
< Cache-control: private
< Transfer-Encoding: chunked
<
{ [16094 bytes data]
- Connection #0 to host www.tisknulevne.cz left intact
```
Other sites are fine, just this one.
We're having the same problem with various sites, .e.g. https://applications.bmi.com/Security/Login.aspx
Every site we're having a problem with, including the site mentioned by OP, is served by Microsoft IIS.
Adding ciphers: 'DES-CBC3-SHA'
to the request options seems to fix it in my case.
Can confirm adding ciphers: 'DES-CBC3-SHA'
fixes it. Why isn't that default, when in other apps it is?
If there is a good reason for it not being default, can you consider adding more descriptive error message than socket hang up
?
CBC ciphers are considered insecure. There isn't really any way for node.js to provide a better error message because the server simply terminates the connection instead of sending back a 'no suitable cipher' alert.
I'll go ahead and close the issue but feel free to ask follow-up questions.
I think if browser loads some page without complaints, node.js should too. If major browsers start rejecting CBC ciphers or marking them as insecure, node.js should too. Thats my opinion.
The current default cipher list came about after ample discussion. We want node.js to be secure by default so you should expect it to become even stricter over time, not looser.
It's not a browser, it targets a different demographic than browsers do (users vs. programmers), so comparing them is not meaningful, IMO.
Aside: you might be interested to know that while Chrome doesn't reject the connection outright, it does complain:
The connection to this site uses an obsolete protocol (TLS 1.0), an obsolete key exchange (RSA), and an obsolete cipher (3DES_EDE_CBC with HMAC-SHA1).
"Obsolete" is Chrome lingo for "on the chopping block and to be killed off when usage drops below a threshold."
ciphers: 'DES-CBC3-SHA' did fixed the problem. But thats strange why is it not adding that header in tls by default
Because DES-CBC3-SHA is an insecure cipher.
Most helpful comment
Adding
ciphers: 'DES-CBC3-SHA'
to the request options seems to fix it in my case.