From b468e59547db4e42b5c1d3f8b865f2b235ccd401 Mon Sep 17 00:00:00 2001 From: thefosk Date: Wed, 16 Nov 2016 21:31:15 -0800 Subject: [PATCH 1/3] feat(proxy) supports websockets --- kong/templates/nginx_kong.lua | 8 ++++ .../05-proxy/04-websockets_spec.lua | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 spec/02-integration/05-proxy/04-websockets_spec.lua diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua index a8ec37ef153f..9fc9f50022f7 100644 --- a/kong/templates/nginx_kong.lua +++ b/kong/templates/nginx_kong.lua @@ -63,6 +63,11 @@ upstream kong_upstream { keepalive ${{UPSTREAM_KEEPALIVE}}; } +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + server { server_name kong; listen ${{PROXY_LISTEN}}; @@ -89,10 +94,13 @@ server { kong.access() } + proxy_http_version 1.1; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $upstream_host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; proxy_pass_header Server; proxy_pass $upstream_url; diff --git a/spec/02-integration/05-proxy/04-websockets_spec.lua b/spec/02-integration/05-proxy/04-websockets_spec.lua new file mode 100644 index 000000000000..d9dfaf371f4a --- /dev/null +++ b/spec/02-integration/05-proxy/04-websockets_spec.lua @@ -0,0 +1,44 @@ +local client = require "resty.websocket.client" +local helpers = require "spec.helpers" +local cjson = require "cjson" + +describe("Websockets", function() + setup(function() + assert(helpers.start_kong()) + + assert(helpers.dao.apis:insert { + request_path = "/ws", + strip_request_path = true, + upstream_url = "http://sockb.in" + }) + end) + + teardown(function() + helpers.stop_kong() + end) + + local function make_request(uri) + local wb = assert(client:new()) + assert(wb:connect(uri)) + assert(wb:send_text("testing Kong")) + + local data = assert(wb:recv_frame()) + assert.equal("testing Kong", cjson.decode(data).reqData) + + assert(wb:send_close()) + + return true + end + + it("works without Kong", function() + assert(make_request("ws://sockb.in")) + end) + + it("works with Kong", function() + assert(make_request("ws://"..helpers.test_conf.proxy_ip..":"..helpers.test_conf.proxy_port.."/ws")) + end) + + it("works with Kong under HTTPS", function() + assert(make_request("wss://"..helpers.test_conf.proxy_ssl_ip..":"..helpers.test_conf.proxy_ssl_port.."/ws")) + end) +end) From eab1ffbdf58a020e9bad8d00c4f13e62761a8ebb Mon Sep 17 00:00:00 2001 From: thefosk Date: Thu, 17 Nov 2016 18:22:41 -0800 Subject: [PATCH 2/3] keep-alive by default, unless it is an Upgrade request --- kong/core/handler.lua | 4 ++++ kong/templates/nginx_kong.lua | 8 ++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kong/core/handler.lua b/kong/core/handler.lua index 7a4372723e66..bbb6c791c6fa 100644 --- a/kong/core/handler.lua +++ b/kong/core/handler.lua @@ -60,6 +60,10 @@ return { ngx.log(ngx.ERR, "failed the initial dns/balancer resolve: ", err) return responses.send_HTTP_INTERNAL_SERVER_ERROR() end + + -- Websocket + local is_upgrade = ngx.var.http_connection and ngx.var.http_connection:lower() == "upgrade" + ngx.var.upstream_connection = is_upgrade and "upgrade" or "keep-alive" end, -- Only executed if the `resolver` module found an API and allows nginx to proxy it. after = function() diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua index 9fc9f50022f7..e7003942d06e 100644 --- a/kong/templates/nginx_kong.lua +++ b/kong/templates/nginx_kong.lua @@ -63,11 +63,6 @@ upstream kong_upstream { keepalive ${{UPSTREAM_KEEPALIVE}}; } -map $http_upgrade $connection_upgrade { - default upgrade; - '' close; -} - server { server_name kong; listen ${{PROXY_LISTEN}}; @@ -89,6 +84,7 @@ server { location / { set $upstream_host nil; set $upstream_url nil; + set $upstream_connection nil; access_by_lua_block { kong.access() @@ -100,7 +96,7 @@ server { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $upstream_host; proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; + proxy_set_header Connection $upstream_connection; proxy_pass_header Server; proxy_pass $upstream_url; From 1bd0d207ad8dbedd9933719e50a82a29215f732c Mon Sep 17 00:00:00 2001 From: thefosk Date: Fri, 18 Nov 2016 17:59:09 -0800 Subject: [PATCH 3/3] bring back maps --- kong/core/handler.lua | 4 ---- kong/templates/nginx_kong.lua | 13 +++++++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/kong/core/handler.lua b/kong/core/handler.lua index bbb6c791c6fa..7a4372723e66 100644 --- a/kong/core/handler.lua +++ b/kong/core/handler.lua @@ -60,10 +60,6 @@ return { ngx.log(ngx.ERR, "failed the initial dns/balancer resolve: ", err) return responses.send_HTTP_INTERNAL_SERVER_ERROR() end - - -- Websocket - local is_upgrade = ngx.var.http_connection and ngx.var.http_connection:lower() == "upgrade" - ngx.var.upstream_connection = is_upgrade and "upgrade" or "keep-alive" end, -- Only executed if the `resolver` module found an API and allows nginx to proxy it. after = function() diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua index e7003942d06e..fbdbc7a1cb69 100644 --- a/kong/templates/nginx_kong.lua +++ b/kong/templates/nginx_kong.lua @@ -63,6 +63,16 @@ upstream kong_upstream { keepalive ${{UPSTREAM_KEEPALIVE}}; } +map $http_upgrade $upstream_connection { + default keep-alive; + websocket upgrade; +} + +map $http_upgrade $upstream_upgrade { + default ''; + websocket websocket; +} + server { server_name kong; listen ${{PROXY_LISTEN}}; @@ -84,7 +94,6 @@ server { location / { set $upstream_host nil; set $upstream_url nil; - set $upstream_connection nil; access_by_lua_block { kong.access() @@ -95,7 +104,7 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $upstream_host; - proxy_set_header Upgrade $http_upgrade; + proxy_set_header Upgrade $upstream_upgrade; proxy_set_header Connection $upstream_connection; proxy_pass_header Server; proxy_pass $upstream_url;