diff --git a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/location.xml b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/location.xml
index 8a8414cb4..b4b76dd60 100644
--- a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/location.xml
+++ b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/location.xml
@@ -242,6 +242,34 @@
trueEnter a custom timout between data received from the client after which the connection is closed.
+
+ location.proxy_buffer_size
+
+ text
+ By default this is the size of one page (4 or 8 Kilobytes). It can be changed.
+ true
+
+
+ location.proxy_buffers_count
+
+ text
+ true
+ Count of buffers for a single connection.
+
+
+ location.proxy_buffers_size
+
+ text
+ true
+ Size of buffers of a single connection
+
+
+ location.proxy_busy_buffers_size
+
+ text
+ true
+ When this buffer size is reached, nginx will send a part of the response to the client.
+ location.proxy_send_timeout
diff --git a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Base/Constraints/NgxBusyBufferConstraint.php b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Base/Constraints/NgxBusyBufferConstraint.php
new file mode 100644
index 000000000..ac100e9f1
--- /dev/null
+++ b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Base/Constraints/NgxBusyBufferConstraint.php
@@ -0,0 +1,96 @@
+getOption('node');
+ if ($node) {
+ $parentNode = $node->getParentNode();
+ if (!$this->isEmpty($node)) {
+ $proxy_buffer_size_node = $parentNode->proxy_buffer_size;
+ $proxy_buffers_count_node = $parentNode->proxy_buffers_count;
+ $proxy_buffers_size_node = $parentNode->proxy_buffers_size;
+ $proxy_busy_buffers_size_node = $parentNode->proxy_busy_buffers_size;
+
+ if(!$this->isEmpty($proxy_buffers_count_node) && !$this->isEmpty($proxy_buffers_size_node)) {
+ $proxy_buffers_count_int = intval((string) $proxy_buffers_count_node);
+ $proxy_buffers_size_int = intval((string) $proxy_buffers_size_node);
+
+ $proxy_buffers_total_minus1_size = ($proxy_buffers_count_int - 1) * $proxy_buffers_size_int;
+ }
+
+ if (!$this->isEmpty($proxy_busy_buffers_size_node)) {
+ $proxy_busy_buffers_size = intval((string) $proxy_busy_buffers_size_node);
+ }
+
+ if (!$this->isEmpty($proxy_buffer_size_node)) {
+ $proxy_buffer_size_int = intval((string) $proxy_buffer_size_node);
+ }
+
+ if (isset($proxy_buffers_total_minus1_size) && isset($proxy_busy_buffers_size) &&
+ $proxy_buffers_total_minus1_size < $proxy_busy_buffers_size) {
+ $validator->appendMessage(new Message(
+ gettext("Proxy Buffer Size must be less than the size of all Proxy Buffers minus one buffer."),
+ $attribute,
+ $this->getOption('name')));
+ }
+
+ // nginx: [emerg] "proxy_busy_buffers_size" must be equal to or greater than the maximum of the value of "proxy_buffer_size" and one of the "proxy_buffers"
+ if (isset($proxy_busy_buffers_size) && isset($proxy_buffers_size_int) &&
+ $proxy_busy_buffers_size < $proxy_buffers_size_int) {
+ $validator->appendMessage(new Message(
+ gettext("Proxy Busy Buffers Size must be equal to or greater than the maximum of one of the Proxy Buffers."),
+ $attribute,
+ $this->getOption('name')));
+ }
+
+ // nginx: [emerg] "proxy_busy_buffers_size" must be equal to or greater than the maximum of the value of "proxy_buffer_size" and one of the "proxy_buffers"
+ if (isset($proxy_busy_buffers_size) && isset($proxy_buffer_size_int) &&
+ $proxy_busy_buffers_size < $proxy_buffer_size_int) {
+ $validator->appendMessage(new Message(
+ gettext("Proxy Busy Buffers Size must be equal to or greater than the maximum of the value of Proxy Buffer Size."),
+ $attribute,
+ $this->getOption('name')));
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml
index aafd17bf6..f6ea27be9 100644
--- a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml
+++ b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml
@@ -367,6 +367,42 @@
Y0
+
+ N
+ 1
+
+
+ NgxBusyBufferConstraint
+
+
+
+
+ N
+ 1
+
+
+ NgxBusyBufferConstraint
+
+
+
+
+ N
+ 1
+
+
+ NgxBusyBufferConstraint
+
+
+
+
+ N
+ 1
+
+
+ NgxBusyBufferConstraint
+
+
+ Y0
diff --git a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf
index 4ed7e97cb..87a6fc7ef 100644
--- a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf
+++ b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf
@@ -87,36 +87,45 @@ location {{ location.matchtype }} {{ location.urlpattern }} {
fastcgi_param TLS-Protocol $ssl_protocol;
fastcgi_param TLS-SNI-Host $ssl_server_name;
fastcgi_param TLS-Client-Intercepted $tls_intercepted;
-{% if server.zero_rtt == '1' %}
+{% if server.zero_rtt == '1' %}
fastcgi_param Early-Data $ssl_early_data;
-{% endif %}
- fastcgi_intercept_errors off;
-{% if location.upstream is not defined %}
- fastcgi_pass unix:/var/run/php-www.socket;
-{% if location.php_override_scriptname is defined and location.php_override_scriptname != '' %}
- fastcgi_param SCRIPT_FILENAME $document_root/{{ location.php_override_scriptname }};
-{% else %}
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
{% endif %}
-{% else %}
+ fastcgi_intercept_errors off;
+{% if location.upstream is not defined %}
+ fastcgi_pass unix:/var/run/php-www.socket;
+{% if location.php_override_scriptname is defined and location.php_override_scriptname != '' %}
+ fastcgi_param SCRIPT_FILENAME $document_root/{{ location.php_override_scriptname }};
+{% else %}
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+{% endif %}
+{% else %}
fastcgi_pass upstream{{ location.upstream.replace('-','') }};
fastcgi_connect_timeout 10s;
-{% if location.php_override_scriptname is defined and location.php_override_scriptname != '' %}
+{% if location.php_override_scriptname is defined and location.php_override_scriptname != '' %}
fastcgi_param SCRIPT_FILENAME {{ location.php_override_scriptname }};
-{% else %}
+{% else %}
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+{% endif %}
{% endif %}
-{% endif %}
{% endif%}
{% if location.upstream is defined and (location.php_enable is not defined or location.php_enable != '1') %}
-{% set upstream = helpers.getUUID(location.upstream) %}
+{% set upstream = helpers.getUUID(location.upstream) %}
proxy_set_header Host $host;
-{% if location.websocket is defined and location.websocket == '1' %}
+{% if location.websocket is defined and location.websocket == '1' %}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
-{% endif %}
-{% if location.cache_path is defined and location.cache_path != '' %}
+{% endif %}
+{% if location.proxy_buffer_size is defined and location.proxy_buffer_size != '' %}
+ proxy_buffer_size {{ location.proxy_buffer_size }}k;
+{% endif %}
+{% if location.proxy_buffers_count is defined and location.proxy_buffers_count != '' and location.proxy_buffers_size is defined and location.proxy_buffers_size != '' %}
+ proxy_buffers {{ location.proxy_buffers_count }} {{ location.proxy_buffers_size }}k;
+{% endif %}
+{% if location.proxy_busy_buffers_size is defined and location.proxy_busy_buffers_size != '' %}
+ proxy_busy_buffers_size {{ location.proxy_busy_buffers_size }}k;
+{% endif %}
+{% if location.cache_path is defined and location.cache_path != '' %}
proxy_cache {{ location.cache_path.replace('-', '') }};
{% if location.cache_use_stale is defined and location.cache_use_stale != '' %}
proxy_cache_use_stale {{ location.cache_use_stale.replace(',', ' ') }};
@@ -131,35 +140,35 @@ location {{ location.matchtype }} {{ location.urlpattern }} {
proxy_set_header X-TLS-Protocol $ssl_protocol;
proxy_set_header X-TLS-SNI-Host $ssl_server_name;
# proxy headers for backend server
-{% if server.verify_client != 'off' %}
+{% if server.verify_client != 'off' %}
proxy_set_header X-Client-Dn $ssl_client_s_dn;
proxy_set_header X-Client-Verify $ssl_client_verify;
-{% endif %}
-{% if server.verify_client == 'optional_no_ca' %}
+{% endif %}
+{% if server.verify_client == 'optional_no_ca' %}
proxy_set_header X-Client-Certificate $ssl_client_escaped_cert;
-{% endif %}
-{% if server.zero_rtt == '1' %}
+{% endif %}
+{% if server.zero_rtt == '1' %}
proxy_set_header Early-Data $ssl_early_data;
-{% endif %}
+{% endif %}
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 X-TLS-Client-Intercepted $tls_intercepted;
-{% if location.proxy_read_timeout is defined and location.proxy_read_timeout != '' %}
+{% if location.proxy_read_timeout is defined and location.proxy_read_timeout != '' %}
proxy_read_timeout {{ location.proxy_read_timeout }}s;
-{% endif %}
-{% if location.proxy_send_timeout is defined and location.proxy_send_timeout != '' %}
+{% endif %}
+{% if location.proxy_send_timeout is defined and location.proxy_send_timeout != '' %}
proxy_send_timeout {{ location.proxy_send_timeout }}s;
-{% endif %}
+{% endif %}
proxy_ignore_client_abort {% if location.proxy_ignore_client_abort == '1' %}on{% else %}off{% endif %};
proxy_request_buffering {% if location.proxy_request_buffering == '1' %}on{% else %}off{% endif %};
proxy_max_temp_file_size {% if location.proxy_max_temp_file_size is defined %}{{ location.proxy_max_temp_file_size }}{% else %}1024{% endif %}m;
proxy_buffering {% if location.proxy_buffering == '1' %}on{% else %}off{% endif %};
-{% if location.path_prefix is defined and location.path_prefix != '' %}
+{% if location.path_prefix is defined and location.path_prefix != '' %}
proxy_pass http{% if upstream.tls_enable == '1' %}s{% endif %}://upstream{{ location.upstream.replace('-','') }}{{ location.path_prefix }};
-{% else %}
+{% else %}
proxy_pass http{% if upstream.tls_enable == '1' %}s{% endif %}://upstream{{ location.upstream.replace('-','') }};
-{% endif %}
+{% endif %}
{% if upstream.tls_enable == '1' %}
{% if upstream.tls_client_certificate is defined and upstream.tls_client_certificate != '' %}
proxy_ssl_certificate_key /usr/local/etc/nginx/key/{{ upstream.tls_client_certificate }}.key;
@@ -190,6 +199,6 @@ location {{ location.matchtype }} {{ location.urlpattern }} {
proxy_hide_header {{ our_header }};
{% endfor %}
{% endif %}
-{% endif %}
+{% endif %}{# honeypod #}
}