diff options
author | Alex W <embezzle.dev@proton.me> | 2025-01-27 20:57:27 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-27 22:57:27 +0200 |
commit | 85be7579f4e93f9da06b5e8775b5296be953d422 (patch) | |
tree | 795902fa16a0b7fb284834d88f4c302a4448ac19 | |
parent | d50cdfee916c6d0b5c60c03d589f9292954b6688 (diff) | |
download | vyos-1x-85be7579f4e93f9da06b5e8775b5296be953d422.tar.gz vyos-1x-85be7579f4e93f9da06b5e8775b5296be953d422.zip |
haproxy: T7081: Support HTTP compression (#4314)
-rw-r--r-- | data/templates/load-balancing/haproxy.cfg.j2 | 5 | ||||
-rw-r--r-- | interface-definitions/load-balancing_haproxy.xml.in | 32 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_load-balancing_haproxy.py | 23 | ||||
-rw-r--r-- | src/conf_mode/load-balancing_haproxy.py | 7 |
4 files changed, 67 insertions, 0 deletions
diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 786ebfb21..c98b739e2 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -93,6 +93,11 @@ frontend {{ front }} http-response set-header {{ header }} '{{ header_config['value'] }}' {% endfor %} {% endif %} +{% if front_config.http_compression is vyos_defined %} + filter compression + compression algo {{ front_config.http_compression.algorithm }} + compression type {{ front_config.http_compression.mime_type | join(' ') }} +{% endif %} {% if front_config.rule is vyos_defined %} {% for rule, rule_config in front_config.rule.items() %} # rule {{ rule }} diff --git a/interface-definitions/load-balancing_haproxy.xml.in b/interface-definitions/load-balancing_haproxy.xml.in index 742272436..ca089d3f0 100644 --- a/interface-definitions/load-balancing_haproxy.xml.in +++ b/interface-definitions/load-balancing_haproxy.xml.in @@ -48,6 +48,38 @@ <valueless/> </properties> </leafNode> + <node name="http-compression"> + <properties> + <help>Compress HTTP responses</help> + </properties> + <children> + <leafNode name="algorithm"> + <properties> + <help>Compression algorithm</help> + <completionHelp> + <list>gzip deflate identity raw-deflate</list> + </completionHelp> + <constraint> + <regex>(gzip|deflate|identity|raw-deflate)</regex> + </constraint> + </properties> + </leafNode> + <leafNode name="mime-type"> + <properties> + <help>MIME types to compress</help> + <valueHelp> + <format>txt</format> + <description>MIME type to compress</description> + </valueHelp> + <multi/> + <constraint> + <regex>\w+\/[-+.\w]+</regex> + </constraint> + <constraintErrorMessage>Invalid MIME type specified</constraintErrorMessage> + </properties> + </leafNode> + </children> + </node> <node name="ssl"> <properties> <help>SSL Certificate, SSL Key and CA</help> diff --git a/smoketest/scripts/cli/test_load-balancing_haproxy.py b/smoketest/scripts/cli/test_load-balancing_haproxy.py index 967eb3869..9f412aa95 100755 --- a/smoketest/scripts/cli/test_load-balancing_haproxy.py +++ b/smoketest/scripts/cli/test_load-balancing_haproxy.py @@ -498,5 +498,28 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase): self.assertIn('log /dev/log local5 notice', config) self.assertIn('log /dev/log local6 crit', config) + def test_10_lb_reverse_proxy_http_compression(self): + # Setup base + self.configure_pki() + self.base_config() + + # Configure compression in frontend + self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'algorithm', 'gzip']) + self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'mime-type', 'text/html']) + self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'mime-type', 'text/javascript']) + self.cli_set(base_path + ['service', 'https_front', 'http-compression', 'mime-type', 'text/plain']) + self.cli_commit() + + # Test compression is present in generated configuration file + config = read_file(HAPROXY_CONF) + self.assertIn('filter compression', config) + self.assertIn('compression algo gzip', config) + self.assertIn('compression type text/html text/javascript text/plain', config) + + # Test setting compression without specifying any mime-types fails verification + self.cli_delete(base_path + ['service', 'https_front', 'http-compression', 'mime-type']) + with self.assertRaises(ConfigSessionError) as e: + self.cli_commit() + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/load-balancing_haproxy.py b/src/conf_mode/load-balancing_haproxy.py index 45042dd52..5fd1beec9 100644 --- a/src/conf_mode/load-balancing_haproxy.py +++ b/src/conf_mode/load-balancing_haproxy.py @@ -78,6 +78,13 @@ def verify(lb): not is_listen_port_bind_service(int(tmp_port), 'haproxy'): raise ConfigError(f'"TCP" port "{tmp_port}" is used by another service') + if 'http_compression' in front_config: + if front_config['mode'] != 'http': + raise ConfigError(f'service {front} must be set to http mode to use http-compression!') + if len(front_config['http_compression']['mime_type']) == 0: + raise ConfigError(f'service {front} must have at least one mime-type configured to use' + f'http_compression!') + for back, back_config in lb['backend'].items(): if 'http_check' in back_config: http_check = back_config['http_check'] |