Hi,

This patch adds support for proxying Docker's "hijacked" HTTP
connections. It shares most logic with websocket's "upgrade" mechanism.

Basically, it detects the 'application/vnd.docker.raw-stream"
Content-Type header and marks the connection for upgrade in this case.

I also hit a strange behavior with the chunked transfer terminating
sequence "0\r\n\r\n" being sent even on this upgraded connection hence
the "u->headers_in.chunked = 0;" in "ngx_http_upstream_upgrade".

Feedback appreciated.

Regards,

PS: I failed to register to this mailing list with jt AT yadutaf DOT fr,
any idea why ?

--
Jean-Tiare

# HG changeset patch
# User Jean-Tiare LE BIGOT <j...@yadutaf.fr>
# Date 1416064918 -3600
#      Sat Nov 15 16:21:58 2014 +0100
# Node ID dd18ab1abb2c0bc55bcbdad04b7d35b98ce15651
# Parent  7d7eac6e31df1d962a644f8093c1fbb8f91620ce
RFC: upgrade connection for proxied docker streams

Docker 'hijacks' its HTTP connection to raw TCP when streaming a console. It
advertises such connections by setting "Content-Type" header to
"application/vnd.docker.raw-stream" in the response.

Currenttly, Nginx has no special handling and interprets it as a chunked
response, which breaks the docker client.

A possible approach is to upgrade the connection when this header is detected
and force off chunked transfer.

diff -r 7d7eac6e31df -r dd18ab1abb2c src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c	Tue Nov 04 19:56:23 2014 +0900
+++ b/src/http/ngx_http_upstream.c	Sat Nov 15 16:21:58 2014 +0100
@@ -89,6 +89,8 @@
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_upstream_process_content_length(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_upstream_process_content_type(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_upstream_process_last_modified(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
@@ -175,7 +177,7 @@
                  ngx_http_upstream_copy_header_line, 0, 0 },
 
     { ngx_string("Content-Type"),
-                 ngx_http_upstream_process_header_line,
+                 ngx_http_upstream_process_content_type,
                  offsetof(ngx_http_upstream_headers_in_t, content_type),
                  ngx_http_upstream_copy_content_type, 0, 1 },
 
@@ -2716,6 +2718,7 @@
     u->write_event_handler = ngx_http_upstream_upgraded_write_upstream;
     r->read_event_handler = ngx_http_upstream_upgraded_read_downstream;
     r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;
+    u->headers_in.chunked = 0;
 
     if (clcf->tcp_nodelay) {
         tcp_nodelay = 1;
@@ -3849,6 +3852,25 @@
 
 
 static ngx_int_t
+ngx_http_upstream_process_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    ngx_int_t ret = ngx_http_upstream_process_header_line(r, h, offset);
+    if (ret != NGX_OK) {
+        return ret;
+    }
+
+    // is docker header ?
+    if (ngx_strstrn(h->value.data,
+                    "application/vnd.docker.raw-stream", 34 - 1) != NULL) {
+        r->upstream->upgrade = 1;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_upstream_process_last_modified(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset)
 {


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to