Skip to content

Commit

Permalink
feat(proxy) add route.response_buffering
Browse files Browse the repository at this point in the history
By default Kong does buffer the response. This is not ideal when upstream
is sending payloads with HTTP 1.1 chunked encoding.

This commit adds a new property to route entity:
```
response_buffering = <true/false>
```

By default that is `true` (which is the same as before). Users can now
turn off the response buffering on route-by-route manner by setting
`route.response_buffering=false`.
  • Loading branch information
bungle committed Sep 21, 2020
1 parent 2c58899 commit f969ea4
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 4 deletions.
7 changes: 7 additions & 0 deletions autodoc/admin-api/data/admin-api.lua
Expand Up @@ -873,6 +873,13 @@ return {
chunked transfer encoding.
]]
},
response_buffering = {
description = [[
Whether to enable response body buffering or not. With HTTP 1.1, it
may make sense to turn this off on services that send data with chunked
transfer encoding.
]]
},
service = {
description = [[
The Service this Route is associated to.
Expand Down
9 changes: 9 additions & 0 deletions kong/db/migrations/core/012_213_to_220.lua
Expand Up @@ -16,6 +16,14 @@ return {
-- Do nothing, accept existing state
END;
$$;
DO $$
BEGIN
ALTER TABLE IF EXISTS ONLY "routes" ADD "response_buffering" BOOLEAN;
EXCEPTION WHEN DUPLICATE_COLUMN THEN
-- Do nothing, accept existing state
END;
$$;
]],
},
cassandra = {
Expand All @@ -30,6 +38,7 @@ return {
);
ALTER TABLE routes ADD request_buffering boolean;
ALTER TABLE routes ADD response_buffering boolean;
]],
}
}
1 change: 1 addition & 0 deletions kong/db/schema/entities/routes.lua
Expand Up @@ -37,6 +37,7 @@ return {
{ path_handling = { type = "string", default = "v0", one_of = { "v0", "v1" }, }, },
{ preserve_host = { type = "boolean", default = false }, },
{ request_buffering = { type = "boolean", required = true, default = true }, },
{ response_buffering = { type = "boolean", required = true, default = true }, },
{ snis = { type = "set",
elements = typedefs.sni }, },
{ sources = typedefs.sources },
Expand Down
14 changes: 12 additions & 2 deletions kong/runloop/handler.lua
Expand Up @@ -1259,8 +1259,18 @@ return {
return ngx.exec("@grpcs")
end
if route.request_buffering == false and http_version == 1.1 then
return ngx.exec("@unbuffered")
if http_version == 1.1 then
if route.request_buffering == false then
if route.response_buffering == false then
return ngx.exec("@unbuffered")
end
return ngx.exec("@unbuffered_request")
end
if route.response_buffering == false then
return ngx.exec("@unbuffered_response")
end
end
end
end,
Expand Down
66 changes: 65 additions & 1 deletion kong/templates/nginx_kong.lua
Expand Up @@ -136,7 +136,8 @@ server {
set $kong_proxy_mode 'http';
proxy_http_version 1.1;
proxy_request_buffering on;
proxy_buffering on;
proxy_request_buffering on;
proxy_set_header TE $upstream_te;
proxy_set_header Host $upstream_host;
Expand Down Expand Up @@ -166,6 +167,7 @@ server {
set $kong_proxy_mode 'unbuffered';
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header TE $upstream_te;
Expand All @@ -190,6 +192,68 @@ server {
proxy_pass $upstream_scheme://kong_upstream$upstream_uri;
}
location @unbuffered_request {
internal;
default_type '';
set $kong_proxy_mode 'unbuffered';
proxy_http_version 1.1;
proxy_buffering on;
proxy_request_buffering off;
proxy_set_header TE $upstream_te;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
proxy_set_header X-Forwarded-For $upstream_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
proxy_set_header X-Forwarded-Host $upstream_x_forwarded_host;
proxy_set_header X-Forwarded-Port $upstream_x_forwarded_port;
proxy_set_header X-Forwarded-Path $upstream_x_forwarded_path;
proxy_set_header X-Forwarded-Prefix $upstream_x_forwarded_prefix;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_header Server;
proxy_pass_header Date;
proxy_ssl_name $upstream_host;
proxy_ssl_server_name on;
> if client_ssl then
proxy_ssl_certificate ${{CLIENT_SSL_CERT}};
proxy_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}};
> end
proxy_pass $upstream_scheme://kong_upstream$upstream_uri;
}
location @unbuffered_response {
internal;
default_type '';
set $kong_proxy_mode 'unbuffered';
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering on;
proxy_set_header TE $upstream_te;
proxy_set_header Host $upstream_host;
proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
proxy_set_header X-Forwarded-For $upstream_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
proxy_set_header X-Forwarded-Host $upstream_x_forwarded_host;
proxy_set_header X-Forwarded-Port $upstream_x_forwarded_port;
proxy_set_header X-Forwarded-Path $upstream_x_forwarded_path;
proxy_set_header X-Forwarded-Prefix $upstream_x_forwarded_prefix;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_header Server;
proxy_pass_header Date;
proxy_ssl_name $upstream_host;
proxy_ssl_server_name on;
> if client_ssl then
proxy_ssl_certificate ${{CLIENT_SSL_CERT}};
proxy_ssl_certificate_key ${{CLIENT_SSL_CERT_KEY}};
> end
proxy_pass $upstream_scheme://kong_upstream$upstream_uri;
}
location @grpc {
internal;
default_type '';
Expand Down
Expand Up @@ -448,6 +448,7 @@ describe("declarative config: process_auto_fields", function()
protocols = { "http", "https" },
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
},
{
hosts = { "example.com" },
Expand All @@ -458,6 +459,7 @@ describe("declarative config: process_auto_fields", function()
protocols = { "http", "https" },
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
},
{
methods = { "GET", "POST" },
Expand All @@ -468,6 +470,7 @@ describe("declarative config: process_auto_fields", function()
protocols = { "http", "https" },
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
},
}
},
Expand All @@ -492,6 +495,7 @@ describe("declarative config: process_auto_fields", function()
protocols = { "http", "https" },
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
},
}
}
Expand Down Expand Up @@ -539,6 +543,7 @@ describe("declarative config: process_auto_fields", function()
regex_priority = 0,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
plugins = {},
}
}
Expand Down Expand Up @@ -603,6 +608,7 @@ describe("declarative config: process_auto_fields", function()
regex_priority = 0,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
plugins = {
{
name = "key-auth",
Expand Down Expand Up @@ -654,6 +660,7 @@ describe("declarative config: process_auto_fields", function()
regex_priority = 0,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
plugins = {
{
name = "basic-auth",
Expand Down
Expand Up @@ -196,6 +196,7 @@ describe("declarative config: flatten", function()
path_handling = "v1",
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}
}
}, idempotent(config))
Expand Down Expand Up @@ -432,6 +433,7 @@ describe("declarative config: flatten", function()
path_handling = "v1",
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}
},
services = {
Expand Down Expand Up @@ -716,6 +718,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
} },
services = { {
connect_timeout = 60000,
Expand Down Expand Up @@ -795,6 +798,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}, {
created_at = 1234567890,
destinations = null,
Expand All @@ -818,6 +822,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}, {
created_at = 1234567890,
destinations = null,
Expand All @@ -841,6 +846,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}, {
created_at = 1234567890,
destinations = null,
Expand All @@ -864,6 +870,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
} },
services = { {
connect_timeout = 60000,
Expand Down Expand Up @@ -946,6 +953,7 @@ describe("declarative config: flatten", function()
path_handling = "v1",
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}
},
services = {
Expand Down Expand Up @@ -1106,6 +1114,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
}, {
created_at = 1234567890,
destinations = null,
Expand All @@ -1129,6 +1138,7 @@ describe("declarative config: flatten", function()
tags = null,
updated_at = 1234567890,
request_buffering = true,
response_buffering = true,
} },
services = { {
connect_timeout = 60000,
Expand Down
6 changes: 6 additions & 0 deletions spec/02-integration/03-db/02-db_core_entities_spec.lua
Expand Up @@ -707,6 +707,7 @@ for _, strategy in helpers.each_strategy() do
service = route.service,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
}, route)
end)

Expand Down Expand Up @@ -750,6 +751,7 @@ for _, strategy in helpers.each_strategy() do
service = route.service,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
}, route)
end)

Expand Down Expand Up @@ -791,6 +793,7 @@ for _, strategy in helpers.each_strategy() do
service = ngx.null,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
}, route)
end)

Expand Down Expand Up @@ -1104,6 +1107,7 @@ for _, strategy in helpers.each_strategy() do
service = route.service,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
}, new_route)


Expand Down Expand Up @@ -1138,6 +1142,7 @@ for _, strategy in helpers.each_strategy() do
service = route.service,
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
}, new_route)
end)

Expand Down Expand Up @@ -1982,6 +1987,7 @@ for _, strategy in helpers.each_strategy() do
},
https_redirect_status_code = 426,
request_buffering = true,
response_buffering = true,
}, route)
local route_in_db, err, err_t = db.routes:select({ id = route.id }, { nulls = true })
Expand Down

0 comments on commit f969ea4

Please sign in to comment.