From eedaa9f220c6f287438c422b73f668a9d8bf0352 Mon Sep 17 00:00:00 2001
From: willy tarreau <willy@wtap.(none)>
Date: Sat, 17 Dec 2005 14:08:03 +0100
Subject: [PATCH] * released 1.1.23 * fixed a stupid bug introduced in 1.1.22
 which caused second and subsequent   'default' sections to keep previous
 parameters, and not initialize logs   correctly. * fixed a second stupid bug
 introduced in 1.1.22 which caused configurations   relying on 'dispatch' mode
 to segfault at the first connection. * 'option httpchk' now supports method,
 HTTP version and a few headers. * now, 'option httpchk', 'cookie' and
 'capture' can be specified in   'defaults' section * a fresh new english
 documentation * large Makefile cleanup for increased portability * new build
 script 'build.cfg' for Formilux-0.1.8 * new startup script
 'init.haproxy.flx0' for Formilux-0.1.8

---
 CHANGELOG                               |   12 +-
 Makefile                                |   49 +-
 TODO                                    |   13 +-
 doc/haproxy-en.txt                      | 1257 +++++++++++++++++++++++
 doc/haproxy.txt                         |   74 +-
 examples/build.cfg                      |   25 +
 examples/config.rc.haproxy              |    1 -
 init.d/haproxy => examples/init.haproxy |    0
 examples/init.haproxy.flx0              |   20 +
 haproxy.c                               |  136 ++-
 tests/defaults.cfg                      |    2 +-
 11 files changed, 1512 insertions(+), 77 deletions(-)
 create mode 100644 doc/haproxy-en.txt
 create mode 100644 examples/build.cfg
 rename init.d/haproxy => examples/init.haproxy (100%)
 create mode 100644 examples/init.haproxy.flx0

diff --git a/CHANGELOG b/CHANGELOG
index 658224b2b..cdf4e5aa5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,17 @@
 ChangeLog :
 ===========
 
-2003/09/10 :
+2003/09/19 : 1.1.23
+  - fixed a stupid bug introduced in 1.1.22 which caused second and subsequent
+    'default' sections to keep previous parameters, and not initialize logs
+    correctly.
+  - fixed a second stupid bug introduced in 1.1.22 which caused configurations
+    relying on 'dispatch' mode to segfault at the first connection.
+  - 'option httpchk' now supports method, HTTP version and a few headers.
+  - now, 'option httpchk', 'cookie' and 'capture' can be specified in
+    'defaults' section
+
+2003/09/10 : 1.1.22
   - 'listen' now supports optionnal address:port-range lists
   - 'bind' introduced to add new listen addresses
   - fixed a bug which caused a session to be kept established on a server till
diff --git a/Makefile b/Makefile
index 45fcad51c..43e4493d4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,53 +1,72 @@
+# This makefile supports different OS and CPU setups.
+# You should use it this way :
+#   make TARGET=os CPU=cpu
+
 # Select target OS. TARGET must match a system for which COPTS and LIBS are
 # correctly defined below.
-# You can set it on make's command line. eg: make TARGET=solaris
 TARGET = linux24
 #TARGET = linux22
 #TARGET = solaris
-#TARGET = solarisv9
 #TARGET = openbsd
 
-CC = gcc
-LD = gcc
+# pass CPU=<cpu_name> to make to optimize for a particular CPU
+CPU = generic
+#CPU = i586
+#CPU = i686
+#CPU = ultrasparc
 
 # By default, we use libc's regex.
 REGEX=libc
 #REGEX=pcre
 
+# tools options
+CC = gcc
+LD = gcc
+
 # This is the directory hosting include/pcre.h and lib/libpcre.* when REGEX=pcre
 PCREDIR	:= $(shell pcre-config --prefix 2>/dev/null || :)
 #PCREDIR=/usr/local
 
 # This is for Linux 2.4 with netfilter
-COPTS.linux24 = -O2 -DNETFILTER
+COPTS.linux24 = -DNETFILTER
 LIBS.linux24 =
 
 # This is for Linux 2.2
-COPTS.linux22 = -O2 -DUSE_GETSOCKNAME
+COPTS.linux22 = -DUSE_GETSOCKNAME
 LIBS.linux22 =
 
 # This is for Solaris 8
-COPTS.solaris = -O2 -fomit-frame-pointer -DSOLARIS
+COPTS.solaris = -fomit-frame-pointer -DSOLARIS
 LIBS.solaris = -lnsl -lsocket
 
-# This is for Solaris 8 on UltraSparc2 processor
-COPTS.solarisv9 = -O6 -mcpu=v9 -mtune=ultrasparc -fomit-frame-pointer -DSOLARIS
-LIBS.solarisv9 = -lnsl -lsocket
-
 # This is for OpenBSD 3.0
-COPTS.openbsd = -O2
+COPTS.openbsd =
 LIBS.openbsd =
 
-COPTS.libc=
-LIBS.libs=
+# CPU dependant optimizations
+COPTS.generic = -O2
+COPTS.i586 = -O2 -march=i586
+COPTS.i686 = -O2 -march=i686
+COPTS.ultrasparc = -O6 -mcpu=v9 -mtune=ultrasparc
 
+# options for standard regex library
+COPTS.libc=
+LIBS.libc=
+
+# options for libpcre
 COPTS.pcre=-DUSE_PCRE -I$(PCREDIR)/include
 LIBS.pcre=-L$(PCREDIR)/lib -lpcreposix -lpcre
 
+# you can enable debug arguments with "DEBUG=-g" or disable them with "DEBUG="
 #DEBUG =
 DEBUG = -g
 
-COPTS=$(COPTS.$(TARGET)) $(COPTS.$(REGEX))
+# global options
+TARGET_OPTS=$(COPTS.$(TARGET))
+REGEX_OPTS=$(COPTS.$(REGEX))
+CPU_OPTS=$(COPTS.$(CPU))
+
+COPTS=$(CPU_OPTS) $(TARGET_OPTS) $(REGEX_OPTS)
 LIBS=$(LIBS.$(TARGET)) $(LIBS.$(REGEX))
 
 # - use -DSTATTIME=0 to disable statistics, else specify an interval in
diff --git a/TODO b/TODO
index 72301b2bf..c11c82f3d 100644
--- a/TODO
+++ b/TODO
@@ -73,11 +73,14 @@ ok>
      ok- les options
      ok- le retry
      ok- les checks
+     ok- les cookies/captures
        - les options des serveurs ?
        - les filtres et regex ?
-       - les cookies/captures
 
 5) impl�menter "balance source" pour faire un hash sur la source.
+   permettre de sp�cifier un masque sur lequel s'applique le hachage,
+   ainsi qu'une option pour hacher en fonction de l'adresse dans le
+   champ "x-forwarded-for".
 
 6) possibilit� d'un process s�par� par listen :
    listen XXX
@@ -86,6 +89,9 @@ ok>
 le fait de sp�cifier group_id fera que toutes les instances utilisant le m�me
 identifiant de groupe seront g�r�es par un m�me processus.
 
+   -> plus souple et plus compr�hensible de faire des sections par processus,
+      ce qui r�soud �galement le cas ci-dessous
+
 7) g�rer un chroot/uid/gid diff�rents par process :
    listen XXX
       chroot /truc
@@ -100,3 +106,8 @@ identifiant de groupe seront g
    - alerte en cas de disparition
    - le nombre max de sessions � lui envoyer
 
+ok> 9) ajouter des param�tres optionnels � l'option "httpchk" permettant
+ok>    de forcer la m�thode, la version HTTP et des headers.
+ok>    ex: option httpchk        -> OPTIONS / HTTP/1.0
+ok> 	   option httpchk /test  -> OPTIONS /test HTTP/1.0
+ok> 	   option httpchk HEAD / HTTP/1.0\nHost:\ www   -> tel quel
diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt
new file mode 100644
index 000000000..7d678d2e1
--- /dev/null
+++ b/doc/haproxy-en.txt
@@ -0,0 +1,1257 @@
+
+         		     H A - P r o x y
+         		     ---------------
+         		      version 1.1.23
+			      willy tarreau
+			       2003/09/20
+
+============
+| Abstract |
+============
+
+HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited for high
+availability environments. Indeed, it can :
+  - route HTTP requests depending on statically assigned cookies ;
+  - spread the load among several servers while assuring server persistence
+    through the use of HTTP cookies ;
+  - switch to backup servers in the event a main one fails ;
+  - accept connections to special ports dedicated to service monitoring ;
+  - stop accepting connections without breaking existing ones ;
+  - add/modify/delete HTTP headers both ways ;
+  - block requests matching a particular pattern ;
+
+It needs very little resource. Its event-driven architecture allows it to easily
+handle thousands of simultaneous connections on hundreds of instances without
+risking the system's stability.
+
+====================
+| Start parameters |
+====================
+
+There are only a few command line options :
+
+    -f <configuration file>
+    -n <high limit for the total number of simultaneous connections>
+    -N <high limit for the per-proxy number of simultaneous connections>
+    -d starts in foregreound with debugging mode enabled
+    -D starts in daemon mode
+    -s shows statistics (only if compiled in)
+    -l shows even more statistics (implies '-s')
+
+
+The maximal number of connections per proxy is used as the default parameter for
+each instance for which the 'maxconn' paramter is not set in the 'listen' section.
+
+The maximal number of total connections limits the number of connections used by
+the whole process if the 'maxconn' parameter is not set in the 'global' section.
+
+The debugging mode has the same effect as the 'debug' option in the 'global'
+section. When the proxy runs in this mode, it dumps every connections,
+disconnections, timestamps, and HTTP headers to stdout. This should NEVER
+be used in an init script since it will prevent the system from starting up.
+
+Statistics are only available if compiled in with the 'STATTIME' option. It's
+only used during code optimization phases.
+
+======================
+| Configuration file |
+======================
+
+Structure
+=========
+
+The configuration file parser ignores empty lines, spaces, tabs. Anything
+between a sharp ('#') not following a backslash ('\'), and the end of a line
+constitutes a comment and is ignored too.
+
+The configuration file is segmented in sections. A section begins whenever
+one of these 3 keywords are encountered :
+
+  - 'global'
+  - 'listen'
+  - 'defaults'
+
+Every parameter refer to the section beginning at the last one of these 3
+keywords.
+
+
+1) Global parameters
+====================
+
+Global parameters affect the whole process behaviour. They are all set in the
+'global' section. There may be several 'global' sections if needed, but their
+parameters will only be merged. Allowed parameters in 'global' section include
+the following ones :
+
+  - log <address> <facility> [max_level]
+  - maxconn <number>
+  - uid <user id>
+  - gid <group id>
+  - chroot <directory>
+  - nbproc <number>
+  - daemon
+  - debug
+  - quiet
+
+1.1) Event logging
+------------------
+Most events are logged : start, stop, servers going up and down, connections and
+errors. Each event generates a syslog message which can be sent to up to 2
+servers. The syntax is :
+
+    log <ip_address> <facility> [max_level]
+
+Connections are logged at level "info". Services initialization and servers
+going up are logged at level "notice", termination signals are logged at
+"warning", and definitive service termination, as well as loss of servers are
+logged at level "alert". The optional parameter <max_level> specifies above
+what level messages should be sent. Level can take one of these 8 values :
+
+    emerg, alert, crit, err, warning, notice, info, debug
+
+For backwards compatibility with versions 1.1.16 and earlier, the default level
+value is "debug" if not specified.
+
+Permitted facilities are :
+    kern, user, mail, daemon, auth, syslog, lpr, news,
+    uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
+    local0, local1, local2, local3, local4, local5, local6, local7
+
+According to RFC3164, messages are truncated to 1024 bytes before being emitted.
+
+Example :
+---------
+    global
+	log 192.168.2.200 local3
+	log 127.0.0.1     local4 notice
+
+1.2) limiting the number of connections
+---------------------------------------
+It is possible and recommended to limit the global number of per-process
+connections. Since one connection includes both a client and a server, it
+means that the max number of TCP sessions will be about the double of this
+number. It's important to understand this when trying to find best values
+for 'ulimit -n' before starting the proxy. To anticipate the number of
+sockets needed, all these parameters must be counted :
+
+  - 1 socket per incoming connection
+  - 1 socket per outgoing connection
+  - 1 socket per address/port/proxy tuple.
+  - 1 socket per server being health-checked
+  - 1 socket for all logs
+
+In simple configurations where each proxy only listens one one address/port,
+set the limit of file descriptors (ulimit -n) to 
+(2 * maxconn + nbproxies + nbservers + 1). In a future release, haproxy may
+be able to set this value itself.
+
+1.3) Drop of priviledges
+------------------------
+In order to reduce the risk and consequences of attacks, in the event where a
+yet non-identified vulnerability would be successfully exploited, it's possible
+to lower the process priviledges and even isolate it in a riskless directory.
+
+In the 'global' section, the 'uid' parameter sets a numerical user identifier
+which the process will switch to after binding its listening sockets. The value
+'0', which normally represents the super-user, here indicates that the UID must
+not change during startup. It's the default behaviour. The 'gid' parameter does
+the same for the group identifier. It's particularly advised against use of
+generic accounts such as 'nobody' because it has the same consequences as using
+'root' if other services use them.
+
+The 'chroot' parameter makes the process isolate itself in an empty directory
+just before switching its UID. This type of isolation (chroot) can sometimes
+be worked around on certain OS (Linux, Solaris), provided that the attacker
+has gained 'root' priviledges and has the ability to use or create a directory.
+For this reason, it's capital to use a dedicated directory and not to share one
+between several services of different nature. To make isolation more resistant,
+it's recommended to use an empty directory without any right, and to change the
+UID of the process so that it cannot do anything there.
+
+Note: in the event where such a vulnerability would be exploited, it's most
+likely that first attempts would kill the process due to 'Segmentation Fault',
+'Bus Error' or 'Illegal Instruction' signals. Eventhough it's true that
+isolating the server reduces the risks of intrusion, it's sometimes useful to
+find why a process dies, via the analysis of a 'core' file, although very rare
+(the last bug of this sort was fixed in 1.1.9). For security reasons, most
+systems disable the generation of core file when a process changes its UID. So
+the two workarounds are either to start the process from a restricted user
+account, which will not be able to chroot itself, or start it as root and not
+change the UID. In both cases the core will be either in the start or the chroot
+directories. Do not forget to allow core dumps prior to start the process :
+
+# ulimit -c unlimited
+
+Example :
+---------
+
+    global
+	uid	30000
+	gid	30000
+	chroot  /var/chroot/haproxy
+
+1.4) Startup modes
+------------------
+The service can start in several different :
+  - foreground / background
+  - quiet / normal / debug
+
+The default mode is normal, foreground, which means that the program doesn't
+return once started. NEVER EVER use this mode in a system startup script, or
+the system won't boot. It needs to be started in background, so that it
+returns immediately after forking. That's accomplished by the 'daemon' option
+in the 'global' section, which is the equivalent of the '-D' command line
+argument.
+
+Moreover, certain alert messages are still sent to the standard output even
+in 'daemon' mode. To make them disappear, simply add the 'quiet' option in the
+'global' section. This option has no command-line equivalent.
+
+Last, the 'debug' mode, enabled with the 'debug' option in the 'global' section,
+and which is equivalent of the '-d' option, allows deep TCP/HTTP analysis, with
+timestamped display of each connection, disconnection, and HTTP headers for both
+ways. This mode is incompatible with 'daemon' and 'quiet' modes for obvious
+reasons.
+
+1.5) Increasing the overall processing power
+--------------------------------------------
+On multi-processor systems, it may seem to be a shame to use only one processor,
+eventhough the load needed to saturate a recent processor are far above common
+usage. Anyway, for very specific needs, the proxy can start several processes
+between which the operating system will spread the incoming connections. The
+number of processes is controlled by the 'nbproc' parameter in the 'global'
+section. It defaults to 1, and obviously works only in 'daemon' mode.
+
+Example :
+---------
+
+    global
+	daemon
+	quiet
+	nbproc	2
+
+
+2) Declaration of a listening service
+=====================================
+
+Service sections start with the 'listen' keyword :
+
+    listen <instance_name> [ <IP_address>:<port_range>[,...] ]
+
+- <instance_name> is the name of the instance. This name will be reported in
+  logs, so it is good to have it reflect the proxied service. No unicity test
+  is done on this name, and it's not mandatory for it to be unique, but highly
+  recommended.
+
+- <IP_address> is the IP address the proxy binds to. Empty address, '*' and
+  '0.0.0.0' all mean that the proxy listens to all valid addresses on the
+  system.
+
+- <port_range> is either a unique port, or a port range for which the proxy will
+  accept connections for the IP address specified above. This range can be :
+    - a numerical port (ex: '80')
+    - a dash-delimited ports range explicitly stating the lower and upper bounds
+      (ex: '2000-2100') which are included in the range.
+
+  Particular care must be taken against port ranges, because every <addr:port>
+  couple consumes one socket (=a file descriptor), so it's easy to eat lots of
+  descriptors with a simple range. The <addr:port> couple must be used only once
+  among all instances running on a same system. Please note that attaching to
+  ports lower than 1024 need particular priviledges to start the program, which
+  are independant of the 'uid' parameter.
+
+- the <IP_address>:<port_range> couple may be repeated indefinitely to require
+  the proxy to listen to other addresses and/or ports. To achieve this, simply
+  separate them with a coma.
+
+Examples :
+---------
+    listen http_proxy :80
+    listen x11_proxy 127.0.0.1:6000-6009
+    listen smtp_proxy 127.0.0.1:25,127.0.0.1:587
+    listen ldap_proxy :389,:663
+
+In the event that all addresses do not fit line width, it's preferable to
+detach secondary addresses on other lines with the 'bind' keyword. If this
+keyword is used, it's not even necessary to specify the first address on the
+'listen' line, which sometimes makes multiple configuration handling easier :
+
+    bind [ <IP_address>:<port_range>[,...] ]
+
+Examples :
+----------
+    listen http_proxy
+        bind :80,:443
+	bind 10.0.0.1:10080,10.0.0.1:10443
+
+2.1) Inhibiting a service
+-------------------------
+A service may be disabled for maintenance reasons, without needing to comment
+out the whole section, simply by specifying the 'disabled' keyword in the
+section to be disabled :
+
+    listen smtp_proxy 0.0.0.0:25
+	disabled
+
+Note: the 'enabled' keyword allows to enable a service which has been disabled
+      previously by a default configuration.
+
+2.2) Modes of operation
+-----------------------
+A service can work in 3 different distinct modes :
+  - TCP
+  - HTTP
+  - monitoring
+
+TCP mode
+--------
+In this mode, the service relays TCP connections as soon as they're established,
+towards one or several servers. No processing is done on the stream. It's only
+an association of source(addr:port) -> destination(addr:port). To use this mode,
+you must specify 'mode tcp' in the 'listen' section. This is the default mode.
+
+Example :
+---------
+    listen smtp_proxy 0.0.0.0:25
+	mode tcp
+
+HTTP mode
+---------
+In this mode, the service relays TCP connections towards one or several servers,
+when it has enough informations to decide, which normally means that all HTTP
+headers have been read. Some of them may be scanned for a cookie or a pattern
+matching a regex. To use this mode, specify 'mode http' in the 'listen' section.
+
+Example :
+---------
+    listen http_proxy 0.0.0.0:80
+	mode http
+
+Health-checking mode
+--------------------
+This mode provides a way for external components to check the proxy's health.
+It is meant to be used with intelligent load-balancers which can use send/expect
+scripts to check for all of their servers' availability. This one simply accepts
+the connection, returns the word 'OK' and closes it. To enable it, simply
+specify 'health' as the working mode :
+
+Example :
+---------
+    listen health_check 0.0.0.0:60000
+	mode health
+
+
+2.3) Limiting the number of simultaneous connections
+----------------------------------------------------
+The 'maxconn' parameter allows a proxy to refuse connections above a certain
+amount of simultaneous ones. When the limit is reached, it simply stops
+listening, but the system may still be accepting them because of the back log
+queue. These connections will be processed further when other ones have freed
+some slots. This provides a serialization effect which helps very fragile
+servers resist to high loads. Se further for system limitations.
+
+Example :
+---------
+    listen tiny_server 0.0.0.0:80
+        maxconn 10
+
+
+2.4) Soft stop
+--------------
+It is possible to stop services without breaking existing connections by the
+sending of the SIG_USR1 signal to the process. All services are then put into
+soft-stop state, which means that they will refuse to accept new connections,
+except for those which have a non-zero value in the 'grace' parameter, in which
+case they will still accept connections for the specified amount of time, in
+milliseconds. This allows to tell a load-balancer that the service is failing,
+while still doing the job during the time it needs to detect it.
+
+Note: active connections are never killed. In the worst case, the user will have
+to wait for all of them to close or to time-out, or simply kill the process
+normally (SIG_TERM). The default 'grace' value is '0'.
+
+Example :
+---------
+    # enter soft stop after 'killall -USR1 haproxy'
+    # the service will still run 10 seconds after the signal
+    listen http_proxy 0.0.0.0:80
+	mode http
+	grace 10000
+
+    # this port is dedicated to a load-balancer, and must fail immediately
+    listen health_check 0.0.0.0:60000
+	mode health
+	grace 0
+
+
+2.5) Connections expiration time
+--------------------------------
+It is possible (and recommended) to configure several time-outs on TCP
+connections. Three independant timers are adjustable with values specified
+in milliseconds. A session will be terminated if either one of these timers
+expire.
+
+  - the time we accept to wait for data from the client, or for the client to
+    accept data : 'clitimeout' :
+
+	# client time-out set to 2mn30.
+	clitimeout	150000
+
+  - the time we accept to wait for data from the server, or for the server to
+    accept data : 'srvtimeout' :
+
+	# server time-out set to 30s.
+	srvtimeout	30000
+
+  - the time we accept to wait for a connection to establish on a server :
+    'contimeout' :
+
+        # we give up if the connection does not complete within 4 seconds
+	contimeout	4000
+
+Notes :
+-------
+  - 'contimeout' and 'srvtimeout' have no sense on 'health' mode servers ;
+  - under high loads, or with a saturated or defective network, it's possible
+    that some packets get lost. Since the first TCP retransmit only happens
+    after 3 seconds, a time-out equal to, or lower than 3 seconds cannot
+    compensate for a packet loss. A 4 seconds time-out seems a reasonable
+    minimum which will considerably reduce connection failures.
+
+2.6) Attempts to reconnect
+--------------------------
+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' paramter.
+
+Example :
+---------
+	# we can retry 3 times max after a failure
+	retries 3
+
+
+2.7) Address of the dispatch server (deprecated)
+------------------------------------------------
+The server which will be sent all new connections is defined by the 'dispatch'
+parameter, in the form <address>:<port>. It generally is dedicated to unknown
+connections and will assign them a cookie, in case of HTTP persistence mode,
+or simply is a single server in case of generic TCP proxy. This old mode is only
+provided for backwards compatibility, but doesn't allow to check remote servers
+state, and has a rather limited usage. All new setups should switch to 'balance'
+mode. The principle of the dispatcher is to be able to perform the load
+balancing itself, but work only on new clients so that the server doesn't need
+to be a big machine.
+
+Example :
+---------
+   	# all new connections go there
+	dispatch 192.168.1.2:80
+
+Note :
+------
+This parameter has no sense for 'health' servers, and is incompatible with
+'balance' mode.
+
+
+2.8) Outgoing source address
+----------------------------
+It is often necessary to bind to a particular address when connecting to some
+remote hosts. This is done via the 'source' parameter which is a per-proxy
+parameter. A newer version may allow to fix different sources to reach different
+servers. The syntax is 'source <address>[:<port>]', where <address> is a valid
+local address (or '0.0.0.0' or '*' or empty to let the system choose), and
+<port> is an optional parameter allowing the user to force the source port for
+very specific needs. If the port is not specified or is '0', the system will
+choose a free port. Note that as of version 1.1.18, the servers health checks
+are also performed from the same source.
+
+Examples :
+----------
+    listen http_proxy *:80
+   	# all connections take 192.168.1.200 as source address
+	source 192.168.1.200:0
+
+    listen rlogin_proxy *:513
+   	# use address 192.168.1.200 and the reserved port 900 (needs to be root)
+	source 192.168.1.200:900
+
+
+2.9) Setting the cookie name
+----------------------------
+In HTTP mode, it is possible to look for a particular cookie which will contain
+a server identifier which should handle the connection. The cookie name is set
+via the 'cookie' parameter.
+
+Example :
+---------
+    listen http_proxy :80
+	mode http
+	cookie SERVERID
+
+It is possible to change the cookie behaviour to get a smarter persistence,
+depending on applications. It is notably possible to delete or modify a cookie
+emitted by a server, insert a cookie identifying the server in an HTTP response
+and even add a header to tell upstream caches not to cache this response.
+
+Examples :
+----------
+
+To remove the cookie for direct accesses (ie when the server matches the one
+which was specified in the client cookie) :
+
+	cookie SERVERID indirect
+
+To replace the cookie value with the one assigned to the server if any (no
+cookie will be created if the server does not provide one, nor if the
+configuration does not provide one). This lets the application put the cookie
+exactly on certain pages (eg: successful authentication) :
+
+	cookie SERVERID rewrite
+
+To create a new cookie and assign the server identifier to it (in this case, all
+servers should be associated with a valid cookie, since no cookie will simply
+delete the cookie from the client's browser) :
+
+	cookie SERVERID insert
+
+To insert a cookie and ensure that no upstream cache will store it, add the
+'nocache' option :
+
+	cookie SERVERID insert nocache
+
+To insert a cookie only after a POST request, add 'postonly' after 'insert'.
+This has the advantage that there's no risk of caching, and that all pages
+seen before the POST one can still be cached :
+
+	cookie SERVERID insert postonly
+
+Notes :
+-----------
+- it is possible to combine 'insert' with 'indirect' or 'rewrite' to adapt to
+  applications which already generate the cookie with an invalid content.
+
+- in the case where 'insert' and 'indirect' are both specified, the cookie is
+  never transmitted to the server, since it wouldn't understand it. This is
+  the most application-transparent mode.
+
+- it is particularly recommended to use 'nocache' in 'insert' mode if any
+  upstream HTTP/1.0 cache is susceptible to cache the result, because this may
+  lead to many clients going to the same server, or even worse, some clients
+  having their server changed while retrieving a page from the cache.
+
+- when the application is well known and controlled, the best method is to
+  only add the persistence cookie on a POST form because it's up to the
+  application to select which page it wants the upstream servers to cache.
+  In this case, you would use 'insert postonly indirect'.
+
+2.10) Associating a cookie value with a server
+----------------------------------------------
+In HTTP mode, it's possible to associate a cookie value to each server. This
+was initially used in combination with 'dispatch' mode to handle direct accesses
+but it is now the standard way of doing the load balancing. The syntax is :
+
+    server <identifier> <address>:<port> cookie <value>
+
+- <identifier> is any name which can be used to identify the server in the logs.
+- <address>:<port> specifies where the server is bound.
+- <value> is the value to put in or to read from the cookie.
+
+Example : the 'SERVERID' cookie can be either 'server01' or 'server02'
+---------
+    listen http_proxy :80
+	mode http
+	cookie SERVERID
+	dispatch 192.168.1.100:80
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+
+Warning : the syntax has changed since version 1.0 !
+---------
+
+3) Autonomous load balancer
+===========================
+
+The proxy can perform the load-balancing itself, both in TCP and in HTTP modes.
+This is the most interesting mode which obsoletes the old 'dispatch' mode
+described above. It has advantages such as server health monitoring, multiple
+port binding and port mapping. To use this mode, the 'balance' keyword is used,
+followed by the selected algorithm. As of version 1.1.23, only 'roundrobin' is
+available, which is also the default value if unspecified. In this mode, there
+will be no dispatch address, but the proxy needs at least one server.
+
+Example : same as the last one, with internal load balancer
+---------
+
+    listen http_proxy :80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+
+
+Since version 1.1.22, it is possible to automatically determine on which port
+the server will get the connection, depending on the port the client connected
+to. Indeed, there now are 4 possible combinations for the server's <port> field:
+
+  - unspecified or '0' :
+    the connection will be sent to the same port as the one on which the proxy
+    received the client connection itself.
+
+  - numerical value (the only one supported in versions earlier than 1.1.22) :
+    the connection will always be sent to the specified port.
+
+  - '+' followed by a numerical value :
+    the connection will be sent to the same port as the one on which the proxy
+    received the connection, plus this value.
+
+  - '-' followed by a numerical value :
+    the connection will be sent to the same port as the one on which the proxy
+    received the connection, minus this value.
+    
+Examples :
+----------
+
+# same as previous example
+
+    listen http_proxy :80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	server web1 192.168.1.1 cookie server01
+	server web2 192.168.1.2 cookie server02
+
+# simultaneous relaying of ports 80, 81 and 8080-8089
+
+    listen http_proxy :80,:81,:8080-8089
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	server web1 192.168.1.1 cookie server01
+	server web2 192.168.1.2 cookie server02
+
+# relaying of TCP ports 25, 389 and 663 to ports 1025, 1389 and 1663
+
+    listen http_proxy :25,:389,:663
+	mode tcp
+	balance roundrobin
+	server srv1 192.168.1.1:+1000
+	server srv2 192.168.1.2:+1000
+
+
+3.1) Servers monitoring
+-----------------------
+
+It is possible to check the servers status by trying to establish TCP
+connections or even sending HTTP requests to them. A server which fails to
+reply to health checks as expected will not be used by the load balancing
+algorithms. To enable monitoring, add the 'check' keyword on a server line.
+It is possible to specify the interval between tests (in milliseconds) with
+the 'inter' parameter, the number of failures supported before declaring that
+the server has fallen down with the 'fall' parameter, and the number of valid
+checks needed for the server to fully get up with the 'rise' parameter. Since
+version 1.1.22, it is also possible to send checks to a different port
+(mandatory when none is specified) with the 'port' parameter. The default
+values are the following ones :
+
+  - inter : 2000
+  - rise  : 2
+  - fall  : 3
+  - port  : default server port
+
+The default mode consists in establishing TCP connections only. But in certain
+types of application failures, it is often that the server continues to accept
+connections because the system does it itself while the application is running
+an endless loop, or is completely stuck. So in version 1.1.16 were introduced
+HTTP health checks which only performed simple lightweight requests and analysed
+the response. Now, as of version 1.1.23, it is possible to change the HTTP
+method, the URI, and the HTTP version string (which even allows to send headers
+with a dirty trick). To enable HTTP health-checks, use 'option httpchk'.
+
+By default, requests use the 'OPTIONS' method because it's very light and easy
+to filter from logs, and does it on '/'. Only HTTP responses 2xx and 3xx are
+considered valid ones, and only if they come before the time to send a new
+request is reached ('inter' parameter). If some servers block this type of
+request, 3 other forms help to forge a request :
+
+  - option httpchk               -> OPTIONS / HTTP/1.0
+  - option httpchk URI           -> OPTIONS <URI> HTTP/1.0
+  - option httpchk METH URI      -> <METH> <URI> HTTP/1.0
+  - option httpchk METH URI VER  -> <METH> <URI> <VER>
+
+See examples below.
+
+Since version 1.1.17, it is possible to specify backup servers. These servers
+are only sollicited when no other server is available. This may only be useful
+to serve a maintenance page, or define one active and one backup server (seldom
+used in TCP mode). To make a server a backup one, simply add the 'backup' option
+on its line. These servers also support cookies, so if a cookie is specified for
+a backup server, clients assigned to this server will stick to it even when the
+other ones come back. Conversely, if no cookie is assigned to such a server,
+the clients will get their cookies removed (empty cookie = removal), and will
+be balanced against other servers once they come back. Please note that there
+is no load-balancing among backup servers. If there are several backup servers,
+the second one will only be used when the first one dies, and so on.
+
+Since version 1.1.17, it is also possible to visually check the status of all
+servers at once. For this, you just have to send a SIGHUP signal to the proxy.
+The servers status will be dumped into the logs at the 'notice' level, as well
+as on <stderr> if not closed. For this reason, it's always a good idea to have
+one local log server at the 'notice' level.
+
+Examples :
+----------
+# same setup as in  paragraph 3) with TCP monitoring
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
+
+# same with HTTP monitoring via 'OPTIONS / HTTP/1.0'
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	option httpchk
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
+
+# same with HTTP monitoring via 'OPTIONS /index.html HTTP/1.0'
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	option httpchk /index.html
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
+
+# same with HTTP monitoring via 'HEAD /index.jsp? HTTP/1.1\r\nHost: www'
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	option httpchk HEAD /index.jsp? HTTP/1.1\r\nHost:\ www
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
+
+# automatic insertion of a cookie in the server's response, and automatic
+# deletion of the cookie in the client request, while asking upstream caches
+# not to cache replies.
+    listen web_appl 0.0.0.0:80
+	mode http
+	cookie SERVERID insert nocache indirect
+	balance roundrobin
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check
+
+# same with off-site application backup and local error pages server
+    listen web_appl 0.0.0.0:80
+	mode http
+	cookie SERVERID insert nocache indirect
+	balance roundrobin
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check
+	server web-backup 192.168.2.1:80 cookie server03 check backup
+	server web-excuse 192.168.3.1:80 check backup
+
+# SMTP+TLS relaying with heakth-checks and backup servers
+
+    listen http_proxy :25,:587
+	mode tcp
+	balance roundrobin
+	server srv1 192.168.1.1 check port 25 inter 30000 rise 1 fall 2
+	server srv2 192.168.1.2 backup
+
+
+3.2) Redistribute connections in case of failure
+------------------------------------------------
+In HTTP mode, if a server designated by a cookie does not respond, the clients
+may definitely stick to it because they cannot flush the cookie, so they will
+not be able to access the service anymore. Specifying 'redispatch' will allow
+the proxy to break their persistence and redistribute them to working servers.
+
+Example :
+---------
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	dispatch 192.168.1.100:80
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+	redispatch # send back to dispatch in case of connection failure
+
+Up to, and including version 1.1.16, this parameter only applied to connection
+failures. Since version 1.1.17, it also applies to servers which have been
+detected as failed by the health check mechanism. Indeed, a server may be broken
+but still accepting connections, which would not solve every case. But it is
+possible to conserve the old behaviour, that is, make a client insist on trying
+to connect to a server even if it is said to be down, by setting the 'persist'
+option :
+
+    listen http_proxy 0.0.0.0:80
+	mode http
+	option persist
+	cookie SERVERID
+	dispatch 192.168.1.100:80
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+	redispatch # send back to dispatch in case of connection failure
+
+
+4) Additionnal features
+=======================
+
+Other features are available. They are transparent mode, event logging and
+header rewriting/filtering.
+
+4.1) Transparent mode
+---------------------
+In HTTP mode, the 'transparent' keyword allows to intercept sessions which are
+routed through the system hosting the proxy. This mode was implemented as a
+replacement for the 'dispatch' mode, since connections without cookie will be
+sent to the original address while known cookies will be sent to the servers.
+This mode implies that the system can redirect sessions to a local port.
+
+Example :
+---------
+    listen http_proxy 0.0.0.0:65000
+	mode http
+	transparent
+	cookie SERVERID
+	server server01 192.168.1.1:80
+	server server02 192.168.1.2:80
+
+    # iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
+      --dport 80 -j REDIRECT --to-ports 65000
+
+Note :
+------
+If the port is left unspecified on the server, the port the client connected to
+will be used. This allows to relay a full port range without using transparent
+mode nor thousands of file descriptors, provided that the system can redirect
+sessions to local ports.
+
+Example :
+---------
+    # redirect all ports to local port 65000, then forward to the server on the
+    # original port.
+    listen http_proxy 0.0.0.0:65000
+	mode tcp
+	server server01 192.168.1.1 check port 60000
+	server server02 192.168.1.2 check port 60000
+
+    # iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
+      -j REDIRECT --to-ports 65000
+
+
+4.2) Event logging
+------------------
+
+
+- 8< - - - 8< - - - 8< - - - 8< - - - 8< - - - 8< - - -
+
+
+
+Les connexions TCP et HTTP peuvent donner lieu � une journalisation sommaire ou
+d�taill�e indiquant, pour chaque connexion, la date, l'heure, l'adresse IP
+source, le serveur destination, la dur�e de la connexion, les temps de r�ponse,
+la requ�te HTTP, le code de retour, la quantit� de donn�es transmises, et m�me
+dans certains cas, la valeur d'un cookie permettant de suivre les sessions.
+Tous les messages sont envoy�s en syslog vers un ou deux serveurs. Se r�f�rer �
+la section 1.1 pour plus d'information sur les cat�gories de logs.  La syntaxe
+est la suivante :
+
+    log <adresse_ip_1> <cat�gorie_1> [niveau_max_1]
+    log <adresse_ip_2> <cat�gorie_2> [niveau_max_2]
+ou
+    log global
+
+Remarque :
+----------
+La syntaxe sp�cifique 'log global' indique que l'on souhaite utiliser les
+param�tres de journalisation d�finis dans la section 'global'.
+
+Exemple :
+---------
+    listen http_proxy 0.0.0.0:80
+	mode http
+	log 192.168.2.200 local3
+	log 192.168.2.201 local4
+
+Par d�faut, les informations contenues dans les logs se situent au niveau TCP
+uniquement. Il faut pr�ciser l'option 'httplog' pour obtenir les d�tails du
+protocole HTTP. Dans les cas o� un m�canisme de surveillance effectuant des
+connexions et d�connexions fr�quentes, polluerait les logs, il suffit d'ajouter
+l'option 'dontlognull', pour ne plus obtenir une ligne de log pour les sessions
+n'ayant pas donn� lieu � un �change de donn�es (requ�te ou r�ponse).
+
+Exemple :
+---------
+    listen http_proxy 0.0.0.0:80
+	mode http
+	option httplog
+	option dontlognull
+	log 192.168.2.200 local3
+
+Depuis la version 1.1.18, un indicateur de compl�tude de la session a �t� ajout�
+dans les logs HTTP. C'est un champ de 4 caract�res pr�c�dant la requ�te HTTP,
+indiquant :
+  - sur le premier caract�re, un code pr�cisant le premier �v�nement qui a caus�
+    la terminaison de la session :
+
+        C : fermeture de la session TCP de la part du client
+	S : fermeture de la session TCP de la part du serveur, ou refus de connexion
+	P : terminaison pr�matur�e des sessions par le proxy, pour cas d'erreur
+	    interne ou de configuration (ex: filtre d'URL)
+	c : expiration du d�lai d'attente c�t� client : clitimeout
+	s : expiration du d�lai d'attente c�t� serveur: srvtimeout et contimeout
+	- : terminaison normale.
+
+  - sur le second caract�re, l'�tat d'avancement de la session HTTP lors de la
+    fermeture :
+
+        R : terminaison en attendant la r�ception totale de la requ�te du client
+	C : terminaison en attendant la connexion vers le serveur
+	H : terminaison en attendant la r�ception totale des ent�tes du serveur
+	D : terminaison durant le transfert des donn�es du serveur vers le client
+	L : terminaison durant le transfert des derni�res donn�es du proxy vers
+	    le client, alors que le serveur a d�j� fini.
+	- : terminaison normale, apr�s fin de transfert des donn�es
+
+  - le troisi�me caract�re indique l'�ventuelle identification d'un cookie de
+    persistence :
+
+        N : aucun cookie de persistence n'a �t� pr�sent�.
+	I : le client a pr�sent� un cookie ne correspondant � aucun serveur
+	    connu.
+	D : le client a pr�sent� un cookie correspondant � un serveur hors
+	    d'usage. Suivant l'option 'persist', il a �t� renvoy� vers un
+	    autre serveur ou a tout de m�me tent� de se connecter sur celui
+	    correspondant au cookie.
+	V : le client a pr�sent� un cookie valide et a pu se connecter au
+	    serveur correspondant.
+	- : non appliquable
+
+  - le dernier caract�re indique l'�ventuel traitement effectu� sur un cookie de
+    persistence retrourn� par le serveur :
+
+        N : aucun cookie de persistence n'a �t� fourni par le serveur.
+        P : un cookie cookie de persistence n'a �t� fourni par le serveur.
+	I : aucun cookie n'a �t� fourni par le serveur, il a �t� ins�r� par le
+	    proxy.
+	D : le cookie pr�sent� par le serveur a �t� supprim� par le proxy pour
+	    ne pas �tre retourn� au client.
+	R : le cookie retourn� par le serveur a �t� modifi� par le proxy.
+	- : non appliquable
+
+Le mot cl� "capture" permet d'ajouter dans des logs HTTP des informations
+captur�es dans les �changes. La version 1.1.17 supporte uniquement une capture
+de cookies client et serveur, ce qui permet dans bien des cas, de reconstituer
+la session d'un utilisateur. La syntaxe est la suivante :
+
+    capture cookie <pr�fixe_cookie> len <longueur_capture>
+
+Le premier cookie dont le nom commencera par <pr�fixe_cookie> sera captur�, et
+transmis sous la forme "NOM=valeur", sans toutefois, exc�der <longueur_capture>
+caract�res (64 au maximum). Lorsque le nom du cookie est fixe et connu, on peut
+le suffixer du signe "=" pour s'assurer qu'aucun autre cookie ne prendra sa
+place dans les logs.
+
+Exemples :
+----------
+    # capture du premier cookie dont le nom commence par "ASPSESSION"
+    capture cookie ASPSESSION len 32
+
+    # capture du premier cookie dont le nom est exactement "vgnvisitor"
+    capture cookie vgnvisitor= len 32
+
+Dans les logs, le champ pr�c�dant l'indicateur de compl�tude contient le cookie
+positionn� par le serveur, pr�c�d� du cookie positionn� par le client. Chacun de
+ces champs est remplac� par le signe "-" lorsqu'aucun cookie n'est fourni par le
+client ou le serveur.
+
+Enfin, l'option 'forwardfor' ajoute l'adresse IP du client dans un champ
+'X-Forwarded-For' de la requ�te, ce qui permet � un serveur web final de
+conna�tre l'adresse IP du client initial.
+
+Exemple :
+---------
+    listen http_proxy 0.0.0.0:80
+	mode http
+	log  global
+	option httplog
+	option dontlognull
+	option forwardfor
+	capture cookie userid= len 20
+
+
+4.3) Modification des ent�tes HTTP
+----------------------------------
+En mode HTTP uniquement, il est possible de remplacer certains en-t�tes dans la
+requ�te et/ou la r�ponse � partir d'expressions r�guli�res. Il est �galement
+possible de bloquer certaines requ�tes en fonction du contenu des en-t�tes ou de
+la requ�te. Une limitation cependant : les en-t�tes fournis au milieu de
+connexions persistentes (keep-alive) ne sont pas vus car ils sont consid�r�s
+comme faisant partie des �changes de donn�es cons�cutifs � la premi�re requ�te.
+Les donn�es ne sont pas affect�es, ceci ne s'applique qu'aux en-t�tes. 
+
+La syntaxe est :
+   reqadd    <string>             pour ajouter un en-t�te dans la requ�te
+   reqrep    <search> <replace>   pour modifier la requ�te
+   reqirep   <search> <replace>   idem sans distinction majuscules/minuscules
+   reqdel    <search>             pour supprimer un en-t�te dans la requ�te
+   reqidel   <search>             idem sans distinction majuscules/minuscules
+   reqallow  <search>             autoriser la requ�te si un ent�te valide <search>
+   reqiallow <search>             idem sans distinction majuscules/minuscules
+   reqdeny   <search>             interdire la requ�te si un ent�te valide <search>
+   reqideny  <search>             idem sans distinction majuscules/minuscules
+   reqpass   <search>             inhibe ces actions sur les ent�tes validant <search>
+   reqipass  <search>             idem sans distinction majuscules/minuscules
+
+   rspadd   <string>              pour ajouter un en-t�te dans la r�ponse
+   rsprep   <search> <replace>    pour modifier la r�ponse
+   rspirep  <search> <replace>    idem sans distinction majuscules/minuscules
+   rspdel   <search>              pour supprimer un en-t�te dans la r�ponse
+   rspidel  <search>              idem sans distinction majuscules/minuscules
+
+
+<search> est une expression r�guli�re compatible POSIX regexp supportant le
+groupage par parenth�ses (sans les '\'). Les espaces et autres s�parateurs
+doivent �tres pr�c�d�s d'un '\' pour ne pas �tre confondus avec la fin de la
+cha�ne. De plus, certains caract�res sp�ciaux peuvent �tre pr�c�d�s d'un
+backslach ('\') :
+
+  \t   pour une tabulation
+  \r   pour un retour charriot
+  \n   pour un saut de ligne
+  \    pour diff�rencier un espace d'un s�parateur
+  \#   pour diff�rencier un di�se d'un commentaire
+  \\   pour utiliser un backslash dans la regex
+  \\\\ pour utiliser un backslash dans le texte
+  \xXX pour un caract�re sp�cifique XX (comme en C)
+
+
+<replace> contient la cha�ne rempla�ant la portion v�rifi�e par l'expression.
+Elle peut inclure les caract�res sp�ciaux ci-dessus, faire r�f�rence � un
+groupe d�limit� par des parenth�ses dans l'expression r�guli�re, par sa
+position num�rale. Les positions vont de 1 � 9, et sont cod�es par un '\'
+suivi du chiffre d�sir�. Il est �galement possible d'ins�rer un caract�re non
+imprimable (utile pour le saut de ligne) inscrivant '\x' suivi du code
+hexad�cimal de ce caract�re (comme en C).
+
+<string> repr�sente une cha�ne qui sera ajout�e syst�matiquement apr�s la
+derni�re ligne d'en-t�te.
+
+Remarques :
+---------
+  - la premi�re ligne de la requ�te et celle de la r�ponse sont trait�es comme
+    des en-t�tes, ce qui permet de r��crire des URL et des codes d'erreur.
+  - 'reqrep' est l'�quivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
+    'srvexp'. Ces noms sont toujours support�s mais d�conseill�s.
+  - pour des raisons de performances, le nombre total de caract�res ajout�s sur
+    une requ�te ou une r�ponse est limit� � 4096 depuis la version 1.1.5 (cette
+    limite �tait � 256 auparavant). Cette valeur est modifiable dans le code.
+    Pour un usage temporaire, on peut gagner de la place en supprimant quelques
+    ent�tes inutiles avant les ajouts.
+
+Exemples :
+--------
+	reqrep	^(GET.*)(.free.fr)(.*) \1.online.fr\3
+	reqrep	^(POST.*)(.free.fr)(.*) \1.online.fr\3
+	reqirep	^Proxy-Connection:.*	Proxy-Connection:\ close
+	rspirep	^Server:.* Server:\ Tux-2.0
+	rspirep	^(Location:\ )([^:]*://[^/]*)(.*) \1\3
+	rspidel  ^Connection:
+	rspadd	Connection:\ close
+
+
+4.4) R�partition avec persistence
+---------------------------------
+
+La combinaison de l'insertion de cookie avec la r�partition de charge interne
+permet d'assurer une persistence dans les sessions HTTP d'une mani�re
+pratiquement transparente pour les applications. Le principe est simple :
+  - attribuer une valeur d'un cookie � chaque serveur
+  - effectuer une r�partition interne
+  - ins�rer un cookie dans les r�ponses issues d'une r�partition uniquement,
+    et faire en sorte que des caches ne m�morisent pas ce cookie.
+  - cacher ce cookie � l'application lors des requ�tes ult�rieures.
+
+Exemple :
+---------
+    listen application 0.0.0.0:80
+	mode http
+	cookie SERVERID insert nocache indirect
+	balance roundrobin
+	server 192.168.1.1:80 cookie server01 check
+	server 192.168.1.2:80 cookie server02 check
+
+4.5) Personalisation des erreurs
+--------------------------------
+
+Certaines situations conduisent � retourner une erreur HTTP au client :
+  - requ�te invalide ou trop longue => code HTTP 400
+  - requ�te mettant trop de temps � venir => code HTTP 408
+  - requ�te interdite (bloqu�e par un reqideny) => code HTTP 403
+  - erreur interne du proxy => code HTTP 500
+  - le serveur a retourn� une r�ponse incompl�te ou invalide => code HTTP 502
+  - aucun serveur disponible pour cette requ�te => code HTTP 503
+  - le serveur n'a pas r�pondu dans le temps imparti => code HTTP 504
+
+Un message d'erreur succint tir� de la RFC accompagne ces codes de retour.
+Cependant, en fonction du type de client�le, on peut pr�f�rer retourner des
+pages personnalis�es. Ceci est possible par le biais de la commande "errorloc" :
+
+    errorloc <code_HTTP> <location>
+
+Au lieu de g�n�rer une erreur HTTP <code_HTTP> parmi les codes cit�s ci-dessus,
+le proxy g�n�rera un code de redirection temporaire (HTTP 302) vers l'adresse
+d'une page pr�cis�e dans <location>. Cette adresse peut �tre relative au site,
+ou absolue. Comme cette r�ponse est tra�t�e par le navigateur du client
+lui-m�me, il est indispensable que l'adresse fournie lui soit accessible.
+
+Exemple :
+---------
+    listen application 0.0.0.0:80
+        errorloc 400 /badrequest.html
+        errorloc 403 /forbidden.html
+        errorloc 408 /toolong.html
+	errorloc 500 http://haproxy.domain.net/bugreport.html
+        errorloc 502 http://192.168.114.58/error50x.html
+        errorloc 503 http://192.168.114.58/error50x.html
+        errorloc 504 http://192.168.114.58/error50x.html
+
+4.6) Changement des valeurs par d�faut
+--------------------------------------
+
+Dans la version 1.1.22 est apparue la notion de valeurs par d�faut, ce qui �vite
+de r�p�ter des param�tres communs � toutes les instances, tels que les timeouts,
+adresses de log, modes de fonctionnement, etc.
+
+Les valeurs par d�faut sont positionn�es dans la derni�re section 'defaults'
+pr�c�dent l'instance qui les utilisera. On peut donc mettre autant de sections
+'defaults' que l'on veut. Il faut juste se rappeler que la pr�sence d'une telle
+section implique une annulation de tous les param�tres par d�faut positionn�s
+pr�c�demment, dans le but de les remplacer.
+
+La section 'defaults' utilise la m�me syntaxe que la section 'listen', aux
+param�tres pr�s qui ne sont pas support�s. Le mot cl� 'defaults' peut accepter
+un commentaire en guise param�tre.
+
+Dans la version 1.1.22, seuls les param�tres suivants peuvent �tre positionn�s
+dans une section 'defaults' :
+  - log (le premier et le second)
+  - mode { tcp, http, health }
+  - balance { roundrobin }
+  - disabled (pour d�sactiver toutes les instances qui suivent)
+  - enabled (pour faire l'op�ration inverse, mais c'est le cas par d�faut)
+  - contimeout, clitimeout, srvtimeout, grace, retries, maxconn
+  - option { redispatch, transparent, keepalive, forwardfor, httplog,
+             dontlognull, persist, httpchk }
+  - redispatch, redisp, transparent, source { addr:port }
+  - cookie, capture
+  - errorloc
+
+Ne sont pas support�s dans cette version, les adresses de dispatch et les
+configurations de serveurs, ainsi que tous les filtres bas�s sur les
+expressions r�guli�res :
+  - dispatch, server,
+  - req*, rsp*, 
+
+Enfin, il n'y a pas le moyen, pour le moment, d'invalider un param�tre bool�en
+positionn� par d�faut. Donc si une option est sp�cifi�e dans les param�tres par
+d�faut, le seul moyen de la d�sactiver pour une instance, c'est de changer les
+param�tres par d�faut avant la d�claration de l'instance.
+
+Exemples :
+----------
+    defaults applications TCP
+	log global
+	mode tcp
+	balance roundrobin
+	clitimeout 180000
+	srvtimeout 180000
+	contimeout 4000
+	retries 3
+	redispatch
+
+    listen app_tcp1 10.0.0.1:6000-6063
+	server srv1 192.168.1.1 check port 6000 inter 10000
+	server srv2 192.168.1.2 backup
+
+    listen app_tcp2 10.0.0.2:6000-6063
+	server srv1 192.168.2.1 check port 6000 inter 10000
+	server srv2 192.168.2.2 backup
+    
+    defaults applications HTTP
+	log global
+	mode http
+	option httplog
+	option forwardfor
+	option dontlognull
+	balance roundrobin
+	clitimeout 20000
+	srvtimeout 20000
+	contimeout 4000
+	retries 3
+
+    listen app_http1 10.0.0.1:80-81
+	cookie SERVERID postonly insert indirect
+	capture cookie userid= len 10
+	server srv1 192.168.1.1:+8000 cookie srv1 check port 8080 inter 1000
+	server srv1 192.168.1.2:+8000 cookie srv2 check port 8080 inter 1000
+
+    defaults
+	# section vide qui annule tous les param�tes par d�faut.
+
+=======================
+| Param�trage syst�me |
+=======================
+
+Sous Linux 2.4
+==============
+
+-- cut here --
+#!/bin/sh
+# set this to about 256/4M (16384 for 256M machine)
+MAXFILES=16384
+echo $MAXFILES > /proc/sys/fs/file-max
+ulimit -n $MAXFILES
+
+if [ -e /proc/sys/net/ipv4/ip_conntrack_max ]; then
+	echo 65536 > /proc/sys/net/ipv4/ip_conntrack_max
+fi
+
+if [ -e /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait ]; then
+	# 30 seconds for fin, 15 for time wait
+	echo 3000 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait
+	echo 1500 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_time_wait
+	echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_invalid_scale
+	echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_out_of_window
+fi
+
+echo 1024 60999 > /proc/sys/net/ipv4/ip_local_port_range
+echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
+echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
+echo 262144 > /proc/sys/net/ipv4/tcp_max_tw_buckets
+echo 262144 > /proc/sys/net/ipv4/tcp_max_orphans
+echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
+echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
+echo 0 > /proc/sys/net/ipv4/tcp_timestamps
+echo 0 > /proc/sys/net/ipv4/tcp_ecn
+echo 0 > /proc/sys/net/ipv4/tcp_sack
+echo 0 > /proc/sys/net/ipv4/tcp_dsack
+
+# auto-tuned on 2.4
+#echo 262143 > /proc/sys/net/core/rmem_max
+#echo 262143 > /proc/sys/net/core/rmem_default
+
+echo 16384 65536 524288 > /proc/sys/net/ipv4/tcp_rmem
+echo 16384 349520 699040 > /proc/sys/net/ipv4/tcp_wmem
+
+-- cut here --
+
+-- fin --
diff --git a/doc/haproxy.txt b/doc/haproxy.txt
index e6bcfb360..5df305dfd 100644
--- a/doc/haproxy.txt
+++ b/doc/haproxy.txt
@@ -1,9 +1,9 @@
 
          		     H A - P r o x y
          		     ---------------
-         		      version 1.1.22
+         		      version 1.1.23
 			      willy tarreau
-			       2003/09/11
+			       2003/09/20
 
 ================
 | Introduction |
@@ -112,7 +112,7 @@ optionnel <niveau_max> d
 valeurs suivantes  :
     emerg, alert, crit, err, warning, notice, info, debug
 
-Par compatibilit� avec les versions 1.1.16 et ant�rieures, La valeur par d�faut
+Par compatibilit� avec les versions 1.1.16 et ant�rieures, la valeur par d�faut
 est "debug" si l'option n'est pas pr�cis�e.
 
 Les cat�gories possibles sont :
@@ -138,12 +138,13 @@ param
 de sockets n�cessaires, il faut prendre en compte ces param�tres :
   - 1 socket par connexion entrante
   - 1 socket par connexion sortante
-  - 1 socket par proxy
+  - 1 socket par couple adresse/port d'�coute par proxy
   - 1 socket pour chaque serveur en cours de health-check
   - 1 socket pour les logs (tous serveurs confondus)
 
-Positionner la limite du nombre de descripteurs de fichiers (ulimit -n) �
-2 * maxconn + nbproxy + nbserveurs + 1. Dans une future version, haproxy sera
+Dans le cas o� chaque proxy n'�coute que sur un couple adresse/port, positionner
+la limite du nombre de descripteurs de fichiers (ulimit -n) � 
+(2 * maxconn + nbproxy + nbserveurs + 1). Dans une future version, haproxy sera
 capable de positionner lui-m�me cette limite.
 
 1.3) Diminution des privil�ges
@@ -165,13 +166,13 @@ processus utilisent les m
 Le param�tre 'chroot' autorise � changer la racine du processus une fois le
 programme lanc�, de sorte que ni le processus, ni l'un de ses descendants ne
 puissent remonter de nouveau � la racine. Ce type de cloisonnement (chroot) est
-parfois contournable sur certains OS (Linux 2.2, Solaris), mais visiblement
-fiable sur d'autres (Linux 2.4). Aussi, il est important d'utiliser un
-r�pertoire sp�cifique au service pour cet usage, et de ne pas mutualiser un m�me
-r�pertoire pour plusieurs services de nature diff�rente. Pour rendre l'isolement
-plus robuste, il est conseill� d'utiliser un r�pertoire vide, sans aucun droit,
-et de changer l'uid du processus de sorte qu'il ne puisse rien faire dans ledit
-r�pertoire.
+g�n�ralement contournable sur certains OS (Linux, Solaris) pour peu que
+l'attaquant poss�de des droits 'root' et soit en mesure d'utiliser ou de cr�er
+un r�pertoire. Aussi, il est important d'utiliser un r�pertoire sp�cifique au
+service pour cet usage, et de ne pas mutualiser un m�me r�pertoire pour
+plusieurs services de nature diff�rente. Pour rendre l'isolement plus robuste,
+il est conseill� d'utiliser un r�pertoire vide, sans aucun droit, et de changer
+l'uid du processus de sorte qu'il ne puisse rien faire dans ledit r�pertoire.
 
 Remarque: dans le cas o� une telle faille serait mise en �vidence, il est fort
 probable que les premi�res tentatives de son exploitation provoquent un arr�t du
@@ -297,16 +298,20 @@ Exemples :
 
 2.1) Inhibition d'un service
 ----------------------------
-Un serveur peut �tre d�sactiv� pour des besoins de maintenance, sans avoir �
+Un service peut �tre d�sactiv� pour des besoins de maintenance, sans avoir �
 commenter toute une partie du fichier. Il suffit de positionner le mot cl�
 "disabled" dans sa section :
 
     listen smtp_proxy 0.0.0.0:25
 	disabled
 
+Remarque: le mot cl� 'enabled' permet de r�activer un service pr�alablement
+	  d�sactiv� par le mot cl� 'disabled', par exemple � cause d'une
+	  configuration par d�faut.
+
 2.2) Mode de fonctionnement
 ---------------------------
-Un serveur peut fonctionner dans trois modes diff�rents :
+Un service peut fonctionner dans trois modes diff�rents :
   - TCP
   - HTTP
   - supervision
@@ -470,7 +475,7 @@ pour permettre aux serveurs de trouver le chemin de retour dans des contextes de
 routage difficiles. Si l'adresse est '0.0.0.0' ou '*' ou vide, elle sera choisie
 librement par le systeme. Si le port est '0' ou vide, il sera choisi librement
 par le syst�me. Il est � noter que depuis la version 1.1.18, les tests de bon
-foncitonnement des serveurs seront aussi effectu�s � partir de la source
+fonctionnement des serveurs seront aussi effectu�s � partir de la source
 sp�cifi�e par ce param�tre.
 
 Exemples :
@@ -540,14 +545,17 @@ Remarques :
 - Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite' pour s'adapter
   � des applications g�n�rant d�j� le cookie, avec un contenu invalide. Il suffit
   pour cela de les sp�cifier sur la m�me ligne.
+
 - dans le cas o� 'insert' et 'indirect' sont sp�cifi�s, le cookie n'est jamais
   transmis au serveur vu qu'il n'en a pas connaissance et ne pourrait pas le
   comprendre.
+
 - il est particuli�rement recommand� d'utiliser 'nocache' en mode insertion si
   des caches peuvent se trouver entre les clients et l'instance du proxy. Dans
   le cas contraire, un cache HTTP 1.0 pourrait cacher la r�ponse, incluant le
   cookie de persistence ins�r�, donc provoquer des changements de serveurs pour
   des clients partageant le m�me cache.
+
 - lorsque l'application est bien connue, et que les parties n�cessitant de la
   persistence sont syst�matiquement acc�d�es par un formulaire en mode POST,
   il est plus efficace encore de combiner le mot cl� "postonly" avec "insert"
@@ -680,7 +688,12 @@ serveur. Seules les r
 compris non-r�ponses) aboutissent � un �chec. Le temps maximal imparti pour une
 r�ponse est �gal � l'intervalle entre deux tests (param�tre "inter"). Pour
 activer ce mode, sp�cifier l'option "httpchk", �ventuellement suivie d'une
-URI. Voir les exemples ci-apr�s.	
+m�thode et d'une URI. L'option "httpchk" accepte donc 4 formes :
+  - option httpchk               -> OPTIONS / HTTP/1.0
+  - option httpchk URI           -> OPTIONS <URI> HTTP/1.0
+  - option httpchk METH URI      -> <METH> <URI> HTTP/1.0
+  - option httpchk METH URI VER  -> <METH> <URI> <VER>
+Voir les exemples ci-apr�s.	
 
 Depuis la version 1.1.17, il est possible de d�finir des serveurs de secours,
 utilis�s uniquement lorsqu'aucun des autres serveurs ne fonctionne. Pour cela,
@@ -735,6 +748,15 @@ Exemples :
 	server web1 192.168.1.1:80 cookie server01 check
 	server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
 
+# idem avec surveillance HTTP par 'HEAD /index.jsp? HTTP/1.1\r\nHost: www'
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	option httpchk HEAD /index.jsp? HTTP/1.1\r\nHost:\ www
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
+
 # Insertion automatique de cookie dans la r�ponse du serveur, et suppression
 # automatique dans la requ�te, tout en indiquant aux caches de ne pas garder
 # ce cookie.
@@ -745,15 +767,15 @@ Exemples :
 	server web1 192.168.1.1:80 cookie server01 check
 	server web2 192.168.1.2:80 cookie server02 check
 
-# idem avec serveur applicatif de secours, et serveur de pages d'erreurs
+# idem avec serveur applicatif de secours sur autre site, et serveur de pages d'erreurs
     listen web_appl 0.0.0.0:80
 	mode http
 	cookie SERVERID insert nocache indirect
 	balance roundrobin
 	server web1 192.168.1.1:80 cookie server01 check
 	server web2 192.168.1.2:80 cookie server02 check
-	server web-backup 192.168.1.3:80 cookie server03 check backup
-	server web-excuse 192.168.1.4:80 check backup
+	server web-backup 192.168.2.1:80 cookie server03 check backup
+	server web-excuse 192.168.3.1:80 check backup
 
 # relayage SMTP+TLS avec test du serveur et serveur de backup
 
@@ -1140,15 +1162,15 @@ dans une section 'defaults' :
   - enabled (pour faire l'op�ration inverse, mais c'est le cas par d�faut)
   - contimeout, clitimeout, srvtimeout, grace, retries, maxconn
   - option { redispatch, transparent, keepalive, forwardfor, httplog,
-             dontlognull, persist }
+             dontlognull, persist, httpchk }
   - redispatch, redisp, transparent, source { addr:port }
-
-Ne sont pas support�s dans cette version, d'une mani�re g�n�rale, tous les
-param�tres qui n�cessitent de m�moriser autre chose que des adresses IP uniques
-et valeurs num�riques simples :
-  - dispatch, server,
   - cookie, capture
   - errorloc
+
+Ne sont pas support�s dans cette version, les adresses de dispatch et les
+configurations de serveurs, ainsi que tous les filtres bas�s sur les
+expressions r�guli�res :
+  - dispatch, server,
   - req*, rsp*, 
 
 Enfin, il n'y a pas le moyen, pour le moment, d'invalider un param�tre bool�en
diff --git a/examples/build.cfg b/examples/build.cfg
new file mode 100644
index 000000000..2dd752729
--- /dev/null
+++ b/examples/build.cfg
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# build script for formilux >0.1.8
+
+PATCH_LIST=
+FILE_LIST=
+
+function do_compile_only {
+    $FLXMAKE CPU_OPTS="-march=$arch -mcpu=$cpu -Os -mpreferred-stack-boundary=2 -momit-leaf-frame-pointer -malign-jumps=0" \
+	     TARGET=linux24
+}
+
+function do_prepack {
+    mkdir -p $ROOTDIR/sbin/init.d ; cp examples/init.haproxy.flx0 $ROOTDIR/sbin/init.d/haproxy
+    mkdir -p $ROOTDIR/usr/sbin ; cp haproxy $ROOTDIR/usr/sbin
+    mkdir -p $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/haproxy/
+    cp examples/haproxy.cfg $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/haproxy/haproxy.cfg
+    cp examples/rc.highsock $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/rc.highsock
+    cp examples/config.rc.haproxy $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/config.rc.haproxy
+    mkdir -p $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER
+    cp doc/haproxy.txt $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER
+    ln -s ../../examples/$PKGRADIX/$PKGRADIX-$PKGVER $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER/examples
+    cp examples/debug2ansi examples/debug2html examples/debugfind $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER/
+    set_default_perm $ROOTDIR
+}
diff --git a/examples/config.rc.haproxy b/examples/config.rc.haproxy
index c7aa83872..067f07a46 100644
--- a/examples/config.rc.haproxy
+++ b/examples/config.rc.haproxy
@@ -1,4 +1,3 @@
 service haproxy
 	config /etc/haproxy/haproxy.cfg
-	maxconn 1024
 
diff --git a/init.d/haproxy b/examples/init.haproxy
similarity index 100%
rename from init.d/haproxy
rename to examples/init.haproxy
diff --git a/examples/init.haproxy.flx0 b/examples/init.haproxy.flx0
new file mode 100644
index 000000000..aa5f0cb48
--- /dev/null
+++ b/examples/init.haproxy.flx0
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+. `dirname $0`/functions
+
+option	config		standard_option	/etc/haproxy/haproxy.cfg
+option	bin		reserved_option	/usr/sbin/haproxy
+option	cmdline		reserved_option	'$bin -q -D -f ${opt_config}'
+
+function do_help {
+    echo "Usage: ${0##*/} <status|start|stop|help>"
+    echo "List of config.rc options (name, type, default value, current value) :"
+    echo
+    echo "   - config ; def=/etc/haproxy/haproxy.cfg ; cur=$opt_confdir"
+    echo
+    exit 1 
+}
+
+
+load_config
+
diff --git a/haproxy.c b/haproxy.c
index 1d24a912b..43c4c65da 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -53,8 +53,8 @@
 #include <linux/netfilter_ipv4.h>
 #endif
 
-#define HAPROXY_VERSION "1.1.22"
-#define HAPROXY_DATE	"2003/09/11"
+#define HAPROXY_VERSION "1.1.23"
+#define HAPROXY_DATE	"2003/09/20"
 
 /* this is for libc5 for example */
 #ifndef TCP_NODELAY
@@ -1475,7 +1475,7 @@ int connect_server(struct session *s) {
 
     /* if this server remaps proxied ports, we'll use
      * the port the client connected to with an offset. */
-    if (s->srv->state & SRV_MAPPORTS) {
+    if (s->srv != NULL && s->srv->state & SRV_MAPPORTS) {
 	struct sockaddr_in sockname;
 	int namelen;
 
@@ -4405,6 +4405,48 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	curproxy->maxconn = defproxy.maxconn;
 	curproxy->conn_retries = defproxy.conn_retries;
 	curproxy->options = defproxy.options;
+
+	if (defproxy.check_req)
+	    curproxy->check_req = strdup(defproxy.check_req);
+	curproxy->check_len = defproxy.check_len;
+
+	if (defproxy.cookie_name)
+	    curproxy->cookie_name = strdup(defproxy.cookie_name);
+	curproxy->cookie_len = defproxy.cookie_len;
+
+	if (defproxy.capture_name)
+	    curproxy->capture_name = strdup(defproxy.capture_name);
+	curproxy->capture_namelen = defproxy.capture_namelen;
+	curproxy->capture_len = defproxy.capture_len;
+
+	if (defproxy.errmsg.msg400)
+	    curproxy->errmsg.msg400 = strdup(defproxy.errmsg.msg400);
+	curproxy->errmsg.len400 = defproxy.errmsg.len400;
+
+	if (defproxy.errmsg.msg403)
+	    curproxy->errmsg.msg403 = strdup(defproxy.errmsg.msg403);
+	curproxy->errmsg.len403 = defproxy.errmsg.len403;
+
+	if (defproxy.errmsg.msg408)
+	    curproxy->errmsg.msg408 = strdup(defproxy.errmsg.msg408);
+	curproxy->errmsg.len408 = defproxy.errmsg.len408;
+
+	if (defproxy.errmsg.msg500)
+	    curproxy->errmsg.msg500 = strdup(defproxy.errmsg.msg500);
+	curproxy->errmsg.len500 = defproxy.errmsg.len500;
+
+	if (defproxy.errmsg.msg502)
+	    curproxy->errmsg.msg502 = strdup(defproxy.errmsg.msg502);
+	curproxy->errmsg.len502 = defproxy.errmsg.len502;
+
+	if (defproxy.errmsg.msg503)
+	    curproxy->errmsg.msg503 = strdup(defproxy.errmsg.msg503);
+	curproxy->errmsg.len503 = defproxy.errmsg.len503;
+
+	if (defproxy.errmsg.msg504)
+	    curproxy->errmsg.msg504 = strdup(defproxy.errmsg.msg504);
+	curproxy->errmsg.len504 = defproxy.errmsg.len504;
+
 	curproxy->clitimeout = defproxy.clitimeout;
 	curproxy->contimeout = defproxy.contimeout;
 	curproxy->srvtimeout = defproxy.srvtimeout;
@@ -4421,6 +4463,19 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	return 0;
     }
     else if (!strcmp(args[0], "defaults")) {  /* use this one to assign default values */
+	/* some variables may have already been initialized earlier */
+	if (defproxy.check_req)     free(defproxy.check_req);
+	if (defproxy.cookie_name)   free(defproxy.cookie_name);
+	if (defproxy.capture_name)  free(defproxy.capture_name);
+	if (defproxy.errmsg.msg400) free(defproxy.errmsg.msg400);
+	if (defproxy.errmsg.msg403) free(defproxy.errmsg.msg403);
+	if (defproxy.errmsg.msg408) free(defproxy.errmsg.msg408);
+	if (defproxy.errmsg.msg500) free(defproxy.errmsg.msg500);
+	if (defproxy.errmsg.msg502) free(defproxy.errmsg.msg502);
+	if (defproxy.errmsg.msg503) free(defproxy.errmsg.msg503);
+	if (defproxy.errmsg.msg504) free(defproxy.errmsg.msg504);
+
+	init_default_instance();
 	curproxy = &defproxy;
 	return 0;
     }
@@ -4460,15 +4515,16 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
     }
     else if (!strcmp(args[0], "cookie")) {  /* cookie name */
 	int cur_arg;
-	if (curproxy == &defproxy) {
-	    Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
-	    return -1;
-	}
+//	  if (curproxy == &defproxy) {
+//	      Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
+//	      return -1;
+//	  }
 
 	if (curproxy->cookie_name != NULL) {
-	    Alert("parsing [%s:%d] : cookie name already specified. Continuing.\n",
-		  file, linenum);
-	    return 0;
+//	      Alert("parsing [%s:%d] : cookie name already specified. Continuing.\n",
+//		    file, linenum);
+//	      return 0;
+	    free(curproxy->cookie_name);
 	}
 	
 	if (*(args[1]) == 0) {
@@ -4510,15 +4566,16 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
     }
     else if (!strcmp(args[0], "capture")) {  /* name of a cookie to capture */
-	if (curproxy == &defproxy) {
-	    Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
-	    return -1;
-	}
+//	  if (curproxy == &defproxy) {
+//	      Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
+//	      return -1;
+//	  }
 
 	if (curproxy->capture_name != NULL) {
-	    Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n",
-		  file, linenum, args[0]);
-	    return 0;
+//	      Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n",
+//		    file, linenum, args[0]);
+//	      return 0;
+	    free(curproxy->capture_name);
 	}
 	
 	if (*(args[4]) == 0) {
@@ -4609,15 +4666,28 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (!strcmp(args[1], "httpchk")) {
 	    /* use HTTP request to check servers' health */
+	    if (curproxy->check_req != NULL) {
+		free(curproxy->check_req);
+	    }
 	    curproxy->options |= PR_O_HTTP_CHK;
-	    if (*args[2]) {
+	    if (!*args[2]) { /* no argument */
+		curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
+		curproxy->check_len = strlen(DEF_CHECK_REQ);
+	    } else if (!*args[3]) { /* one argument : URI */
 		int reqlen = strlen(args[2]) + strlen("OPTIONS / HTTP/1.0\r\n\r\n");
 		curproxy->check_req = (char *)malloc(reqlen);
 		curproxy->check_len = snprintf(curproxy->check_req, reqlen,
 			 "OPTIONS %s HTTP/1.0\r\n\r\n", args[2]); /* URI to use */
-	    } else {
-		curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
-		curproxy->check_len = strlen(DEF_CHECK_REQ);
+	    } else { /* more arguments : METHOD URI [HTTP_VER] */
+		int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n\r\n");
+		if (*args[4])
+		    reqlen += strlen(args[4]);
+		else
+		    reqlen += strlen("HTTP/1.0");
+		    
+		curproxy->check_req = (char *)malloc(reqlen);
+		curproxy->check_len = snprintf(curproxy->check_req, reqlen,
+			 "%s %s %s\r\n\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
 	    }
 	}
 	else if (!strcmp(args[1], "persist")) {
@@ -5194,10 +5264,10 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	int errnum;
 	char *err;
 
-	if (curproxy == &defproxy) {
-	    Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
-	    return -1;
-	}
+	// if (curproxy == &defproxy) {
+	//     Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
+	//     return -1;
+	// }
 
 	if (*(args[2]) == 0) {
 	    Alert("parsing [%s:%d] : <errorloc> expects <error> and <url> as arguments.\n", file, linenum);
@@ -5210,7 +5280,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 
 	if (errnum == 400) {
 	    if (curproxy->errmsg.msg400) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg400);
 	    }
 	    curproxy->errmsg.msg400 = err;
@@ -5218,7 +5288,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (errnum == 403) {
 	    if (curproxy->errmsg.msg403) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg403);
 	    }
 	    curproxy->errmsg.msg403 = err;
@@ -5226,7 +5296,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (errnum == 408) {
 	    if (curproxy->errmsg.msg408) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg408);
 	    }
 	    curproxy->errmsg.msg408 = err;
@@ -5234,7 +5304,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (errnum == 500) {
 	    if (curproxy->errmsg.msg500) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg500);
 	    }
 	    curproxy->errmsg.msg500 = err;
@@ -5242,7 +5312,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (errnum == 502) {
 	    if (curproxy->errmsg.msg502) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg502);
 	    }
 	    curproxy->errmsg.msg502 = err;
@@ -5250,7 +5320,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (errnum == 503) {
 	    if (curproxy->errmsg.msg503) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg503);
 	    }
 	    curproxy->errmsg.msg503 = err;
@@ -5258,7 +5328,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
 	}
 	else if (errnum == 504) {
 	    if (curproxy->errmsg.msg504) {
-		Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
+		//Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum);
 		free(curproxy->errmsg.msg504);
 	    }
 	    curproxy->errmsg.msg504 = err;
@@ -5298,6 +5368,8 @@ int readcfgfile(char *file) {
     if ((f=fopen(file,"r")) == NULL)
 	return -1;
 
+    init_default_instance();
+
     while (fgets(line = thisline, sizeof(thisline), f) != NULL) {
 	linenum++;
 
diff --git a/tests/defaults.cfg b/tests/defaults.cfg
index 463ed6c6f..7621dc8d7 100644
--- a/tests/defaults.cfg
+++ b/tests/defaults.cfg
@@ -35,7 +35,7 @@ listen	appli3-relais 127.0.0.1:10000-10100#,192.64.19.22:3129
 	#option	httplog
 	#option	dontlognull
 	#balance roundrobin
-        server  app1_0 127.0.0.2 check port 113 inter 100 rise 2 fall 5
+        server  app1_0 127.0.0.1:+12000 check port 113 inter 100 rise 2 fall 5
 	#        server  app1_1 127.0.0.1:8000 check inter 100 rise 2 fall 5
         #server  app1_2 127.0.0.1:8001 check inter 100 rise 2 fall 5 backup
 	#retries	1