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

HttpDuplex.end() breaks output #48

Open
jonasfj opened this issue Aug 9, 2015 · 10 comments
Open

HttpDuplex.end() breaks output #48

jonasfj opened this issue Aug 9, 2015 · 10 comments

Comments

@jonasfj
Copy link

jonasfj commented Aug 9, 2015

So playing with attach streams... specifically for docker exec, I've found that you can't end the stdin stream... The HttpDuplex.end() implementation breaks the TCP stream - not just closing this side.

So if you do the equivalent of echo "test" | docker exec CONTAINER wc -c you don't get the expected output.

Looking at the docker implementation, it seems that we should:

  1. Set Connection: upgrade and Upgrade: tcp headers, see docker cli code.
  2. And then just hijack the raw TCP socket and forget all about HTTP, or ensure that HttpDuplex only closes this side of the request (should be the same right?).

Either way, this seems to fix my issue:

HttpDuplex.prototype.end = function(chunk, encoding, cb) {
  var req = this.req;
  return req.end(chunk, encoding, function() {
    req.socket.end();
    if (cb) {
      cb();
    }
  });
};

Not sure why I'm having to close the TCP socket. It ought to just end on it's own.
Current code does this._output.socket.destroy(); which is probably why I miss any output arriving after stdin is closed.

@jonasfj
Copy link
Author

jonasfj commented Aug 9, 2015

Also if I do:

exec.start({stdin: true, stream: true, ...}, function(err, stream) {
  stream = stream.req.socket;
  // Attach as normally...
});

Then everything works as expected... So perhaps we don't need the HttpDuplex wrapper at all.
stream.req.socket.end() closes the stdin side of the socket as expected.

@jonasfj
Copy link
Author

jonasfj commented Aug 9, 2015

Update... I've just realized that I loose some initial output if I use stream = stream.req.socket.
So this probably have to the the upgrade thing.

@jonasfj
Copy link
Author

jonasfj commented Aug 17, 2015

@EggyLv999, any chance you can take a look at this.
I'm not sure if docker-modem is easily fixed, or we need some special methods to support docker exec.

@JohnyDays
Copy link

Also having this issue, being unable to manually end the connection

@JohnyDays
Copy link

Tried your fix @jonasfj, worked for me. Making a fork for now

@jonasfj
Copy link
Author

jonasfj commented Aug 27, 2015

@JohnyDays, I experienced other issues with my fix. I suspect the best solution is to send the Upgrade: tcp headers as expected by docker.

@JohnyDays
Copy link

I was using the logs() function to monitor logging and look for a signal that a certain container is ready for action. But it just wasn't working, there was no reliable way to close the connection that did not result in disaster. So I am now polling the logs every X seconds (with a slight modification in a fork, not to use streams) and checking that way

@dcolens
Copy link

dcolens commented Mar 10, 2017

FYI https://github.com/mafintosh/docker-remote-api does not have this issue.

@apocas
Copy link
Owner

apocas commented Mar 10, 2017

This issue is a bit (a lot) old, lost track of it, since then (long time ago) we have implemented hijacking.

Described in here: https://github.com/apocas/dockerode#streams-goodness

Do you have this issue using hijacking?

@dcolens
Copy link

dcolens commented Mar 11, 2017 via email

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

No branches or pull requests

4 participants