aboutsummaryrefslogtreecommitdiffstats
path: root/config/haproxy-devel
diff options
context:
space:
mode:
authormarcelloc <marcellocoutinho@gmail.com>2013-02-22 11:29:44 -0300
committermarcelloc <marcellocoutinho@gmail.com>2013-02-22 11:29:44 -0300
commit53eb86fcb96be2cf952153f285f42e92820b0fc5 (patch)
tree47c56d1c0d555f1fbc97f2134b340e9232065460 /config/haproxy-devel
parent478636ec059cfba7b796d35309ea2562b3051fe1 (diff)
downloadpfsense-packages-53eb86fcb96be2cf952153f285f42e92820b0fc5.tar.gz
pfsense-packages-53eb86fcb96be2cf952153f285f42e92820b0fc5.tar.bz2
pfsense-packages-53eb86fcb96be2cf952153f285f42e92820b0fc5.zip
haproxy-devel - package version to haproxy 1.5 devel with ssl offloading
Diffstat (limited to 'config/haproxy-devel')
-rw-r--r--config/haproxy-devel/haproxy.inc440
-rw-r--r--config/haproxy-devel/haproxy.xml114
-rwxr-xr-xconfig/haproxy-devel/haproxy_frontend.xml225
-rwxr-xr-xconfig/haproxy-devel/haproxy_frontends.php149
-rwxr-xr-xconfig/haproxy-devel/haproxy_frontends_edit.php768
-rwxr-xr-xconfig/haproxy-devel/haproxy_global.php328
-rwxr-xr-xconfig/haproxy-devel/haproxy_servers.php169
-rwxr-xr-xconfig/haproxy-devel/haproxy_servers_edit.php435
8 files changed, 2628 insertions, 0 deletions
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc
new file mode 100644
index 00000000..9fbb606d
--- /dev/null
+++ b/config/haproxy-devel/haproxy.inc
@@ -0,0 +1,440 @@
+<?php
+/*
+ haproxy.inc
+ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
+ Copyright (C) 2008 Remco Hoef
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* include all configuration functions */
+require_once("functions.inc");
+require_once("pkg-utils.inc");
+require_once("notices.inc");
+
+$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+
+function haproxy_custom_php_deinstall_command() {
+ exec("rm /usr/local/sbin/haproxy");
+ exec("rm /usr/local/pkg/haproxy.inc");
+ exec("rm /usr/local/www/haproxy*");
+}
+
+function haproxy_custom_php_install_command() {
+ global $g, $config;
+ conf_mount_rw();
+
+ $haproxy = <<<EOD
+#!/bin/sh
+
+# PROVIDE: haproxy
+# REQUIRE: LOGIN
+# KEYWORD: FreeBSD
+
+. /etc/rc.subr
+
+name="haproxy"
+rcvar=`set_rcvar`
+command="/usr/local/bin/haproxy"
+haproxy_enable=\${haproxy-"YES"}
+
+start_cmd="haproxy_start"
+stop_postcmd="haproxy_stop"
+
+load_rc_config \$name
+
+haproxy_start () {
+ echo "Starting haproxy."
+ /usr/bin/env \
+ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
+ /usr/local/bin/php -q -d auto_prepend_file=config.inc <<ENDOFF
+ <?php
+ require_once("globals.inc");
+ require_once("functions.inc");
+ require_once("haproxy.inc");
+ haproxy_configure();
+ ?>
+ENDOFF
+}
+
+haproxy_stop () {
+ echo "Stopping haproxy."
+ killall haproxy
+}
+
+run_rc_command "\$1"
+
+EOD;
+
+ $fd = fopen("/usr/local/etc/rc.d/haproxy.sh", "w");
+ fwrite($fd, $haproxy);
+ fclose($fd);
+ exec("chmod a+rx /usr/local/etc/rc.d/haproxy.sh");
+
+ conf_mount_ro();
+
+ exec("/usr/local/etc/rc.d/haproxy.sh start");
+}
+
+function haproxy_configure() {
+ global $config, $g;
+
+ $a_global = &$config['installedpackages']['haproxy'];
+ $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+ $a_frontends = &$config['installedpackages']['haproxy']['ha_frontends']['item'];
+ $a_servers = &$config['installedpackages']['haproxy']['ha_servers']['item'];
+
+ $fd = fopen("{$g['varetc_path']}/haproxy.cfg", "w");
+
+ if(is_array($a_global)) {
+ fwrite ($fd, "global\n");
+ if($a_global['advanced'])
+ fwrite ($fd, "\t" . base64_decode($a_global['advanced']) . "\n");
+ fwrite ($fd, "\tmaxconn\t\t\t".$a_global['maxconn']."\n");
+ if($a_global['remotesyslog'])
+ fwrite ($fd, "\tlog\t\t\t{$a_global['remotesyslog']}\tlocal0\n");
+ fwrite ($fd, "\tuid\t\t\t80\n");
+ fwrite ($fd, "\tgid\t\t\t80\n");
+ // Set numprocs if defined or use system default (#cores)
+ if($a_global['nbproc'])
+ $numprocs = $a_global['nbproc'];
+ else
+ $numprocs = trim(`/sbin/sysctl kern.smp.cpus | cut -d" " -f2`);
+ fwrite ($fd, "\tnbproc\t\t\t$numprocs\n");
+ fwrite ($fd, "\tchroot\t\t\t/var/empty\n");
+ fwrite ($fd, "\tdaemon\n");
+ fwrite ($fd, "\n");
+ }
+
+ // Construct and write out configuration file
+ if(is_array($a_backends)) {
+ foreach ($a_backends as $backend) {
+ //check ssl info
+ if ($backend['ssloffload']){
+ //ssl crt ./server.pem ca-file ./ca.crt verify optional crt-ignore-err all crl-file ./ca_crl.pem
+ $ssl_info="ssl crt /var/etc/{$backend['name']}.{$backend['port']}.crt {$backend['dcertadv']}";
+ file_put_contents("/var/etc/{$backend['name']}.{$backend['port']}.crt",base64_decode($backend['dcert']));
+ }else{
+ $ssl_info="";
+ unlink_if_exists("var/etc/{$backend['name']}.{$backend['port']}.crt");
+ }
+ // Define our backend name
+ $backendinfo = "listen {$backend['name']}\n";
+
+ // Prepare ports for processing by splitting
+ $portss = "{$backend['port']},";
+ $ports = split(",", $portss);
+
+ // Initialize variable
+ $listenip = "";
+
+ // Process and add bind directives for ports
+ foreach($ports as $port) {
+ if($port) {
+ if($backend['extaddr'] == "any")
+ $listenip .= "\tbind\t\t\t0.0.0.0:{$port} {$ssl_info}\n";
+ elseif($backend['extaddr'])
+ $listenip .= "\tbind\t\t\t{$backend['extaddr']}:{$port} {$ssl_info}\n";
+ else
+ $listenip .= "\tbind\t\t\t" . get_current_wan_address('wan') . ":{$port} {$ssl_info}\n";
+ }
+ }
+
+ fwrite ($fd, "{$backendinfo}");
+ fwrite ($fd, "{$listenip}");
+
+ // Advanced pass thru
+ if($backend['advanced']) {
+ $advanced = base64_decode($backend['advanced']);
+ fwrite($fd, "\t" . $advanced . "\n");
+ }
+
+ // https is an alias for tcp for clarity purpouses
+ if(strtolower($backend['type']) == "https") {
+ $backend_type = "tcp";
+ $httpchk = "ssl-hello-chk";
+ } else {
+ $backend_type = $backend['type'];
+ $httpchk = "httpchk";
+ }
+
+ fwrite ($fd, "\tmode\t\t\t" . $backend_type . "\n");
+ fwrite ($fd, "\tlog\t\t\tglobal\n");
+ fwrite ($fd, "\toption\t\t\tdontlognull\n");
+
+ if($backend['httpclose'])
+ fwrite ($fd, "\toption\t\t\thttpclose\n");
+
+ if($backend['forwardfor'])
+ fwrite ($fd, "\toption\t\t\tforwardfor\n");
+
+ if($backend['max_connections'])
+ fwrite ($fd, "\tmaxconn\t\t\t" . $backend['max_connections'] . "\n");
+
+ if($backend['client_timeout'])
+ fwrite ($fd, "\tclitimeout\t\t" . $backend['client_timeout'] . "\n");
+
+ if($backend['balance'])
+ fwrite ($fd, "\tbalance\t\t\t" . $backend['balance'] . "\n");
+
+ if($backend['connection_timeout'])
+ fwrite ($fd, "\tcontimeout\t\t" . $backend['connection_timeout'] . "\n");
+
+ if($backend['server_timeout'])
+ fwrite ($fd, "\tsrvtimeout\t\t" . $backend['server_timeout'] . "\n");
+
+ if($backend['retries'])
+ fwrite ($fd, "\tretries\t\t\t" . $backend['retries'] . "\n");
+
+ if($backend['cookie_name'])
+ fwrite ($fd, "\tcookie\t\t\t" . $backend['cookie_name'] . " insert indirect\n");
+
+ if($backend['monitor_uri'])
+ fwrite ($fd, "\toption\t\t\t{$httpchk} HEAD " . $backend['monitor_uri'] . " HTTP/1.0\n");
+
+ if($backend['stats_enabled']=='yes') {
+ fwrite ($fd, "\tstats\t\t\tenable\n");
+ if($backend['stats_uri'])
+ fwrite ($fd, "\tstats\t\t\turi ".$backend['stats_uri']."\n");
+ if($backend['stats_realm'])
+ fwrite ($fd, "\tstats\t\t\trealm " . $backend['stats_realm'] . "\n");
+ else
+ fwrite ($fd, "\tstats\t\t\trealm .\n");
+ fwrite ($fd, "\tstats\t\t\tauth " . $backend['stats_username'].":". $backend['stats_password']."\n");
+ if($backend['stats_node_enabled']=='yes')
+ fwrite ($fd, "\tstats\t\t\tshow-node " . $backend['stats_node'] . "\n");
+ if($backend['stats_desc'])
+ fwrite ($fd, "\tstats\t\t\tshow-desc " . $backend['stats_desc'] . "\n");
+ if($backend['stats_refresh'])
+ fwrite ($fd, "\tstats\t\t\trefresh " . $backend['stats_refresh'] . "\n");
+ }
+
+ $a_acl=&$frontend['ha_acls']['item'];
+ if(!is_array($a_acl))
+ $a_acl=array();
+
+ foreach ($a_acl as $acl)
+ fwrite ($fd, "\tacl\t\t\t".$acl['name']."\t\t".$acl['expression']."\n");
+
+ $server['backend'] .= " ";
+ if(is_array($a_servers)) {
+ foreach ($a_servers as $server) {
+ $backends_to_process = split(" ", $server['backend']);
+ foreach($backends_to_process as $backends) {
+ if($backends == "")
+ continue;
+ if($backends == $backend['name']) {
+ $server_ports = array();
+ if($server['status'] != 'inactive') {
+ if($server['cookie'])
+ $cookie = " cookie {$server['cookie']} ";
+ else
+ $cookie = "";
+ if(!$server['port']) {
+ foreach($ports as $port) {
+ if($port)
+ $server_ports[] = $port;
+ }
+ } else {
+ $server_ports[] = $server['port'];
+ }
+ if($server['advanced']) {
+ $advanced = base64_decode($server['advanced']);
+ $advanced_txt = " " . $advanced;
+ } else {
+ $advanced_txt = "";
+ }
+ if($server['status'] != 'active') {
+ $status = " " . $server['status'];
+ } else {
+ $status = "";
+ }
+ if($server['checkinter'])
+ $checkinter = "check inter {$server['checkinter']}";
+ else
+ $checkinter = "check inter 1000";
+ foreach($server_ports as $pport)
+ fwrite ($fd, "\tserver\t\t\t" . $server['name'] . " " . $server['address'].":" . $pport . " $cookie " . " $checkinter weight " . $server['weight'] . $status . "{$advanced_txt}\n");
+ }
+ }
+ }
+ }
+ }
+ fwrite ($fd, "\n");
+ }
+ // Sync HAProxy configuration (if enabled)
+ if(isset($config['installedpackages']['haproxy']['enablesync'])) {
+ if($config['installedpackages']['haproxy']['synchost1']) {
+ haproxy_do_xmlrpc_sync($config['installedpackages']['haproxy']['synchost1'],
+ $config['installedpackages']['haproxy']['syncpassword']);
+ }
+ if($config['installedpackages']['haproxy']['synchost2']) {
+ haproxy_do_xmlrpc_sync($config['installedpackages']['haproxy']['synchost2'],
+ $config['installedpackages']['haproxy']['syncpassword']);
+ }
+ if($config['installedpackages']['haproxy']['synchost3']) {
+ haproxy_do_xmlrpc_sync($config['installedpackages']['haproxy']['synchost3'],
+ $config['installedpackages']['haproxy']['syncpassword']);
+ }
+ }
+ }
+
+ // create config file
+ fclose($fd);
+
+ $freebsd_version = substr(trim(`uname -r`), 0, 1);
+ if(!file_exists("/usr/bin/limits")) {
+ exec("fetch -q -o /usr/bin/limits http://files.pfsense.org/extras/{$freebsd_version}/limits");
+ exec("chmod a+rx /usr/bin/limits");
+ }
+
+ exec("/usr/bin/limits -n 300014");
+
+ // reload haproxy
+ if(isset($a_global['enable'])) {
+ if(is_process_running('haproxy')) {
+ exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -st `cat /var/run/haproxy.pid`");
+ } else {
+ exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -D");
+ }
+ return (0);
+ } else {
+ return (1);
+ }
+}
+
+function haproxy_do_xmlrpc_sync($sync_to_ip, $password) {
+ global $config, $g;
+
+ if(!$password)
+ return;
+
+ if(!$sync_to_ip)
+ return;
+
+ // Do not allow syncing to self.
+ $donotsync = false;
+ $lanip = find_interface_ip($config['interfaces']['lan']['if']);
+ if($lanip == $sync_to_ip)
+ $donotsync = true;
+ $wanip = find_interface_ip($config['interfaces']['wan']['if']);
+ if($wanip == $sync_to_ip)
+ $donotsync = true;
+ for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+ $optip = find_interface_ip($config['interfaces']['opt' . $j]['if']);
+ if($optip == $sync_to_ip)
+ $donotsync = true;
+ }
+ if($donotsync) {
+ log_error("Disallowing sync loop for HAProxy sync.");
+ return;
+ }
+
+ $xmlrpc_sync_neighbor = $sync_to_ip;
+ if($config['system']['webgui']['protocol'] != "") {
+ $synchronizetoip = $config['system']['webgui']['protocol'];
+ $synchronizetoip .= "://";
+ }
+ $port = $config['system']['webgui']['port'];
+ /* if port is empty lets rely on the protocol selection */
+ if($port == "") {
+ if($config['system']['webgui']['protocol'] == "http")
+ $port = "80";
+ else
+ $port = "443";
+ }
+ $synchronizetoip .= $sync_to_ip;
+
+ /* xml will hold the sections to sync */
+ $xml = array();
+ $xml['haproxy'] = $config['installedpackages']['haproxy'];
+
+ // Prevent sync loops
+ unset($xml['haproxy']['synchost1']);
+ unset($xml['haproxy']['synchost2']);
+ unset($xml['haproxy']['synchost3']);
+ unset($xml['haproxy']['syncpassword']);
+
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($xml)
+ );
+
+ /* set a few variables needed for sync code borrowed from filter.inc */
+ $url = $synchronizetoip;
+ log_error("Beginning HAProxy XMLRPC sync to {$url}:{$port}.");
+ $method = 'pfsense.merge_installedpackages_section_xmlrpc';
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials('admin', $password);
+ if($g['debug'])
+ $cli->setDebug(1);
+ /* send our XMLRPC message and timeout after 250 seconds */
+ $resp = $cli->send($msg, "250");
+ if(!$resp) {
+ $error = "A communications error occurred while attempting HAProxy XMLRPC sync with {$url}:{$port}.";
+ log_error($error);
+ file_notice("sync_settings", $error, "HAProxy Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, "250");
+ $error = "An error code was received while attempting HAProxy XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "HAProxy Settings Sync", "");
+ } else {
+ log_error("HAProxy XMLRPC sync successfully completed with {$url}:{$port}.");
+ }
+
+ /* tell haproxy to reload our settings on the destionation sync host. */
+ $method = 'pfsense.exec_php';
+ $execcmd = "require_once('/usr/local/pkg/haproxy.inc');\n";
+ $execcmd .= "haproxy_configure();\n";
+
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($execcmd)
+ );
+
+ log_error("HAProxy XMLRPC reload data {$url}:{$port}.");
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials('admin', $password);
+ $resp = $cli->send($msg, "250");
+ if(!$resp) {
+ $error = "A communications error occurred while attempting HAProxy XMLRPC sync with {$url}:{$port} (pfsense.exec_php).";
+ log_error($error);
+ file_notice("sync_settings", $error, "HAProxy Settings Reload", "");
+ } elseif($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, "250");
+ $error = "An error code was received while attempting HAProxy XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "HAProxy Settings Sync", "");
+ } else {
+ log_error("HAProxy XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php).");
+ }
+}
+
+?>
diff --git a/config/haproxy-devel/haproxy.xml b/config/haproxy-devel/haproxy.xml
new file mode 100644
index 00000000..a7166d6f
--- /dev/null
+++ b/config/haproxy-devel/haproxy.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ haproxy.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2009 Scott Ullrich
+ Copyright (C) 2013 Marcello Coutinho
+ All rights reserved.
+ */
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>haproxy</name>
+ <version>1.0</version>
+ <title>HAProxy</title>
+ <aftersaveredirect>/pkg_edit.php?xml=haproxy_servers.php</aftersaveredirect>
+ <include_file>/usr/local/pkg/haproxy.inc</include_file>
+ <menu>
+ <name>HAProxy</name>
+ <tooltiptext></tooltiptext>
+ <section>Services</section>
+ <url>/haproxy_global.php</url>
+ </menu>
+ <service>
+ <name>HAProxy</name>
+ <rcfile>haproxy.sh</rcfile>
+ <executable>haproxy</executable>
+ <description>The Reliable, High Performance TCP/HTTP Load Balancer</description>
+ </service>
+ <configpath>installedpackages->haproxy->config</configpath>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_frontends.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_frontends_edit.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_global.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_servers.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_servers_edit.php</item>
+ </additional_files_needed>
+ <custom_delete_php_command>
+ </custom_delete_php_command>
+ <custom_add_php_command>
+ </custom_add_php_command>
+ <custom_php_resync_config_command>
+ </custom_php_resync_config_command>
+ <custom_php_install_command>
+ /*
+ included in package install
+ $freebsdv=trim(`uname -r | cut -d'.' -f1`);
+ conf_mount_rw();
+ `fetch -q -o /usr/local/sbin/ http://www.pfsense.org/packages/config/haproxy-devel/binaries{$freebsdv}/haproxy`;
+ exec("chmod a+rx /usr/local/sbin/haproxy");
+ */
+ haproxy_custom_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ haproxy_custom_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_command_before_form>
+ </custom_php_command_before_form>
+</packagegui> \ No newline at end of file
diff --git a/config/haproxy-devel/haproxy_frontend.xml b/config/haproxy-devel/haproxy_frontend.xml
new file mode 100755
index 00000000..fc31306e
--- /dev/null
+++ b/config/haproxy-devel/haproxy_frontend.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* ========================================================================== */
+/*
+ haproxy_frontend.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2013 Marcello Coutinho
+
+ All rights reserved.
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code MUST retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>haproxyfrontend</name>
+ <version>1.0</version>
+ <title>Services: HaProxy - Frontend Lists</title>
+ <include_file>/usr/local/pkg/haproxy.inc</include_file>
+ <tabs>
+<tab>
+ <text>Settings</text>
+ <url>/haproxy_global.php</url>
+ </tab>
+ <tab>
+ <text>General</text>
+ <url>/pkg.php?xml=haproxy_frontend.xml</url>
+ </tab>
+ <tab>
+ <text>Servers</text>
+ <url>/haproxy_servers.php</url>
+ </tab>
+</tabs>
+<adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Name</fielddescr>
+ <fieldname>name</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Description</fielddescr>
+ <fieldname>description</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Stats URI</fielddescr>
+ <fieldname>uri</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Type</fielddescr>
+ <fieldname>type</fieldname>
+ </columnitem>
+ <movable>on</movable>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <name>Site Access Lists</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Name</fielddescr>
+ <fieldname>name</fieldname>
+ <description></description>
+ <type>input</type>
+ <size>25</size>
+ </field>
+ <field>
+ <fielddescr>description</fielddescr>
+ <fieldname>description</fieldname>
+ <type>input</type>
+ <size>80</size>
+ </field>
+ <field>
+ <name>Banned</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Enable</fielddescr>
+ <fieldname>bannedsite_enabled</fieldname>
+ <type>checkbox</type>
+ <description></description>
+ </field>
+ <field>
+ <fielddescr>Include</fielddescr>
+ <fieldname>banned_includes</fieldname>
+ <description><![CDATA[Select Include files to banned phrase filter.]]></description>
+ <type>select_source</type>
+ <source><![CDATA[$config['installedpackages']['dansguardianblacklistsdomains']['config']]]></source>
+ <source_name>descr</source_name>
+ <source_value>file</source_value>
+ <multiple/>
+ <size>6</size>
+ </field>
+ <field>
+ <fielddescr>Config</fielddescr>
+ <fieldname>banned_sitelist</fieldname>
+ <description><![CDATA[Enter Banned Site List for this group.<br>
+ Leave empty to load dansguardian defaults]]></description>
+ <type>textarea</type>
+ <cols>80</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <name>Grey</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Enable</fielddescr>
+ <fieldname>greysite_enabled</fieldname>
+ <type>checkbox</type>
+ <description></description>
+ </field>
+ <field>
+ <fielddescr>Config</fielddescr>
+ <fieldname>grey_sitelist</fieldname>
+ <description><![CDATA[Enter Weighted Site List for this group.<br>
+ Leave empty to load dansguardian defaults]]></description>
+ <type>textarea</type>
+ <cols>80</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <name>Exception</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Enable</fielddescr>
+ <fieldname>exceptionsite_enabled</fieldname>
+ <type>checkbox</type>
+ <description></description>
+ </field>
+ <field>
+ <fielddescr>Include</fielddescr>
+ <fieldname>exception_includes</fieldname>
+ <description><![CDATA[Select Include files to exception site lists.]]></description>
+ <type>select_source</type>
+ <source><![CDATA[$config['installedpackages']['dansguardianwhitelistsdomains']['config']]]></source>
+ <source_name>descr</source_name>
+ <source_value>file</source_value>
+ <multiple/>
+ <size>5</size>
+ </field>
+ <field>
+ <fielddescr>Config</fielddescr>
+ <fieldname>exception_sitelist</fieldname>
+ <description><![CDATA[Enter exception Site List for this group.<br>
+ Leave empty to load dansguardian defaults]]></description>
+ <type>textarea</type>
+ <cols>80</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <fielddescr>File</fielddescr>
+ <fieldname>exceptionfile_sitelist</fieldname>
+ <description><![CDATA[Enter exception File Site List for this group.<br>
+ Leave empty to load dansguardian defaults]]></description>
+ <type>textarea</type>
+ <cols>80</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <name>Log</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Enable</fielddescr>
+ <fieldname>logsite_enabled</fieldname>
+ <type>checkbox</type>
+ <description></description>
+ </field>
+ <field>
+ <fielddescr>Config</fielddescr>
+ <fieldname>log_sitelist</fieldname>
+ <description><![CDATA[Enter log only site List for this group.<br>
+ Leave empty to load dansguardian defaults]]></description>
+ <type>textarea</type>
+ <cols>80</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+
+ </fields>
+ <custom_php_install_command>
+ dansguardian_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ dansguardian_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ dansguardian_validate_input($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ sync_package_dansguardian();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/haproxy-devel/haproxy_frontends.php b/config/haproxy-devel/haproxy_frontends.php
new file mode 100755
index 00000000..11a1e8c6
--- /dev/null
+++ b/config/haproxy-devel/haproxy_frontends.php
@@ -0,0 +1,149 @@
+<?php
+/* $Id: load_balancer_virtual_server.php,v 1.6.2.1 2006/01/02 23:46:24 sullrich Exp $ */
+/*
+ haproxy_baclkends.php
+ part of pfSense (http://www.pfsense.com/)
+ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
+ Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code MUST retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("guiconfig.inc");
+
+$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+
+require_once("haproxy.inc");
+
+if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
+ $config['installedpackages']['haproxy']['ha_backends']['item'] = array();
+}
+$a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+
+if ($_POST) {
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ config_lock();
+ $retval = haproxy_configure();
+ config_unlock();
+ $savemsg = get_std_save_message($retval);
+ unlink_if_exists($d_haproxyconfdirty_path);
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_backend[$_GET['id']]) {
+ if (!$input_errors) {
+ unset($a_backend[$_GET['id']]);
+ write_config();
+ touch($d_haproxyconfdirty_path);
+ header("Location: haproxy_frontends.php");
+ exit;
+ }
+ }
+}
+
+$pfSversion = str_replace("\n", "", file_get_contents("/etc/version"));
+if(strstr($pfSversion, "1.2"))
+ $one_two = true;
+
+$pgtitle = "Services: HAProxy: Frontend";
+include("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<form action="haproxy_frontends.php" method="post">
+<?php if($one_two): ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<?php endif; ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_haproxyconfdirty_path)): ?><p>
+<?php print_info_box_np("The virtual server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td class="tabnavtbl">
+ <?php
+ /* active tabs */
+ $tab_array = array();
+ $tab_array[] = array("Settings", false, "haproxy_global.php");
+ $tab_array[] = array("Frontends", true, "haproxy_frontends.php");
+ $tab_array[] = array("Servers", false, "haproxy_servers.php");
+ display_top_tabs($tab_array);
+ ?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">Name</td>
+ <td width="40%" class="listhdrr">Description</td>
+ <td width="10%" class="listhdrr">Stats URI</td>
+ <td width="10%" class="listhdrr">Type</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_backend as $backend): ?>
+ <tr>
+ <td class="listlr" ondblclick="document.location='haproxy_frontends_edit.php?id=<?=$i;?>';">
+ <?=$backend['name'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_frontends_edit.php?id=<?=$i;?>';">
+ <?=$backend['desc'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_frontends_edit.php?id=<?=$i;?>';">
+ <?=$backend['stats_uri'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_frontends_edit.php?id=<?=$i;?>';">
+ <?=$backend['type'];?>
+ </td>
+ <td class="list" nowrap>
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
+ <td valign="middle"><a href="haproxy_frontends_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td>
+ <td valign="middle"><a href="haproxy_frontends.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4"></td>
+ <td class="list">
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
+ <td valign="middle"><a href="haproxy_frontends_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/haproxy-devel/haproxy_frontends_edit.php b/config/haproxy-devel/haproxy_frontends_edit.php
new file mode 100755
index 00000000..c0c634b0
--- /dev/null
+++ b/config/haproxy-devel/haproxy_frontends_edit.php
@@ -0,0 +1,768 @@
+<?php
+/* $Id: load_balancer_pool_edit.php,v 1.24.2.23 2007/03/03 00:07:09 smos Exp $ */
+/*
+ haproxy_frontends_edit.php
+ part of pfSense (http://www.pfsense.com/)
+ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
+ Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
+ Copyright (C) 2013 Marcello Coutinho <marcellocoutinho@gmail.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+
+if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
+ $config['installedpackages']['haproxy']['ha_backends']['item'] = array();
+}
+
+$a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+else
+ $id = $_GET['id'];
+
+if (isset($id) && $a_backend[$id]) {
+ $pconfig['name'] = $a_backend[$id]['name'];
+ $pconfig['desc'] = $a_backend[$id]['desc'];
+ $pconfig['connection_timeout'] = $a_backend[$id]['connection_timeout'];
+ $pconfig['server_timeout'] = $a_backend[$id]['server_timeout'];
+ $pconfig['retries'] = $a_backend[$id]['retries'];
+
+ $pconfig['type'] = $a_backend[$id]['type'];
+ $pconfig['balance'] = $a_backend[$id]['balance'];
+ $pconfig['monitor_uri'] = $a_backend[$id]['monitor_uri'];
+
+ $pconfig['forwardfor'] = $a_backend[$id]['forwardfor'];
+ $pconfig['httpclose'] = $a_backend[$id]['httpclose'];
+
+ $pconfig['stats_enabled'] = $a_backend[$id]['stats_enabled'];
+ $pconfig['stats_username'] = $a_backend[$id]['stats_username'];
+ $pconfig['stats_password'] = $a_backend[$id]['stats_password'];
+ $pconfig['stats_uri'] = $a_backend[$id]['stats_uri'];
+ $pconfig['stats_realm'] = $a_backend[$id]['stats_realm'];
+ $pconfig['stats_node_enabled'] = $a_backend[$id]['stats_node_enabled'];
+ $pconfig['stats_node'] = $a_backend[$id]['stats_node'];
+ $pconfig['stats_desc'] = $a_backend[$id]['stats_desc'];
+ $pconfig['stats_refresh'] = $a_backend[$id]['stats_refresh'];
+
+ $pconfig['type'] = $a_backend[$id]['type'];
+ $pconfig['extaddr'] = $a_backend[$id]['extaddr'];
+ $pconfig['max_connections'] = $a_backend[$id]['max_connections'];
+ $pconfig['client_timeout'] = $a_backend[$id]['client_timeout'];
+ $pconfig['port'] = $a_backend[$id]['port'];
+ $pconfig['a_acl']=&$a_backend[$id]['ha_acls']['item'];
+ $pconfig['advanced'] = base64_decode($a_backend[$id]['advanced']);
+ $pconfig['dcert'] = base64_decode($a_backend[$id]['dcert']);
+ $pconfig['dcertadv'] = $a_backend[$id]['dcertadv'];
+ $pconfig['ssloffload'] = $a_backend[$id]['ssloffload'];
+}
+
+$changedesc = "Services: HAProxy: Frontend";
+$changecount = 0;
+
+if ($_POST) {
+ $changecount++;
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ if ($_POST['stats_enabled']) {
+ $reqdfields = explode(" ", "name connection_timeout server_timeout stats_username stats_password stats_uri stats_realm");
+ $reqdfieldsn = explode(",", "Name,Connection timeout,Server timeout,Stats Username,Stats Password,Stats Uri,Stats Realm");
+ } else {
+ $reqdfields = explode(" ", "name connection_timeout server_timeout");
+ $reqdfieldsn = explode(",", "Name,Connection timeout,Server timeout");
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ $reqdfields = explode(" ", "name type port max_connections client_timeout");
+ $reqdfieldsn = explode(",", "Name,Type,Port,Max connections,Client timeout");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['name']))
+ $input_errors[] = "The field 'Name' contains invalid characters.";
+
+ if (!is_numeric($_POST['connection_timeout']))
+ $input_errors[] = "The field 'Connection timeout' value is not a number.";
+
+ if (!is_numeric($_POST['server_timeout']))
+ $input_errors[] = "The field 'Server timeout' value is not a number.";
+
+ if (!$_POST['retries'] && is_numeric($_POST['retries']))
+ $input_errors[] = "The field 'Retries' value is not a number.";
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['stats_username']))
+ $input_errors[] = "The field 'Stats Username' contains invalid characters.";
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['stats_password']))
+ $input_errors[] = "The field 'Stats Password' contains invalid characters.";
+
+ if (!is_numeric($_POST['max_connections']))
+ $input_errors[] = "The field 'Max connections' value is not a number.";
+
+ $ports = split(",", $_POST['port'] . ",");
+ foreach($ports as $port)
+ if ($port && !is_numeric($port))
+ $input_errors[] = "The field 'Port' value is not a number.";
+
+ if (!is_numeric($_POST['client_timeout']))
+ $input_errors[] = "The field 'Client timeout' value is not a number.";
+
+ /* Ensure that our pool names are unique */
+ for ($i=0; isset($config['installedpackages']['haproxy']['ha_backends']['item'][$i]); $i++)
+ if (($_POST['name'] == $config['installedpackages']['haproxy']['ha_backends']['item'][$i]['name']) && ($i != $id))
+ $input_errors[] = "This backend name has already been used. Frontend names must be unique.";
+
+ $a_acl=array();
+ $acl_names=array();
+ for($x=0; $x<99; $x++) {
+ $acl_name=$_POST['acl_name'.$x];
+ $acl_expression=$_POST['acl_expression'.$x];
+
+ if ($acl_name) {
+ // check for duplicates
+ if (in_array($acl_name, $acl_names)) {
+ $input_errors[] = "The name '$acl_name' is duplicate.";
+ }
+
+ $acl_names[]=$acl_name;
+
+ $acl=array();
+ $acl['name']=$acl_name;
+ $acl['expression']=$acl_expression;
+ $a_acl[]=$acl;
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $acl_name))
+ $input_errors[] = "The field 'Name' contains invalid characters.";
+
+ if (!preg_match("/.{2,}/", $acl_expression))
+ $input_errors[] = "The field 'Expression' is required.";
+
+ if (!preg_match("/.{2,}/", $acl_name))
+ $input_errors[] = "The field 'Name' is required.";
+
+ }
+ }
+
+ $pconfig['a_acl']=$a_acl;
+
+ if (!$input_errors) {
+ $backend = array();
+ if(isset($id) && $a_backend[$id])
+ $backend = $a_backend[$id];
+
+ if($backend['name'] != "")
+ $changedesc .= " modified '{$backend['name']}' pool:";
+
+ if ($backend['name']!=$_POST['name']) {
+ // name changed:
+ // * update servers
+ // * update frontend (default backend and acl)
+ if (!is_array($config['installedpackages']['haproxy']['ha_servers']['item'])) {
+ $config['installedpackages']['haproxy']['ha_servers']['item'] = array();
+ }
+ $a_server = &$config['installedpackages']['haproxy']['ha_servers']['item'];
+
+ for ( $i = 0; $i < count($a_server); $i++) {
+ if ($a_server[$i]['backend']==$backend['name']) {
+ $a_server[$i]['backend']=$_POST['name'];
+ }
+ }
+
+ if (!is_array($config['installedpackages']['haproxy']['ha_frontends']['item'])) {
+ $config['installedpackages']['haproxy']['ha_frontends']['item'] = array();
+ }
+ $a_frontend = &$config['installedpackages']['haproxy']['ha_frontends']['item'];
+
+ for ( $i = 0; $i < count($a_frontend); $i++) {
+ if ($a_frontend[$i]['backend']==$backend['name']) {
+ $a_frontend[$i]['backend']=$_POST['name'];
+ }
+
+ if (!is_array($a_frontend[$i]['ha_acls']['item'])) {
+ $a_frontend[$i]['ha_acls']['item'] = array();
+ }
+
+ $a_acl = &$a_frontend[$i]['ha_acls']['item'];
+ for ( $j = 0; $j < count($a_acl); $j++) {
+ if ($a_acl[$j]['backend']==$backend['name']) {
+ $a_acl[$j]['backend']=$_POST['name'];
+ }
+ }
+ }
+ }
+
+ update_if_changed("name", $backend['name'], $_POST['name']);
+ update_if_changed("description", $backend['desc'], $_POST['desc']);
+ update_if_changed("connection_timeout", $backend['connection_timeout'], $_POST['connection_timeout']);
+ update_if_changed("server_timeout", $backend['server_timeout'], $_POST['server_timeout']);
+ update_if_changed("retries", $backend['retries'], $_POST['retries']);
+ update_if_changed("type", $backend['type'], $_POST['type']);
+ update_if_changed("balance", $backend['balance'], $_POST['balance']);
+ update_if_changed("cookie_name", $backend['cookie_name'], $_POST['cookie_name']);
+ update_if_changed("monitor_uri", $backend['monitor_uri'], $_POST['monitor_uri']);
+ update_if_changed("forwardfor", $backend['forwardfor'], $_POST['forwardfor']);
+ update_if_changed("httpclose", $backend['httpclose'], $_POST['httpclose']);
+ update_if_changed("stats_enabled", $backend['stats_enabled'], $_POST['stats_enabled']);
+ update_if_changed("stats_username", $backend['stats_username'], $_POST['stats_username']);
+ update_if_changed("stats_password", $backend['stats_password'], $_POST['stats_password']);
+ update_if_changed("stats_uri", $backend['stats_uri'], $_POST['stats_uri']);
+ update_if_changed("stats_realm", $backend['stats_realm'], $_POST['stats_realm']);
+ update_if_changed("stats_node_enabled", $backend['stats_node_enabled'], $_POST['stats_node_enabled']);
+ update_if_changed("stats_node", $backend['stats_node'], $_POST['stats_node']);
+ update_if_changed("stats_desc", $backend['stats_desc'], $_POST['stats_desc']);
+ update_if_changed("stats_desc", $backend['stats_refresh'], $_POST['stats_refresh']);
+ update_if_changed("type", $backend['type'], $_POST['type']);
+ update_if_changed("port", $backend['port'], $_POST['port']);
+ update_if_changed("extaddr", $backend['extaddr'], $_POST['extaddr']);
+ update_if_changed("max_connections", $backend['max_connections'], $_POST['max_connections']);
+ update_if_changed("client_timeout", $backend['client_timeout'], $_POST['client_timeout']);
+ update_if_changed("advanced", $backend['advanced'], base64_encode($_POST['advanced']));
+ update_if_changed("dcert", $backend['dcert'], base64_encode($_POST['dcert']));
+ update_if_changed("dcertadv", $backend['dcertadv'], $_POST['dcertadv']);
+ update_if_changed("ssloffload", $backend['ssloffload'], $_POST['ssloffload']);
+ $backend['ha_acls']['item'] = $a_acl;
+
+ if (isset($id) && $a_backend[$id]) {
+ $a_backend[$id] = $backend;
+ } else {
+ $a_backend[] = $backend;
+ }
+
+ if ($changecount > 0) {
+ touch($d_haproxyconfdirty_path);
+ write_config($changedesc);
+ }
+
+ header("Location: haproxy_frontends.php");
+ exit;
+ }
+}
+
+$pfSversion = str_replace("\n", "", file_get_contents("/etc/version"));
+if(strstr($pfSversion, "1.2"))
+ $one_two = true;
+
+$pgtitle = "HAProxy: Frontend: Edit";
+include("head.inc");
+
+?>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<script type="text/javascript">
+ // Global Variables
+ var rowname = new Array(99);
+ var rowtype = new Array(99);
+ var newrow = new Array(99);
+ var rowsize = new Array(99);
+
+ for (i = 0; i < 99; i++) {
+ rowname[i] = '';
+ rowtype[i] = '';
+ newrow[i] = '';
+ rowsize[i] = '25';
+ }
+
+ var field_counter_js = 0;
+ var loaded = 0;
+ var is_streaming_progress_bar = 0;
+ var temp_streaming_text = "";
+
+ var addRowTo = (function() {
+ return (function (tableId) {
+ var d, tbody, tr, td, bgc, i, ii, j;
+ d = document;
+ tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0);
+ tr = d.createElement("tr");
+ totalrows++;
+ for (i = 0; i < field_counter_js; i++) {
+ td = d.createElement("td");
+ if(rowtype[i] == 'textbox') {
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + "'></input> ";
+ } else if(rowtype[i] == 'select') {
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><select name='" + rowname[i] + totalrows + "'><?php foreach ($a_backend as $backend) {?><option value=\"<?=$backend['name']?>\"><?=$backend['name']?></option><?php }?></select> ";
+ } else {
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input type='checkbox' name='" + rowname[i] + totalrows + "'></input> ";
+ }
+ tr.appendChild(td);
+ }
+ td = d.createElement("td");
+ td.rowSpan = "1";
+ td.className = "list";
+ td.innerHTML = '<img src="/themes/' + theme + '/images/icons/icon_x.gif" width="17" height="17" border="0" onclick="removeRow(this); return false;">';
+ tr.appendChild(td);
+ tbody.appendChild(tr);
+ });
+ })();
+
+ function removeRow(el) {
+ var cel;
+ while (el && el.nodeName.toLowerCase() != "tr")
+ el = el.parentNode;
+
+ if (el && el.parentNode) {
+ cel = el.getElementsByTagName("td").item(0);
+ el.parentNode.removeChild(el);
+ }
+ }
+
+ function find_unique_field_name(field_name) {
+ // loop through field_name and strip off -NUMBER
+ var last_found_dash = 0;
+ for (var i = 0; i < field_name.length; i++) {
+ // is this a dash, if so, update
+ // last_found_dash
+ if (field_name.substr(i,1) == "-" )
+ last_found_dash = i;
+ }
+ if (last_found_dash < 1)
+ return field_name;
+ return(field_name.substr(0,last_found_dash));
+ }
+
+ rowname[0] = "acl_name";
+ rowtype[0] = "textbox";
+ rowsize[0] = "30";
+
+ rowname[1] = "acl_expression";
+ rowtype[1] = "textbox";
+ rowsize[1] = "35";
+
+ rowname[2] = "acl_backend";
+ rowtype[2] = "select";
+ rowsize[2] = "10";
+
+ function toggle_stats() {
+ var stats_enabled=document.getElementById('stats_enabled');
+ var stats_realm_row=document.getElementById('stats_realm_row');
+ var stats_username_row=document.getElementById('stats_username_row');
+ var stats_password_row=document.getElementById('stats_password_row');
+ var stats_uri_row=document.getElementById('stats_uri_row');
+ var stats_node_enabled_row=document.getElementById('stats_node_enabled_row');
+ var stats_node_row=document.getElementById('stats_node_row');
+ var stats_desc_row=document.getElementById('stats_desc_row');
+ var stats_desc_row=document.getElementById('stats_refresh_row');
+
+ if (stats_enabled.checked) {
+ stats_realm_row.style.display='';
+ stats_username_row.style.display='';
+ stats_password_row.style.display='';
+ stats_uri_row.style.display='';
+ stats_node_enabled_row.style.display='';
+ stats_node_row.style.display='';
+ stats_desc_row.style.display='';
+ stats_refresh_row.style.display='';
+ } else {
+ stats_realm_row.style.display='none';
+ stats_username_row.style.display='none';
+ stats_password_row.style.display='none';
+ stats_uri_row.style.display='none';
+ stats_node_enabled_row.style.display='none';
+ stats_node_row.style.display='none';
+ stats_desc_row.style.display='none';
+ stats_refresh_row.style.display='none';
+ }
+ }
+</script>
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if($one_two): ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<?php endif; ?>
+<form action="haproxy_frontends_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Edit haproxy backend</td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Name</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="25" maxlength="25">
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Description</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="desc" type="text" <?if(isset($pconfig['desc'])) echo "value=\"{$pconfig['desc']}\"";?> size="64">
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Connection timeout</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="connection_timeout" type="text" <?if(isset($pconfig['connection_timeout'])) echo "value=\"{$pconfig['connection_timeout']}\"";?> size="64">
+ <div>the time (in milliseconds) we give up if the connection does not complete within (30000).</div>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Server timeout</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="server_timeout" type="text" <?if(isset($pconfig['server_timeout'])) echo "value=\"{$pconfig['server_timeout']}\"";?> size="64">
+ <div>the time (in milliseconds) we accept to wait for data from the server, or for the server to accept data (30000).</div>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Retries</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="retries" type="text" <?if(isset($pconfig['retries'])) echo "value=\"{$pconfig['retries']}\"";?> size="64">
+ <div>After a connection failure to a server, it is possible to retry, potentially
+on another server. This is useful if health-checks are too rare and you don't
+want the clients to see the failures. The number of attempts to reconnect is
+set by the 'retries' parameter (2).</div>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Type</td>
+ <td width="78%" class="vtable" colspan="2">
+ <select name="type" id="type" onchange="type_change();">
+ <option value="http"<?php if($pconfig['type'] == "http") echo " SELECTED"; ?>>HTTP</option>
+ <option value="https"<?php if($pconfig['type'] == "https") echo " SELECTED"; ?>>HTTPS</option>
+ <option value="tcp"<?php if($pconfig['type'] == "tcp") echo " SELECTED"; ?>>TCP</option>
+ <option value="health"<?php if($pconfig['type'] == "health") echo " SELECTED"; ?>>Health</option>
+ </select>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Balance</td>
+ <td width="78%" class="vtable" colspan="2">
+ <table width="100%">
+ <tr>
+ <td width="20%" valign="top">
+ <input type="radio" name="balance" id="balance" value="roundrobin"<?php if($pconfig['balance'] == "roundrobin") echo " CHECKED"; ?>>Round robin</input>
+ </td>
+ <td>
+ Each server is used in turns, according to their weights.
+ This is the smoothest and fairest algorithm when the server's
+ processing time remains equally distributed. This algorithm
+ is dynamic, which means that server weights may be adjusted
+ on the fly for slow starts for instance.
+ </td>
+ </tr>
+ <tr>
+ <td width="20%" valign="top">
+ <input type="radio" name="balance" id="balance" value="static-rr"<?php if($pconfig['balance'] == "static-rr") echo " CHECKED"; ?>>Static Round Robin</input>
+ </td>
+ <td>
+ Each server is used in turns, according to their weights.
+ This algorithm is as similar to roundrobin except that it is
+ static, which means that changing a server's weight on the
+ fly will have no effect. On the other hand, it has no design
+ limitation on the number of servers, and when a server goes
+ up, it is always immediately reintroduced into the farm, once
+ the full map is recomputed. It also uses slightly less CPU to
+ run (around -1%).
+ </td>
+ </tr>
+ <tr>
+ <td width="20%" valign="top">
+ <input type="radio" name="balance" id="balance" value="leastconn"<?php if($pconfig['balance'] == "leastconn") echo " CHECKED"; ?>>Least Connections</input>
+ </td>
+ <td>
+ The server with the lowest number of connections receives the
+ connection. Round-robin is performed within groups of servers
+ of the same load to ensure that all servers will be used. Use
+ of this algorithm is recommended where very long sessions are
+ expected, such as LDAP, SQL, TSE, etc... but is not very well
+ suited for protocols using short sessions such as HTTP. This
+ algorithm is dynamic, which means that server weights may be
+ adjusted on the fly for slow starts for instance.
+ </td>
+ </tr>
+ <tr><td valign="top"><input type="radio" name="balance" id="balance" value="source"<?php if($pconfig['balance'] ==
+"source") echo " CHECKED"; ?>>Source</input></td><td>
+ The source IP address is hashed and divided by the total
+ weight of the running servers to designate which server will
+ receive the request. This ensures that the same client IP
+ address will always reach the same server as long as no
+ server goes down or up. If the hash result changes due to the
+ number of running servers changing, many clients will be
+ directed to a different server. This algorithm is generally
+ used in TCP mode where no cookie may be inserted. It may also
+ be used on the Internet to provide a best-effort stickyness
+ to clients which refuse session cookies. This algorithm is
+ static, which means that changing a server's weight on the
+ fly will have no effect.
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Stats Enabled</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_enabled" name="stats_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_enabled']=='yes') echo "checked"; ?> onclick='toggle_stats();'><br/>
+ EXAMPLE: haproxystats
+ </td>
+ </tr>
+ <tr align="left" id='stats_realm_row' name='stats_realm_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncellreq">Stats Realm</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_realm" name="stats_realm" type="text" <?if(isset($pconfig['stats_realm'])) echo "value=\"{$pconfig['stats_realm']}\"";?> size="64">
+ </td>
+ </tr>
+ <tr align="left" id='stats_uri_row' name='stats_uri_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncellreq">Stats Uri</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_uri" name="stats_uri" type="text" <?if(isset($pconfig['stats_uri'])) echo "value=\"{$pconfig['stats_uri']}\"";?> size="64"><br/>
+ EXAMPLE: /haproxy?stats
+ </td>
+ </tr>
+ <tr align="left" id='stats_username_row' name='stats_username_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncellreq">Stats Username</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_username" name="stats_username" type="text" <?if(isset($pconfig['stats_username'])) echo "value=\"{$pconfig['stats_username']}\"";?> size="64">
+ </td>
+ </tr>
+
+ <tr align="left" id='stats_password_row' name='stats_password_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncellreq">Stats Password</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_password" name="stats_password" type="password" <?if(isset($pconfig['stats_password'])) echo "value=\"{$pconfig['stats_password']}\"";?> size="64">
+ <br/>
+ </td>
+ </tr>
+ <tr align="left" id='stats_node_enabled_row' name='stats_node_enabled_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncell">Stats Enable Node Name</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_node_enabled" name="stats_node_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_node_enabled']=='yes') echo "checked"; ?>>
+ <br/>
+ </td>
+ </tr>
+ <tr align="left" id='stats_node_row' name='stats_node_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncell">Stats Node</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_node" name="stats_node" type="text" <?if(isset($pconfig['stats_node'])) echo "value=\"{$pconfig['stats_node']}\"";?> size="64"><br/>
+ The node name is displayed in the stats and helps to differentiate which server in a cluster is actually serving clients.<br/>
+ Leave blank to use the system name.
+ </td>
+ </tr>
+ <tr align="left" id='stats_desc_row' name='stats_desc_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncell">Stats Description</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_desc" name="stats_desc" type="text" <?if(isset($pconfig['stats_node'])) echo "value=\"{$pconfig['stats_desc']}\"";?> size="64"><br/>
+ </td>
+ </tr>
+ <tr align="left" id='stats_refresh_row' name='stats_refresh_row' <?if ($pconfig['stats_enabled']!='yes') echo "style=\"display: none;\"";?>>
+ <td width="22%" valign="top" class="vncell">Stats Refresh</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="stats_refresh" name="stats_refresh" type="text" <?if(isset($pconfig['stats_refresh'])) echo "value=\"{$pconfig['stats_refresh']}\"";?> size="10" maxlength="30"><br/>
+ Specify the refresh rate of the stats page in seconds, or specified time unit (us, ms, s, m, h, d).
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" id="monitorport_text" class="vncell">Monitor Uri</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="monitor_uri" type="text" <?if(isset($pconfig['monitor_uri'])) echo "value=\"{$pconfig['monitor_uri']}\"";?> size="50" maxlength="50">
+ <br/>
+ Example: / or /index.php or /index.html or /testmypage.cgi
+ </td>
+ </tr>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Port</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="30" maxlength="500">
+ <div>The port to listen to. To specify multiple ports, separate with a comma (,). EXAMPLE: 80,443</div>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">External address</td>
+ <td width="78%" class="vtable">
+ <select name="extaddr" class="formfld">
+ <option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>Interface address</option>
+ <?php
+ if (is_array($config['virtualip']['vip'])):
+ foreach ($config['virtualip']['vip'] as $sn):
+ ?>
+ <option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['extaddr']) echo "selected"; ?>>
+ <?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?>
+ </option>
+ <?php
+ endforeach;
+ endif;
+ ?>
+ <option value="any" <?php if($pconfig['extaddr'] == "any") echo "selected"; ?>>any</option>
+ </select>
+ <br />
+ <span class="vexpl">
+ If you want this rule to apply to another IP address than the IP address of the interface chosen above,
+ select it here (you need to define <a href="firewall_virtual_ip.php">Virtual IP</a> addresses on the first).
+ Also note that if you are trying to redirect connections on the LAN select the "any" option.
+ </span>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Max connections</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="max_connections" type="text" <?if(isset($pconfig['max_connections'])) echo "value=\"{$pconfig['max_connections']}\"";?> size="10" maxlength="10">
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Client timeout</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="client_timeout" type="text" <?if(isset($pconfig['client_timeout'])) echo "value=\"{$pconfig['client_timeout']}\"";?> size="10" maxlength="10">
+ <div>the time (in milliseconds) we accept to wait for data from the client, or for the client to accept data (30000).</div>
+ </td>
+ </tr>
+<?php
+/*
+ <tr>
+ <td width="22%" valign="top" class="vncell">Access Control lists</td>
+ <td width="78%" class="vtable" colspan="2" valign="top">
+ <table class="" width="100%" cellpadding="0" cellspacing="0" id='acltable'>
+ <tr>
+ <td width="35%" class="">Name</td>
+ <td width="40%" class="">Expression</td>
+ <td width="20%" class="">Backend</td>
+ <td width="5%" class=""></td>
+ </tr>
+ <?php
+ $a_acl=$pconfig['a_acl'];
+
+ if (!is_array($a_acl)) {
+ $a_acl=array();
+ }
+
+ $i=0;
+ foreach ($a_acl as $acl) {
+ ?>
+ <tr>
+ <td><input name="acl_name<?=$i;?>" type="text" value="<?=$acl['name']; ?>" size="30"/></td>
+ <td><input name="acl_expression<?=$i;?>" type="text" value="<?=$acl['expression']; ?>" size="35"/></td>
+ <td>
+ <select name="acl_backend<?=$i;?>" id="acl_backend<?=$i;?>">
+ <?php
+ if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
+ $config['installedpackages']['haproxy']['ha_backends']['item'] = array();
+ }
+ $a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+ foreach ($a_backend as $backend) { ?>
+ <option value="<?=$backend['name'];?>"<?php if($acl['backend'] == $backend['name']) echo " SELECTED"; ?>><?=$backend['name'];?></option>
+ <?php $i++; } ?>
+ </select>
+ </td>
+ <td class="list"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" onclick="removeRow(this); return false;"></td>
+ </tr>
+ <?php
+ $i++;
+ }
+ ?>
+ </table>
+ <a onclick="javascript:addRowTo('acltable'); return false;" href="#">
+ <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" />
+ </a><br/>
+ Fore more information about ACL's please see <a href='http://haproxy.1wt.eu/download/1.3/doc/configuration.txt' target='_new'>HAProxy Documentation</a> Section 7 - Using ACL's
+ </td>
+ </tr>
+*/
+?>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Use 'forwardfor' option</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="forwardfor" name="forwardfor" type="checkbox" value="yes" <?php if ($pconfig['forwardfor']=='yes') echo "checked"; ?>>
+ <br/>
+ The 'forwardfor' option creates an HTTP 'X-Forwarded-For' header which
+ contains the client's IP address. This is useful to let the final web server
+ know what the client address was (eg for statistics on domains)
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Use 'httpclose' option</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="httpclose" name="httpclose" type="checkbox" value="yes" <?php if ($pconfig['httpclose']=='yes') echo "checked"; ?>>
+ <br/>
+ The 'httpclose' option removes any 'Connection' header both ways, and
+ adds a 'Connection: close' header in each direction. This makes it easier to
+ disable HTTP keep-alive than the previous 4-rules block.
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Advanced pass thru</td>
+ <td width="78%" class="vtable" colspan="2">
+ <textarea name='advanced' rows="4" cols="70" id='advanced'><?php echo $pconfig['advanced']; ?></textarea>
+ <br/>
+ NOTE: paste text into this box that you would like to pass thru.
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">SSL Offloading</td>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Use Offloading</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked"; ?>>
+ <br/>
+ The SSL Offloading will reduce web servers load by encrypt data to users on internet and send it without encrytion to internal servers.
+ </td>
+ </tr>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">cert</td>
+ <td width="78%" class="vtable" colspan="2">
+ <textarea name='dcert' rows="8" cols="70" id='dcert'><?php echo $pconfig['dcert']; ?></textarea>
+ <br/>
+ NOTE: paste cert and rsa key to use on this frontend.
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Advanced ssl options</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input type='text' name='dcertadv' size="64" id='dcertadv' <?if(isset($pconfig['dcertadv'])) echo "value=\"{$pconfig['dcertadv']}\"";?> size="10" maxlength="64">
+ <br/>
+ NOTE: Paste additional ssl options(without commas) to include on ssl listening options.<br>
+ some options: force-sslv3, force-tlsv10 force-tlsv11 force-tlsv12 no-sslv3 no-tlsv10 no-tlsv11 no-tlsv12 no-tls-tickets
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <input type="button" class="formbtn" value="Cancel" onclick="history.back()">
+ <?php if (isset($id) && $a_backend[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ <tr>
+ <br/>&nbsp;<br/>
+ <td colspan='3'>
+ <span class="vexpl"><b>NOTE:</b> You must add a firewall rule permitting access to this frontend!</span>
+ </td>
+ </tr>
+ </table>
+ </form>
+<br>
+<script type="text/javascript">
+ field_counter_js = 3;
+ rows = 1;
+ <?php $counter=0; ?>
+ totalrows = <?php echo $counter; ?>;;
+ loaded = <?php echo $counter; ?>;;
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/haproxy-devel/haproxy_global.php b/config/haproxy-devel/haproxy_global.php
new file mode 100755
index 00000000..b0486fb8
--- /dev/null
+++ b/config/haproxy-devel/haproxy_global.php
@@ -0,0 +1,328 @@
+<?php
+/* $Id: load_balancer_pool.php,v 1.5.2.6 2007/03/02 23:48:32 smos Exp $ */
+/*
+ haproxy_global.php
+ part of pfSense (http://www.pfsense.com/)
+ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
+ Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("globals.inc");
+require("guiconfig.inc");
+require_once("haproxy.inc");
+
+$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+
+if (!is_array($config['installedpackages']['haproxy']))
+ $config['installedpackages']['haproxy'] = array();
+
+
+if ($_POST) {
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ config_lock();
+ $retval = haproxy_configure();
+ config_unlock();
+ $savemsg = get_std_save_message($retval);
+ unlink_if_exists($d_haproxyconfdirty_path);
+ } else {
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "maxconn");
+ $reqdfieldsn = explode(",", "Maximum connections");
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['maxconn'] && (!is_numeric($_POST['maxconn'])))
+ $input_errors[] = "The maximum number of connections should be numeric.";
+
+ if($_POST['synchost1'] && !is_ipaddr($_POST['synchost1']))
+ $input_errors[] = "Synchost1 needs to be an IPAddress.";
+ if($_POST['synchost2'] && !is_ipaddr($_POST['synchost2']))
+ $input_errors[] = "Synchost2 needs to be an IPAddress.";
+ if($_POST['synchost3'] && !is_ipaddr($_POST['synchost3']))
+ $input_errors[] = "Synchost3 needs to be an IPAddress.";
+
+ if (!$input_errors) {
+ $config['installedpackages']['haproxy']['enable'] = $_POST['enable'] ? true : false;
+ $config['installedpackages']['haproxy']['maxconn'] = $_POST['maxconn'] ? $_POST['maxconn'] : false;
+ $config['installedpackages']['haproxy']['enablesync'] = $_POST['enablesync'] ? true : false;
+ $config['installedpackages']['haproxy']['synchost1'] = $_POST['synchost1'] ? $_POST['synchost1'] : false;
+ $config['installedpackages']['haproxy']['synchost2'] = $_POST['synchost2'] ? $_POST['synchost2'] : false;
+ $config['installedpackages']['haproxy']['synchost3'] = $_POST['synchost3'] ? $_POST['synchost3'] : false;
+ $config['installedpackages']['haproxy']['remotesyslog'] = $_POST['remotesyslog'] ? $_POST['remotesyslog'] : false;
+ $config['installedpackages']['haproxy']['syncpassword'] = $_POST['syncpassword'] ? $_POST['syncpassword'] : false;
+ $config['installedpackages']['haproxy']['advanced'] = $_POST['advanced'] ? base64_encode($_POST['advanced']) : false;
+ $config['installedpackages']['haproxy']['nbproc'] = $_POST['nbproc'] ? $_POST['nbproc'] : false;
+ touch($d_haproxyconfdirty_path);
+ write_config();
+ }
+ }
+
+}
+
+$pconfig['enable'] = isset($config['installedpackages']['haproxy']['enable']);
+$pconfig['maxconn'] = $config['installedpackages']['haproxy']['maxconn'];
+$pconfig['enablesync'] = isset($config['installedpackages']['haproxy']['enablesync']);
+$pconfig['syncpassword'] = $config['installedpackages']['haproxy']['syncpassword'];
+$pconfig['synchost1'] = $config['installedpackages']['haproxy']['synchost1'];
+$pconfig['synchost2'] = $config['installedpackages']['haproxy']['synchost2'];
+$pconfig['synchost3'] = $config['installedpackages']['haproxy']['synchost3'];
+$pconfig['remotesyslog'] = $config['installedpackages']['haproxy']['remotesyslog'];
+$pconfig['advanced'] = base64_decode($config['installedpackages']['haproxy']['advanced']);
+$pconfig['nbproc'] = $config['installedpackages']['haproxy']['nbproc'];
+
+$pfSversion = str_replace("\n", "", file_get_contents("/etc/version"));
+if(strstr($pfSversion, "1.2"))
+ $one_two = true;
+
+$pgtitle = "Services: HAProxy: Settings";
+include("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<script type="text/javascript" src="javascript/scriptaculous/prototype.js"></script>
+<script type="text/javascript" src="javascript/scriptaculous/scriptaculous.js"></script>
+<?php include("fbegin.inc"); ?>
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+ var endis;
+ endis = !(document.iform.enable.checked || enable_change);
+ document.iform.maxconn.disabled = endis;
+}
+//-->
+</script>
+<?php if($one_two): ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<?php endif; ?>
+<form action="haproxy_global.php" method="post" name="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_haproxyconfdirty_path)): ?><p>
+<?php print_info_box_np("The load balancer configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td class="tabnavtbl">
+ <?php
+ /* active tabs */
+ $tab_array = array();
+ $tab_array[] = array("Settings", true, "haproxy_global.php");
+ $tab_array[] = array("Frontends", false, "haproxy_frontends.php");
+ $tab_array[] = array("Servers", false, "haproxy_servers.php");
+ display_top_tabs($tab_array);
+ ?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">General settings</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable HAProxy</strong></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">
+ Maximum connections
+ </td>
+ <td class="vtable">
+ <table><tr><td>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <input name="maxconn" type="text" class="formfld" id="maxconn" size="5" <?if ($pconfig['enable']!='yes') echo "enabled=\"false\"";?> value="<?=htmlspecialchars($pconfig['maxconn']);?>"> per Backend.
+ </td>
+ </tr>
+ </table>
+ Sets the maximum per-process number of concurrent connections to X.<br/>
+ <strong>NOTE:</strong> setting this value too high will result in HAProxy not being able to allocate enough memory.<br/>
+ <?php
+ $hascpu = trim(`top | grep haproxy | awk '{ print $6 }'`);
+ if($hascpu)
+ echo "<p>Current memory usage {$hascpu}.</p>";
+ ?>
+ </td><td>
+ <table style="border: 1px solid #000;">
+ <tr>
+ <td><font size=-1>Connections</td>
+ <td><font size=-1>Memory usage</td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <hr noshade style="border: 1px solid #000;">
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><font size=-1>999</td>
+ <td><font size=-1>1888K</td>
+ </tr>
+ <tr>
+ <td align="right"><font size=-1>99999</td>
+ <td><font size=-1>8032K</td>
+ </tr>
+ <tr>
+ <td align="right"><font size=-1>999999</td>
+ <td><font size=-1>50016K</td>
+ </tr>
+ <tr>
+ <td align="right"><font size=-1>9999999</td>
+ <td><font size=-1>467M</td>
+ </tr>
+ </table>
+ </td></tr></table>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">
+ Number of processes to start
+ </td>
+ <td class="vtable">
+ <input name="nbproc" type="text" class="formfld" id="nbproc" size="18" value="<?=htmlspecialchars($pconfig['nbproc']);?>">
+ <br/>
+ Defaults to number of cores/processors installed if left blank (<?php echo trim(`/sbin/sysctl kern.smp.cpus | cut -d" " -f2`); ?> detected).
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">
+ Remote syslog host
+ </td>
+ <td class="vtable">
+ <input name="remotesyslog" type="text" class="formfld" id="remotesyslog" size="18" value="<?=htmlspecialchars($pconfig['remotesyslog']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Global Advanced pass thru</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <textarea name='advanced' rows="4" cols="70" id='advanced'><?php echo $pconfig['advanced']; ?></textarea>
+ <br/>
+ NOTE: paste text into this box that you would like to pass thru in the global settings area.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Configuration synchronization</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="enablesync" type="checkbox" value="yes" <?php if ($pconfig['enablesync']) echo "checked"; ?>>
+ <strong>Sync HAProxy configuration to backup CARP members via XMLRPC.</strong>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Synchronization password</td>
+ <td width="78%" class="vtable">
+ <input name="syncpassword" type="password" value="<?=$pconfig['syncpassword'];?>">
+ <br/>
+ <strong>Enter the password that will be used during configuration synchronization. This is generally the remote webConfigurator password.</strong>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Sync host #1</td>
+ <td width="78%" class="vtable">
+ <input name="synchost1" value="<?=$pconfig['synchost1'];?>">
+ <br/>
+ <strong>Synchronize settings to this hosts IP address.</strong>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Sync host #2</td>
+ <td width="78%" class="vtable">
+ <input name="synchost2" value="<?=$pconfig['synchost2'];?>">
+ <br/>
+ <strong>Synchronize settings to this hosts IP address.</strong>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Sync host #3</td>
+ <td width="78%" class="vtable">
+ <input name="synchost3" value="<?=$pconfig['synchost3'];?>">
+ <br/>
+ <strong>Synchronize settings to this hosts IP address.</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)">
+ </td>
+ </td>
+ </tr>
+ </table>
+ </div>
+</table>
+
+<?php if(file_exists("/var/etc/haproxy.cfg")): ?>
+ <p/>
+ <div id="configuration" style="display:none; border-style:dashed; padding: 8px;">
+ <b><i>/var/etc/haproxy.cfg file contents:</b></i>
+ <?php
+ if(file_exists("/var/etc/haproxy.cfg")) {
+ echo "<pre>" . trim(file_get_contents("/var/etc/haproxy.cfg")) . "</pre>";
+ }
+ ?>
+ </div>
+ <div id="showconfiguration">
+ <a onClick="new Effect.Fade('showconfiguration'); new Effect.Appear('configuration'); setTimeout('scroll_after_fade();', 250); return false;" href="#">Show</a> automatically generated configuration.
+ </div>
+<?php endif; ?>
+
+</form>
+<script language="JavaScript">
+ function scroll_after_fade() {
+ scrollTo(0,99999999999);
+ }
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/haproxy-devel/haproxy_servers.php b/config/haproxy-devel/haproxy_servers.php
new file mode 100755
index 00000000..cacf995a
--- /dev/null
+++ b/config/haproxy-devel/haproxy_servers.php
@@ -0,0 +1,169 @@
+<?php
+/* $Id: load_balancer_virtual_server.php,v 1.6.2.1 2006/01/02 23:46:24 sullrich Exp $ */
+/*
+ haproxy_servers.php
+ part of pfSense (http://www.pfsense.com/)
+ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
+ Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("guiconfig.inc");
+require_once("haproxy.inc");
+
+$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+
+if (!is_array($config['installedpackages']['haproxy']['ha_servers']['item'])) {
+ $config['installedpackages']['haproxy']['ha_servers']['item'] = array();
+}
+
+$a_server = &$config['installedpackages']['haproxy']['ha_servers']['item'];
+$a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+
+if ($_POST) {
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ config_lock();
+ $retval = haproxy_configure();
+ config_unlock();
+ $savemsg = get_std_save_message($retval);
+ unlink_if_exists($d_haproxyconfdirty_path);
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_server[$_GET['id']]) {
+ if (!$input_errors) {
+ unset($a_server[$_GET['id']]);
+ write_config();
+ touch($d_haproxyconfdirty_path);
+ header("Location: haproxy_servers.php");
+ exit;
+ }
+ }
+}
+
+$pfSversion = str_replace("\n", "", file_get_contents("/etc/version"));
+if(strstr($pfSversion, "1.2"))
+ $one_two = true;
+
+$pgtitle = "Services: HAProxy: Servers";
+include("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<?php if($one_two): ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<?php endif; ?>
+<form action="haproxy_servers.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_haproxyconfdirty_path)): ?><p>
+<?php print_info_box_np("The virtual server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td class="tabnavtbl">
+ <?php
+ /* active tabs */
+ $tab_array = array();
+ $tab_array[] = array("Settings", false, "haproxy_global.php");
+ $tab_array[] = array("Frontends", false, "haproxy_frontends.php");
+ $tab_array[] = array("Servers", true, "haproxy_servers.php");
+ display_top_tabs($tab_array);
+ ?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">Name</td>
+ <td width="30%" class="listhdrr">Server</td>
+ <td width="20%" class="listhdrr">Status</td>
+ <td width="30%" class="listhdrr">Frontend</td>
+ <td width="10%" class="listhdrr">Cookie</td>
+ <td width="10%" class="listhdrr">Weight</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_server as $server): ?>
+ <tr>
+ <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';">
+ <?=$server['name'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';">
+ <?=$server['address'] . ":"?>
+<?php
+ if($server['port']) {
+ echo $server['port'];
+ } else {
+ foreach ($a_backends as $backend) {
+ if($backend['name'] == $server['backend']) {
+ echo $backend['port'];
+ }
+ }
+ }
+?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';">
+ <?=$server['status'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';">
+ <?=$server['backend'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';">
+ <?=$server['cookie'];?>
+ </td>
+ <td class="listlr" ondblclick="document.location='haproxy_servers_edit.php?id=<?=$i;?>';">
+ <?=$server['weight'];?>
+ </td>
+ <td class="list" nowrap>
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
+ <td valign="middle"><a href="haproxy_servers_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td>
+ <td valign="middle"><a href="haproxy_servers.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="6"></td>
+ <td class="list">
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
+ <td valign="middle"><a href="haproxy_servers_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/haproxy-devel/haproxy_servers_edit.php b/config/haproxy-devel/haproxy_servers_edit.php
new file mode 100755
index 00000000..a4360b04
--- /dev/null
+++ b/config/haproxy-devel/haproxy_servers_edit.php
@@ -0,0 +1,435 @@
+<?php
+/* $Id: load_balancer_pool_edit.php,v 1.24.2.23 2007/03/03 00:07:09 smos Exp $ */
+/*
+ haproxy_servers_edit.php
+ part of pfSense (http://www.pfsense.com/)
+ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
+ Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+$a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+
+if (!is_array($config['installedpackages']['haproxy']['ha_servers']['item'])) {
+ $config['installedpackages']['haproxy']['ha_servers']['item'] = array();
+}
+
+$a_server = &$config['installedpackages']['haproxy']['ha_servers']['item'];
+
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+else
+ $id = $_GET['id'];
+
+if (isset($id) && $a_server[$id]) {
+ $pconfig['name'] = $a_server[$id]['name'];
+ $pconfig['address'] = $a_server[$id]['address'];
+ $pconfig['port'] = $a_server[$id]['port'];
+ $pconfig['backend'] = $a_server[$id]['backend'];
+ $pconfig['weight'] = $a_server[$id]['weight'];
+ $pconfig['checkinter'] = $a_server[$id]['checkinter'];
+ $pconfig['cookie'] = $a_server[$id]['cookie'];
+ $pconfig['status'] = $a_server[$id]['status'];
+ $pconfig['advanced'] = base64_decode($a_server[$id]['advanced']);
+}
+
+$changedesc = "Services: HAProxy: Servers: ";
+$changecount = 0;
+
+if ($_POST) {
+ $changecount++;
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ $reqdfields = explode(" ", "name address weight");
+ $reqdfieldsn = explode(",", "Name,Address,Weight");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['name']))
+ $input_errors[] = "The field 'Name' contains invalid characters.";
+
+ if (preg_match("/[^a-zA-Z0-9\.]/", $_POST['address']))
+ $input_errors[] = "The field 'Address' contains invalid characters.";
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['cookie']))
+ $input_errors[] = "The field 'Cookie' contains invalid characters.";
+
+ if ($_POST['port'] && !is_numeric($_POST['port']))
+ $input_errors[] = "The field 'Port' value is not a number.";
+ else {
+ if ($_POST['port'])
+ if (!($_POST['port']>=1 && $_POST['port']<=65535))
+ $input_errors[] = "The field 'Port' value must be between 1 and 65535.";
+ }
+
+ if (!is_numeric($_POST['weight']))
+ $input_errors[] = "The field 'Weight' value is not a number.";
+ else {
+ if (!($_POST['weight']>=1 && $_POST['weight']<=256))
+ $input_errors[] = "The field 'Weight' value must be between 1 and 256.";
+ }
+
+ /* Ensure that our pool names are unique */
+ for ($i=0; isset($config['installedpackages']['haproxy']['ha_servers']['item'][$i]); $i++)
+ if (($_POST['name'] == $config['installedpackages']['haproxy']['ha_servers']['item'][$i]['name']) && ($i != $id))
+ $input_errors[] = "This server name has already been used. Server names must be unique.";
+
+ $backend = "";
+ for($x=0; $x<299; $x++) {
+ $comd = "\$backends = \$_POST['backend" . $x . "'];";
+ eval($comd);
+ if($backends)
+ $backend .= "$backends ";
+ }
+ $backend = trim($backend);
+
+ if (!$input_errors) {
+ $server = array();
+ if(isset($id) && $a_server[$id])
+ $server = $a_server[$id];
+
+ if($server['name'] != "")
+ $changedesc .= " modified '{$server['name']}' pool:";
+
+ update_if_changed("name", $server['name'], $_POST['name']);
+ update_if_changed("port", $server['port'], $_POST['port']);
+ update_if_changed("backend", $server['backend'], $backend);
+ update_if_changed("cookie", $server['cookie'], $_POST['cookie']);
+ update_if_changed("weight", $server['weight'], $_POST['weight']);
+ update_if_changed("status", $server['status'], $_POST['status']);
+ update_if_changed("address", $server['address'], $_POST['address']);
+ update_if_changed("advanced", $server['advanced'], base64_encode($_POST['advanced']));
+ update_if_changed("checkinter", $server['checkinter'], $_POST['checkinter']);
+
+ if (isset($id) && $a_server[$id]) {
+ $a_server[$id] = $server;
+ } else {
+ $a_server[] = $server;
+ }
+
+ if ($changecount > 0) {
+ touch($d_haproxyconfdirty_path);
+ write_config($changedesc);
+ /*
+ echo "<PRE>";
+ print_r($config);
+ echo "</PRE>";
+ */
+ }
+
+ header("Location: haproxy_servers.php");
+ exit;
+ }
+}
+
+$pfSversion = str_replace("\n", "", file_get_contents("/etc/version"));
+if(strstr($pfSversion, "1.2"))
+ $one_two = true;
+
+$pgtitle = "HAProxy: Server: Edit";
+include("head.inc");
+
+row_helper();
+
+?>
+
+<input type='hidden' name='address_type' value='textbox' />
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<script type="text/javascript" language="javascript" src="pool.js"></script>
+
+<script language="javascript">
+function clearcombo(){
+ for (var i=document.iform.serversSelect.options.length-1; i>=0; i--){
+ document.iform.serversSelect.options[i] = null;
+ }
+ document.iform.serversSelect.selectedIndex = -1;
+}
+</script>
+<script type="text/javascript">
+ rowname[0] = "backend";
+ rowtype[0] = "select";
+ rowsize[0] = "1";
+</script>
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if($one_two): ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<?php endif; ?>
+ <form action="haproxy_servers_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Edit HAProxy server</td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Name</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="16" maxlength="16">
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Frontend(s)</td>
+ <td width="78%" class="vtable">
+ <table id="frontendtable">
+ <tbody>
+ <tr>
+ <td><div id="onecolumn"></div></td>
+ </tr>
+ <?php
+ $counter = 0;
+ $tracker = 0;
+ $backend = $pconfig['backend'];
+ $item = explode(" ", $backend);
+ foreach($item as $ww) {
+ $address = $ww;
+ if($counter > 0)
+ $tracker = $counter + 1;
+ ?>
+ <tr>
+ <td>
+ <select name="backend<?php echo $tracker; ?>">
+ <?php
+ $i = 0;
+ if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item']))
+ $config['installedpackages']['haproxy']['ha_backends']['item'] = array();
+ $backends = split(" ", $pconfig['backend']);
+ foreach ($a_backend as $backend) {
+ ?>
+ <option value="<?=$backend['name'];?>" <?php if($backend['name'] == $ww) echo "SELECTED";?>>
+ <?=$backend['name'];?>
+ </option>
+ <?php } ?>
+ </select>
+ </td>
+ <td>
+ <?php
+ if($counter > 0)
+ echo "<input type=\"image\" src=\"/themes/".$g['theme']."/images/icons/icon_x.gif\" onclick=\"removeRow(this); return false;\" value=\"Delete\" />";
+ ?>
+ </td>
+ </tr>
+ <?php
+ $counter++;
+ } // end foreach
+ ?>
+ </tbody>
+ <tfoot>
+ </tfoot>
+ </table>
+ <a onclick="javascript:addRowTo('frontendtable'); return false;" href="#">
+ <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" />
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">
+ <div id="addressnetworkport">
+ IP Address
+ </div>
+ </td>
+ <td width="78%" class="vtable">
+ <input name="address" type="text" id="address" size="30" value="<?=htmlspecialchars($pconfig['address']);?>" />
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Port</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="5">
+ <br/>
+ NOTE: Leave blank to use Frontend port selection.
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncellreq">Status</td>
+ <td width="78%" class="vtable" colspan="2">
+ <select name="status">
+ <option value="active" <?php if($pconfig['status']=='active') echo "SELECTED";?>>active</option>
+ <option value="backup" <?php if($pconfig['status']=='backup') echo "SELECTED";?>>backup</option>
+ <option value="disabled" <?php if($pconfig['status']=='disabled') echo "SELECTED";?>>disabled</option>
+ <option value="inactive" <?php if($pconfig['status']=='inactive') echo "SELECTED";?>>inactive</option>
+ </select>
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Cookie</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="cookie" type="text" <?if(isset($pconfig['cookie'])) echo "value=\"{$pconfig['cookie']}\"";?>size="64"><br/>
+ This value will be checked in incoming requests, and the first
+ operational server possessing the same value will be selected. In return, in
+ cookie insertion or rewrite modes, this value will be assigned to the cookie
+ sent to the client. There is nothing wrong in having several servers sharing
+ the same cookie value, and it is in fact somewhat common between normal and
+ backup servers. See also the "cookie" keyword in backend section.
+
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Check inter</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="checkinter" type="text" <?if(isset($pconfig['checkinter'])) echo "value=\"{$pconfig['checkinter']}\"";?>size="64">
+ <br/>Defaults to 1000 if left blank.
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Weight</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="weight" type="text" <?if(isset($pconfig['weight'])) echo "value=\"{$pconfig['weight']}\"";?>size="64"><br/>
+ The default weight is 1, and the maximal value is 255.<br/>
+ NOTE: If this
+ parameter is used to distribute the load according to server's capacity, it
+ is recommended to start with values which can both grow and shrink, for
+ instance between 10 and 100 to leave enough room above and below for later
+ adjustments.
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top" class="vncell">Advanced pass thru</td>
+ <td width="78%" class="vtable" colspan="2">
+ <textarea name='advanced' rows="4" cols="70" id='advanced'><?php echo $pconfig['advanced']; ?></textarea>
+ <br/>
+ NOTE: paste text into this box that you would like to pass thru.
+ </td>
+ </tr>
+ <tr align="left">
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <input type="button" class="formbtn" value="Cancel" onclick="history.back()">
+ <?php if (isset($id) && $a_server[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+ </form>
+<br>
+<?php include("fend.inc"); ?>
+<script type="text/javascript">
+ field_counter_js = 1;
+ rows = 1;
+ totalrows = <?php echo $counter; ?>;
+ loaded = <?php echo $counter; ?>;
+</script>
+</body>
+</html>
+
+<?php
+
+function row_helper() {
+ global $pconfig, $a_backend;
+ $options = "";
+ if($a_backend) {
+ foreach ($a_backend as $backend) {
+ $options .= "<option value='{$backend['name']}'";
+ if($backend['name'] == $pconfig['backend'])
+ $options .= "SELECTED";
+ $options .= ">";
+ $options .= $backend['name'];
+ $options .= "</option>";
+ }
+ }
+
+ echo <<<EOF
+<script type="text/javascript">
+// Global Variables
+var rowname = new Array(99);
+var rowtype = new Array(99);
+var newrow = new Array(99);
+var rowsize = new Array(99);
+
+for (i = 0; i < 99; i++) {
+ rowname[i] = '';
+ rowtype[i] = '';
+ newrow[i] = '';
+ rowsize[i] = '25';
+}
+
+var field_counter_js = 0;
+var loaded = 0;
+var is_streaming_progress_bar = 0;
+var temp_streaming_text = "";
+
+var addRowTo = (function() {
+ return (function (tableId) {
+ var d, tbody, tr, td, bgc, i, ii, j;
+ d = document;
+ tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0);
+ tr = d.createElement("tr");
+ totalrows++;
+ for (i = 0; i < field_counter_js; i++) {
+ td = d.createElement("td");
+ if(rowtype[i] == 'textbox') {
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + "'></input> ";
+ } else if(rowtype[i] == 'select') {
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><select size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + "'>$options</select> ";
+ } else {
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input type='checkbox' name='" + rowname[i] + totalrows + "'></input> ";
+ }
+ tr.appendChild(td);
+ }
+ td = d.createElement("td");
+ td.rowSpan = "1";
+
+ td.innerHTML = '<input type="image" src="/themes/' + theme + '/images/icons/icon_x.gif" onclick="removeRow(this); return false;" value="Delete">';
+ tr.appendChild(td);
+ tbody.appendChild(tr);
+ });
+})();
+
+function removeRow(el) {
+ var cel;
+ while (el && el.nodeName.toLowerCase() != "tr")
+ el = el.parentNode;
+
+ if (el && el.parentNode) {
+ cel = el.getElementsByTagName("td").item(0);
+ el.parentNode.removeChild(el);
+ }
+}
+
+function find_unique_field_name(field_name) {
+ // loop through field_name and strip off -NUMBER
+ var last_found_dash = 0;
+ for (var i = 0; i < field_name.length; i++) {
+ // is this a dash, if so, update
+ // last_found_dash
+ if (field_name.substr(i,1) == "-" )
+ last_found_dash = i;
+ }
+ if (last_found_dash < 1)
+ return field_name;
+ return(field_name.substr(0,last_found_dash));
+}
+</script>
+
+EOF;
+
+}
+
+?> \ No newline at end of file