diff --git a/start_esp/nginx-auto.conf.template b/start_esp/nginx-auto.conf.template index f620433c0..6aede64ab 100644 --- a/start_esp/nginx-auto.conf.template +++ b/start_esp/nginx-auto.conf.template @@ -51,6 +51,9 @@ http { server_tokens off; client_max_body_size ${client_max_body_size}; client_body_buffer_size ${client_body_buffer_size}; +% if client_body_timeout: + client_body_timeout ${client_body_timeout}; +% endif % if large_client_header_buffers: large_client_header_buffers ${large_client_header_buffers}; % endif diff --git a/start_esp/start_esp.py b/start_esp/start_esp.py index 01c708313..fc4f5a5db 100755 --- a/start_esp/start_esp.py +++ b/start_esp/start_esp.py @@ -150,6 +150,7 @@ def write_nginx_conf(ingress, nginx_conf, args): enable_backend_routing=args.enable_backend_routing, client_max_body_size=args.client_max_body_size, client_body_buffer_size=args.client_body_buffer_size, + client_body_timeout=args.client_body_timeout, large_client_header_buffers=args.large_client_header_buffers, keepalive_timeout=args.keepalive_timeout, worker_processes=args.worker_processes, @@ -649,6 +650,11 @@ def make_argparser(): http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout. ''') + parser.add_argument('--client_body_timeout', default=None, help=''' + Sets the timeout for reading client request body. This flag will pass to Nginx config directly. + http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout. + ''') + parser.add_argument('--rewrite', action='append', help= '''Internally redirect the request uri with a pair of pattern and replacement. Pattern and replacement should be separated by whitespace. diff --git a/start_esp/test/start_esp_test.py b/start_esp/test/start_esp_test.py index 6ceea96e3..3fcec9dd9 100644 --- a/start_esp/test/start_esp_test.py +++ b/start_esp/test/start_esp_test.py @@ -153,6 +153,11 @@ def test_keepalive_timeout_output_is_as_expected(self): config_generator = self.basic_config_generator + " --keepalive_timeout=600s" self.run_test_with_expectation(expected_config_file, self.generated_nginx_config_file, config_generator) + def test_client_body_timeout_output_is_as_expected(self): + expected_config_file = "./start_esp/test/testdata/expected_client_body_timeout_nginx.conf" + config_generator = self.basic_config_generator + " --client_body_timeout=86600s" + self.run_test_with_expectation(expected_config_file, self.generated_nginx_config_file, config_generator) + def test_allow_invalid_headers_arg_output_is_as_expected(self): expected_config_file = "./start_esp/test/testdata/expected_allow_invalid_headers_nginx.conf" config_generator = self.basic_config_generator + " --allow_invalid_headers" diff --git a/start_esp/test/testdata/expected_client_body_timeout_nginx.conf b/start_esp/test/testdata/expected_client_body_timeout_nginx.conf new file mode 100644 index 000000000..a6e588ee5 --- /dev/null +++ b/start_esp/test/testdata/expected_client_body_timeout_nginx.conf @@ -0,0 +1,127 @@ +# Auto-generated by start_esp +# Copyright (C) Extensible Service Proxy Authors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +daemon off; + +user nginx nginx; + +pid ./start_esp/test/pid_file; + +# Worker/connection processing limits +worker_processes 1; +worker_rlimit_nofile 10240; +events { worker_connections 10240; } + +# Logging to stderr enables better integration with Docker and GKE/Kubernetes. +error_log stderr warn; + +http { + include /etc/nginx/mime.types; + include /etc/nginx/conf/*.conf; + server_tokens off; + client_max_body_size 32m; + client_body_buffer_size 128k; + client_body_timeout 86600s; + + # HTTP subrequests + endpoints_resolver 8.8.8.8; + endpoints_certificates /etc/nginx/trusted-ca-certificates.crt; + + upstream app_server0 { + server 127.0.0.1:8081; + keepalive 128; + } + + set_real_ip_from 0.0.0.0/0; + set_real_ip_from 0::/0; + real_ip_header X-Forwarded-For; + real_ip_recursive on; + + + server { + server_name ""; + resolver 8.8.8.8; + + + listen 8080 backlog=16384; + + access_log /dev/stdout; + + + + + location / { + # Begin Endpoints v2 Support + endpoints { + on; + server_config /etc/nginx/server_config.pb.txt; + google_authentication_secret key; + metadata_server http://169.254.169.254; + } + # End Endpoints v2 Support + + + + proxy_pass http://app_server0; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Google-Real-IP $remote_addr; + + # Enable the upstream persistent connection + proxy_http_version 1.1; + proxy_set_header Connection ""; + + # 86400 seconds (24 hours) is the maximum a server is allowed. + proxy_send_timeout 86400s; + proxy_read_timeout 86400s; + } + + include /var/lib/nginx/extra/*.conf; + } + + server { + # expose /nginx_status and /endpoints_status but on a different port to + # avoid external visibility / conflicts with the app. + listen 8090; + location /nginx_status { + stub_status on; + access_log off; + } + location /endpoints_status { + endpoints_status; + access_log off; + } + location /healthz { + return 200; + access_log off; + } + location / { + root /dev/null; + } + } +}