From 708ed02891afbc9744e70c0fb547dd8b128a69e7 Mon Sep 17 00:00:00 2001 From: Philipp Thun Date: Fri, 9 Oct 2026 15:00:50 +0200 Subject: [PATCH] Add configurable nginx client_body_timeout for uploads Slow or stalling clients uploading large bits can hit nginx's built-in default client_body_timeout before the upload completes. nginx then aborts the request, which surfaces to clients as a failed upload. Add cc.nginx_client_body_timeout_for_uploads_in_seconds, rendered into the public upload endpoints only when set. With no value configured, no directive is emitted and nginx's default behavior is unchanged. --- jobs/cloud_controller_ng/spec | 2 ++ .../templates/public_upload.conf.erb | 4 ++++ spec/cloud_controller_ng/nginx_spec.rb | 23 +++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/jobs/cloud_controller_ng/spec b/jobs/cloud_controller_ng/spec index ba7e1b0d25..f81c122f4e 100644 --- a/jobs/cloud_controller_ng/spec +++ b/jobs/cloud_controller_ng/spec @@ -809,6 +809,8 @@ properties: cc.app_bits_max_body_size: default: "2048M" description: "Maximum body size for nginx bits uploads" + cc.nginx_client_body_timeout_for_uploads_in_seconds: + description: "nginx client_body_timeout in seconds for the public upload endpoints. When unset, nginx's built-in default applies." cc.additional_allowed_process_users: default: [] diff --git a/jobs/cloud_controller_ng/templates/public_upload.conf.erb b/jobs/cloud_controller_ng/templates/public_upload.conf.erb index 1882246a3f..83e1fa8abd 100644 --- a/jobs/cloud_controller_ng/templates/public_upload.conf.erb +++ b/jobs/cloud_controller_ng/templates/public_upload.conf.erb @@ -4,6 +4,10 @@ upload_pass @cc_uploads; # Allow large uploads client_max_body_size <%= p("cc.app_bits_max_body_size") %>; #already enforced upstream/but doesn't hurt. +<% if_p("cc.nginx_client_body_timeout_for_uploads_in_seconds") do |timeout| -%> +client_body_timeout <%= timeout %>s; +<% end -%> + # Store files to this directory upload_store <%= p("cc.directories.tmpdir") %>/uploads; diff --git a/spec/cloud_controller_ng/nginx_spec.rb b/spec/cloud_controller_ng/nginx_spec.rb index 55b4273b9c..a728c6d65e 100644 --- a/spec/cloud_controller_ng/nginx_spec.rb +++ b/spec/cloud_controller_ng/nginx_spec.rb @@ -245,6 +245,29 @@ module Test end end end + + describe 'public_upload.conf' do + let(:template) { job.template('config/public_upload.conf') } + let(:manifest_properties) { {} } + + before do + @rendered_file = template.render(manifest_properties, consumes: {}) + end + + context 'when nginx_client_body_timeout_for_uploads_in_seconds is not configured' do + it 'does not render a client_body_timeout directive' do + expect(@rendered_file).not_to match(/^\s*client_body_timeout/) + end + end + + context 'when nginx_client_body_timeout_for_uploads_in_seconds is configured' do + let(:manifest_properties) { { 'cc' => { 'nginx_client_body_timeout_for_uploads_in_seconds' => 150 } } } + + it 'renders client_body_timeout with the configured value in seconds' do + expect(@rendered_file).to match(/^client_body_timeout 150s;$/) + end + end + end end end end