-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Set HTTP upgrade headers when hijacking connection #9652
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
Conversation
Signed-off-by: Jean-Tiare Le Bigot <jt@yadutaf.fr>
nice! |
LGTM but I feel like @icecrime would know for sure because he just fixed something with TLS and hijack :) |
@yadutaf would you be able to provide us with a simple way of testing this? :) |
At least we should try this with |
Sounds perfectly reasonable, my only remark would be the following: maybe we should check for the |
@tiborvass You can easily test this PR with an Nginx config file looking like:
With Docker daemon listening on port 8080: @icecrime Sounds like a good idea to check for the |
@@ -887,7 +887,12 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re | |||
|
|||
var errStream io.Writer | |||
|
|||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") | |||
|
|||
if len(r.Header.Get("Upgrade")) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how we should deal with an empty, yet provided "Upgrade"
header field. Anyway, I think a more idiomatic way of checking, which doesn't involve testing the field's value length would be:
if _, ok := r.Header.Get("Upgrade"); ok {
I'll let you check the spec if syntax isn't clear (also, parenthesis around conditions are not required in Go).
Signed-off-by: Jean-Tiare Le Bigot <jt@yadutaf.fr>
@icecrime thanks for the review. Should be fine now. I also fixed the formating issue. |
mmm, it occurs to me this should be documented in the API docs :) |
Signed-off-by: Jean-Tiare Le Bigot <jt@yadutaf.fr>
@SvenDowideit Done. |
LGTM |
Thanks @yadutaf! LGTM (a.k.a: "yapludtaf") |
Set HTTP upgrade headers when hijacking connection
NOTE to sven&fred: please do not merge this into a docs update for 1.4.1 - the API doc needed to be in the 1.17 API doc. |
@jfrazelle @LK4D4 this needs to be fixed up in master - as this change is not in 1.4, it should not be documented in the 1.16 API docs. |
Because the patch is not in 1.4, the v1.16 docs shouldn't have been updated. Docs were promoted to v1.17 by moby#9742. Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
Revert doc changes from #9652
@@ -887,7 +887,11 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re | |||
|
|||
var errStream io.Writer | |||
|
|||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") | |||
if _, ok := r.Header["Upgrade"]; ok { | |||
fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of hardcoding tcp
here should we look at the Upgrade
value in the env ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would not make sense. Let's say you have a client telling you "I want websocket" protocol. Then you answer "Sure, here is websocket protocol" while actually sending raw tcp, I fear some debugging nightmare.
If need be, I'd rather add a check on the incoming UPGRADE header to make sure this is something we can speak.
The reason why I did not bother doing it is that this is barely a hint for potential proxies. Docker just ignores it (I mean, It won't affect its behavior in any way beyond sending headers) and Nginx at least will just plainly ignore the value. Actually, If the value had been important here, I'd have used a standard, well known one instead.
Opinion ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, it makes sense for me to leave it like this. Thanks.
Because the patch is not in 1.4, the v1.16 docs shouldn't have been updated. Docs were promoted to v1.17 by moby#9742. Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
When setting up a reverse proxy like Nginx behind Docker client and Docker remote API most commands works fine except
docker attach
anddocker exec
. When these commands are used, docker "hijacks" the HTTP connection back to raw bi-directional TCP. As the reverse proxy was expecting plain HTTP it is completely lost.This Pull Request adds
Connection: Upgrade
andUpgrade: tcp
HTTP headers as well as return code of101 UPGRADED
in this scenario. It is fully backward compatible and, while 'tcp' upgrade is not standard, it is enough to trigger Nginx connection upgrade path as used by websockets.