From b9ea7116970d9f60077a37843aab7d2e120e968b Mon Sep 17 00:00:00 2001 From: Alex W Date: Sun, 19 May 2024 20:34:04 +0100 Subject: [PATCH] reverse-proxy: T6370: Set custom HTTP headers in reverse-proxy responses --- data/templates/load-balancing/haproxy.cfg.j2 | 10 +++++++ .../haproxy/http-response-headers.xml.i | 29 +++++++++++++++++++ .../load-balancing_reverse-proxy.xml.in | 2 ++ .../cli/test_load-balancing_reverse-proxy.py | 16 ++++++++++ 4 files changed, 57 insertions(+) create mode 100644 interface-definitions/include/haproxy/http-response-headers.xml.i diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 7917c82570e..474c7a79ce1 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -81,6 +81,11 @@ frontend {{ front }} {% endif %} {% endfor %} {% endif %} +{% if front_config.mode == 'http' and front_config.http_response_headers is vyos_defined %} +{% for header, header_config in front_config.http_response_headers.items() %} + http-response set-header {{ header }} '{{ header_config['value'] }}' +{% endfor %} +{% endif %} {% endif %} {% if front_config.rule is vyos_defined %} {% for rule, rule_config in front_config.rule.items() %} @@ -158,6 +163,11 @@ backend {{ back }} {% endif %} {% if back_config.mode is vyos_defined %} mode {{ back_config.mode }} +{% if back_config.mode == 'http' and back_config.http_response_headers is vyos_defined %} +{% for header, header_config in back_config.http_response_headers.items() %} + http-response set-header {{ header }} '{{ header_config['value'] }}' +{% endfor %} +{% endif %} {% endif %} {% if back_config.rule is vyos_defined %} {% for rule, rule_config in back_config.rule.items() %} diff --git a/interface-definitions/include/haproxy/http-response-headers.xml.i b/interface-definitions/include/haproxy/http-response-headers.xml.i new file mode 100644 index 00000000000..9e7ddfd28e4 --- /dev/null +++ b/interface-definitions/include/haproxy/http-response-headers.xml.i @@ -0,0 +1,29 @@ + + + + Headers to include in HTTP response + + txt + HTTP header name + + + [-a-zA-Z]+ + + Header names must only include alphabetical characters and hyphens + + + + + HTTP header value + + txt + HTTP header value + + + [[:ascii:]]{1,256} + + + + + + diff --git a/interface-definitions/load-balancing_reverse-proxy.xml.in b/interface-definitions/load-balancing_reverse-proxy.xml.in index 6a3b3cef1ce..011e1b53c69 100644 --- a/interface-definitions/load-balancing_reverse-proxy.xml.in +++ b/interface-definitions/load-balancing_reverse-proxy.xml.in @@ -39,6 +39,7 @@ #include #include #include + #include Redirect HTTP to HTTPS @@ -90,6 +91,7 @@ #include #include + #include Backend parameters diff --git a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py index c8b17316f95..e3b47394168 100755 --- a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py +++ b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py @@ -385,5 +385,21 @@ def test_06_lb_reverse_proxy_tcp_mode(self): self.assertIn(f'mode {mode}', config) self.assertIn(f'server {bk_name} {bk_server}:{bk_server_port}', config) + def test_07_lb_reverse_proxy_http_response_headers(self): + # Setup base + self.configure_pki() + self.base_config() + + # Set example headers in both frontend and backend + self.cli_set(base_path + ['service', 'https_front', 'http-response-headers', 'Cache-Control', 'value', 'max-age=604800']) + self.cli_set(base_path + ['backend', 'bk-01', 'http-response-headers', 'Proxy-Backend-ID', 'value', 'bk-01']) + self.cli_commit() + + # Test headers are present in generated configuration file + config = read_file(HAPROXY_CONF) + self.assertIn('http-response set-header Cache-Control \'max-age=604800\'', config) + self.assertIn('http-response set-header Proxy-Backend-ID \'bk-01\'', config) + + if __name__ == '__main__': unittest.main(verbosity=2)