Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

socket.connecting is false before calling the connect listener #25328

Closed
szmarczak opened this issue Jan 3, 2019 · 13 comments
Closed

socket.connecting is false before calling the connect listener #25328

szmarczak opened this issue Jan 3, 2019 · 13 comments

Comments

@szmarczak
Copy link
Member

szmarczak commented Jan 3, 2019

  • Version: v11.6.0
  • Platform: Ubuntu 18.10
  • Subsystem: net

According to the docs:

socket.connecting
[...] Will be set to true before emitting 'connect' event and/or calling socket.connect(options[, connectListener])'s callback.

I don't think socket.connecting should be false before emitting the connect event.

Demo: https://runkit.com/szmarczak/5c2e555cc7b0160012352b15

It breaks for example http-timer.

@sam-github
Copy link
Contributor

You didn't say whether you felt the docs were wrong or the behaviour was wrong, but reading behind the lines, I think you found the docs unclear.

Does #25333 help?

@szmarczak
Copy link
Member Author

You didn't say whether you felt the docs were wrong or the behaviour was wrong

I've said that indirectly. Anyway, I'm saying it now: I feel the behavior is wrong.

Does #25333 help?

👍, but I still don't know if the described behavior above is right or it's just a bug.

@sam-github
Copy link
Contributor

I don't understand why you think its a bug.

You provided code, but what is it about the code that you think is wrong? What do you think it should do differently?

@szmarczak
Copy link
Member Author

You provided code, but what is it about the code that you think is wrong? What do you think it should do differently?

I think it should do differently because the connection hasn't been fully estabilished yet.
The connect event occurs when it has been fully estabilished. Until that socket.connecting should be true.

@szmarczak
Copy link
Member Author

Or maybe there's another way to check if the socket has been estabilished?

@sam-github
Copy link
Contributor

You don't want to know when the TCP connection is established, it seems you want to know when the TLS handshake has completed. .connecting does not, as you see, tell you that.

Maybe tls.TLSSocket should override the meaning of the connect event, and .connecting property, so that the socket isn't considered connected until the TLS handshake has completed.... but that isn't how it was done, and it would be a really big and backwards incompatible change to change them now.

The callback function to tls.connect() is attached to the secureConnect event (unlike the cb function to net.connect(), which is attached to connect).

Generally, waiting for events is preferred to polling properties for their state, but on the client side you could look at https://nodejs.org/api/tls.html#tls_tlssocket_authorized, it will be set to true just before secureConnect is emitted.

@szmarczak
Copy link
Member Author

You don't want to know when the TCP connection is established, it seems you want to know when the TLS handshake has completed. .connecting does not, as you see, tell you that.

Nope (maybe?) 😄 I want to see if the TCP connection has been established: for example, http-timer needs this - it works with the http module too (where TCP socket is used, not TLS) ;)

You don't want to know when the TCP connection is established, it seems you want to know when the TLS handshake has completed. .connecting does not, as you see, tell you that.

Good to know ^_^

@sam-github
Copy link
Contributor

I want to see if the TCP connection has been established

Then you can use the 'connect' event and .connecting property, and not use the callback to tls.connect(). If you want code that works for tls or net, change

[net,tls].connect(.., callback);

to

[net,tls].connect(...).once('connect', callback)

@szmarczak
Copy link
Member Author

You don't get it. This issue is not solved yet.

not use the callback to tls.connect()

It's no difference if I add the connect listener through net.connect() or socket.on('connect, ...). Not sure what did you mean here.

Then you can use the 'connect' event and .connecting property

I have no idea how many times I've told you that socket.connecting becomes false before the connect event. It's not fully connected. See the demo.

Could you reopen this issue? Otherwise I'll make a new one.

@sam-github sam-github reopened this Jan 4, 2019
@sam-github
Copy link
Contributor

.connecting is supposed to become false before the connect event is emitted, as documented, and as implemented:

node/lib/net.js

Lines 1057 to 1066 in 9dfbc39

self.connecting = false;
self._sockname = null;
if (status === 0) {
self.readable = readable;
if (!self._writableState.ended)
self.writable = writable;
self._unrefTimer();
self.emit('connect');

Your example code shows that .connecting becomes false before the secureConnect event, as it should do. This is unrelated to your assertion (since it doesn't use the connect event).

Please provide example code, with a clear description of what about that code's behaviour you believe to be a bug.

@szmarczak
Copy link
Member Author

Thanks for your interest, I really appreciate it! 🙌

Here's the example: https://runkit.com/szmarczak/5c2fc4a004d48e001292057c

On the finish event socket.connecting is false though the connect event hasn't been emitted yet. How to prove that it hasn't been fully connected at that point? Is it even possible? (without setting additional connect event - there may be a case when it has been already emitted for example)

@sam-github
Copy link
Contributor

sam-github commented Jan 7, 2019

@Trott I think this should be moved to nodejs/help

@szmarczak

On the finish event socket.connecting is false though the connect event hasn't been emitted yet.

Sorry, while I am not an expert in the HTTP sub-system, this doesn't surprise me. finish is triggered by your call to .end(), see https://nodejs.org/api/stream.html#stream_event_finish

You are probably seeing the finish event before the underlying socket has had .connect() called on it.

Also, there is connection pooling by the agent with request. Its possible that the socket was already connected, and is being reused, in which case an http.request() will not even cause a .connect() call to be made on a socket.

I'd suggest asking in nodejs/help, describing what you are trying to accomplish, and perhaps someone can help you find a way.

sam-github added a commit to sam-github/node that referenced this issue Jan 8, 2019
sam-github added a commit that referenced this issue Jan 9, 2019
Fixes: #25328

PR-URL: #25333
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
addaleax pushed a commit that referenced this issue Jan 14, 2019
Fixes: #25328

PR-URL: #25333
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
BridgeAR pushed a commit to BridgeAR/node that referenced this issue Jan 16, 2019
Fixes: nodejs#25328

PR-URL: nodejs#25333
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
BethGriggs pushed a commit that referenced this issue Apr 28, 2019
Fixes: #25328

PR-URL: #25333
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
BethGriggs pushed a commit that referenced this issue May 10, 2019
Fixes: #25328

PR-URL: #25333
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
MylesBorins pushed a commit that referenced this issue May 16, 2019
Fixes: #25328

PR-URL: #25333
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
@szmarczak
Copy link
Member Author

Hmm. I assumed that tls.connect(..., listener) stands for the connect event. It stands for the secureConnect event. secureConnect is not connect, so I was wrong from the beginning.

Sorry for disturbing you guys. Feel free to move this to the help repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants