diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile
index bc5ac0c84..fc7cf3517 100644
--- a/net/haproxy/Makefile
+++ b/net/haproxy/Makefile
@@ -1,5 +1,5 @@
PLUGIN_NAME= haproxy
-PLUGIN_VERSION= 5.0
+PLUGIN_VERSION= 5.1
PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer
PLUGIN_DEPENDS= haproxy py${PLUGIN_PYTHON}-haproxy-cli
PLUGIN_MAINTAINER= opnsense@moov.de
diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr
index 75ae2c0e4..48c8151c5 100644
--- a/net/haproxy/pkg-descr
+++ b/net/haproxy/pkg-descr
@@ -6,6 +6,15 @@ very high loads while needing persistence or Layer7 processing.
Plugin Changelog
================
+5.1
+
+Added:
+* more conditions have support for converters
+* add support for mapfile URLs (#4825)
+
+Fixed:
+* migration fails if a http-request/-response "lua" rule is configured
+
5.0
WARNING: This is a new major release, which may result in
diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml
index 8c7d74b41..23a439474 100644
--- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml
+++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml
@@ -21,6 +21,12 @@
mapfile.content
textbox
- HAProxy documentation for a full description.]]>
+ HAProxy documentation for a full description.]]>
+
+
+ mapfile.url
+
+ text
+
diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml
index b6ee4174e..4d0ae9b9b 100644
--- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml
+++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml
@@ -3646,6 +3646,7 @@
do-log
do-resolve
early-hint
+ lua
normalize-uri
redirect
reject
@@ -3689,7 +3690,7 @@
track-sc1
track-sc2
unset-var
- use-service
+ use-service - use a lua service
wait-for-body
wait-for-handshake
@@ -3711,6 +3712,7 @@
del-map
deny
do-log
+ lua
redirect
replace-header
replace-value
@@ -3804,7 +3806,7 @@
content track-sc1
content track-sc2
content unset-var
- content use-service
+ content use-service - use a lua service
inspect-delay
session accept
session attach-srv
@@ -4363,8 +4365,12 @@
- Y
+ N
+
+ /^.{1,4096}$/u
+ N
+
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php
index fe2e682f7..eebeaa773 100755
--- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php
@@ -2,7 +2,7 @@
OPNsense->HAProxy->mapfiles)) {
foreach ($configObj->OPNsense->HAProxy->mapfiles->children() as $mapfile) {
$mf_name = (string)$mapfile->name;
$mf_id = (string)$mapfile->id;
+ $mf_url = (string)$mapfile->url;
if ($mf_id != "") {
- $mf_content = htmlspecialchars_decode(str_replace("\r", "", (string)$mapfile->content));
$mf_filename = $export_path . $mf_id . ".txt";
- file_put_contents($mf_filename, $mf_content);
- chmod($mf_filename, 0600);
- echo "map file exported to " . $mf_filename . "\n";
+ // Download file from URL (if URL was provided).
+ try {
+ if ($mf_url == "") {
+ throw new \Exception("no URL provided");
+ }
+ $fp = fopen($mf_filename, 'wb');
+ if ($fp === false) {
+ throw new \Exception("unable to open {$mf_filename} for writing");
+ }
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $mf_url);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 60);
+ curl_setopt($ch, CURLOPT_FAILONERROR, true);
+ curl_setopt($ch, CURLOPT_FILE, $fp);
+
+ if (!curl_exec($ch)) {
+ throw new \Exception("download error: " . curl_error($ch));
+ }
+ echo "map file downloaded to " . $mf_filename . "\n";
+ } catch (\Exception $e) {
+ // Show error message only if URL was specified.
+ if ($mf_url != "") {
+ echo "download of map file failed, error: " . $e->getMessage() . "\n";
+ echo "trying to fill map file with fallback content\n";
+ $mf_content = "# NOTE: Download failed, this is the fallback content.\n";
+ } else {
+ $mf_content = '';
+ }
+
+ // Write contents to map file.
+ // This is also used as a fallback if map file download fails.
+ $mf_content = $mf_content . htmlspecialchars_decode(str_replace("\r", "", (string)$mapfile->content));
+ file_put_contents($mf_filename, $mf_content);
+ echo "map file exported to " . $mf_filename . "\n";
+ } finally {
+ if (isset($ch)) {
+ curl_close($ch);
+ }
+ if (isset($fp) && is_resource($fp)) {
+ fclose($fp);
+ }
+ chmod($mf_filename, 0600);
+ chown($mf_filename, 'www');
+ }
}
}
}
diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
index e722821ee..2e9c90d76 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
@@ -448,7 +448,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_conn_cnt(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_conn_cnt_comparison ~ ' ' ~ acl_data.sc_conn_cnt) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_conn_cnt(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_conn_cnt_comparison ~ ' ' ~ acl_data.sc_conn_cnt) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -460,7 +465,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_conn_cur(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_conn_cur_comparison ~ ' ' ~ acl_data.sc_conn_cur) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_conn_cur(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_conn_cur_comparison ~ ' ' ~ acl_data.sc_conn_cur) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -472,7 +482,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_conn_rate(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_conn_rate_comparison ~ ' ' ~ acl_data.sc_conn_rate) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_conn_rate(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_conn_rate_comparison ~ ' ' ~ acl_data.sc_conn_rate) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -784,7 +799,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_http_err_cnt(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_http_err_cnt_comparison ~ ' ' ~ acl_data.sc_http_err_cnt) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_http_err_cnt(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_http_err_cnt_comparison ~ ' ' ~ acl_data.sc_http_err_cnt) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -796,7 +816,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_http_err_rate(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_http_err_rate_comparison ~ ' ' ~ acl_data.sc_http_err_rate) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_http_err_rate(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_http_err_rate_comparison ~ ' ' ~ acl_data.sc_http_err_rate) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -808,7 +833,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_http_fail_cnt(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_http_fail_cnt_comparison ~ ' ' ~ acl_data.sc_http_fail_cnt) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_http_fail_cnt(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_http_fail_cnt_comparison ~ ' ' ~ acl_data.sc_http_fail_cnt) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -820,7 +850,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_http_fail_rate(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_http_fail_rate_comparison ~ ' ' ~ acl_data.sc_http_fail_rate) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_http_fail_rate(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_http_fail_rate_comparison ~ ' ' ~ acl_data.sc_http_fail_rate) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -832,7 +867,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_http_req_cnt(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_http_req_cnt_comparison ~ ' ' ~ acl_data.sc_http_req_cnt) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_http_req_cnt(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_http_req_cnt_comparison ~ ' ' ~ acl_data.sc_http_req_cnt) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -844,7 +884,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_http_req_rate(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_http_req_rate_comparison ~ ' ' ~ acl_data.sc_http_req_rate) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_http_req_rate(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_http_req_rate_comparison ~ ' ' ~ acl_data.sc_http_req_rate) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -964,7 +1009,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_sess_cnt(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_sess_cnt_comparison ~ ' ' ~ acl_data.sc_sess_cnt) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_sess_cnt(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_sess_cnt_comparison ~ ' ' ~ acl_data.sc_sess_cnt) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters
@@ -976,7 +1026,12 @@
{% else %}
{% set table_data = '' %}
{% endif %}
-{% do acl_options.append('sc_sess_rate(' ~ acl_data.sc_number ~ table_data ~ ') ' ~ acl_data.sc_sess_rate_comparison ~ ' ' ~ acl_data.sc_sess_rate) %}
+{% if acl_data.converter|default("") != "" %}
+{% set converter_data = ',' ~ acl_data.converter %}
+{% else %}
+{% set converter_data = '' %}
+{% endif %}
+{% do acl_options.append('sc_sess_rate(' ~ acl_data.sc_number ~ table_data ~ ')' ~ converter_data ~ ' ' ~ acl_data.sc_sess_rate_comparison ~ ' ' ~ acl_data.sc_sess_rate) %}
{% else %}
{% set acl_enabled = '0' %}
# ERROR: missing parameters