找回密码
 注册
查看: 6038|回复: 0

configuration

[复制链接]

40

主题

29

回帖

471

积分

新手上路

积分
471
发表于 2016-8-17 21:51:30 | 显示全部楼层 |阅读模式
                         ----------------------5 U. V/ E8 d. w3 r, f$ ^3 F$ z' Q, Y
                                 HAProxy, Z+ y4 [* h3 }- h, B* @- }5 Z+ x
                          Configuration Manual
% E3 P% {) L8 \7 o                         ----------------------  O+ J/ D; K0 D7 z+ F
                             version 1.4.27
0 {& W, O4 Y" o2 L& F3 X6 L                             willy tarreau
1 w& R" K$ k! T8 |/ b: u                               2016/03/13* f! e# a# ]. A4 J9 f. Z

7 L) j+ F5 f3 T" g! A/ y+ J5 v7 T9 U$ M
This document covers the configuration language as implemented in the version3 r: \4 F) J1 `
specified above. It does not provide any hint, example or advice. For such7 w, w7 a: G5 M. ]% A" \
documentation, please refer to the Reference Manual or the Architecture Manual.
- c% H4 ?! R/ G* H, ~4 k) AThe summary below is meant to help you search sections by name and navigate1 S5 K' V5 F7 y! ^! F% a, W
through the document.. B7 p& E4 E# ^) c4 t

* K7 q* ~0 L2 k2 g$ l+ s- D% G0 {  qNote to documentation contributors :' T4 o0 Q& V, Z
    This document is formated with 80 columns per line, with even number of" `: Y6 V2 f2 Q: b# |
    spaces for indentation and without tabs. Please follow these rules strictly
( y4 k5 ]1 q8 f$ S& I    so that it remains easily printable everywhere. If a line needs to be
6 I- z! l3 `5 u9 ]    printed verbatim and does not fit, please end each line with a backslash" n+ a- s3 g; t" s* ]- g& G
    ('\') and continue on next line. If you add sections, please update the4 [1 b2 r' k: _% {0 _
    summary below for easier searching.
9 k' `! ^( }/ y4 F, }
4 U: a1 U# R! v" r5 I
. }# b. w6 c# Q' ^Summary1 ~* I+ B0 `6 Q; w
-------' j- ?" W1 t( [( |' k0 _6 J
' E0 @2 V  \5 x( |6 b1 F
1.    Quick reminder about HTTP% ~' z2 V6 k& T! v9 c
1.1.      The HTTP transaction model
" i2 f7 \0 R  @9 _. \& [7 n: ~1.2.      HTTP request. X; j+ J$ ?% T4 X2 Q; p: Q
1.2.1.        The Request line8 S/ \/ @2 B7 Y+ |6 V; z
1.2.2.        The request headers! E  R$ l4 d# D6 P
1.3.      HTTP response
: q0 ?; @, g. A! p, Q+ ~0 ^1.3.1.        The Response line
2 O8 {% }3 M9 ?% w5 a6 p6 \( A1.3.2.        The response headers3 c! p4 n: B6 w, f! |0 H2 C

+ L3 j+ g2 c4 G3 b3 U" R# d4 W( ^2.    Configuring HAProxy; L. Q. D0 G2 ]/ }! z3 z7 y
2.1.      Configuration file format
0 ~7 N) n# i' F5 I2.2.      Time format
2 T! r( |! Z. `8 M" t2.3.      Examples5 N- x) b" p9 }- G- }+ s( S+ |

; x* l7 S& L4 H* i0 @! X8 Q3.    Global parameters
) _' S5 A& V9 O7 O9 r7 o$ i2 r; x7 F3.1.      Process management and security$ {0 \# Z4 Y/ z% h) ~
3.2.      Performance tuning- ?9 u: M+ D/ M
3.3.      Debugging# H" [# g4 T- X, E4 {6 _0 Q) a
3.4.      Userlists
( t' J6 p6 L0 W/ O, U; p1 q9 n& U
4.    Proxies, t" P. K* S* ~( S
4.1.      Proxy keywords matrix
& F( }4 c/ A$ ~8 {  L4.2.      Alphabetically sorted keywords reference. o, d4 E" U# ?# f; p3 M5 M* }  P% b

& ?  l1 k& c5 e' s6 _5 Q% C4 R  @5.    Server and default-server options/ A) N  [2 Y, U/ {: c

/ q2 G8 F1 G# N; V2 s" s6.    HTTP header manipulation
3 T9 H8 j# [) t8 H' V- K8 p9 k. a6 Z0 ~7 f
7.    Using ACLs and pattern extraction
/ o; |& d8 W! X7 W7.1.      Matching integers
9 ^( i: s! r3 h0 n$ e7.2.      Matching strings8 B: {+ E# M* i$ u9 U5 E1 Z# G  U" a
7.3.      Matching regular expressions (regexes)) D* n, D! A* m' D$ \- \( D" ^' }
7.4.      Matching IPv4 addresses
3 O  b  t% v/ j4 q. \5 [/ \7.5.      Available matching criteria. S7 ?3 p8 Q" ]' H
7.5.1.        Matching at Layer 4 and below
: }) A' Q0 i6 P+ g; z. B: q7.5.2.        Matching contents at Layer 40 q. B6 T% [& L8 V" V7 A. n. I
7.5.3.        Matching at Layer 72 Z, Q5 E9 ^! N. C9 f, k3 N6 J
7.6.      Pre-defined ACLs, ~+ ^8 K& S8 N1 }. C' m5 I7 z% s/ ~
7.7.      Using ACLs to form conditions
# p5 }2 c3 R/ B4 l: ?. |; U, p8 d7.8.      Pattern extraction& i  y6 c& L: a9 e' ~2 z, ?) m

4 C3 E: k4 O" ]* J8.    Logging
1 e9 g; P, h9 Y+ Q1 q2 [( {8.1.      Log levels  a: d: a" Y0 {& ]5 I, M
8.2.      Log formats- R( j/ [8 h5 V4 w  D) H* ?. A
8.2.1.        Default log format
8 _7 P0 W" D' q8.2.2.        TCP log format  U$ W# ?. [0 C6 n; @! o9 z
8.2.3.        HTTP log format
5 m: t! d; M, ?6 [  k# v8.3.      Advanced logging options
6 {9 ]% o& T* C5 q  R8.3.1.        Disabling logging of external tests! q( V) X* D! n: n, M& ?$ N
8.3.2.        Logging before waiting for the session to terminate. `. E& t" B' d' N" m7 J; }
8.3.3.        Raising log level upon errors
3 J7 n6 {) ]4 D+ C5 b8.3.4.        Disabling logging of successful connections0 k, f1 n% ?* k/ S
8.4.      Timing events
' w7 n) `3 a3 \, y3 h8 g8.5.      Session state at disconnection% B! L% a% y. ]' k* w" h# h- |. i- a
8.6.      Non-printable characters1 Z7 y$ c- ?1 S6 J
8.7.      Capturing HTTP cookies
7 f  }, X+ X& K8.8.      Capturing HTTP headers1 H. _( N7 [  d0 W/ V& @
8.9.      Examples of logs
' N  o9 N  m8 ~/ R8 w4 m
" f+ J+ ~: F8 Y6 K/ y8 q; X6 @9.    Statistics and monitoring$ q1 W2 p; Z( ^" M# T, T; k7 R
9.1.      CSV format
  K. C* B+ \* R4 v9.2.      Unix Socket commands! f5 H" E9 S* b* ]% m; P, g

* @! m  r% q" \' Y3 Q" T# q7 A6 I+ Q# s2 c3 {
1. Quick reminder about HTTP
( v- b: u% A9 G9 Q; u) c----------------------------
6 V+ e, S+ @' W! c: L8 w9 \, ~
" I0 b  w8 E- z( `7 d- r7 HWhen haproxy is running in HTTP mode, both the request and the response are6 U! E- y7 y& E7 Y$ o
fully analyzed and indexed, thus it becomes possible to build matching criteria
- x# s3 D" Y: e6 f$ t9 O0 b5 z) M* Don almost anything found in the contents.) [' y- M' e/ K/ Q( z% c# G' x& J

1 @# U" ^2 M: k1 hHowever, it is important to understand how HTTP requests and responses are' X* D  o4 W5 ]$ X; Y
formed, and how HAProxy decomposes them. It will then become easier to write( N' x, F9 @: @1 p
correct rules and to debug existing configurations.: l8 g7 b+ B0 O1 C3 |1 I, q5 \

4 j1 a$ m- h3 W4 P6 D
% L$ b3 P/ x0 Z6 t; s( [1.1. The HTTP transaction model2 P) s9 a- j" U: ?
-------------------------------
0 v& z* W* c+ J7 U6 I0 L0 L. ]- V5 u' I7 ^
The HTTP protocol is transaction-driven. This means that each request will lead4 h; K& W4 X# P" q: q, d
to one and only one response. Traditionally, a TCP connection is established8 E8 M" B3 B( l0 O- ]
from the client to the server, a request is sent by the client on the- a$ [$ U, V( `+ R4 [4 w
connection, the server responds and the connection is closed. A new request: E& n. v5 V6 U) o; ]5 O/ J
will involve a new connection :# z$ c, B  A* ?0 |7 Y% u

/ j( Y+ |# U0 w  [CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] .../ M# @5 G1 `& _. a/ c
/ `7 D3 [: O$ @6 i& g
In this mode, called the "HTTP close" mode, there are as many connection" R$ {2 Z0 G7 r0 K
establishments as there are HTTP transactions. Since the connection is closed
, h0 E* e! C& B0 o3 yby the server after the response, the client does not need to know the content
% @8 N0 h& ~$ R6 [3 N4 olength.3 O( Z( L0 u+ D5 f9 u- S
  k7 o0 U$ q" K) Y( Y
Due to the transactional nature of the protocol, it was possible to improve it3 d2 n" H! d- l0 _( _6 r
to avoid closing a connection between two subsequent transactions. In this mode
/ h' w7 R$ H6 s- ?; Whowever, it is mandatory that the server indicates the content length for each
# C2 I4 J: m* Z' y' Dresponse so that the client does not wait indefinitely. For this, a special5 S( ^! {8 ]- a! W/ Y2 Z
header is used: "Content-length". This mode is called the "keep-alive" mode :# K% t- v: K$ s/ j. \: V

5 }# L' {$ I/ a9 q. K3 X  [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ...
) u2 [! Q3 L5 q  m% [# Z' a1 ]; L7 T- e2 f: s  [1 W
Its advantages are a reduced latency between transactions, and less processing
% a2 r! i0 u& M0 wpower required on the server side. It is generally better than the close mode,6 h  A' Z# c( A2 b; I0 M
but not always because the clients often limit their concurrent connections to
; g8 `- g- ~9 Z! J) m' E: F5 A, s3 ta smaller value.
1 N3 h% C/ g" M  `" {6 p: P# u; v9 G1 P* \0 B  J- k) R% x
A last improvement in the communications is the pipelining mode. It still uses
' i( q. F9 i8 b- f) Qkeep-alive, but the client does not wait for the first response to send the
6 a, u% g, G' {second request. This is useful for fetching large number of images composing a
, e- N$ ^! m+ _( R- C3 b8 Spage :; l, N' r' W+ Y' I  M! f; ^0 c
$ F! z2 ?8 O: q. M7 y2 J+ }
  [CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] .../ _' Z2 m) w! M" d

) i+ s3 T& r" Q! NThis can obviously have a tremendous benefit on performance because the network# D- M) j7 q& `: w, B3 x
latency is eliminated between subsequent requests. Many HTTP agents do not
8 g( E7 o& q+ i# q) Rcorrectly support pipelining since there is no way to associate a response with  a# N( R" d" T- J) A; y- {$ Z" a
the corresponding request in HTTP. For this reason, it is mandatory for the
5 t1 r" S  P( Z- g4 Bserver to reply in the exact same order as the requests were received.5 x! p( {" N, F% ^

2 k: ~1 n2 t7 g4 a6 LBy default HAProxy operates in a tunnel-like mode with regards to persistent" E# [. s* G& E1 H$ w9 H6 H8 U
connections: for each connection it processes the first request and forwards- Z# ~3 c7 ]1 h% d
everything else (including additional requests) to selected server. Once/ i! x( L/ w" z! B) o- E( o
established, the connection is persisted both on the client and server
1 c9 _7 l. d6 qsides. Use "option http-server-close" to preserve client persistent connections
$ u2 H0 E' c" M9 wwhile handling every incoming request individually, dispatching them one after
2 ]# A5 C, d# q4 Q. ganother to servers, in HTTP close mode. Use "option httpclose" to switch both
0 M1 Y4 G' P% ?! ]% I$ y! rsides to HTTP close mode. "option forceclose" and "option
/ Y1 ?8 Z4 o3 ?http-pretend-keepalive" help working around servers misbehaving in HTTP close; d# j+ o1 r2 {! Y' F4 |' k: b+ ]$ Z
mode.
& J7 M2 H# C0 E8 e* _: A8 h
3 \. s# O/ @7 G( x# s7 V
. }3 y6 V6 d1 P) o- p! E- g% z1.2. HTTP request  }, u/ z' {% n- C  n, r6 o! X
-----------------; u6 |) v6 X+ x  Z/ b

' ~( Y# d* ]! xFirst, let's consider this HTTP request :
& ~) t7 D, ^. b6 _9 U
& m8 N; s( E! m; j9 @  Line     Contents) t$ E* Q2 F2 Q0 h0 l' G) U6 D( x
  number) T, `% f5 B# e5 e( R  W" s7 G* P& T
     1     GET /serv/login.php?lang=en&profile=2 HTTP/1.19 ?# _; m5 d! {# m
     2     Host: www.mydomain.com
( N' W# |; u4 S$ t! [2 Z: [     3     User-agent: my small browser
4 s3 m. M. _: G+ P     4     Accept: image/jpeg, image/gif6 A$ I. [3 U0 o' d4 D: `
     5     Accept: image/png
# c2 ?8 o/ C" `* n( I+ Y6 v
- x' h% |) B' h8 X6 `5 P- F- T  f  u( L7 |8 `
1.2.1. The Request line" ~  t' l4 N. A
-----------------------
8 @9 W8 [/ C* i* z# Y$ B. ~- q- N8 k  D' g
Line 1 is the "request line". It is always composed of 3 fields :/ y! H. k8 m4 }( z+ H. y

8 n/ h& V( _' e3 ~9 o8 F) k  - a METHOD      : GET
9 K+ F: p8 s$ t  - a URI         : /serv/login.php?lang=en&profile=21 {5 p( P) r5 g1 g7 a
  - a version tag : HTTP/1.1$ I* f; f- ~1 O( [

# N8 U9 G5 {3 B. \6 j7 MAll of them are delimited by what the standard calls LWS (linear white spaces),7 e, J- [4 D. m1 f7 ]; t  G
which are commonly spaces, but can also be tabs or line feeds/carriage returns8 J. ~* d6 @' R
followed by spaces/tabs. The method itself cannot contain any colon (':') and
& f5 I6 ?2 d6 f2 }# a) m/ M6 P2 O# eis limited to alphabetic letters. All those various combinations make it$ s( C0 i, }% ~  X% r
desirable that HAProxy performs the splitting itself rather than leaving it to  ~' X  V" I  x8 w* F
the user to write a complex or inaccurate regular expression.
! ^* V% F$ W" ^! V" b, Z. r& N' F; Q8 E* y3 O
The URI itself can have several forms :
4 X$ U0 ?+ X; Q6 ~+ b
0 C( U  q$ `: r0 S5 q4 L9 O  - A "relative URI" :
" _6 x' J( c, d  W$ c& {( h
0 z! l9 w* |, t+ c  T5 v& n; C      /serv/login.php?lang=en&profile=24 Q3 Z* _' V# @3 l2 x) H

1 q3 ?4 s2 m. a; d    It is a complete URL without the host part. This is generally what is; `  V1 O) E9 |, e" k4 B
    received by servers, reverse proxies and transparent proxies.
! y6 z/ k; ], l- E
# _$ G( l0 S8 I9 P6 t2 `  - An "absolute URI", also called a "URL" :
" z+ x$ g0 V, K" f5 S' {
: j$ ?+ N2 n# L8 T      http://192.168.0.12:8080/serv/login.php?lang=en&profile=2
8 Q) ]9 a# j7 f) Q% ?, B
5 Z* D3 `9 @* D- e3 }    It is composed of a "scheme" (the protocol name followed by '://'), a host6 u7 b6 W/ H. \9 V/ Z
    name or address, optionally a colon (':') followed by a port number, then
7 H1 s* L, N4 l7 C    a relative URI beginning at the first slash ('/') after the address part.- P" d# F3 K5 U
    This is generally what proxies receive, but a server supporting HTTP/1.1
" ]! {8 t& ?3 n# s9 i    must accept this form too.
, S$ j, d3 r$ F- s5 l  y- @
  n) q1 ^, Z. O4 c- L- Q  {" d' u& {  - a star ('*') : this form is only accepted in association with the OPTIONS
# W" p6 L/ S* V    method and is not relayable. It is used to inquiry a next hop's
8 K6 W  ?$ @+ ]- H4 K    capabilities.
( b% s% G. C0 `, M1 B: k/ H7 f8 L( p1 Y) B8 o; U2 m- U
  - an address:port combination : 192.168.0.12:80; T# W# I* j$ l4 S) t2 {
    This is used with the CONNECT method, which is used to establish TCP; H6 }% ?6 N% p7 p3 T& Z: }
    tunnels through HTTP proxies, generally for HTTPS, but sometimes for
" y+ n4 c  X! Q  E8 b7 U. k    other protocols too.
: A# [* O: q% r  ?( V; n' Y! ~
$ v6 b. b: a  t& y& RIn a relative URI, two sub-parts are identified. The part before the question
* i4 f* h0 X" {- A, mmark is called the "path". It is typically the relative path to static objects  I0 O9 `" N8 L$ q9 k& I
on the server. The part after the question mark is called the "query string".
# {) }( a3 C1 M2 B' NIt is mostly used with GET requests sent to dynamic scripts and is very
2 T9 r2 p& ~, D2 g7 x+ w% U0 d- C+ nspecific to the language, framework or application in use.8 o$ R9 n/ I" E8 B: C" F
4 B/ L5 D6 ?3 |
/ ~( n: P2 {6 l8 x/ U2 G
1.2.2. The request headers5 a5 s) ^" J+ X$ S+ Z
--------------------------, {0 L3 S  E8 [# ?  O
$ f0 l" N& J/ z$ y# d- ?+ z
The headers start at the second line. They are composed of a name at the1 ]* B7 e1 A* f
beginning of the line, immediately followed by a colon (':'). Traditionally,/ W6 N8 v; \  \8 Q' Z: d6 T
an LWS is added after the colon but that's not required. Then come the values., [  r) C) I9 N/ `
Multiple identical headers may be folded into one single line, delimiting the
; o$ B7 U# q8 H5 @* Yvalues with commas, provided that their order is respected. This is commonly
+ m9 H& l. I! ^  x2 U" J9 yencountered in the "Cookie:" field. A header may span over multiple lines if/ Q! v* A' G7 y$ x3 f5 u" r
the subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 5
* ]; _, `) L. adefine a total of 3 values for the "Accept:" header.
% S' @6 l, V/ e9 m4 g* n, u/ S4 B# J) O9 A6 D
Contrary to a common mis-conception, header names are not case-sensitive, and5 E! R  o% x) O6 C' U- [3 W$ B
their values are not either if they refer to other header names (such as the
4 e3 I1 Y$ r0 X- M) \"Connection:" header).
- R' Q9 Z* U' T* N
" b# M) ^, d) l% N0 oThe end of the headers is indicated by the first empty line. People often say
1 C4 r2 o* d! z% t4 K3 `: cthat it's a double line feed, which is not exact, even if a double line feed
& Q+ [/ l/ h* j$ E# ~$ N4 A3 [: Gis one valid form of empty line.& r4 _( h' g1 [3 L9 ?

/ H  a* _9 T. x* W5 ~) P- r9 h" aFortunately, HAProxy takes care of all these complex combinations when indexing3 f+ b/ t3 t% F5 g+ @! t( n
headers, checking values and counting them, so there is no reason to worry6 _5 K3 k" S6 R1 j6 c% s
about the way they could be written, but it is important not to accuse an, Y% W$ Y: ]7 l
application of being buggy if it does unusual, valid things.
9 _  n1 T8 r2 H5 {4 X; |2 F% q0 g
# L/ c$ p3 W9 e2 P5 [" z* DImportant note:
/ E  h& Q2 [1 v6 t* n$ y$ w   As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks/ k; d: A1 X6 T% I" t
   in the middle of headers by LWS in order to join multi-line headers. This) z5 T; M3 N' ^" ]
   is necessary for proper analysis and helps less capable HTTP parsers to work
  M$ ~! V2 M( _3 _1 A/ \, G   correctly and not to be fooled by such complex constructs.6 i7 R6 v, A% l/ {4 l1 ?+ ~
5 P9 K) @/ j, B& \$ P2 h, D) K2 h
5 z3 G  y  N1 t; W
1.3. HTTP response! I/ Q" u) r6 |  l
------------------
3 a) t  n9 Y9 a* z, ~) o4 @3 V1 F5 k3 `1 @( b) e
An HTTP response looks very much like an HTTP request. Both are called HTTP
! f7 F! W# O9 s( M1 Cmessages. Let's consider this HTTP response :: i9 |9 o# y; D9 o

) l) H* \& ~& I0 \4 q2 S! x: x! T  Line     Contents5 R! f( O! {# `2 ~- Q0 ~
  number. x/ x+ V" @, _1 f
     1     HTTP/1.1 200 OK$ |/ p8 _8 t* s) \7 R
     2     Content-length: 350
  m& u# d7 q: b& J$ g$ V     3     Content-Type: text/html
  E! \$ R3 H* X- y+ s1 x8 v, h; _+ M3 f7 c  w/ v
As a special case, HTTP supports so called "Informational responses" as status
2 d: ]3 h( q0 A9 e5 Scodes 1xx. These messages are special in that they don't convey any part of the7 B' x2 V( c9 f8 |2 f, k
response, they're just used as sort of a signaling message to ask a client to
# {( s4 l* \0 U5 U$ x: Lcontinue to post its request for instance. In the case of a status 100 response2 G9 D( d: ?1 N+ W' u) k
the requested information will be carried by the next non-100 response message
5 ~3 P! H! ^8 ffollowing the informational one. This implies that multiple responses may be) l7 u  O* b; H. \# O; ^: N6 q' ~4 r
sent to a single request, and that this only works when keep-alive is enabled
" Y; {. K4 ?) ?- n! K(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to
7 O; L4 Z0 \* U/ j  H& Y7 ucorrectly forward and skip them, and only process the next non-100 response. As
8 h5 N7 g6 v- q7 O+ @/ `such, these messages are neither logged nor transformed, unless explicitly) p& `  Z/ f7 d3 B3 H1 I
state otherwise. Status 101 messages indicate that the protocol is changing# ~; W9 B+ Z. K" {
over the same connection and that haproxy must switch to tunnel mode, just as2 _. a2 @+ I' K# a3 m& L: n; o
if a CONNECT had occurred. Then the Upgrade header would contain additional3 K( i/ b( r$ c
information about the type of protocol the connection is switching to.  q. ^% z9 q$ p

# d/ T3 s3 B, a9 ~. E( K9 c
3 A  E* u! Q1 ?; {1 z$ @1.3.1. The Response line; K; G2 J! S( n& u. Q, {% [0 m5 f
------------------------. B. y2 Q$ K) ~- P  c3 `) w7 ]

6 O, @7 l* b6 u9 b/ l. i: M/ [Line 1 is the "response line". It is always composed of 3 fields :
+ L9 N! S; h. F4 }* ^: F+ @8 d+ z) Q
  - a version tag : HTTP/1.1
- {+ J" L6 u4 ?" @  - a status code : 200
6 [# d3 B0 C4 I" A  T  - a reason      : OK6 D6 v( Q% Q# _  P4 c: e6 A8 u
- p, Q9 ~5 v8 p6 \' M
The status code is always 3-digit. The first digit indicates a general status :* }2 h9 M' |3 U1 a8 U: ^# f
- 1xx = informational message to be skipped (eg: 100, 101)( y7 R1 h1 p% j3 u; k
- 2xx = OK, content is following   (eg: 200, 206)
& b+ J% ]3 X8 ]  J) X - 3xx = OK, no content following   (eg: 302, 304)
1 O2 m7 g/ |2 J( { - 4xx = error caused by the client (eg: 401, 403, 404)4 R$ o8 L; k! _, Y$ c2 E
- 5xx = error caused by the server (eg: 500, 502, 503)) C7 O! m, p4 p% w( G& ~  v
+ Z2 _1 ~( S( [3 C# E0 i: w- C0 \. t2 h
Please refer to RFC2616 for the detailed meaning of all such codes. The
# T" F! _- A) B' A7 ["reason" field is just a hint, but is not parsed by clients. Anything can be
% G- f9 F" A) Gfound there, but it's a common practice to respect the well-established
+ ?! [+ F' \5 q* @% z* zmessages. It can be composed of one or multiple words, such as "OK", "Found",8 p# M, o2 ?# m8 a. l/ @+ A
or "Authentication Required".
+ ?. q  X7 [# G+ y! \+ ^( E. s0 t: |$ B+ i! t
Haproxy may emit the following status codes by itself :. m0 M2 ~+ }4 P. h  n; q
6 x0 @7 i2 R. s
  Code  When / reason
, ^" K6 E8 t7 F   200  access to stats page, and when replying to monitoring requests
( i' S( {6 [5 F/ G6 R  W% W- S   301  when performing a redirection, depending on the configured code# |/ V  ]4 j9 G: @) F8 e
   302  when performing a redirection, depending on the configured code1 u" O1 s1 z; ~, H: i" Q3 @
   303  when performing a redirection, depending on the configured code6 y: ~8 g$ ^# j- n3 B& J5 a' W) q
   307  when performing a redirection, depending on the configured code: {% M% z' R  Z( `* V
   308  when performing a redirection, depending on the configured code  B: u/ P' \2 F+ X% U9 M
   400  for an invalid or too large request
9 W( h0 l; Y8 Z. Z9 G   401  when an authentication is required to perform the action (when6 u& j, X" k+ R+ ?9 D: w
        accessing the stats page)5 {# o  N6 f1 }" W% H# e
   403  when a request is forbidden by a "block" ACL or "reqdeny" filter
8 t9 h7 @; T, o6 b  M   408  when the request timeout strikes before the request is complete
( `* q% D5 f4 \. D) Z   500  when haproxy encounters an unrecoverable internal error, such as a& ~" Q( v# I' F
        memory allocation failure, which should never happen6 [1 g) t' t  p  I. W% c. m6 }/ M1 Y# i
   502  when the server returns an empty, invalid or incomplete response, or
$ l) I9 J& X& @" m. N5 _        when an "rspdeny" filter blocks the response.2 v$ R& l( o0 B! }  j* n, `: F
   503  when no server was available to handle the request, or in response to& A* o" X% f# `' S& u1 B
        monitoring requests which match the "monitor fail" condition
+ u- a" f: V, g8 l3 m   504  when the response timeout strikes before the server responds% \+ ]4 H" z* I: [- C
! m! t+ H0 K; b% a: `8 q$ m. V
The error 4xx and 5xx codes above may be customized (see "errorloc" in section. E  |2 H4 a! C" n
4.2)./ `- f/ h- v7 h% R' k

2 t/ B# c- e( g. L: t! G- y) G6 c1 |: |2 n* o
1.3.2. The response headers4 I. ~3 o8 [' e, r( Q
---------------------------7 n! S0 R. F0 }! |8 n& _1 K: _( R
+ _7 b1 f$ a9 t; R) ]
Response headers work exactly like request headers, and as such, HAProxy uses
) a$ v1 V3 X% X9 _, R6 b% @- jthe same parsing function for both. Please refer to paragraph 1.2.2 for more
1 }, @3 @$ K! r; \1 vdetails.
$ b6 w& {4 }8 v/ V# r- a% I: R0 h7 R# O1 b9 b

3 R8 b; r- i9 I5 D1 ^% }/ ^5 t2. Configuring HAProxy4 G, X3 ]2 M* \7 p- m- m2 v
----------------------
* D0 g# d# k+ L( i  M2 W; D: H4 d4 R. T) k
2.1. Configuration file format
" S4 ?/ }' y) ]! T$ l  d' f4 C------------------------------
- x& d; P5 o1 S9 }( [3 m; u' C. l. W6 ?
HAProxy's configuration process involves 3 major sources of parameters :, x: N0 l- n! D0 _- E& `
) G0 K' n& p7 {
  - the arguments from the command-line, which always take precedence
# g9 ?; {) r' A. W% S) \/ a  - the "global" section, which sets process-wide parameters
8 M) t3 m* |1 q# p( \# ~+ ^, i  - the proxies sections which can take form of "defaults", "listen",% `. n! |2 U8 @" N
    "frontend" and "backend".* g4 d+ W* Z1 @5 N) Z$ e
; D6 j4 U6 F2 |0 n
The configuration file syntax consists in lines beginning with a keyword) i5 s7 Y: ]3 X3 l" i
referenced in this manual, optionally followed by one or several parameters
) ^5 H  {  P! f) l1 t. u9 gdelimited by spaces. If spaces have to be entered in strings, then they must be0 G4 H6 n: W. ^; i
preceded by a backslash ('\') to be escaped. Backslashes also have to be
* Y3 x  Q8 {9 s3 e6 Yescaped by doubling them.- w( ^, [" r* O- V' ?
, o2 w8 O# G" p+ S" }( X& x  g

/ u. B$ G+ K% f; {. D- v) e) g2.2. Time format1 h6 y5 e7 `1 \7 @- c
----------------' f7 [" i$ y' b
' {; Y3 _$ U) [0 T
Some parameters involve values representing time, such as timeouts. These4 d* q. k. V' K. v' O
values are generally expressed in milliseconds (unless explicitly stated2 z6 Z, J7 ?3 Q3 i  ~
otherwise) but may be expressed in any other unit by suffixing the unit to the( t& g7 c; }# U: c& D1 Z
numeric value. It is important to consider this because it will not be repeated& h5 x" e* A8 I9 c5 E: y: L
for every keyword. Supported units are :  i# @+ ~- {' W

# `/ y/ x0 ?( t. I6 M  - us : microseconds. 1 microsecond = 1/1000000 second
9 s  c; E/ b, D" J# d  - ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.# d) Y7 k: F& C
  - s  : seconds. 1s = 1000ms
+ S. Y  [( F8 }& @7 i  H  - m  : minutes. 1m = 60s = 60000ms) m; w- |1 J. H- S( l- J$ m4 `6 @& ]2 y
  - h  : hours.   1h = 60m = 3600s = 3600000ms
# B  `, {4 h( f& I! x$ n1 @: P  - d  : days.    1d = 24h = 1440m = 86400s = 86400000ms
3 r! l, i- y2 w5 I: m4 ?% v, c6 z$ C9 H# F% [! Y7 |0 O/ W3 b

3 a$ J* A5 Z4 Z1 `4 G( P- p2.3. Examples
" \9 h4 {' Z0 H" i-------------. I1 _5 \% ?* m4 T7 u/ F! I3 z6 [

- y2 H0 Q0 U- i4 |/ {6 B8 c# Z    # Simple configuration for an HTTP proxy listening on port 80 on all
0 q! q4 g# t  w* h; C. ?( g; h    # interfaces and forwarding requests to a single backend "servers" with a$ u; d4 ?, _7 ]$ X3 r
    # single server "server1" listening on 127.0.0.1:8000( e$ g* Z7 E% c
    global$ f, x( E% Z  x- @& V  E/ E
        daemon
! f/ s1 M; x4 w8 E8 ?7 w# y2 ?* ^2 D        maxconn 2560 j2 f+ h4 d# A. p4 I6 S

$ @5 @8 B- K3 c' e) g% T    defaults
9 `4 I8 A( ~" U- G3 `        mode http. s6 N9 I$ @9 h1 {
        timeout connect 5000ms3 U- B% F4 S& q: i# P; B9 l
        timeout client 50000ms
# r7 d; R* R: j) I        timeout server 50000ms) G/ g$ H: ?7 w+ g& e3 D
3 Z  n5 v* }5 r, P
    frontend http-in7 H$ r% M0 b" h4 v
        bind *:80: W" t+ N2 j9 O) O5 }) w$ m) v
        default_backend servers
# T9 R) z/ e' c
2 }, _+ O; W9 T! E) a. Y% f9 r( j    backend servers$ A" T( x8 V: d! ~6 y2 o/ }, T$ q
        server server1 127.0.0.1:8000 maxconn 328 q% i, z' D) w, ~# j; s
2 w, @5 u% }6 I/ t
: |7 O, I& z/ ]4 t* D; b7 X- Q9 C" \
    # The same configuration defined with a single listen block. Shorter but
- a1 ]& u- ^4 l! g; F/ u    # less expressive, especially in HTTP mode.& `$ J4 p; a) _+ l& ]" }. Q" f
    global
, e1 \+ Q9 \. W' X# |) \        daemon+ r" F( u. Q9 w. ^- O/ S
        maxconn 256
/ \( {' C  l- ~: N6 ?7 K
9 z& l" r: G, Q5 |    defaults6 V- q, a8 q1 b5 }# J
        mode http
' b. t2 z4 Z6 X# B2 B        timeout connect 5000ms
  q! z* B' L" s9 B/ S        timeout client 50000ms- D- h% b) h" r
        timeout server 50000ms' }; H- a. G+ @0 @8 i
4 n4 c' O, F5 D1 \% T$ M& N& \
    listen http-in
* H. o1 E; Y9 W# W, g" @8 ^: l! a. v        bind *:80
3 s" X/ ]& p* j/ S        server server1 127.0.0.1:8000 maxconn 32' {3 |( W( M; c3 B% Q9 q
- l: I5 l0 k8 [/ q, z" \

7 e! a( }; c$ J+ B# e/ m0 A$ k1 Z% yAssuming haproxy is in $PATH, test these configurations in a shell with:3 q; p) \* x: `. |

9 M* I9 J9 z6 G: r    $ sudo haproxy -f configuration.conf -c2 {/ ~* `" T- B( ?1 V

. g! B! s" F/ e/ f8 C  d
# q( a/ ]9 p6 F" O0 F: N3. Global parameters
$ _8 n8 I: y! ^* ]7 O) o--------------------
3 o6 |5 Y5 X/ F& X; a
/ C9 O/ c+ r) B0 Z% I! MParameters in the "global" section are process-wide and often OS-specific. They
( w3 a/ B. f2 ~& `; g: [4 mare generally set once for all and do not need being changed once correct. Some
$ O. }- k$ I+ c/ ]! q" N3 Nof them have command-line equivalents.9 ^2 u, w& `3 w3 l# _4 P" h
! |$ z7 K, P' I$ i; B+ j
The following keywords are supported in the "global" section :
9 f2 l8 W+ `, B) O
4 N- p: H% d$ Q2 x) G8 ] * Process management and security. a' o( G6 ~! @  \/ u: h
   - chroot
6 }; v" \0 _- C# Y! {% B   - daemon
1 v0 t) H/ [  F$ x) O* @" o   - gid
4 ^) v5 ^2 |" A' g* C. I   - group6 i3 K2 ?  Y6 ~
   - log+ Q1 z7 x! K  ^# D& l; m9 ]1 j+ z
   - log-send-hostname1 h  K) ^( Z& `4 N; ?
   - nbproc
- x( H9 x" I' ?7 F7 j! T5 `$ v' [   - pidfile
  ^. k* @+ I5 o( Z! `   - uid9 k2 H( I5 S' r* ~; h4 A& n9 `
   - ulimit-n! d3 i( c' r$ c* y1 W
   - user$ Z7 R* W1 h- s6 {: ?
   - stats
3 _6 z6 o' g) T! \" H4 _' H   - node1 v/ g# r  R3 c/ @7 @, E
   - description* Z( J+ n1 M5 v) R7 ~

6 ]4 k0 n! ?: f) }/ i' h6 l# ] * Performance tuning( P4 j, P6 `1 g, B9 R( N4 M- G
   - maxconn
* k* q& x+ n" c   - maxpipes
! z* k( w: K- x% }9 X0 z   - noepoll
( c9 r; X6 }. [1 h6 R   - nokqueue4 h, Y) c3 v1 S/ ^( W
   - nopoll% f# C; ?. `; q- i' ]9 b
   - nosepoll0 S$ R4 A$ _  C% v$ Z8 j5 _
   - nosplice
$ H9 a5 g; \: G. @* M1 [. N   - spread-checks2 F. B, r+ H: y0 J
   - tune.bufsize& E6 q! }% [/ O2 ~5 j& Q
   - tune.chksize% _! |4 \& v. v3 h/ {# O2 c) f' c
   - tune.maxaccept! ]7 I4 x) ^) L; ~3 B) V
   - tune.maxpollevents
- ?6 Q* L% H8 P  U6 S   - tune.maxrewrite
4 Q/ f4 q7 v" h% Q- U   - tune.rcvbuf.client
$ `/ H7 y3 v) E; l; x1 i   - tune.rcvbuf.server/ o5 _- U; x6 t: M  S
   - tune.sndbuf.client
5 u8 F! U( p1 k5 f$ j( @9 G( e! N   - tune.sndbuf.server) T3 u: V* B5 R$ `

& P+ v: k  g: }" q. c* Z7 U * Debugging# g3 I3 s1 R( F$ T
   - debug$ s  k+ ~1 q$ w8 m8 H) A) h
   - quiet% b! H, {  t- P$ i* s% I# q( D

+ E' |$ ?" F' q  h/ _6 f$ r  l
: F: E) j# I4 n9 T5 T% _0 F, r" E) @3.1. Process management and security
2 w' L8 P/ R; Z9 w; \) b------------------------------------3 M( [% g, s8 D9 h. P

2 R- y: \2 w% C: i% U' s/ pchroot <jail dir>
3 o# G: L( B/ t% O/ M1 \, s' C  Changes current directory to <jail dir> and performs a chroot() there before
8 O- v# l* z% o) X) b5 ~) l4 f; X  dropping privileges. This increases the security level in case an unknown
9 F( U+ E- u+ a  vulnerability would be exploited, since it would make it very hard for the
$ ^/ f" h7 A+ D  attacker to exploit the system. This only works when the process is started3 N' J! H. F/ w( E$ V/ e
  with superuser privileges. It is important to ensure that <jail_dir> is both
4 b2 d3 P3 u7 t2 H% ]& i. _  empty and unwritable to anyone.! Q! ?: K5 w& t$ L3 A

& W- p8 y9 R$ b0 f; tdaemon
- k+ h* Y& c, U7 r# ]  Makes the process fork into background. This is the recommended mode of
& l, \) A9 {+ G# u1 e  operation. It is equivalent to the command line "-D" argument. It can be6 N2 n/ E) _6 z, x8 W
  disabled by the command line "-db" argument.- h# U) n6 z( K7 V, r

' m3 h* k1 L( q0 D" D! Y: }gid <number>
7 r% o0 g# e# j0 C  Changes the process' group ID to <number>. It is recommended that the group" @! }5 q' }6 @4 k
  ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must
8 B2 x+ Z% O8 S) J1 q- q& h  be started with a user belonging to this group, or with superuser privileges.7 M/ Z; s6 ?' b! F
  Note that if haproxy is started from a user having supplementary groups, it
1 z- G# `) Z+ b6 n+ G; t  will only be able to drop these groups if started with superuser privileges.
; @$ ~- }0 ^! e% s7 }. d8 o) D3 Q  See also "group" and "uid".
0 V* p( u5 G3 h8 F) r+ W- Z7 w( }/ z! D; ]: L& J4 e3 f( ?
group <group name>
9 m) S+ z1 }" n% o% S  Similar to "gid" but uses the GID of group name <group name> from /etc/group.
  }' i1 k5 Y! ?3 {) s7 Q5 x  See also "gid" and "user".+ P+ C9 p' I: y9 k  \8 ^
) U0 f) p( i: A- G
log <address> <facility> [max level [min level]]& o( A$ c5 I$ d; D; |: V: z$ J( r
  Adds a global syslog server. Up to two global servers can be defined. They
; ?" `% s" t) T# \2 a2 O: m  will receive logs for startups and exits, as well as all logs from proxies8 a$ ?+ O/ d" y9 L& ?
  configured with "log global".
' W4 x- i. E$ u* b+ N4 x6 [/ W
( X# @: n& Z) f3 m  <address> can be one of:
# B  \( D" a3 m
% r1 Q* Z# a+ P& A! U- K' ]        - An IPv4 address optionally followed by a colon and a UDP port. If" Z' [  f/ c: A1 C+ S8 l8 @
          no port is specified, 514 is used by default (the standard syslog& n, ]) B: ~- M; m
          port).- T1 M" {9 ]& k* a3 t6 D1 o
, z6 r+ W: C6 M! i2 N) l  x
        - A filesystem path to a UNIX domain socket, keeping in mind# _( U% s: V5 m/ {+ e$ J6 W
          considerations for chroot (be sure the path is accessible inside
" q$ G( W5 b( O* n          the chroot) and uid/gid (be sure the path is appropriately/ r! @& P( g/ K% O  |
          writeable).1 Z0 [# U" N2 E* T$ i9 \, |

4 r8 k5 C5 ]" t9 q" g7 e8 x' ?/ }  <facility> must be one of the 24 standard syslog facilities :! v" o4 R" Z0 z  j) i( }

- B, s7 M) X6 l+ h* m          kern   user   mail   daemon auth   syslog lpr    news5 `4 V+ C7 i0 X8 ~% q7 H; \
          uucp   cron   auth2  ftp    ntp    audit  alert  cron2: P6 x, V4 X8 Q/ S" l6 `, E2 w
          local0 local1 local2 local3 local4 local5 local6 local7( z% G. m- H" ]5 {) w3 P

) B, n8 z, e) @% W  An optional level can be specified to filter outgoing messages. By default,& A- O; @' V) O5 g& C5 N, ^
  all messages are sent. If a maximum level is specified, only messages with a" B+ z+ k  L) m) ^9 G3 k, V% @# w) R( R
  severity at least as important as this level will be sent. An optional minimum
2 v& C" V3 j7 h  o; O+ G' _+ J: V  level can be specified. If it is set, logs emitted with a more severe level
+ S4 w/ m+ F$ n) ~  than this one will be capped to this level. This is used to avoid sending
1 i$ Y+ K! P8 o5 v2 V  "emerg" messages on all terminals on some default syslog configurations.( q7 x7 A( y! p' G, J" V' v
  Eight levels are known :: M+ @3 k6 {2 e2 _3 @* I5 f. r) h

4 g; G" j4 e) ]' S3 I          emerg  alert  crit   err    warning notice info  debug
5 D4 l) X0 g0 S: w5 r; |3 a2 K# q# T& d5 R
log-send-hostname [<string>]
- x) G, T6 B! y! e! x  Sets the hostname field in the syslog header. If optional "string" parameter. n0 d$ t! _2 a
  is set the header is set to the string contents, otherwise uses the hostname& x  Q8 R7 y5 c( A, z! [- X
  of the system. Generally used if one is not relaying logs through an/ _7 E$ O9 D, |2 z
  intermediate syslog server or for simply customizing the hostname printed in
$ a# ~* Z9 q9 w9 m% q- J, s( Y  the logs.
$ u" @2 l& ]4 w. N7 m
  U3 r( e- k* Tlog-tag <string>6 ?7 H8 E- h, S1 g
  Sets the tag field in the syslog header to this string. It defaults to the. S0 s$ p. V$ ^. l5 x
  program name as launched from the command line, which usually is "haproxy".4 A7 L+ }. k6 l' o4 T+ [7 e. l
  Sometimes it can be useful to differentiate between multiple processes1 }, y& w6 }% o$ A6 y. D; T
  running on the same host.6 S1 i% @( E: V2 a8 T, C0 U
& f, m* o) b5 c! j3 m
nbproc <number>
) D7 S7 V: F- V+ a! ~  Creates <number> processes when going daemon. This requires the "daemon"
; h( a3 L6 B( \  mode. By default, only one process is created, which is the recommended mode
5 Y7 e$ n) n2 M$ G, q: p# S  of operation. For systems limited to small sets of file descriptors per  g8 s# {$ S: G% U4 E. [
  process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES
  W0 K2 y" B# Z: M2 @  IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".: n! _5 l8 I! q3 Q: w- }# j4 E6 G
5 T( F- \" z- `* y, S2 v0 J
pidfile <pidfile>. B# t1 |; S/ ]( k1 z% L
  Writes pids of all daemons into file <pidfile>. This option is equivalent to# F  k& \  e0 p/ x; K/ e% t. q
  the "-p" command line argument. The file must be accessible to the user: m3 \8 [$ S. s0 g1 d
  starting the process. See also "daemon".5 C7 ~$ q" k! J- A6 ^, d+ u: [  O

& H0 \9 ?, R! Y: M/ V! Q$ S; I& L% I) s) Wstats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]
" G3 G) }3 O8 y% c             [level <level>]
/ ]) O- e2 F, {' v/ K6 N
# e' h% a" n' ~7 z6 p& e* t/ j1 @  Creates a UNIX socket in stream mode at location <path>. Any previously! x, y; U+ B" x8 q
  existing socket will be backed up then replaced. Connections to this socket9 ~' D- x5 D; ^6 y
  will return various statistics outputs and even allow some commands to be
& S$ e1 u" _6 a& }) W1 S7 O% E  issued. Please consult section 9.2 "Unix Socket commands" for more details.+ J/ s3 v0 a! T3 l' d9 M
' Y3 I! O" V$ s, l
  An optional "level" parameter can be specified to restrict the nature of1 C8 V& G5 x1 s
  the commands that can be issued on the socket :9 a% l1 b& S7 O& M1 q/ x
    - "user" is the least privileged level ; only non-sensitive stats can be
& V  |1 E1 I7 P5 Z      read, and no change is allowed. It would make sense on systems where it
7 y. V, r  k! F# N      is not easy to restrict access to the socket.
. {+ q  e" i" s8 O: [5 [% c6 V7 ]2 B+ P. `$ v
    - "operator" is the default level and fits most common uses. All data can- Q( A  L" |' R6 B* k* ~* H
      be read, and only non-sensitive changes are permitted (eg: clear max
# J4 O$ j$ ~5 M4 ^1 @% O4 C      counters).
. {: |( N5 }6 T" Y
( M. E4 j3 F; t5 H5 L    - "admin" should be used with care, as everything is permitted (eg: clear
' Z' ^# M. U1 G, i' c      all counters).5 w' c4 C' L8 M( J, B$ i4 Z  S& L
  ]9 y3 h4 y+ |: t  c
  On platforms which support it, it is possible to restrict access to this: R6 M$ Y# ?/ Y: A4 g
  socket by specifying numerical IDs after "uid" and "gid", or valid user and
$ m7 a4 I, e8 u  group names after the "user" and "group" keywords. It is also possible to
; I7 G/ r  M+ s5 F& V( e  restrict permissions on the socket by passing an octal value after the "mode"
3 |+ Q, m0 k' B+ z  keyword (same syntax as chmod). Depending on the platform, the permissions on' @3 R$ r  }: ~- v0 u
  the socket will be inherited from the directory which hosts it, or from the
6 S4 ~1 s- a9 q- G, ]  user the process is started with.
0 R" c$ ~; ~, w% n, q
; f& t' g& G/ l4 i2 @$ ostats timeout <timeout, in milliseconds>1 [+ C  B, T8 F2 a. h' H0 j6 p
  The default timeout on the stats socket is set to 10 seconds. It is possible
1 {$ U( i; L' E& W4 q( }/ W  to change this value with "stats timeout". The value must be passed in8 x* k; B! O' f: \6 l3 n! h( r
  milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }., w1 n3 n% H, b) s4 M, x

! Q4 O# E' o6 H; m, hstats maxconn <connections>3 ^" t2 p5 W# c% J/ L
  By default, the stats socket is limited to 10 concurrent connections. It is" F8 f2 H' M4 |7 s9 l  l4 W
  possible to change this value with "stats maxconn".
1 u2 A2 q! ^3 O
4 h. ~# [5 h8 V/ p/ wuid <number>
0 I' p4 i  o4 g! V2 D4 U- P  Changes the process' user ID to <number>. It is recommended that the user ID
# r2 y7 F/ z2 o7 ^! c  is dedicated to HAProxy or to a small set of similar daemons. HAProxy must" y; i2 D) k5 _% X2 T( x8 v+ U# q
  be started with superuser privileges in order to be able to switch to another3 U8 k1 T9 w2 w" V& H9 E8 u# Y/ Y
  one. See also "gid" and "user".
" ^6 `! t. Q. v( F  ]7 J! X0 @/ p% h+ ~, y% Q" _3 E, _$ X* M& J0 g: p
ulimit-n <number>
2 [) C% f% |3 a: u  Sets the maximum number of per-process file-descriptors to <number>. By
+ j. e; \; b( T. P# Y" E# s  default, it is automatically computed, so it is recommended not to use this; X. n9 B7 @; J7 B' ^' s
  option." B, Q5 H* B, u% O, C

* ]) z) w' Q5 [* {: d4 Z+ H5 T, M& nuser <user name>9 h+ H0 Q% k3 m' x) I% ]' H- w! ], F
  Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.) o! ]# G. V0 n% ]1 a# Y
  See also "uid" and "group".
! D, i- _9 ?: |4 g" x/ w
6 O% L, L7 d/ w) C8 Y$ f, Znode <name>
% I8 C8 T9 g+ i$ s. Y7 m+ H  Only letters, digits, hyphen and underscore are allowed, like in DNS names.1 g2 ~1 U. g" ~6 Y# T' \* {
/ q5 z% {1 ~7 I! z2 i- |" l- R
  This statement is useful in HA configurations where two or more processes or0 E" H3 e4 J" R0 B6 {
  servers share the same IP address. By setting a different node-name on all  i/ @' t6 V7 X, s. C
  nodes, it becomes easy to immediately spot what server is handling the2 U( w7 }  a( O) {" u9 o/ a9 o8 e! a
  traffic.
* O! \/ Z$ `4 a& F* G6 F+ T7 Y  p
9 P6 V) E6 e$ x* y0 n8 Z2 M; [description <text>
5 D. H+ A4 a5 m" {, n1 K, r+ o  Add a text that describes the instance.+ i, p0 l' w  c* J

5 V; m+ _3 q; t  Please note that it is required to escape certain characters (# for example)
  C6 |5 `/ u7 V2 M" L0 V  and this text is inserted into a html page so you should avoid using8 W6 K2 y* n2 v  [3 g4 Z
  "<" and ">" characters.. a1 b5 e. R) ?/ u' U
' ^1 I$ V- Q, H9 |

  l, ^) s) ~1 }) a# Q3.2. Performance tuning' Z( A4 r, s/ Q. b6 W/ Z5 X* S6 b) o
-----------------------* N& J' o' k# J4 j0 |
$ w+ n* H* o5 X7 y6 X2 U1 _
maxconn <number>+ w! y! D7 |2 @! O
  Sets the maximum per-process number of concurrent connections to <number>. It8 K$ b! t; N* y( H% f# K2 S1 q2 m
  is equivalent to the command-line argument "-n". Proxies will stop accepting# O) |/ e$ h& P. k$ `: x
  connections when this limit is reached. The "ulimit-n" parameter is
, H# ^/ E) p  J$ w! Q! {  automatically adjusted according to this value. See also "ulimit-n"./ L' _9 T% N+ O7 x/ Z
( @% h% `" Z: y# c
maxpipes <number>
1 M8 w1 x* o3 C8 }* _, q3 V  Sets the maximum per-process number of pipes to <number>. Currently, pipes
+ ?, ]; G1 @2 K# Q, p  are only used by kernel-based tcp splicing. Since a pipe contains two file
, c2 k* l/ A6 @' J" {; j& F  Z  descriptors, the "ulimit-n" value will be increased accordingly. The default, }) Z9 W& ~. n% b# D8 F8 Y
  value is maxconn/4, which seems to be more than enough for most heavy usages.9 A. e# a# `% a% a5 ?0 S
  The splice code dynamically allocates and releases pipes, and can fall back6 R2 X  \" _- U
  to standard copy, so setting this value too low may only impact performance.
( k, ~( ~# K# F' D
2 i, ~- c5 d' @5 p5 a, O8 r$ M; W. Vnoepoll
+ s$ o  W; V, C  Disables the use of the "epoll" event polling system on Linux. It is
0 T' @4 P+ K: ]8 w/ j, g: I  equivalent to the command-line argument "-de". The next polling system
* F* r$ g" G# ]  used will generally be "poll". See also "nosepoll", and "nopoll".( F5 }6 e. J- K
' M' g# p$ Y  M3 \7 \3 [3 Y) P* u
nokqueue, G! [& Y1 N/ i- e* Z' x
  Disables the use of the "kqueue" event polling system on BSD. It is
" r+ J! N7 B, Y% P. @- k$ d7 x  equivalent to the command-line argument "-dk". The next polling system) P  u" `9 f+ h3 p8 H- b
  used will generally be "poll". See also "nopoll".7 R$ E! _! U; M

& t1 F) s1 J0 ]/ e6 H) Inopoll, B" N1 Y+ @# H1 s( ~7 |: F
  Disables the use of the "poll" event polling system. It is equivalent to the
. P* r  [/ m+ a  command-line argument "-dp". The next polling system used will be "select".
" ~9 m) ]: l( K0 Y& u6 B* Y) \  Y+ J  It should never be needed to disable "poll" since it's available on all
' z1 v, J6 p8 h2 i  platforms supported by HAProxy. See also "nosepoll", and "nopoll" and
0 s) A6 H" ^1 h7 o# ~$ k" Y  "nokqueue".
' X# I, z& B" F$ K+ w
# I6 C/ R5 Q0 Z0 ^- bnosepoll! M$ b) i! |  l4 A8 _0 @! l; @. G
  Disables the use of the "speculative epoll" event polling system on Linux. It
' j/ o( o6 \/ m! j6 q$ t  is equivalent to the command-line argument "-ds". The next polling system
- c- X& }  Z6 B4 `3 r  used will generally be "epoll". See also "noepoll", and "nopoll".
0 I7 V- |1 |: J  F  |  u
$ |( X) {' [7 J7 g9 a' J6 mnosplice8 x: C- o6 k2 L2 _! S
  Disables the use of kernel tcp splicing between sockets on Linux. It is0 x2 M! t. k/ N" {  ^+ h
  equivalent to the command line argument "-dS".  Data will then be copied1 a2 \+ w, j2 t
  using conventional and more portable recv/send calls. Kernel tcp splicing is
% o; c0 d" H0 d# ?3 q( P( z3 }9 V  limited to some very recent instances of kernel 2.6. Most versions between+ V. M; H+ R4 x3 F! Z" o$ m
  2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not5 W; L* t& }' K0 O! E* s
  be used. This option makes it easier to globally disable kernel splicing in
7 D" P1 r/ o6 K% x5 _2 F$ l  case of doubt. See also "option splice-auto", "option splice-request" and& x. S: |; m% a4 N( o  v& @
  "option splice-response".
9 h; L! R1 w9 n) ?5 `% }7 e) g; F2 Z0 h( |! l
spread-checks <0..50, in percent>
+ q2 K' d$ L/ a8 e8 k+ z  Sometimes it is desirable to avoid sending health checks to servers at exact7 W3 ]* `+ Q9 a9 X& G& g
  intervals, for instance when many logical servers are located on the same$ Q6 y" E* l' ~' |% I6 V& {/ R( k
  physical server. With the help of this parameter, it becomes possible to add
0 V, y6 z4 d* S; v( d0 O  some randomness in the check interval between 0 and +/- 50%. A value between0 c3 y+ ]3 ~$ s$ k* p( `5 |% N
  2 and 5 seems to show good results. The default value remains at 0.$ L: u, m3 G6 M2 x

; t6 p* ~9 h) M* z* itune.bufsize <number>
8 j+ _5 e1 h8 t/ U0 s3 P1 P  Sets the buffer size to this size (in bytes). Lower values allow more
! ^" I- g5 a( ~3 U1 L  sessions to coexist in the same amount of RAM, and higher values allow some- @' g% v9 g4 Q
  applications with very large cookies to work. The default value is 16384 and
. `% @# d) B; H# p: _6 W3 B$ r  can be changed at build time. It is strongly recommended not to change this
6 D# M1 l. m' ~; y: h  from the default value, as very low values will break some services such as
- K5 _% T( N% j9 k# K  statistics, and values larger than default size will increase memory usage,& Y9 J" t& I8 I/ m6 `. ?
  possibly causing the system to run out of memory. At least the global maxconn/ J0 |, l6 o9 u2 z
  parameter should be decreased by the same factor as this one is increased.. S+ g7 @# L2 K5 q
& l& K; c% f$ A7 h6 g' U, K" R
tune.chksize <number>2 s- t! ]# X7 J3 [
  Sets the check buffer size to this size (in bytes). Higher values may help0 x: ?  |5 o* x0 j0 Z' b
  find string or regex patterns in very large pages, though doing so may imply' s+ c* D- [+ Q6 M2 u+ ^4 _
  more memory and CPU usage. The default value is 16384 and can be changed at
- j1 d& X( }( L8 ~3 b7 ^  build time. It is not recommended to change this value, but to use better0 C" f5 ?. {# Q3 S% P& {
  checks whenever possible.2 B; r4 S# V) Y( E, }& p

5 R, o) X- S: M1 x( q; A7 g' s- rtune.maxaccept <number>1 Z7 u' h  i9 [: q' \
  Sets the maximum number of consecutive accepts that a process may perform on
6 R8 W8 n" H. V4 j8 z  a single wake up. High values give higher priority to high connection rates,4 c* a2 b6 k# x; A3 F
  while lower values give higher priority to already established connections.
5 Z$ @1 C' `4 C6 H% g* j/ t2 L6 m# N  This value is limited to 100 by default in single process mode. However, in
9 k6 Y% e4 Z/ |' p- W- _  multi-process mode (nbproc > 1), it defaults to 8 so that when one process& K2 q  z( ]+ f4 B
  wakes up, it does not take all incoming connections for itself and leaves a
/ U; `# M- v: Q. q% R  part of them to other processes. Setting this value to -1 completely disables
: l0 n& r$ K- q  q% t  [  c9 F+ n# W  the limitation. It should normally not be needed to tweak this value.
3 f" x1 o! ?* X  m
, V+ V# g' @! w/ n2 q4 dtune.maxpollevents <number>) E* }6 \% |; s. H  ]
  Sets the maximum amount of events that can be processed at once in a call to0 ]  j& C) R/ q& W0 J
  the polling system. The default value is adapted to the operating system. It
  y3 ^  T8 ?% T- Q5 s4 `1 X  has been noticed that reducing it below 200 tends to slightly decrease
1 Z4 `8 L9 ~8 L0 F7 H" S  latency at the expense of network bandwidth, and increasing it above 200
. Z/ Z7 \# ^$ N9 ^) c4 \  tends to trade latency for slightly increased bandwidth.' M& I% [' `4 f& k) g$ o& i! g$ U
( q8 M9 k. l+ T, O! h2 @
tune.maxrewrite <number>- _# ~- m. E( U) y
  Sets the reserved buffer space to this size in bytes. The reserved space is! Z& D6 v; D+ D9 M; o& W) c" s9 T
  used for header rewriting or appending. The first reads on sockets will never
! n& {: K4 ~+ ~9 E5 K  fill more than bufsize-maxrewrite. Historically it has defaulted to half of
. b6 h5 M5 D$ o  bufsize, though that does not make much sense since there are rarely large5 V$ J2 `0 J* R/ Q) u5 O) p
  numbers of headers to add. Setting it too high prevents processing of large
  I- T- c. @! \6 g4 o2 @6 S6 f  requests or responses. Setting it too low prevents addition of new headers0 ^0 b% U( j5 ]+ M) q( m* L( a, J
  to already large requests or to POST requests. It is generally wise to set it
  }0 V8 }1 T9 V7 i) e0 C  to about 1024. It is automatically readjusted to half of bufsize if it is
' c& y+ p8 a0 A6 Y' `+ E7 m  larger than that. This means you don't have to worry about it when changing
- y9 O: g5 h. [; a$ Q  bufsize.  e# D) G+ v& b2 q. W
' A( ]2 J! V3 G+ r1 `
tune.rcvbuf.client <number>0 E% r, j9 t; F1 @8 S9 u
tune.rcvbuf.server <number>- i' g7 \" {; I3 J7 l9 y3 n
  Forces the kernel socket receive buffer size on the client or the server side
2 w, R9 q. m: V$ |  to the specified value in bytes. This value applies to all TCP/HTTP frontends$ _( v) d' f4 `2 }4 |
  and backends. It should normally never be set, and the default size (0) lets( |8 I& o" h$ q& S' T" e
  the kernel autotune this value depending on the amount of available memory.
. M  t4 y, x$ A, \0 R; z0 q. d7 V. Y% L  However it can sometimes help to set it to very low values (eg: 4096) in
& y( H( D; r, _# m/ G  order to save kernel memory by preventing it from buffering too large amounts0 ]; I2 l; {$ D" o1 f- _
  of received data. Lower values will significantly increase CPU usage though.. z  n1 L4 C0 }6 T! a2 j
. ^$ E, A, v) i! d' Z
tune.sndbuf.client <number>0 X" U$ G! X3 L" o; |4 u
tune.sndbuf.server <number>, m# Z' M7 U% o+ r& a+ k
  Forces the kernel socket send buffer size on the client or the server side to% w% K0 o3 q' K/ n2 D0 w" k* Q
  the specified value in bytes. This value applies to all TCP/HTTP frontends
' b4 M5 ?9 w! @5 i  V  and backends. It should normally never be set, and the default size (0) lets
: U: o. q& g4 o5 f. l  the kernel autotune this value depending on the amount of available memory.2 p: Y  Y) {6 w! I7 `: y
  However it can sometimes help to set it to very low values (eg: 4096) in' G. Y4 K8 f  v
  order to save kernel memory by preventing it from buffering too large amounts
$ [6 J) F0 _+ L. Z6 o# U# b  of received data. Lower values will significantly increase CPU usage though.
* k4 h/ J6 P7 |9 ?3 A6 r3 O  Another use case is to prevent write timeouts with extremely slow clients due; Q4 T0 `' F$ [( _3 Z- [
  to the kernel waiting for a large part of the buffer to be read before+ a' j; N0 X  ]6 g7 _( V1 v
  notifying haproxy again.
7 ~6 w% ]) d- Y; A' J$ Q4 G+ A* \4 b6 w3 ~$ c7 p5 p3 u

, S7 ^. z2 m& n, M4 B3.3. Debugging
# i1 K  g/ w- f--------------
2 [% \) L9 X, S3 O+ b8 P0 p/ v- `8 u5 y" v% U" N
debug
3 f2 K9 T4 F" ?" |! V8 B; z$ y1 [1 Y  Enables debug mode which dumps to stdout all exchanges, and disables forking  T2 u+ z2 d3 s" E/ y8 o
  into background. It is the equivalent of the command-line argument "-d". It! e5 V* \: ?6 @1 o
  should never be used in a production configuration since it may prevent full
+ @- D% i2 V! ^+ ^  system startup.
/ [& m- y: b1 x
0 s# D6 J4 A( m% ~& B9 v) i$ X$ Xquiet; ~" a3 M, d% W6 D+ A: O  o( N
  Do not display any message during startup. It is equivalent to the command-+ C- N5 q3 f9 o) w, Q
  line argument "-q".9 Z7 g/ o7 o  C8 \

' o) p' I4 e" Q1 [( t1 N% ~3.4. Userlists
" w9 u# s) U+ ?--------------0 m9 C! d. _& i0 {8 ~3 P
It is possible to control access to frontend/backend/listen sections or to
; W, E$ A" P( ?: _4 qhttp stats by allowing only authenticated and authorized users. To do this,/ _! D& q6 S8 u
it is required to create at least one userlist and to define users.
3 O% o# X! t4 j% w: Y- e
& C4 Q' G" S3 d; m0 h/ ruserlist <listname>
+ @7 Z0 a$ o% E) a2 w; m/ }  Creates new userlist with name <listname>. Many independent userlists can be( H3 O4 F3 ~1 C! T3 w! z3 s+ J( G
  used to store authentication & authorization data for independent customers.
$ d& s% u/ a9 m1 v! f
" D/ B# A4 d% fgroup <groupname> [users <user>,<user>,(...)]
& f- j& g0 e+ L- @4 D  S/ t* R  Adds group <groupname> to the current userlist. It is also possible to% K3 O! a2 `! @7 _! X( U. q
  attach users to this group by using a comma separated list of names
3 d8 {1 U& e9 C# W1 a  proceeded by "users" keyword.
! {: e8 V8 C! _) r0 B! A" f4 ?4 O* @. u1 }( i: c7 g
user <username> [password|insecure-password <password>]
9 a* q2 l1 A: M; e* E                [groups <group>,<group>,(...)]
& k. n" ]/ r. o, p  Adds user <username> to the current userlist. Both secure (encrypted) and
9 S4 [1 X2 t) r1 t3 Y' }/ H% m  insecure (unencrypted) passwords can be used. Encrypted passwords are
- W: w; a0 t6 s) y  evaluated using the crypt(3) function so depending of the system's8 o7 D" I, S! X
  capabilities, different algorithms are supported. For example modern Glibc. C' W6 A  h! [$ o6 T) I/ M7 X
  based Linux system supports MD5, SHA-256, SHA-512 and of course classic,
7 b1 q( \4 B) y' T0 I  DES-based method of crypting passwords.
) J. O% Z9 k4 s' G+ c% s7 c# b8 S4 L8 x- v  V* L) M. ]

9 B1 k6 r' J" x/ N& F  Example:9 ^) @4 z4 D) S6 w( s! W- ]
        userlist L1
: X& E/ W8 y' L! V" y& m, g          group G1 users tiger,scott6 r; t9 O$ I# K0 v; K' c1 m
          group G2 users xdb,scott9 ^- h5 E# o- a& b; A# d9 ]$ l
, @) M% b: |" D
          user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91
# t$ d  I* y5 T  r, X* Q          user scott insecure-password elgato
* Y- Y2 n# t; Q          user xdb insecure-password hello# ^4 u- M: Y: w4 F7 e0 G

2 }+ c1 B0 p- e; t- b. y$ z        userlist L2
5 C) ]/ [! |0 |6 B3 S$ |          group G1
( T( `' [. a( _1 ~4 |. `% K" P          group G2
1 [6 i: ]! {7 ?5 q" I
6 r% t5 V- K( t+ x5 z' ?" d          user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1: k; J5 D+ G4 r5 m! e# O! |
          user scott insecure-password elgato groups G1,G29 |4 L+ R! G% F; ?2 r4 g
          user xdb insecure-password hello groups G2/ A. R! M+ i7 c( t0 b

" {/ N; ?9 T& p; i) S) y: ^  Please note that both lists are functionally identical.5 Z7 Q# c+ k7 p1 S
, r3 j$ `" k8 f3 H1 O8 r6 j
4. Proxies- q# d* c+ @; n) @4 X# N
----------
9 N4 a/ m; X4 L- A% R4 e- l* z7 e$ l5 b* `
Proxy configuration can be located in a set of sections :
1 G0 Y- X1 G) z. i! l - defaults <name>7 Z2 h  {* u0 b6 a6 t
- frontend <name>
* B* F7 O8 Z) G1 u* Q, d. D - backend  <name>6 _& b7 b  e9 f- b( ~' s! F8 ~8 S
- listen   <name>
4 M6 y0 @$ c& B' \0 H: s$ W% e( \
A "defaults" section sets default parameters for all other sections following
: X9 Q9 l$ p1 M) Y- W. f* w& Nits declaration. Those default parameters are reset by the next "defaults"# n* {  s& Z6 Q& \" W" t0 [# z5 K
section. See below for the list of parameters which can be set in a "defaults"
1 }* u) x. ^/ m- P4 m" ~) Usection. The name is optional but its use is encouraged for better readability.4 P  Z1 }. i, B  Q
: {. |4 p5 u8 y2 |" U5 E5 b0 V
A "frontend" section describes a set of listening sockets accepting client) H. u' i$ q% `+ \7 f$ T; d
connections.
4 v8 x) ]/ R7 x: i6 w2 C8 Q, n/ U  |6 }, R  p
A "backend" section describes a set of servers to which the proxy will connect
7 V4 K* s. G8 x3 Oto forward incoming connections.
" o( Y; M6 m  K# j5 U1 `* ]& G+ X% |5 x4 W
A "listen" section defines a complete proxy with its frontend and backend4 f0 Y' o) a! w5 a1 i4 }
parts combined in one section. It is generally useful for TCP-only traffic.$ u! m* g( D5 K+ s
6 h" g# n6 N( W; o( S: b* j
All proxy names must be formed from upper and lower case letters, digits,% N# F# D0 e. g
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are
/ S5 n0 s/ H# T3 O& Z. N, s3 k7 Kcase-sensitive, which means that "www" and "WWW" are two different proxies.
% ]+ Q0 T6 ]* }2 t: ~- w) c( F9 ^# t: @( U/ D, f
Historically, all proxy names could overlap, it just caused troubles in the
" F- K9 j/ B) A1 n2 e- W0 Dlogs. Since the introduction of content switching, it is mandatory that two
  d4 t8 Q0 A4 L' \7 h9 a* |( ]proxies with overlapping capabilities (frontend/backend) have different names.
- D/ f4 L4 N( ]6 U' E- ?7 nHowever, it is still permitted that a frontend and a backend share the same
5 e  M7 c. s: g1 l: g$ @0 Oname, as this configuration seems to be commonly encountered.
" C9 g# a/ z. ?: [$ Z: V. j
% j1 t5 _0 |4 t+ LRight now, two major proxy modes are supported : "tcp", also known as layer 4,; Q6 f0 a/ o- ^9 V  O* e  @
and "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards  i& R8 S( T6 E0 i6 e4 R; P2 O. z
bidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the
8 }# S' p4 b9 F9 G" A6 t. _protocol, and can interact with it by allowing, blocking, switching, adding,
+ g+ t. Z7 Z! U: ?4 t, O. Gmodifying, or removing arbitrary contents in requests or responses, based on+ ~4 A6 V& s3 S4 K1 A. Q, l
arbitrary criteria.8 H2 ^/ K+ u3 k1 ]4 l; @, T# ]
! G) E6 e" M7 w. l! P) C; x
5 u9 b: t! a1 C. r. Z
4.1. Proxy keywords matrix
2 Z* q* Z/ a- T) d. w- N--------------------------
& r* R; K: s. `$ t9 Y8 T6 ?1 C- r6 c0 U( m2 n( i
The following list of keywords is supported. Most of them may only be used in a- H  C+ W% K. T& l' i
limited set of section types. Some of them are marked as "deprecated" because% d, V) ~9 M( e# N) J& I3 g% C4 ~
they are inherited from an old syntax which may be confusing or functionally
  }/ G: j& o9 ]# N# ?* {limited, and there are new recommended keywords to replace them. Keywords
: C7 \7 j6 c: G: \marked with "(*)" can be optionally inverted using the "no" prefix, eg. "no3 F8 j/ X3 ^& Z
option contstats". This makes sense when the option has been enabled by default& j. o& c2 k, s1 Q
and must be disabled for a specific instance. Such options may also be prefixed$ p! c$ d+ _. ?
with "default" in order to restore default settings regardless of what has been( s; Z- C* @$ E6 D
specified in a previous "defaults" section.0 c; d! _! _; b7 j& O# H

% a9 A( O, V9 M$ g2 v3 ~; r( S4 v5 C6 h  g7 o6 j: @
keyword                              defaults   frontend   listen    backend5 P$ t$ I: D2 E' |' `
------------------------------------+----------+----------+---------+---------6 K: U) P+ r( N! k, D
acl                                       -          X         X         X& u% N9 z# g' \% J, c
appsession                                -          -         X         X) h8 d8 r! {/ M
backlog                                   X          X         X         -
9 Y- x$ m, ^# r8 Y3 v0 Obalance                                   X          -         X         X
) a! @0 t$ H6 G) p0 H' }1 ibind                                      -          X         X         -/ e1 l2 a0 X) S" Y
bind-process                              X          X         X         X
% h) l5 a/ _5 g) G4 O( v4 Qblock                                     -          X         X         X
6 p, r4 Z4 X( V) Rcapture cookie                            -          X         X         -
$ Q4 n8 e3 Y" {, Gcapture request header                    -          X         X         -
$ ?4 y4 \9 V( W5 I/ d- U/ h: ocapture response header                   -          X         X         -
/ f- d0 Q& m) H+ l+ L( ]. P! ~clitimeout                  (deprecated)  X          X         X         -7 Y- [$ l, A1 L( W
contimeout                  (deprecated)  X          -         X         X
( v3 S9 s( v3 U7 Ncookie                                    X          -         X         X
* Q* _% h+ q4 s! x1 ?: Zdefault-server                            X          -         X         X# V* u3 R; D. ]' T: B& }" X9 a6 W
default_backend                           X          X         X         -* A& F, }6 q) i
description                               -          X         X         X
2 m8 g: e9 _: P3 jdisabled                                  X          X         X         X" K1 u& ?+ {  U* M, K4 Q
dispatch                                  -          -         X         X
9 M% h: x" N: R- k# K. b5 F6 Venabled                                   X          X         X         X. x6 t. u  m$ {5 ?( d/ I" f# q. k
errorfile                                 X          X         X         X
4 `3 Q" K4 \0 H, werrorloc                                  X          X         X         X
( t" h! J" p2 i( ?errorloc302                               X          X         X         X. i# |3 l4 S" a" y8 r& _( M* q
-- keyword -------------------------- defaults - frontend - listen -- backend -
1 k1 _1 j, I% rerrorloc303                               X          X         X         X2 {! A. d  }( C* ]4 W( k, {
force-persist                             -          X         X         X
* D- t7 G) `. X7 Nfullconn                                  X          -         X         X5 W2 b6 o5 h& i' p
grace                                     X          X         X         X& D4 }8 E$ d* b7 D5 G% f
hash-type                                 X          -         X         X
6 Q) P9 f, c$ `8 `( J! B2 Xhttp-check disable-on-404                 X          -         X         X
  @6 A- ?: ], t) H; ~9 h: f. o: mhttp-check expect                         -          -         X         X8 T: ~. k) I/ p, H& d
http-check send-state                     X          -         X         X; b3 \. |# J3 w  L
http-request                              -          X         X         X8 a0 s" p& F2 P% s7 ?! P: x2 q* b
id                                        -          X         X         X8 s4 I5 w3 T6 w$ H" i" `
ignore-persist                            -          X         X         X, b8 X7 e& Z" j" \8 E, m
log                                       X          X         X         X! v! w5 x# T; B1 k& S# q
maxconn                                   X          X         X         -
3 S7 u/ U* u! e1 D% N* h) f2 imode                                      X          X         X         X, G; |4 m( F$ y$ D6 X) ~, }
monitor fail                              -          X         X         -5 Z' y: k( n: d
monitor-net                               X          X         X         -
& L& ?/ X, e! L* K9 \3 Gmonitor-uri                               X          X         X         -* \* N7 t5 `6 }1 R3 u7 o3 G
option abortonclose                  (*)  X          -         X         X+ |3 E& P/ @7 F" J% q. {
option accept-invalid-http-request   (*)  X          X         X         -* l; q$ H, ~5 S* y# x7 g+ \# z" \& f
option accept-invalid-http-response  (*)  X          -         X         X! e- k" @3 W, d6 j) l7 A# q: s! Z
option allbackups                    (*)  X          -         X         X
$ S" h; D0 O& v3 J. S! toption checkcache                    (*)  X          -         X         X
$ U, B. S6 `- b) r, [8 Z! \' ?option clitcpka                      (*)  X          X         X         -' W, q0 v  `0 G: S% K, `
option contstats                     (*)  X          X         X         -
* B9 F! w! ?4 F9 F$ i, P9 eoption dontlog-normal                (*)  X          X         X         -
1 s/ D/ w2 s3 T3 @4 z' r, o8 ooption dontlognull                   (*)  X          X         X         -
% ]/ i" h9 H6 P+ R9 N* \' Xoption forceclose                    (*)  X          X         X         X
* f* E; |  I" ^. U-- keyword -------------------------- defaults - frontend - listen -- backend -
# L$ i6 T6 g/ o( ], ^# \option forwardfor                         X          X         X         X7 m' \1 Q% U/ g% U0 v  c( n% H
option http-no-delay                 (*)  X          X         X         X
2 ], Q. w/ C# o6 l! e1 K  d0 U6 Foption http-pretend-keepalive        (*)  X          X         X         X; Y  P4 v5 m9 F. G; Q6 B2 K# Y
option http-server-close             (*)  X          X         X         X
3 Y( }+ Y/ G& y" B* m: |option http-use-proxy-header         (*)  X          X         X         -
8 s$ D; y2 ~. q/ {7 @* Boption httpchk                            X          -         X         X
0 @: n8 D& J9 A% Q1 Z% Z# Z+ i! r  Zoption httpclose                     (*)  X          X         X         X
  ?4 [* Z8 [1 N: A9 toption httplog                            X          X         X         X. X2 D" C3 a$ c- j( e
option http_proxy                    (*)  X          X         X         X
" F& R, J1 s  n, v7 g* {- Moption independant-streams           (*)  X          X         X         X( ?- T2 k* ]( M5 j" |
option ldap-check                         X          -         X         X
0 H4 v+ b$ l+ f0 ^. l7 d$ P. Moption log-health-checks             (*)  X          -         X         X1 ~) O& G1 K+ v" n# \
option log-separate-errors           (*)  X          X         X         -8 i8 s2 H/ C( p% D; i) b, h& X, Z
option logasap                       (*)  X          X         X         -
' [$ Q5 w7 v+ N! W0 z* i$ ?0 Ioption mysql-check                        X          -         X         X
/ [: C( L" x, M+ ^7 Aoption nolinger                      (*)  X          X         X         X2 V" Y4 u+ S& S3 p% s, n" R
option originalto                         X          X         X         X" j8 y4 ?9 Z: |2 O# ^" o6 b
option persist                       (*)  X          -         X         X
: H- }/ t, V$ p/ Eoption redispatch                    (*)  X          -         X         X
, [9 ]: H9 W/ A  G( F8 }option smtpchk                            X          -         X         X
) n* |" E* m9 g- w2 noption socket-stats                  (*)  X          X         X         -
7 [4 s& [# p+ Y3 N" J; hoption splice-auto                   (*)  X          X         X         X
  c0 T% P# h! Hoption splice-request                (*)  X          X         X         X3 {  ]! H" i) D- C9 o, F
option splice-response               (*)  X          X         X         X
! o3 o! v- P' Z8 Y7 i$ Poption srvtcpka                      (*)  X          -         X         X  }" c1 U- `% m
option ssl-hello-chk                      X          -         X         X
1 O5 u' V! k+ ~' V  f-- keyword -------------------------- defaults - frontend - listen -- backend -+ \# ?) I6 P/ ?  {7 s; ^( r9 P
option tcp-smart-accept              (*)  X          X         X         -/ K8 A% r+ L. I: m! ]
option tcp-smart-connect             (*)  X          -         X         X
' `: F! j; T3 H* l0 [option tcpka                              X          X         X         X" A& Q) n1 @! z/ o$ z; u
option tcplog                             X          X         X         X$ E6 f. E& d, }
option transparent                   (*)  X          -         X         X
* v( |0 E3 W+ ]* }4 {  k& kpersist rdp-cookie                        X          -         X         X* {5 }0 u2 b) j, w
rate-limit sessions                       X          X         X         -8 x* n# a  _, X- b$ s- W+ w
redirect                                  -          X         X         X
9 R. V' K2 G+ predisp                      (deprecated)  X          -         X         X4 j  M/ R7 K( w& {/ U
redispatch                  (deprecated)  X          -         X         X
/ t+ f" M" G) f: S' Greqadd                                    -          X         X         X
1 b* I( ?! u. G' n4 t: s1 h- Oreqallow                                  -          X         X         X' A: Z2 c; N5 W# Z1 \( t
reqdel                                    -          X         X         X( ?  V' n) X0 t- w4 I: G; \0 [
reqdeny                                   -          X         X         X
  D/ N' i7 U2 X' ]reqiallow                                 -          X         X         X: }( [0 {2 X( _( C! M. j' j4 G! F
reqidel                                   -          X         X         X" m1 Y6 |2 I1 f
reqideny                                  -          X         X         X
. Q- W; U1 L) V5 Dreqipass                                  -          X         X         X  H" f& u( k2 [2 s
reqirep                                   -          X         X         X
2 p7 b/ K; \1 D% l& @" greqisetbe                                 -          X         X         X
2 h8 f; ?  O2 {' k8 i3 i- Z+ m( y! Xreqitarpit                                -          X         X         X
8 e7 V- O. C' [* N3 Lreqpass                                   -          X         X         X
; o' o$ z8 n; breqrep                                    -          X         X         X; R& L1 n+ h1 I. g
-- keyword -------------------------- defaults - frontend - listen -- backend -1 S$ B0 k3 B0 ?% b) w' Y5 Y* _! |: A
reqsetbe                                  -          X         X         X
: D" I! E$ `- c: P3 ?reqtarpit                                 -          X         X         X& i+ _& \7 [! I. N) r
retries                                   X          -         X         X4 R0 X7 X# E1 P3 \( `1 M0 c+ @: Y6 z
rspadd                                    -          X         X         X
, Y3 n5 a) A. f$ X3 ]. {. _& Jrspdel                                    -          X         X         X
2 O+ O! @# W  {; W* w6 ^( r' [rspdeny                                   -          X         X         X+ b3 _% s, x$ Z* x2 L
rspidel                                   -          X         X         X' k+ y4 S% [$ M5 a- p/ n
rspideny                                  -          X         X         X
; c( h# `% }2 \0 @  Srspirep                                   -          X         X         X5 ]4 D# @2 r$ |3 D7 P
rsprep                                    -          X         X         X
( i5 |( ^/ k  G2 v% u: dserver                                    -          -         X         X
5 t; }* r1 m- g, J2 I( G1 G* Nsource                                    X          -         X         X' ?- l$ G9 N7 S6 i
srvtimeout                  (deprecated)  X          -         X         X. _2 j+ p! F5 H! H( Y# x0 [, a
stats admin                               -          -         X         X
4 Q, r% e$ `: h1 y' o' Dstats auth                                X          -         X         X: z8 {" i" s) b3 p  t
stats enable                              X          -         X         X
+ O' r( e5 }9 I. X3 T7 Hstats hide-version                        X          -         X         X
9 n, S; @3 K. \" x7 n) P$ Cstats http-request                        -          -         X         X
& \- R$ q1 a- n! Vstats realm                               X          -         X         X
% _4 T* F% I0 U, o5 t. [/ W5 |stats refresh                             X          -         X         X& a0 R( K  A: L0 [" a
stats scope                               X          -         X         X1 i# S) H" s8 \+ X6 Q9 g
stats show-desc                           X          -         X         X' \4 a# K! k0 ]* O8 t) E1 V
stats show-legends                        X          -         X         X4 |$ a8 z$ U& @4 ]) s/ d+ u
stats show-node                           X          -         X         X2 m8 l0 s7 F6 H3 W
stats uri                                 X          -         X         X2 l( q2 i- O6 s; r2 ^/ @. N
-- keyword -------------------------- defaults - frontend - listen -- backend -
: w, [. K1 \1 Kstick match                               -          -         X         X
$ U6 }/ |. }: b+ T& ]& i- Vstick on                                  -          -         X         X
& g( C0 ?4 O0 N) K+ \stick store-request                       -          -         X         X
; B# s# J  `' }! K( ^+ Qstick-table                               -          -         X         X
2 b+ T) \6 u, m0 jtcp-request content accept                -          X         X         -! D" P8 v( h$ \" U3 [+ U
tcp-request content reject                -          X         X         -$ @. m$ X& G$ b
tcp-request inspect-delay                 -          X         X         -2 v6 c9 h3 [* J1 H
timeout check                             X          -         X         X
+ m3 I; i- J; Stimeout client                            X          X         X         -
% u  k$ c' C! z" ltimeout clitimeout          (deprecated)  X          X         X         -
2 d- y3 b. p: h* m! Z3 }timeout connect                           X          -         X         X
& F  ^+ _/ d. w' @: [timeout contimeout          (deprecated)  X          -         X         X
& k/ P- K4 J' @; Vtimeout http-keep-alive                   X          X         X         X2 ]; X- y' y1 D; c. @
timeout http-request                      X          X         X         X: ?$ H* U- s' q- R+ w/ I1 T' K  x
timeout queue                             X          -         X         X+ G/ j. ]2 F/ Q+ Y9 _* {5 D+ r
timeout server                            X          -         X         X9 D: ^3 D: ]" [& n. R
timeout srvtimeout          (deprecated)  X          -         X         X
! q8 z& q5 V5 ^6 H3 |# }: Utimeout tarpit                            X          X         X         X
% W8 c& ~8 |% c& Q- z5 R0 [transparent                 (deprecated)  X          -         X         X
2 X6 E. _$ K1 Suse_backend                               -          X         X         -+ C" W( |! ?7 j( `
------------------------------------+----------+----------+---------+---------
+ Z" A) {. o, f: Y" X- r  u2 w keyword                              defaults   frontend   listen    backend
, s( N. Z, a% q4 N( V6 V: N2 F+ o) A

$ s+ n, _6 v1 d, B* p$ \2 S& e* w0 x4.2. Alphabetically sorted keywords reference
3 }* Y3 q* G, e3 L4 q---------------------------------------------; [; S- S  W, {) ^1 h. f3 J

/ t% \) j# l1 v. g  r; VThis section provides a description of each keyword and its usage.$ ^0 F& e! P, B2 l

+ }/ a. G8 H' N. }2 F' h5 |; ]$ w$ H4 [
acl <aclname> <criterion> [flags] [operator] <value> ...
# i' ?: B% M3 l$ Q9 K1 z) V/ U  Declare or complete an access list.
. B7 b* x3 l  g! B; ]* @  May be used in sections :   defaults | frontend | listen | backend( s0 A5 u/ K, {  D
                                 no    |    yes   |   yes  |   yes' Y3 G3 y, ^, A" u* \5 p" p7 J* [
  Example:" w5 L. Y* A, G* e- k  t% n' @. t
        acl invalid_src  src          0.0.0.0/7 224.0.0.0/3+ W% o% U& y, m  L' N
        acl invalid_src  src_port     0:1023
9 B4 T* B% V+ d) @) Y! W; W6 j        acl local_dst    hdr(host) -i localhost" \/ d8 R& E2 m+ X/ Q' x6 X; d
  b8 T  l* ^4 J& N& ~) ~0 }: Y
  See section 7 about ACL usage., B( v0 @4 r: y" e8 S+ f

% @4 [5 T- J: H. X8 W% q  F8 A7 f% E
appsession <cookie> len <length> timeout <holdtime>
% W. i% D  K/ H# G% K; _, f# @           [request-learn] [prefix] [mode <path-parameters|query-string>]$ D, v" ]" z3 S7 ]' `
  Define session stickiness on an existing application cookie.- V' i2 n3 M3 Q) u* R9 @/ _+ C$ L
  May be used in sections :   defaults | frontend | listen | backend
- H# V# u* D6 e/ k& G+ i/ g                                 no    |    no    |   yes  |   yes
, h! K" ^& A6 N/ r6 c" w  Arguments :
* Z: Y! P$ G' p! i    <cookie>   this is the name of the cookie used by the application and which0 @# X9 ]$ {9 ]8 {% p0 ^
               HAProxy will have to learn for each new session.
) q7 u9 G" |0 a5 Y& w
9 G$ s; n# o' K9 k  b: k& b* {6 g' R    <length>   this is the max number of characters that will be memorized and% z/ _3 j% C' E1 i! [* g
               checked in each cookie value.5 R- V: v$ b7 _, m1 d% [

7 p  U2 _) K, ^. p& K* k    <holdtime> this is the time after which the cookie will be removed from
) @+ S0 n* J* _" E8 \               memory if unused. If no unit is specified, this time is in
1 Q. l, c+ o, y9 g, q4 E- a. v- R               milliseconds.* x" G- ]2 R1 V8 }+ Y) _
8 W( v0 H+ u" L( d. |7 n( T
    request-learn" ^) i* ~: A' A$ u# T1 x& B+ ^
               If this option is specified, then haproxy will be able to learn6 Z3 q* H$ q- N; [
               the cookie found in the request in case the server does not' p* ~1 c& h- K' _( e6 C4 K
               specify any in response. This is typically what happens with
, ^0 O/ A0 C5 D; Z* w               PHPSESSID cookies, or when haproxy's session expires before
- _+ R# W$ k0 C# I. v9 ^5 ?               the application's session and the correct server is selected.8 q: M  l% ?( T% r2 `( B
               It is recommended to specify this option to improve reliability.
: z, v% ?; |( X$ w
1 ]6 b$ L1 E; z    prefix     When this option is specified, haproxy will match on the cookie1 G: J  p' `% @; H; Q( S/ ]
               prefix (or URL parameter prefix). The appsession value is the
8 B2 x7 @- ?) M# B6 N% S               data following this prefix.
% p% l$ B5 Y; e; P$ r1 h" n2 u& L* ]0 Y: C8 U% d1 Q5 }
               Example :
; Q/ _2 e' c! q3 q               appsession ASPSESSIONID len 64 timeout 3h prefix5 U7 d5 _5 f+ B) Q

4 F. W2 {  f# T8 d9 T3 |               This will match the cookie ASPSESSIONIDXXXX=XXXXX,0 W4 y; _" \- e5 `9 s
               the appsession value will be XXXX=XXXXX.) x9 Q8 H+ ~( u+ n. H! {& m
, \  e! ?4 q! }+ }
    mode       This option allows to change the URL parser mode.7 F. r) D; G0 C9 [; P% E( m
               2 modes are currently supported :; _# m* C+ q6 l3 R8 j; V+ w
               - path-parameters :1 U2 q' t5 ?8 ~$ @& \# x! i, m
                 The parser looks for the appsession in the path parameters( x- J1 t3 Z/ G  P) P
                 part (each parameter is separated by a semi-colon), which is* s9 p- S! i# }! S: _4 u
                 convenient for JSESSIONID for example.
/ V8 z  G& o  p  r                 This is the default mode if the option is not set.
/ n0 ~0 c7 w* {, J0 f! P; b2 P7 v6 F               - query-string :
' @, Q7 F" F5 u8 W4 K8 k                 In this mode, the parser will look for the appsession in the( d, \. M3 L9 u0 w
                 query string.* w( ?9 p# v+ F& P8 |1 P

) X- X2 ]  l& E* ~- z% L  When an application cookie is defined in a backend, HAProxy will check when0 t% C( m6 n" R
  the server sets such a cookie, and will store its value in a table, and
! _! S) _- [0 [  associate it with the server's identifier. Up to <length> characters from
, L, o# f( v  x  z; Q1 x0 c2 A: x5 s4 g  the value will be retained. On each connection, haproxy will look for this
7 H/ }9 D. _7 P8 \9 {8 e- ?0 |  cookie both in the "Cookie:" headers, and as a URL parameter (depending on  ?3 M. i6 |' W+ K2 |, K: p- s+ t
  the mode used). If a known value is found, the client will be directed to the
/ A- E0 V6 P! k; ?- }9 V& M  server associated with this value. Otherwise, the load balancing algorithm is, F9 ?6 a7 S: o' Z4 `
  applied. Cookies are automatically removed from memory when they have been
' U+ t: ^% g4 e: W9 F; m  unused for a duration longer than <holdtime>.
9 m; ^4 v' J. I) l, R" v7 |* q+ ~2 H" {; p  t
  The definition of an application cookie is limited to one per backend.
' B2 c) T8 o5 f3 o/ x
7 c3 A6 C& j4 M  t+ {' v2 a5 x  Note : Consider not using this feature in multi-process mode (nbproc > 1)
. J0 X# ?" E8 @* Y. P& n" F         unless you know what you do : memory is not shared between the
! B/ D( M; D) p: o1 A; i         processes, which can result in random behaviours.. g8 h% |3 B0 f, W4 k+ |

- M; M* E: D* K- s8 q% H  Example :
9 G( |+ I( Y. ]: F2 k9 A9 _        appsession JSESSIONID len 52 timeout 3h. y2 B6 P/ c7 [" s# T& i

. t( w3 I( P1 g$ K1 p  See also : "cookie", "capture cookie", "balance", "stick", "stick-table",3 l7 o0 _. V6 i4 t* r( Z4 }
             "ignore-persist", "nbproc" and "bind-process".& }1 t3 g; E4 N; {# G

8 |$ \, y/ K9 g) W# L
7 J; ^  h. j6 P" i8 r8 W! n8 Gbacklog <conns>
, x4 M1 M* \! g* s5 N  B  Give hints to the system about the approximate listen backlog desired size" P2 K% }% W  Q
  May be used in sections :   defaults | frontend | listen | backend" n7 ?0 I. I* l/ i: n7 ]; \
                                 yes   |    yes   |   yes  |   no7 T; i7 H, m7 V' D
  Arguments :9 V% R& g! j, z/ x( Y$ w
    <conns>   is the number of pending connections. Depending on the operating
+ g, \" n4 V  W# y; g' R* F              system, it may represent the number of already acknowledged9 p$ r% i1 H' |
              connections, of non-acknowledged ones, or both.
% U) O# ^4 T$ W! R: M  g
* |1 X% `6 ]4 \$ F  In order to protect against SYN flood attacks, one solution is to increase
4 m: l1 G; c3 l2 M  the system's SYN backlog size. Depending on the system, sometimes it is just
% W3 V2 o. d$ }8 R# ~  tunable via a system parameter, sometimes it is not adjustable at all, and
" j/ q7 u. D) a  sometimes the system relies on hints given by the application at the time of
4 j6 l2 S1 G- ?5 g: Y6 y  the listen() syscall. By default, HAProxy passes the frontend's maxconn value$ j" Q/ y& p1 S8 Y. o# ~
  to the listen() syscall. On systems which can make use of this value, it can
: h4 T- ]7 W+ x- {5 {" A  sometimes be useful to be able to specify a different value, hence this
- l$ n) Y1 t- n# v7 d$ u; m- m9 }# B  backlog parameter.! D- F- L1 V8 X, s

" e# y5 j% m  F* O8 y/ T- ]: r  On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is
9 X) H; A' l/ |$ L  used as a hint and the system accepts up to the smallest greater power of+ j& W" N: V- U, W$ i: u
  two, and never more than some limits (usually 32768).# a) k7 J- w) c. Y

0 r8 Z1 G' `7 [" D" P  See also : "maxconn" and the target operating system's tuning guide.5 Z! i* `  d2 w  Y/ z

) w$ I/ F) t3 j( W/ V
. X% R# g9 Z' K1 a* \9 Fbalance <algorithm> [ <arguments> ]5 z" \9 q# n0 h) Q  w  e. [
balance url_param <param> [check_post [<max_wait>]]7 ~& y, Y% C1 F. m  B& x
  Define the load balancing algorithm to be used in a backend.4 O. f8 _2 T* R8 q" Q7 @& D% H
  May be used in sections :   defaults | frontend | listen | backend4 D4 Q& r3 G. `" ?
                                 yes   |    no    |   yes  |   yes$ h8 C& L" j. p* B$ T' S2 y  b
  Arguments :: U# _- P  o6 H/ V# j) A7 ^
    <algorithm> is the algorithm used to select a server when doing load
9 u6 U$ }2 V: u6 Q                balancing. This only applies when no persistence information
9 i  _- u) o* `/ b4 G; N$ E                is available, or when a connection is redispatched to another8 L; `& g' E% ?% ]
                server. <algorithm> may be one of the following :
! H  o2 P+ a- H* V
( \0 R2 \% D: A7 U) X) u: g  b      roundrobin  Each server is used in turns, according to their weights.7 J6 d- C3 a- Y/ T) [! p2 M
                  This is the smoothest and fairest algorithm when the server's
) r8 e- A4 v% h$ `- x1 ?, e3 G                  processing time remains equally distributed. This algorithm
" d! n: [& F4 m, D1 `( o                  is dynamic, which means that server weights may be adjusted
1 n! ^& ?+ s& N/ B% v1 W                  on the fly for slow starts for instance. It is limited by4 w' f( S2 {( E. W
                  design to 4095 active servers per backend. Note that in some
  ~0 }* j! n: v, x                  large farms, when a server becomes up after having been down  t) B# p5 Y8 h
                  for a very short time, it may sometimes take a few hundreds0 I' t8 s# S* m( {
                  requests for it to be re-integrated into the farm and start
2 M4 R& ~( Q# P                  receiving traffic. This is normal, though very rare. It is; l: Z# _0 X) ?% V4 t3 I% {
                  indicated here in case you would have the chance to observe
7 p- j6 ]9 I6 }1 c7 Y( |$ V# U                  it, so that you don't worry.
! w+ C+ P: R- u6 w: c7 O+ E
/ ]9 D! k( G- o3 Z" \5 y+ e7 z$ f7 @      static-rr   Each server is used in turns, according to their weights.
8 J: @8 @& s' `; Z, S                  This algorithm is as similar to roundrobin except that it is  M. [# B/ u7 u9 ^) c2 M
                  static, which means that changing a server's weight on the
; I' w2 q' p  B( v1 ]                  fly will have no effect. On the other hand, it has no design
8 u, V- {% f  @% ?                  limitation on the number of servers, and when a server goes
1 d& x. o: d, n1 p7 O                  up, it is always immediately reintroduced into the farm, once+ }3 f: e, Y7 Z) {4 |
                  the full map is recomputed. It also uses slightly less CPU to8 D2 E6 W* W4 s3 F* }. b0 C
                  run (around -1%).3 A' V% I& x0 T+ `: B! m* L9 \

. ]1 O1 N" F% j! }" ^" i      leastconn   The server with the lowest number of connections receives the
! z1 [  \5 I; L) c4 {8 y                  connection. Round-robin is performed within groups of servers3 K! z( T4 c" `4 e/ o4 r4 K* a: c% K
                  of the same load to ensure that all servers will be used. Use1 N. S* U% G) u1 M" r/ q
                  of this algorithm is recommended where very long sessions are
# d' ~# k( q6 ]5 R0 \9 ?" D1 Z                  expected, such as LDAP, SQL, TSE, etc... but is not very well! H, [+ d2 F" l
                  suited for protocols using short sessions such as HTTP. This
5 P8 v6 @3 T! B  i                  algorithm is dynamic, which means that server weights may be
* y0 }& H3 f: C                  adjusted on the fly for slow starts for instance.
# Y' u6 \% y2 y+ C3 B
- B0 }, o  m$ c& P3 N- g      source      The source IP address is hashed and divided by the total- w+ a# C, F7 d: _
                  weight of the running servers to designate which server will
* t: X2 n# H0 P5 m' K% V$ X                  receive the request. This ensures that the same client IP' [$ Z0 J6 C7 N2 M; R* L. R
                  address will always reach the same server as long as no! Y3 U& l0 u3 k" l6 X
                  server goes down or up. If the hash result changes due to the
0 c9 l' c+ m' ?1 L0 S! [+ D. [                  number of running servers changing, many clients will be
. A  |6 x& t$ I! [                  directed to a different server. This algorithm is generally5 E$ p  H9 |! I6 ?
                  used in TCP mode where no cookie may be inserted. It may also
% t8 r% v& d4 ^, B5 p+ Z+ a8 v                  be used on the Internet to provide a best-effort stickiness& o5 E  L9 Q$ |: n- ?" c
                  to clients which refuse session cookies. This algorithm is
0 s4 |9 @% p. m. }, P9 h/ W- r                  static by default, which means that changing a server's
/ Y* o9 I4 x0 ?  B                  weight on the fly will have no effect, but this can be7 b6 f2 b. c. w7 d
                  changed using "hash-type".
8 {9 K' M  A2 n8 L) T% l# L
4 C/ I: i9 F0 _4 Z1 g5 R      uri         This algorithm hashes either the left part of the URI (before
. l) f5 q& m* l# H5 S                  the question mark) or the whole URI (if the "whole" parameter
$ {- [$ v, ?: r: ?  \                  is present) and divides the hash value by the total weight of
  P: z: N! a9 \$ f# u0 R                  the running servers. The result designates which server will
1 U$ v" c% z; P: s" E                  receive the request. This ensures that the same URI will
8 R0 w" k5 [1 K- Y7 R8 _                  always be directed to the same server as long as no server- j; S$ @% Z8 H7 c
                  goes up or down. This is used with proxy caches and/ S$ P5 Q. t0 n" e' b5 v* x- a
                  anti-virus proxies in order to maximize the cache hit rate.- V( g" y7 `4 g0 }0 S. w5 ~9 A
                  Note that this algorithm may only be used in an HTTP backend.
3 v; ~" l8 }: @                  This algorithm is static by default, which means that
; A0 F& [- c1 b6 X4 C                  changing a server's weight on the fly will have no effect,
1 P$ F# i) l9 S                  but this can be changed using "hash-type".
: }$ w6 M" O, @5 S- _) |: O5 s# q3 F7 D+ _
                  This algorithm supports two optional parameters "len" and2 o$ p2 C0 a# Y9 n" B- d
                  "depth", both followed by a positive integer number. These
+ H1 m' p' J$ x. ]- C8 _6 _8 A                  options may be helpful when it is needed to balance servers
8 P% U: l/ x1 q  B                  based on the beginning of the URI only. The "len" parameter9 a8 [1 Q6 f9 i& f% [5 }
                  indicates that the algorithm should only consider that many+ v) E" ^6 x+ @4 ?& J- b$ l
                  characters at the beginning of the URI to compute the hash.
( J! X" K' ]7 }, K9 {; g) c                  Note that having "len" set to 1 rarely makes sense since most8 }6 F$ i0 [0 E" ?4 u' c
                  URIs start with a leading "/".
8 X6 b  y5 O) }4 D- F2 Y
. m6 m4 o* z! T; c+ U" z                  The "depth" parameter indicates the maximum directory depth8 Z: y# P9 A6 ]4 [/ r( Z
                  to be used to compute the hash. One level is counted for each
6 L$ `. g; e: N4 k0 w8 a/ W                  slash in the request. If both parameters are specified, the
" J+ p2 a9 z7 H% J                  evaluation stops when either is reached., f5 [+ S6 u7 a3 q7 `! J5 n

, u" _- n; ]5 n$ L      url_param   The URL parameter specified in argument will be looked up in9 L7 G: k" Y1 X! n6 }
                  the query string of each HTTP GET request.
: o+ m/ z% r- z' ]4 l' G
) L( ]+ E0 W+ t                  If the modifier "check_post" is used, then an HTTP POST: s. S5 `4 c0 z0 j  ~' n
                  request entity will be searched for the parameter argument,
6 n( c; o( p$ a& w* ?# }                  when it is not found in a query string after a question mark
. d2 Z5 S5 a+ e8 }% A. J5 d8 X) `                  ('?') in the URL. Optionally, specify a number of octets to9 h( x% I7 M; Y' s0 `9 s
                  wait for before attempting to search the message body. If the  S2 p7 c3 u; f
                  entity can not be searched, then round robin is used for each0 M& C- E, L) F  s* C
                  request. For instance, if your clients always send the LB- P0 g2 v) c8 Q: g2 y3 e% {/ E* `
                  parameter in the first 128 bytes, then specify that. The
! r! h5 Z" R9 ~5 B: k                  default is 48. The entity data will not be scanned until the6 m- l+ z" u) z. Y$ \' V
                  required number of octets have arrived at the gateway, this  _# a# b" F- ~5 U1 {
                  is the minimum of: (default/max_wait, Content-Length or first
& W9 d& k- G, m& y: u7 W: D: @2 q1 `                  chunk length). If Content-Length is missing or zero, it does" D' g8 w0 n& u6 j6 R
                  not need to wait for more data than the client promised to& p) v) q9 `, ?( l  U  U! ~
                  send. When Content-Length is present and larger than: ~0 j) i7 h9 D* s/ {* D
                  <max_wait>, then waiting is limited to <max_wait> and it is7 B$ J3 g, K* q9 o) u8 D6 k
                  assumed that this will be enough data to search for the
0 H$ h. k" H" ^: s" c                  presence of the parameter. In the unlikely event that
5 m! W' r6 q6 k                  Transfer-Encoding: chunked is used, only the first chunk is
9 C" \* M/ I2 @, |9 i9 \8 {                  scanned. Parameter values separated by a chunk boundary, may
$ J% E5 s: k# N                  be randomly balanced if at all.
+ g+ f8 m# W- X# A: e5 X* ?
3 Z, a8 s8 {% w0 n; _                  If the parameter is found followed by an equal sign ('=') and
$ Q/ Q4 b7 v5 p                  a value, then the value is hashed and divided by the total
8 f& Q1 S- D: e" W5 ?8 X' {) Y  Z                  weight of the running servers. The result designates which8 O3 ?3 [! W1 n! q  ]' ~
                  server will receive the request.
. W  O7 m. f& Z; J8 L  A  ^6 ?0 u: q/ i# ?9 b9 u. w# @4 `- X
                  This is used to track user identifiers in requests and ensure) w/ W. B' y4 h8 I; l
                  that a same user ID will always be sent to the same server as
; g" ~) ]/ `+ h                  long as no server goes up or down. If no value is found or if! ?2 e+ `5 }$ \: A- L/ t
                  the parameter is not found, then a round robin algorithm is
" m4 @# b4 [+ W. ^* \2 Y5 t+ S                  applied. Note that this algorithm may only be used in an HTTP# D6 d4 Q6 X/ T# _- X3 a
                  backend. This algorithm is static by default, which means
& z, w% a5 o# n; ?" H; b' c                  that changing a server's weight on the fly will have no% \2 I/ r3 T' {) H: P( H
                  effect, but this can be changed using "hash-type".
8 ?& S6 E! B# {9 N/ B. a: O( R1 Z. B2 V( `1 H
      hdr(<name>) The HTTP header <name> will be looked up in each HTTP request.
- ~! H/ {$ p% Y( @                  Just as with the equivalent ACL 'hdr()' function, the header" i- w/ O0 ^) k4 z# a% Y
                  name in parenthesis is not case sensitive. If the header is6 P5 Y! y' }, F; A5 q- j3 ^# e
                  absent or if it does not contain any value, the roundrobin; m" K% q2 y# S' a# X
                  algorithm is applied instead.
/ G, Y6 w" h2 I! N  q2 a7 A! Y! _$ M* E
                  An optional 'use_domain_only' parameter is available, for
. e  Y. M, G) Q                  reducing the hash algorithm to the main domain part with some$ L! s' \" l$ R
                  specific headers such as 'Host'. For instance, in the Host/ Z5 K5 S! z/ s" G% |. S
                  value "haproxy.1wt.eu", only "1wt" will be considered.
; ^  p" n& N1 M2 x+ t9 h; j! P5 e
) O6 g3 U/ h4 R' Q0 ^8 j                  This algorithm is static by default, which means that& v. S" ^) c/ F% S) k3 S) i- J
                  changing a server's weight on the fly will have no effect,' Q( T7 \2 U" {% `' d
                  but this can be changed using "hash-type".
* o! f. k% g9 X+ x" ?. r, x
6 O; i! {* d  L  h; E* r- y3 X      rdp-cookie
) f+ m9 K) O' r* v      rdp-cookie(name)8 r, \/ M1 W9 d- U4 ]7 |' r2 j
                  The RDP cookie <name> (or "mstshash" if omitted) will be
2 H# ?3 L5 \& {0 l                  looked up and hashed for each incoming TCP request. Just as
9 g4 G5 D1 w  m                  with the equivalent ACL 'req_rdp_cookie()' function, the name1 P7 H' O5 \. Z. T9 q: N0 f
                  is not case-sensitive. This mechanism is useful as a degraded
8 \% K( y9 ]" J- C                  persistence mode, as it makes it possible to always send the7 [# w3 B7 ]+ D5 ~' M4 H( O
                  same user (or the same session ID) to the same server. If the0 p' l9 E$ R9 ^0 h1 ?
                  cookie is not found, the normal roundrobin algorithm is
! I; V% k/ Z) O) |5 G' Z+ `, @& d                  used instead.
! H; w5 i1 w( s# d" @1 j9 K" A+ e  w- i6 t1 Z
                  Note that for this to work, the frontend must ensure that an
/ X. J1 [( K5 _                  RDP cookie is already present in the request buffer. For this
+ k: F2 c. k% l& L* a. q                  you must use 'tcp-request content accept' rule combined with
7 o/ w9 e5 |- G                  a 'req_rdp_cookie_cnt' ACL.; S1 K# L  B) F
+ d$ G1 M; I: P& Z3 W2 ]
                  This algorithm is static by default, which means that1 ?7 M* c4 w* Q# L
                  changing a server's weight on the fly will have no effect,& D4 ^" Q0 ]4 ~3 b
                  but this can be changed using "hash-type".& g0 |4 v' e4 ~3 k, k5 m8 K) Z6 L
. d, r3 z: b4 R6 g1 Q
    <arguments> is an optional list of arguments which may be needed by some( r# \+ B5 T8 t, O5 L. [
                algorithms. Right now, only "url_param" and "uri" support an1 x) [& p& a& x0 C6 |* W
                optional argument.  k- `9 B  G, g" P
# f, B4 W! o, J1 s: O8 y. l( c' J
                balance uri [len <len>] [depth <depth>]
/ z$ C) l! O/ @. e- [8 d# a                balance url_param <param> [check_post [<max_wait>]]; [+ P* S) l4 K) F4 K

8 u0 O; D8 c& z+ p  The load balancing algorithm of a backend is set to roundrobin when no other1 {& U! h8 X; @9 }. E' s' ]# U. t, T9 b
  algorithm, mode nor option have been set. The algorithm may only be set once6 p+ G5 i/ A7 H: K! w8 Z
  for each backend.2 f) ^$ u9 r8 Z/ j% \/ h
! f% h5 T+ X  ~+ V0 @
  Examples :
" y7 ~: R3 E) k$ B9 m        balance roundrobin
  N# [7 Y; E2 |& \+ k        balance url_param userid
+ x( `7 q1 n3 `        balance url_param session_id check_post 644 u8 w7 [* m5 I" e, w
        balance hdr(User-Agent)* L8 }( Y5 y4 B- }
        balance hdr(host)
1 U" ~" V4 j( K3 }        balance hdr(Host) use_domain_only
2 @( D; P8 w5 b+ J+ @5 p! g9 s: E2 f, D8 G/ R
  Note: the following caveats and limitations on using the "check_post"
. k5 D( p& Y0 T9 p0 o  extension with "url_param" must be considered :; Q: Z& ~2 x, s" x

8 ~8 y) U6 V5 U    - all POST requests are eligible for consideration, because there is no way
. u  e  s. a% j; T% Q6 Z: J. G      to determine if the parameters will be found in the body or entity which
/ u0 a6 c, F" @. C      may contain binary data. Therefore another method may be required to; @  g# O7 \3 z/ S
      restrict consideration of POST requests that have no URL parameters in
( D0 V- Z: Z' N2 ~0 k0 m4 Q      the body. (see acl reqideny http_end)
0 i' J. ]; C  y( p, q0 @# R1 _! R' e% Y5 s
    - using a <max_wait> value larger than the request buffer size does not$ i2 w1 U! u7 ^& Q6 K/ U* r4 u
      make sense and is useless. The buffer size is set at build time, and5 Z, d7 q! i) [. J- A" d2 d
      defaults to 16 kB.  I  J% b' l- u8 I
- T$ g! X; C; \$ P8 x
    - Content-Encoding is not supported, the parameter search will probably
+ Q1 f) C- @, X# G) {$ @% B4 n      fail; and load balancing will fall back to Round Robin.
$ R. ?) M6 t, F* _2 h5 p6 k- X0 E+ y3 ]: |
    - Expect: 100-continue is not supported, load balancing will fall back to' F5 C' k- R6 K8 G2 C
      Round Robin.& m0 {. b7 U4 a5 r" ?. g' U

- O/ B, q1 r8 l/ n& a) w    - Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk.
' w" s* J: q$ n( \, W. a5 e      If the entire parameter value is not present in the first chunk, the* X( `1 Z8 p1 `, `* t% o7 Z
      selection of server is undefined (actually, defined by how little) v% S* j2 _# h% X( U
      actually appeared in the first chunk).* R& j7 V! U4 k1 q8 L0 i+ Q9 Z0 E" p
$ w' @! w1 {7 U2 K$ J7 f% j4 f& H
    - This feature does not support generation of a 100, 411 or 501 response.  z4 m7 K6 D, [2 V! Q! D9 S
# ?& Q; V% c5 A# ]8 M: a
    - In some cases, requesting "check_post" MAY attempt to scan the entire, T, e8 Q, ^; X. q5 L; T
      contents of a message body. Scanning normally terminates when linear4 y7 r! ^! }' @
      white space or control characters are found, indicating the end of what
6 C. r* {4 _5 z, S; {' S      might be a URL parameter list. This is probably not a concern with SGML2 |* d! _, T. \4 `0 w/ x" q
      type message bodies.5 @, V" H8 L$ S& d
* \0 w6 `! N' T4 `1 h
  See also : "dispatch", "cookie", "appsession", "transparent", "hash-type" and
- Q* J4 v( r. }" f; V) S# B& t             "http_proxy".
6 j# M' ]5 }( b1 _
9 x& _" z8 A# m* D/ ?" p9 I0 P
( W3 L: v: m4 m1 B* vbind [<address>]:<port_range> [, ...]
2 s9 d- W4 d1 fbind [<address>]:<port_range> [, ...] interface <interface>' j0 a* K3 a& h7 X
bind [<address>]:<port_range> [, ...] mss <maxseg>$ m3 ~2 R) Y, v2 z! M* N" v
bind [<address>]:<port_range> [, ...] transparent  O- `2 [/ D& w) U0 P  W
bind [<address>]:<port_range> [, ...] id <id>( s" I3 m8 {# M# i
bind [<address>]:<port_range> [, ...] name <name>" B# ]" G# t  E2 H. X$ [! p
bind [<address>]:<port_range> [, ...] defer-accept4 t4 t1 F' O) U  ]6 X+ Z+ w5 s* X; v% F
  Define one or several listening addresses and/or ports in a frontend.2 a4 n4 a! Z- t
  May be used in sections :   defaults | frontend | listen | backend2 N  |: M$ P+ d  s/ Q7 C1 Z
                                  no   |    yes   |   yes  |   no
" s3 s& g, \8 t" D4 s  Arguments :3 S" Y' l  A2 s
    <address>     is optional and can be a host name, an IPv4 address, an IPv6
, w2 @' [3 Z  f- N& U/ E* }                  address, or '*'. It designates the address the frontend will2 y1 ]5 p  M: i, b. h8 Z
                  listen on. If unset, all IPv4 addresses of the system will be8 h5 L0 O/ n( H* y) M, S; F1 Q& \
                  listened on. The same will apply for '*' or the system's  z: k! }! a9 [5 X, o! H
                  special address "0.0.0.0"., N7 e( e( F" ]/ b9 D8 M6 d
2 N: l1 a% F- S! C8 c; I
    <port_range>  is either a unique TCP port, or a port range for which the
* M( h1 {, f8 z( A5 n! H6 w# u4 H                  proxy will accept connections for the IP address specified
* N% O4 R* `9 ]1 L8 X8 v                  above. The port is mandatory. Note that in the case of an+ ]- t3 l( Y- C4 ~& Z
                  IPv6 address, the port is always the number after the last5 S. B! M$ {" H8 M0 w# O) {
                  colon (':'). A range can either be :/ \+ }' M% j. N- P2 j/ M1 b4 ~
                   - a numerical port (ex: '80')
% `! k: u) Q* y4 j; T& F4 u                   - a dash-delimited ports range explicitly stating the lower' _# K9 q2 g, J3 H6 m: Q/ w$ v6 H
                     and upper bounds (ex: '2000-2100') which are included in) B! m$ e$ @' O/ o& r
                     the range.
& Z* ^* n; u* o0 w9 Y* E  Z7 u# q4 `* \
                  Particular care must be taken against port ranges, because  ~* R9 L, i4 }$ G. B9 a4 `9 A
                  every <address:port> couple consumes one socket (= a file
+ r, u& l5 H/ T2 Y                  descriptor), so it's easy to consume lots of descriptors
- O9 V& y5 K( _9 I, P                  with a simple range, and to run out of sockets. Also, each
1 T  y+ ]( _0 \( G3 D% e                  <address:port> couple must be used only once among all+ `! Y3 }( w, T8 S
                  instances running on a same system. Please note that binding
; @6 b6 G8 T6 M/ `& \& k1 h                  to ports lower than 1024 generally require particular- a6 |8 W3 ^9 m$ x' |5 Z
                  privileges to start the program, which are independant of
$ D; s( U+ z, [& Q. z; S                  the 'uid' parameter.
- `, I# b' d. ]4 e8 Z8 |/ A3 y! g. ]9 h6 F
    <interface>   is an optional physical interface name. This is currently) v% x2 w( N& ^' |( o5 ^
                  only supported on Linux. The interface must be a physical
6 O# z* A) v& J4 n; m* S5 |0 \  W8 L                  interface, not an aliased interface. When specified, all
5 ]6 j- d3 _6 y/ h. x& \                  addresses on the same line will only be accepted if the
1 ?$ E  q5 h, \! f( C- F' N                  incoming packet physically come through the designated2 c/ V; Q* _/ g4 i
                  interface. It is also possible to bind multiple frontends to
% w4 k  V" B( z. J- Q7 \                  the same address if they are bound to different interfaces.3 D5 `7 n7 w: Q; V& U. d
                  Note that binding to a physical interface requires root- r* W# }) b! J) {
                  privileges.
# Z; F9 @- w1 z$ S% I
9 O% `8 w  |9 V& f/ X9 B  j9 t3 D2 B1 P    <maxseg>      is an optional TCP Maximum Segment Size (MSS) value to be
$ \# w# I/ n& t6 h, h                  advertised on incoming connections. This can be used to force
* i  I, z# H! P- u                  a lower MSS for certain specific ports, for instance for' A  F4 F0 c7 ~: ~
                  connections passing through a VPN. Note that this relies on a
, A# L, S% I* [5 l- K5 p3 O                  kernel feature which is theorically supported under Linux but
# Y& P9 v$ U0 g- t                  was buggy in all versions prior to 2.6.28. It may or may not
- s3 l) x' d$ o                  work on other operating systems. The commonly advertised4 [; p" \* c1 H- S( o& V4 L
                  value on Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP)./ c' Y& |) l  y; Y

; |# B. D. U1 C    <id>          is a persistent value for socket ID. Must be positive and/ w  t2 D8 ~( |
                  unique in the proxy. An unused value will automatically be
6 I6 i& U/ v/ v* T2 A                  assigned if unset. Can only be used when defining only a
7 W7 ?& E" E" `6 P  H                  single socket.
+ ^2 G- ?) H5 S3 P3 {, U2 I: Z& V6 g4 B4 G0 Z6 I* l$ [# d. F
    <name>        is an optional name provided for stats8 O# m1 x/ `+ x5 z

! ~2 `: b# |! ?9 e+ s  E/ b    transparent   is an optional keyword which is supported only on certain% t6 y* R6 x% E1 v4 C: p. @& V! w
                  Linux kernels. It indicates that the addresses will be bound+ U7 |& v+ l& b9 x
                  even if they do not belong to the local machine. Any packet" U* V0 Y( K1 N" t' K
                  targeting any of these addresses will be caught just as if
% v3 `  ~8 h/ V+ ?) V' }$ o# u                  the address was locally configured. This normally requires6 R/ c6 U0 a/ x; g$ F1 F4 d
                  that IP forwarding is enabled. Caution! do not use this with
% ^9 b; X' V0 @# d. E0 ^/ I- v' n                  the default address '*', as it would redirect any traffic for
% J5 q9 p' E& M$ \  a# L                  the specified port. This keyword is available only when
9 L8 A: U% A6 Z4 K/ M2 I: W                  HAProxy is built with USE_LINUX_TPROXY=1.# U) t2 R$ T; ~- v: G( o( l

+ }9 a: \) z; Z8 ~8 ~) Q    defer-accept  is an optional keyword which is supported only on certain) q# j" Z9 C9 V: C2 e0 L
                  Linux kernels. It states that a connection will only be
1 K4 m/ t# R8 O4 k8 J/ R                  accepted once some data arrive on it, or at worst after the5 h" H* `1 F7 i( @. D3 B
                  first retransmit. This should be used only on protocols for% g2 e7 k' i, ^& p
                  which the client talks first (eg: HTTP). It can slightly9 S2 Z& l( G+ G! a( i
                  improve performance by ensuring that most of the request is7 H+ S1 F3 m! U8 A
                  already available when the connection is accepted. On the  {; l( [# N9 T: o2 D# o
                  other hand, it will not be able to detect connections which
# T$ q  H* D+ e                  don't talk. It is important to note that this option is
# q  \0 F. P, e! i/ T" t                  broken in all kernels up to 2.6.31, as the connection is2 w' F& B7 z" P: m' |
                  never accepted until the client talks. This can cause issues. a* \0 b! w1 V2 y0 m
                  with front firewalls which would see an established5 s4 A9 I* k% Z: ]) B0 x$ ?3 A
                  connection while the proxy will only see it in SYN_RECV.
) O1 g1 S% u6 \& |8 b# x3 H3 I1 }5 H: A! u4 t& _
  It is possible to specify a list of address:port combinations delimited by6 L+ R5 A$ K6 O4 g( Z* t0 n
  commas. The frontend will then listen on all of these addresses. There is no; g; o) W  s3 i. Y! h
  fixed limit to the number of addresses and ports which can be listened on in
* D% ]1 v9 m  Q) u+ ?$ `/ h  a frontend, as well as there is no limit to the number of "bind" statements6 G: j  b  ^9 L5 W
  in a frontend.9 n! L  h+ F" y1 |6 S' Y2 z$ U

. B$ F2 n  r/ L$ B/ I" C+ l  Example :
! c1 p! K' \( n3 e8 a# C& @        listen http_proxy
- V1 R6 v1 ]6 }            bind :80,:443
$ U- t0 D9 L% W9 C& }5 g1 r            bind 10.0.0.1:10080,10.0.0.1:10443
5 e6 o, J2 T. g$ ~
3 d& v; G$ v) _: I. L" ~  See also : "source".
2 y+ Z' A8 m  ^% G
7 j( n" b2 P7 Z. A# \4 U; \
+ q8 B$ B' t$ wbind-process [ all | odd | even | <number 1-32> ] ...
. `+ o4 D' \( k  Limit visibility of an instance to a certain set of processes numbers.1 `. R1 L( O6 D
  May be used in sections :   defaults | frontend | listen | backend5 E: f3 f. I! Z- f
                                 yes   |    yes   |   yes  |   yes3 |' Z7 |1 ^( m7 Y
  Arguments :0 Y  _7 h  s" v0 N( `  Z
    all           All process will see this instance. This is the default. It9 W+ c" R. ]# p' c5 s
                  may be used to override a default value.
: Y: q9 a- M* {0 H5 ^2 m& x) t, K3 |$ c$ r+ P  @
    odd           This instance will be enabled on processes 1,3,5,...31. This& y1 u/ F& b0 i1 Z* T; I
                  option may be combined with other numbers.
% C7 s2 \: T6 I# d) @  `3 M3 J
% i7 I9 q& O3 w/ m$ b/ u- c    even          This instance will be enabled on processes 2,4,6,...32. This
, k$ g# F3 l, u% E+ ]                  option may be combined with other numbers. Do not use it0 b5 g) U* ?5 A( O5 ]
                  with less than 2 processes otherwise some instances might be- t, v* N6 j3 F4 v4 a/ E# y2 ^* D
                  missing from all processes.
4 i# [+ J* h' U6 P: p# z
% C6 t* J0 p0 B3 y    number        The instance will be enabled on this process number, between
, C& `, T8 m: V0 f" y; P" e+ B                  1 and 32. You must be careful not to reference a process/ C/ R+ u) B9 n+ A$ ]- [
                  number greater than the configured global.nbproc, otherwise- Z  A5 X% D6 _1 c3 K* j4 E+ w* n
                  some instances might be missing from all processes.
6 X. w5 D+ k- g2 f8 k/ K+ u8 E" n9 v2 d3 l
  This keyword limits binding of certain instances to certain processes. This
# e+ g8 [, g: N  is useful in order not to have too many processes listening to the same% G' a3 X$ K, B
  ports. For instance, on a dual-core machine, it might make sense to set
" J; T0 a1 i& K8 D; K  'nbproc 2' in the global section, then distributes the listeners among 'odd'" o2 d# g/ h1 Y+ I
  and 'even' instances.
2 \: a& I9 \- k
# A! {  I+ o: w1 G  At the moment, it is not possible to reference more than 32 processes using' N( B( P& H+ E' \
  this keyword, but this should be more than enough for most setups. Please
; X. S6 I6 s8 x& e  note that 'all' really means all processes and is not limited to the first4 p/ n4 I. F- r) E
  32.
2 s* y1 M. L" y' J7 u1 U7 h: j2 d/ i# P- q/ T5 t& s
  If some backends are referenced by frontends bound to other processes, the
7 Y8 h  }2 G7 a8 @" t) R( y  backend automatically inherits the frontend's processes.
! B4 ?0 [9 g. C' \6 O% f
6 t' L0 c- j' L% m  Example :  C/ H9 |0 g2 d0 N/ m
        listen app_ip1
9 D4 ^) E8 E3 `/ V+ Z            bind 10.0.0.1:80
! Q6 d/ e5 h7 S, g            bind-process odd* p" D$ d' c9 a: H. J) h, _" c& i
. Y# t" q) }# q2 l4 j
        listen app_ip2% w. J  J' z- n" [3 C( W$ g( {
            bind 10.0.0.2:80  v$ E4 Q) s( M- s  w4 c
            bind-process even
( U! E0 Y; ]4 j5 T" }2 _
+ n+ T9 a3 c) S3 c8 T- ~7 h        listen management
6 [8 p0 o3 `- N6 ~9 d* t6 t( n            bind 10.0.0.3:80
, R8 }: t' z+ X0 W            bind-process 1 2 3 4
0 O) _( b+ }; L, z
( B1 F1 @% n' }3 ^  See also : "nbproc" in global section.
- C2 n, Q/ l* {/ |9 G5 E# x* L9 G5 F7 a8 f; d* I) I7 a, a

- S' b( G& Q" B* h% Eblock { if | unless } <condition>
3 n+ }6 ]/ a2 g6 s7 D! I2 B7 d0 z  Block a layer 7 request if/unless a condition is matched0 [! ]7 h& {9 e" l8 g
  May be used in sections :   defaults | frontend | listen | backend
7 f) Q+ `0 E, K$ H, d2 ^: B                                 no    |    yes   |   yes  |   yes
  M& p) V! O- t3 H5 O! _# L6 P% h9 y  R+ T! @/ e" _, _
  The HTTP request will be blocked very early in the layer 7 processing$ ]0 Z7 h; p  D
  if/unless <condition> is matched. A 403 error will be returned if the request
8 V9 p. g7 Z. K: n# q4 E3 m' ]4 _  is blocked. The condition has to reference ACLs (see section 7). This is
6 j. B' Q* L( f+ c2 L  typically used to deny access to certain sensitive resources if some
" P; r2 N8 S9 O$ e  conditions are met or not met. There is no fixed limit to the number of' R1 @/ U5 v1 |' j
  "block" statements per instance.. U, m  S% o5 M+ U# P# Z- r2 C$ @
) {1 g: e7 ?8 t, V
  Example:9 p/ T' ?; |" C9 d/ ^# l4 i
        acl invalid_src  src          0.0.0.0/7 224.0.0.0/3
. p- \8 w+ t$ |2 T% r  a        acl invalid_src  src_port     0:1023
2 q; V1 N% [" R0 {- K) n3 s- }        acl local_dst    hdr(host) -i localhost
; Y9 f: B- u6 V- Q2 H2 [9 p3 r        block if invalid_src || local_dst, G  N/ G: c% L

& x2 J5 _6 V, X: @( o  See section 7 about ACL usage.# d/ W% [+ }& z+ Q; N6 `7 x

3 Z7 ]* N: @% T3 ?
' a2 f+ L; N/ c  ~5 B8 c. Icapture cookie <name> len <length>. I. S2 E6 X% B% M
  Capture and log a cookie in the request and in the response.! _* Q7 P7 x# x8 a9 K
  May be used in sections :   defaults | frontend | listen | backend
) w9 x) ]. C- X! Y6 F' }                                  no   |    yes   |   yes  |   no% q1 O7 \% w9 j) g) F% O
  Arguments :
+ k6 D* ~' @# |+ z% ?! |$ U* r: J    <name>    is the beginning of the name of the cookie to capture. In order3 W- ?( g8 S8 K9 x! {
              to match the exact name, simply suffix the name with an equal
, r+ k3 `0 L: R9 s( O4 p              sign ('='). The full name will appear in the logs, which is% p. Y  g6 u; G7 t  H0 {; s
              useful with application servers which adjust both the cookie name
6 s2 n. }" j8 Z  o              and value (eg: ASPSESSIONXXXXX).
) T9 A. ^; j. V) k, _' k6 W$ B. R/ f# K4 D! q- z5 `
    <length>  is the maximum number of characters to report in the logs, which
* c  x3 r* o. O7 S; m              include the cookie name, the equal sign and the value, all in the7 \, x3 x2 b/ d6 D* ^! a
              standard "name=value" form. The string will be truncated on the4 |) B* X. X* [' M
              right if it exceeds <length>.
# T) B, {$ \# z3 h& K2 }9 E5 a
! k' F- c# j2 g) U  Only the first cookie is captured. Both the "cookie" request headers and the
- ]* K$ Y5 e! @7 R& o  "set-cookie" response headers are monitored. This is particularly useful to  S5 H0 D6 b: x% V7 \/ B% B
  check for application bugs causing session crossing or stealing between
2 _' {7 Q2 M! q+ w' n  users, because generally the user's cookies can only change on a login page.
% R% U9 j1 r( q! r1 v; x4 ]( b6 h. v- Y/ L8 j, @
  When the cookie was not presented by the client, the associated log column
2 X" O( a% X  J1 ^! M9 Y  will report "-". When a request does not cause a cookie to be assigned by the
2 Q# ~2 O* D' T* O) |  server, a "-" is reported in the response column.3 @5 ]4 y/ A6 }& P
9 l3 A, h$ C- F7 v6 T9 M6 \
  The capture is performed in the frontend only because it is necessary that- y( {( k7 ^; g% F
  the log format does not change for a given frontend depending on the
! V& d0 h/ M& S- f  a6 J  backends. This may change in the future. Note that there can be only one
; \6 |; ~+ U8 {# r6 L  "capture cookie" statement in a frontend. The maximum capture length is: C/ t  K# s5 j1 A5 R$ G
  configured in the sources by default to 64 characters. It is not possible to
0 O2 O# j0 S' [! Y' l$ ?  specify a capture in a "defaults" section.+ j' ?( ]% k0 \2 R% j4 G4 e- @0 p5 u
2 Q6 ]5 M+ h' u4 z" A3 c
  Example:
$ l  h# n, W7 e) ?5 N        capture cookie ASPSESSION len 32) S0 a3 ]; I$ o

0 d( s& Y2 c9 N" p5 a  See also : "capture request header", "capture response header" as well as) `0 W- _7 L; i9 y5 O9 c
            section 8 about logging.( B) F, p0 d& {* l) D) y
( W2 P6 }5 Q8 G% {
1 D! a5 X2 r( f, y. o# S3 V, F* Y
capture request header <name> len <length>
$ K& U- N+ r( s2 X7 [7 x6 a* n# c  Capture and log the first occurrence of the specified request header.' g7 K  b/ R# z/ o" r/ ~4 Q
  May be used in sections :   defaults | frontend | listen | backend5 {  o: N0 G) V" X9 ]! c
                                  no   |    yes   |   yes  |   no
- Z. {  d( b5 w& s  Arguments :6 o. X& V  m& i1 o) m
    <name>    is the name of the header to capture. The header names are not
' V" o3 W7 [6 i% k# _* k/ v              case-sensitive, but it is a common practice to write them as they
6 N, `9 r  Y" R3 n              appear in the requests, with the first letter of each word in! A/ h# v& q9 k. a6 M1 h$ F
              upper case. The header name will not appear in the logs, only the1 d% x7 _4 K$ y" g7 ?
              value is reported, but the position in the logs is respected.
6 j/ p; h2 `* z
% r( l$ U9 x+ K1 D% s, V+ S3 _- U    <length>  is the maximum number of characters to extract from the value and
& j* y) q# p' A3 @, l6 s! w9 |              report in the logs. The string will be truncated on the right if
; w* b, R& E+ q2 T6 Q0 E              it exceeds <length>.
0 l! I  I3 l/ R- g' S* s: i8 v3 J  L  |- ]
  Only the first value of the last occurrence of the header is captured. The
+ ^# t) V4 a0 G7 N, s  value will be added to the logs between braces ('{}'). If multiple headers
/ j3 c# V) |" X  are captured, they will be delimited by a vertical bar ('|') and will appear
% \% Y6 K9 r! \  in the same order they were declared in the configuration. Non-existent" y6 y$ }2 y( d! k7 l
  headers will be logged just as an empty string. Common uses for request2 z+ K4 r& z8 H  d
  header captures include the "Host" field in virtual hosting environments, the3 d* G- f) W: ]" {
  "Content-length" when uploads are supported, "User-agent" to quickly$ t/ I! h( F- l9 q
  differentiate between real users and robots, and "X-Forwarded-For" in proxied! v; X, Y5 P# U: F, k
  environments to find where the request came from.
/ [* e' \+ v5 h* j/ J( F! I3 d3 \4 J
0 p9 l9 }- G2 s! u7 w0 D6 M$ D2 o  Note that when capturing headers such as "User-agent", some spaces may be
! U6 N  L/ A& S0 w  \5 P  logged, making the log analysis more difficult. Thus be careful about what1 K% q* N# m6 }, O7 d2 o
  you log if you know your log parser is not smart enough to rely on the
3 T8 u4 j5 g- c  braces.: i# L9 ~+ N- [4 o6 M
( r* {$ q1 d, h" z, f8 Z8 g
  There is no limit to the number of captured request headers, but each capture
7 S1 J$ H8 |+ s+ j( i/ S2 u5 w  is limited to 64 characters. In order to keep log format consistent for a
6 u3 n; G- ^- k% N0 m4 D7 V  same frontend, header captures can only be declared in a frontend. It is not8 L3 c& }8 _8 k! o2 c
  possible to specify a capture in a "defaults" section.
  e2 W$ _4 c: }0 }# g! i- B) ~/ ~( J; D& M8 l! i% b, H
  Example:
" ]3 z, p8 g0 z% [5 l  n* K% I1 M4 l. u        capture request header Host len 15
+ h' F+ e% v% W! d( W, u  ?        capture request header X-Forwarded-For len 15! n4 _4 G- o' P0 A
        capture request header Referer len 15
) T7 {, M1 V( A5 n* p5 {2 _
3 z* W- \8 i8 W9 `# V% X( n% k  See also : "capture cookie", "capture response header" as well as section 8
: O7 ?% n; |5 N0 v9 B9 G: w1 P             about logging.6 j3 _, ~  L, d1 U
7 T, o) s7 y; {

( G; L" j# E0 X! c- Dcapture response header <name> len <length>
1 m3 ]) g4 N4 i) j  Capture and log the first occurrence of the specified response header.
& h* `5 F6 x' |  May be used in sections :   defaults | frontend | listen | backend
8 m7 k: D9 W8 U' M                                  no   |    yes   |   yes  |   no
7 R# ~- K2 X& X/ b% a2 ^0 y  Arguments :# U" y% |0 v, C
    <name>    is the name of the header to capture. The header names are not
: q+ I4 s% H. z              case-sensitive, but it is a common practice to write them as they
6 P- `3 \+ b& M$ R              appear in the response, with the first letter of each word in
; Z7 y3 K9 [2 r% I' L- e& t) t              upper case. The header name will not appear in the logs, only the0 h8 R1 W$ R) C" A/ E+ _0 m
              value is reported, but the position in the logs is respected.+ o* r) U! U- Z( @2 @

: O6 Z4 m" o0 u3 n    <length>  is the maximum number of characters to extract from the value and
5 t5 d+ Y; l; ]5 u7 Y7 n              report in the logs. The string will be truncated on the right if
3 _# ]. Y6 J3 X& E) `# j              it exceeds <length>.5 W( m6 m' Z: D7 m- u8 B
5 u3 Q2 ^  C! j. L  J
  Only the first value of the last occurrence of the header is captured. The
: Y) m$ x3 G) M# R4 @7 p" j1 W  result will be added to the logs between braces ('{}') after the captured* Z% t6 ]& {5 \* J
  request headers. If multiple headers are captured, they will be delimited by
0 j6 r: `& V  F2 J3 Y5 R  a vertical bar ('|') and will appear in the same order they were declared in+ `, S) ?1 k% m+ h9 h1 p. y
  the configuration. Non-existent headers will be logged just as an empty
- ~; {2 p6 x/ q5 b+ O( @) ]  string. Common uses for response header captures include the "Content-length"
( L5 b) d6 C7 D" B6 Q  header which indicates how many bytes are expected to be returned, the
( j1 {% B3 j+ F  t  "Location" header to track redirections.2 t% \- i# M- L7 z; U' x
" q. p' L& i; y: E8 S. i/ Z/ Z
  There is no limit to the number of captured response headers, but each7 A" O# |+ _2 M9 X" W# ?  ]
  capture is limited to 64 characters. In order to keep log format consistent- k2 }9 N- j, x2 G+ k, Z, }* f
  for a same frontend, header captures can only be declared in a frontend. It+ `9 ^; V9 I8 ^2 R
  is not possible to specify a capture in a "defaults" section.5 X( ^1 J; I9 H+ `7 c3 U8 j

  Z7 ^' h: I2 Q0 N  Example:2 x7 ~; V7 V( Y: g
        capture response header Content-length len 9: [- W/ v; R9 x/ q
        capture response header Location len 15
. h& y3 L( e, T: L2 V
8 v9 y" a$ C* V* F! j, t& _9 i  See also : "capture cookie", "capture request header" as well as section 82 k6 t; @. \, G/ p: |
             about logging.- E2 {* y4 r$ `. S
0 q: K, p, }" h8 S1 b$ d
$ s) B0 s6 f1 e' @# }0 P
clitimeout <timeout> (deprecated)
% G5 c7 E0 \. h5 }1 {  Set the maximum inactivity time on the client side.: }9 A* v% x  B4 H0 `
  May be used in sections :   defaults | frontend | listen | backend
' ^) K3 k5 z/ @. H                                 yes   |    yes   |   yes  |   no2 O9 ]+ O% x3 }, v0 W  z! L" R
  Arguments :8 t. W$ z1 Z& O2 `7 I. Y5 ~. {1 R$ G
    <timeout> is the timeout value is specified in milliseconds by default, but/ h! ]8 x+ J, l9 z* N
              can be in any other unit if the number is suffixed by the unit,
$ Q' W7 W4 G; \& P- b; `, }              as explained at the top of this document.6 \7 i' `! z7 o; c
( r1 ?+ Z' ~% F1 T8 r+ a
  The inactivity timeout applies when the client is expected to acknowledge or
4 d! T; S: ]0 p) |; K* R: ^  send data. In HTTP mode, this timeout is particularly important to consider
6 u2 h# ^. ?- k. N5 A  during the first phase, when the client sends the request, and during the
" @* z6 ~$ Z4 J. S4 m' p* f  response while it is reading data sent by the server. The value is specified# i3 i4 b3 ?) T5 `
  in milliseconds by default, but can be in any other unit if the number is
7 |/ ^  L( W3 k! R  d1 o  \  suffixed by the unit, as specified at the top of this document. In TCP mode
5 Y5 X  j, g7 l5 a! |1 Q  (and to a lesser extent, in HTTP mode), it is highly recommended that the0 Z1 q, D9 W! V* F% ^" C
  client timeout remains equal to the server timeout in order to avoid complex
, X* E1 n$ U+ X  situations to debug. It is a good practice to cover one or several TCP packet0 q+ a$ @2 c' i5 U' b
  losses by specifying timeouts that are slightly above multiples of 3 seconds( U% u/ ], d- I5 l
  (eg: 4 or 5 seconds).
* X' D7 G8 {# l, j' ~$ u# Z4 k; `' T: s, h, k& u- X2 r6 j
  This parameter is specific to frontends, but can be specified once for all in
( q' J) M% }3 s' f; m4 H  "defaults" sections. This is in fact one of the easiest solutions not to" T! R1 M( `6 J1 z
  forget about it. An unspecified timeout results in an infinite timeout, which; s, h4 m6 d( ~5 m3 k
  is not recommended. Such a usage is accepted and works but reports a warning
) Z( q; R8 j  [  during startup because it may results in accumulation of expired sessions in  {+ F5 p6 ~$ U7 d
  the system if the system's timeouts are not configured either.6 E5 e& B" [; Q; X, G/ m

  {+ ~! W0 Z' u- V  This parameter is provided for compatibility but is currently deprecated.3 a9 [5 x1 f4 w( O$ b0 f
  Please use "timeout client" instead.
, K) |0 h/ p% K6 H- ?0 C! d6 _2 n" B- n2 a- O
  See also : "timeout client", "timeout http-request", "timeout server", and
' E; B3 g+ P; x$ d: s; u; N             "srvtimeout".
4 e$ E% K! D1 p" x# V' Y9 q3 l' S/ _' E

5 ?. ]9 O; K7 Hcontimeout <timeout> (deprecated): B5 j8 x5 a- s
  Set the maximum time to wait for a connection attempt to a server to succeed.
4 {1 l! t$ g; E" x3 }2 ?, G  May be used in sections :   defaults | frontend | listen | backend! A! k* K; x1 R! D+ Z% ?$ v/ g
                                 yes   |    no    |   yes  |   yes
( p- x7 ?- J: g9 a3 s  Arguments :9 ]5 u; C5 ^; t# [! L- X3 g+ q
    <timeout> is the timeout value is specified in milliseconds by default, but
. l. L9 J/ v6 d0 Y* W1 Q              can be in any other unit if the number is suffixed by the unit," F6 `- S8 u" G9 T  h) Z: n
              as explained at the top of this document.
( `; Z0 W5 x9 G. J2 h$ q6 a4 N* Z' R
  If the server is located on the same LAN as haproxy, the connection should be. `  B3 O' u# _
  immediate (less than a few milliseconds). Anyway, it is a good practice to
) M4 I; B8 u4 _3 `' Q  X; h( d  cover one or several TCP packet losses by specifying timeouts that are
  ^- ]% j# _8 p0 _- L  slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the+ d' z$ d! _' \' M8 M/ ?$ H
  connect timeout also presets the queue timeout to the same value if this one, ~* A8 W  `9 K# Y2 ^
  has not been specified. Historically, the contimeout was also used to set the
1 ~5 I# u. p) V6 x$ g. Q" L$ p) ^1 j  tarpit timeout in a listen section, which is not possible in a pure frontend.
! e+ M8 b$ h3 |+ e3 Y; k! D3 k2 P1 P/ {+ ^1 q0 H
  This parameter is specific to backends, but can be specified once for all in
! |9 f# @, z" |% W: q0 B; `  "defaults" sections. This is in fact one of the easiest solutions not to
& H% G; F' c. q; M- E  w) R  forget about it. An unspecified timeout results in an infinite timeout, which7 ?0 Z1 A' _+ M& `' H
  is not recommended. Such a usage is accepted and works but reports a warning
  J$ [, Q% h9 ?# t6 D/ `  during startup because it may results in accumulation of failed sessions in
; X# u0 r. r  v+ @  the system if the system's timeouts are not configured either." V/ f" Y" q, s+ p$ P5 W& g) p

% s1 P& q( `0 c  k* k- v$ u2 k  This parameter is provided for backwards compatibility but is currently) F' ^: n5 G1 L9 {* u0 e/ |
  deprecated. Please use "timeout connect", "timeout queue" or "timeout tarpit"1 P7 `) I1 k4 e+ B$ z$ W1 J1 J
  instead.* y$ _( e7 o! R5 ^
* b5 L. u: S) x& q9 T
  See also : "timeout connect", "timeout queue", "timeout tarpit",& w. C# L* y$ {2 X
             "timeout server", "contimeout".* a8 \% o8 `# v- Y% I; g% a! d

. u  Y% x* u0 i9 Z$ T( @
* d' n; e9 t0 {. q7 W9 f; b5 k& O; xcookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]$ \) h! V, l3 S
              [ postonly ] [ preserve ] [ httponly ] [ secure ]0 R! Q( t: u4 ~- ~8 P# h
              [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
' o4 D7 Y1 ^2 `% G8 d# ^  Enable cookie-based persistence in a backend.+ H: ]# D* n* W- ^' [
  May be used in sections :   defaults | frontend | listen | backend4 U  U, q( z1 o! N% S
                                 yes   |    no    |   yes  |   yes" G, ^2 ?- ~: C. I
  Arguments :
+ y2 H+ h2 |9 H; O    <name>    is the name of the cookie which will be monitored, modified or; {+ w) _# n" h- P5 x1 R
              inserted in order to bring persistence. This cookie is sent to
7 U' M* P, ?! h5 H( X& `              the client via a "Set-Cookie" header in the response, and is) f( ^/ n! y1 M+ R
              brought back by the client in a "Cookie" header in all requests.9 ]) n. g4 S% |) N
              Special care should be taken to choose a name which does not1 N/ M, m7 I0 h1 L
              conflict with any likely application cookie. Also, if the same
5 J* _: @# F0 \5 G, t) P8 O6 N              backends are subject to be used by the same clients (eg:; W6 |4 j7 ?# b7 U' c
              HTTP/HTTPS), care should be taken to use different cookie names( W* }* ?5 e/ m& n
              between all backends if persistence between them is not desired.& G0 n8 C# _2 e; [5 R

* g: ^/ `; z* H2 i% r6 X" Z    rewrite   This keyword indicates that the cookie will be provided by the) Q7 W0 i  d& e/ O2 y. t; U) ^
              server and that haproxy will have to modify its value to set the1 e& Q2 S/ i) q1 h% M( M
              server's identifier in it. This mode is handy when the management% f' H/ L' O. j/ S
              of complex combinations of "Set-cookie" and "Cache-control"
8 R/ y# a" ~2 y              headers is left to the application. The application can then, [8 o! h$ W" U5 m2 z/ `
              decide whether or not it is appropriate to emit a persistence  Q3 a& E. K& J9 h6 c
              cookie. Since all responses should be monitored, this mode only
& S2 P0 x) G" J' x/ w) l3 |. {4 i              works in HTTP close mode. Unless the application behaviour is
' ?6 r, i9 K5 A! D              very complex and/or broken, it is advised not to start with this
/ \0 U1 @7 F& D3 F' _              mode for new deployments. This keyword is incompatible with
$ V$ C) M! D- u$ b+ R  w              "insert" and "prefix".
3 \: P. E+ S: e+ Y3 _+ ]
- c0 v- r: i! G3 r. l, C4 U    insert    This keyword indicates that the persistence cookie will have to
+ A* b) x6 s- [9 r/ @: G              be inserted by haproxy in server responses if the client did not
8 {7 u3 {: n2 g& C: U  y! V1 }5 \& o% k
              already have a cookie that would have permitted it to access this/ }5 T; t( |$ u& l
              server. When used without the "preserve" option, if the server
  |, o5 o. y3 F* y7 j8 x& |1 y* ^6 z              emits a cookie with the same name, it will be remove before
8 k, r. ]- B) T3 y8 n4 [5 S              processing.  For this reason, this mode can be used to upgrade9 ^! P7 A% p; v. x& D& U7 ^" v2 X
              existing configurations running in the "rewrite" mode. The cookie
+ R; E' `( J' H* [! F              will only be a session cookie and will not be stored on the
, P% p3 ]) x1 h* I6 n              client's disk. By default, unless the "indirect" option is added,# v8 S0 h* U; j
              the server will see the cookies emitted by the client. Due to
8 o6 k" g8 V) d7 T, o0 i2 r              caching effects, it is generally wise to add the "nocache" or  b8 o2 X& O& M$ L( k
              "postonly" keywords (see below). The "insert" keyword is not& R+ V& k! W- W6 p& ]) N
              compatible with "rewrite" and "prefix".. L" r9 Q0 b/ f4 V. p/ Z
1 s+ o+ J) I, q+ A  B5 ^
    prefix    This keyword indicates that instead of relying on a dedicated
" j8 k8 L; B: b  Q              cookie for the persistence, an existing one will be completed.
3 R8 W& o& ]/ y% L: B) ~              This may be needed in some specific environments where the client
) y  F; G) ~, A# b, j              does not support more than one single cookie and the application' V" `+ a' p% d. [; Z( i% D
              already needs it. In this case, whenever the server sets a cookie
! l. l1 K. _! J5 D$ E5 S% n( e              named <name>, it will be prefixed with the server's identifier( i- g5 v+ Y0 y  o" ^
              and a delimiter. The prefix will be removed from all client9 V2 J/ @" n# k+ e5 V$ t- a
              requests so that the server still finds the cookie it emitted.7 p, T, M( i4 i. t
              Since all requests and responses are subject to being modified,( ?& }2 N# k. w* I/ W
              this mode requires the HTTP close mode. The "prefix" keyword is7 Y2 G9 T; A2 [7 e. N) p
              not compatible with "rewrite" and "insert"./ F, W: X: `2 v2 d! U* C

. q' S! e6 q/ s; B5 z    indirect  When this option is specified, no cookie will be emitted to a( U; w# c: d/ t0 ]2 t0 d, I: E$ r
              client which already has a valid one for the server which has2 Q, R( y( D0 c2 v4 f6 ?0 J4 b
              processed the request. If the server sets such a cookie itself,
! E9 s" `% ~* A              it will be removed, unless the "preserve" option is also set. In
  ]! S) E! Q$ }9 O9 Y8 L              "insert" mode, this will additionally remove cookies from the- l1 {8 N4 T  h) P, a
              requests transmitted to the server, making the persistence
) I  u8 [! q3 M% q) T: i9 |9 D              mechanism totally transparent from an application point of view.
$ I. z: S2 [) ]+ M4 x6 a
2 H! ]! J) [% w6 _1 E    nocache   This option is recommended in conjunction with the insert mode7 ~* b7 J) B1 Q7 p* P, x
              when there is a cache between the client and HAProxy, as it  k( D1 B1 M% O, D0 G7 W5 v
              ensures that a cacheable response will be tagged non-cacheable if' X: E# [" ]& K& K$ t& L2 j0 D
              a cookie needs to be inserted. This is important because if all/ p! E- I0 }9 f9 f7 `
              persistence cookies are added on a cacheable home page for
) `: f, a# Z3 r& T5 ~              instance, then all customers will then fetch the page from an5 I' t, R0 y0 C2 d/ j
              outer cache and will all share the same persistence cookie,
1 B" z8 d/ u  R( s% O  p6 v              leading to one server receiving much more traffic than others.- U6 L1 ^; [5 B4 K
              See also the "insert" and "postonly" options.2 f5 h0 X% o7 W' `2 D) ^% u& h

9 y' @* U0 ]% Z/ Z( [, F    postonly  This option ensures that cookie insertion will only be performed
8 B) h: v* A; W, t8 C              on responses to POST requests. It is an alternative to the, ?" r5 {4 i6 \# N. }7 T
              "nocache" option, because POST responses are not cacheable, so
, v6 F) Z+ j; v4 M% ?              this ensures that the persistence cookie will never get cached.% w5 ]) H% w* j; \" ~  {, z
              Since most sites do not need any sort of persistence before the
6 L, P) l/ [* r              first POST which generally is a login request, this is a very6 a) P9 S; ?) Y% n% q
              efficient method to optimize caching without risking to find a
, i- A. v- M9 k( E; F. i+ \              persistence cookie in the cache.
  j6 K- a; o% W0 {              See also the "insert" and "nocache" options.; V4 E8 m6 ?8 f

1 Y5 R& m+ C" J" m8 U    preserve  This option may only be used with "insert" and/or "indirect". It8 ?; e* D7 R' J3 b& v/ F8 l
              allows the server to emit the persistence cookie itself. In this# S1 ]6 O3 Z4 Q  N9 A* c, K# U  }
              case, if a cookie is found in the response, haproxy will leave it
4 K4 }: {4 `9 t. K  v              untouched. This is useful in order to end persistence after a
2 A5 [5 D- ]/ t4 X: {% I0 j              logout request for instance. For this, the server just has to8 O; P8 K+ o9 _, @( |: _
              emit a cookie with an invalid value (eg: empty) or with a date in$ j3 l9 ~* u* n/ j- z
              the past. By combining this mechanism with the "disable-on-404"
0 i) a$ X/ D+ w$ ]% |; d+ T& u              check option, it is possible to perform a completely graceful- D: H5 M% p8 x, P" V5 O  s
              shutdown because users will definitely leave the server after
+ k  [+ S" {" P+ l% k; Z$ M              they logout.2 p3 ?9 y( c, u( H7 Y
/ Q: c3 c, p& s# m4 a$ A
    httponly  This option tells haproxy to add an "HttpOnly" cookie attribute
$ `6 @& o1 B9 L$ H              when a cookie is inserted. This attribute is used so that a
- u$ w# |7 f( Z, n" L" y              user agent doesn't share the cookie with non-HTTP components.
1 e" D' Q; q" \8 U& D$ S# ]! @              Please check RFC6265 for more information on this attribute.! u2 z; s* {+ z  J& S/ b3 D3 b) x

. @: x# f* Q' ?$ U" ]    secure    This option tells haproxy to add a "Secure" cookie attribute when
$ g" V9 W7 D/ \. i( T  h; `" Q: U              a cookie is inserted. This attribute is used so that a user agent
) U# s2 y, S& g7 g! I: I              never emits this cookie over non-secure channels, which means
3 v* u$ s0 \6 J" J7 ?3 D2 d" M              that a cookie learned with this flag will be presented only over
: e3 X* O6 {3 q: V- p" d& q4 h: \' p              SSL/TLS connections. Please check RFC6265 for more information on
) }3 X6 J0 |4 g9 H2 z              this attribute." j9 y' f7 i/ I. t
7 ?( J6 ~$ f; @/ i! S) W! a  O6 M
    domain    This option allows to specify the domain at which a cookie is
# n% A$ F% x! l2 I9 r0 y              inserted. It requires exactly one parameter: a valid domain
3 K1 X! T4 X: a              name. If the domain begins with a dot, the browser is allowed to
- Q! u; }/ `# O3 p2 M6 T  ~              use it for any host ending with that name. It is also possible to( b4 F" Y/ y! k
              specify several domain names by invoking this option multiple7 R! {$ @# K, }* r
              times. Some browsers might have small limits on the number of
* Y. f4 \, |" ?, W8 D              domains, so be careful when doing that. For the record, sending
; P# T6 O9 ?6 W              10 domains to MSIE 6 or Firefox 2 works as expected.
' x  T+ O- K% X9 X7 l6 g0 D3 v& R8 `5 U! ~4 d) v
    maxidle   This option allows inserted cookies to be ignored after some idle, b5 f" i' N8 Z
              time. It only works with insert-mode cookies. When a cookie is  V0 l& d8 i" K6 D* \% I' X/ e
              sent to the client, the date this cookie was emitted is sent too.& `: d. v& T9 S6 S, a
              Upon further presentations of this cookie, if the date is older: i0 S# h- S# E
              than the delay indicated by the parameter (in seconds), it will5 {2 F$ p% U* O5 i0 J/ n! ~
              be ignored. Otherwise, it will be refreshed if needed when the
7 Z3 b% J* g, n  \0 W. k7 B              response is sent to the client. This is particularly useful to0 V" j5 _: Z* T
              prevent users who never close their browsers from remaining for
( C$ k2 E! p( `8 h# ?/ K$ _7 Z              too long on the same server (eg: after a farm size change). When
% N9 O8 l; O  G              this option is set and a cookie has no date, it is always1 g$ @; ^0 }0 E8 G2 I: T7 m( R& ?3 I3 [
              accepted, but gets refreshed in the response. This maintains the( c2 U) ~" h+ j1 h% ]
              ability for admins to access their sites. Cookies that have a
" k; M( n! s- P( s0 Z1 w              date in the future further than 24 hours are ignored. Doing so
7 u6 {$ \3 b- o              lets admins fix timezone issues without risking kicking users off
4 d& B- X7 n! C! e              the site.
0 k  |7 S& J1 a$ h( P  d( }
( R- o! K- h. [( f5 h' W. T' p' F/ w& z    maxlife   This option allows inserted cookies to be ignored after some life6 J/ H# }5 ^7 _9 ]  _0 B
              time, whether they're in use or not. It only works with insert# t; O/ w( p8 N* W# ~' ~4 f
              mode cookies. When a cookie is first sent to the client, the date
  n- c. V; O8 k              this cookie was emitted is sent too. Upon further presentations' Z0 N7 U3 A* R
              of this cookie, if the date is older than the delay indicated by
" A' Y4 D! K2 T- L4 [) `7 `              the parameter (in seconds), it will be ignored. If the cookie in* |6 ~, ^, [7 u! P  s0 H7 _
              the request has no date, it is accepted and a date will be set.
1 `; O& I/ A. E) J8 \              Cookies that have a date in the future further than 24 hours are
& P0 ~! c# g9 N/ b1 v6 }4 ]& Q              ignored. Doing so lets admins fix timezone issues without risking, q3 s& H' I$ f8 l2 R, K. q3 x6 J$ z
              kicking users off the site. Contrary to maxidle, this value is( i9 G* j3 Y( U6 N3 q& p" a5 q* N; X
              not refreshed, only the first visit date counts. Both maxidle and
1 k2 K% o* [6 }              maxlife may be used at the time. This is particularly useful to' Y2 c# ^* B) e$ k; T
              prevent users who never close their browsers from remaining for, h: e. h* j" e' m5 K2 u% S
              too long on the same server (eg: after a farm size change). This
* _# v7 N# \; X; C. M- D) t/ T+ z$ w              is stronger than the maxidle method in that it forces a- K4 z3 R8 @5 S+ x
              redispatch after some absolute delay.
4 D! s5 H: D1 C" U. V. c7 a( X8 x: E3 p& T5 w
  There can be only one persistence cookie per HTTP backend, and it can be
2 b4 z) r- h' \( _7 ^3 Z# I4 V  declared in a defaults section. The value of the cookie will be the value' j. g5 e8 i$ A) C/ I1 T
  indicated after the "cookie" keyword in a "server" statement. If no cookie
* j; y5 y$ |. a9 b2 R# W  is declared for a given server, the cookie is not set.
! }) C* @- }9 @3 ?/ B/ W1 N
3 j0 e8 @9 A( ?( R* A  Examples :3 v, D8 m7 U# c. c, v
        cookie JSESSIONID prefix
# p# ~/ e* ^# h3 E% J/ B" I! G        cookie SRV insert indirect nocache
7 G" g% w" H! i        cookie SRV insert postonly indirect
: c9 V& Q& M0 f        cookie SRV insert indirect nocache maxidle 30m maxlife 8h# `5 T" @1 t$ a

1 h$ a1 U' T! {* z1 w3 k' i' k- J  See also : "appsession", "balance source", "capture cookie", "server"
1 O5 O) Y' _! V$ Q             and "ignore-persist".
  {$ g1 \: ]# J$ E1 ^. D
0 o! k" P; W! G1 x4 b: U& B9 g# T% W3 a3 p7 N
default-server [param*]$ V: \  Z  O3 z: P
  Change default options for a server in a backend
2 A) q0 }; Z  E) i  May be used in sections :   defaults | frontend | listen | backend$ H* ~/ T+ i/ @* @( k: p' ]" y
                                 yes   |    no    |   yes  |   yes
' }9 S, V5 m+ o  Arguments:
$ f: \% d* V5 e0 [* d    <param*>  is a list of parameters for this server. The "default-server"
8 A/ H1 k0 Z4 n. L              keyword accepts an important number of options and has a complete9 n6 l2 f$ C4 h0 U/ X1 m3 K
              section dedicated to it. Please refer to section 5 for more+ Z; ^; D" g$ }9 O; r* ]+ [$ U( S
              details.
* g6 ^" E& ]# ]* q  A) S- o
+ K) A) y! u) p" `) k  Example :
% {  C) j7 d/ l( e  G2 P  l        default-server inter 1000 weight 13) b" L/ L0 |) R( y: u$ U. V5 h
7 m5 X+ }0 T3 K% i; t- {6 m
  See also: "server" and section 5 about server options2 }4 I. W* k) z. `. }  f3 d

" p4 B$ _, W* c7 {" W; x2 Y# j3 j9 D  d% Q; ]1 d! d8 h
default_backend <backend>
. O2 Q' u0 e1 t: z/ Q  Specify the backend to use when no "use_backend" rule has been matched.
" W; @* {! t* t3 t; q6 K  May be used in sections :   defaults | frontend | listen | backend& ]3 J' d8 P( J9 J, J/ A# T4 v
                                 yes   |    yes   |   yes  |   no, d5 J  A3 t5 c2 }- E2 i; Q$ O! e0 X
  Arguments :
$ n6 {% _* m+ o    <backend> is the name of the backend to use.
, [, O$ e, s5 B  {! d$ [( @8 a0 d' f7 l. }/ N
  When doing content-switching between frontend and backends using the
% [  m1 Q; T# d, \  "use_backend" keyword, it is often useful to indicate which backend will be
1 i! l$ j7 U8 q2 R  used when no rule has matched. It generally is the dynamic backend which
, [2 m; Q6 H% }+ ?( P  will catch all undetermined requests.$ ]+ T  f! `# a$ h# ]8 M% m

/ i/ c% x7 r/ X' t9 T* o" i. w  Example :
8 _1 U( {. R5 ?) C! j- B4 F* s! c0 q8 p# R7 }! M' N8 y/ i
        use_backend     dynamic  if  url_dyn
9 F: W* o6 U: g* F2 e        use_backend     static   if  url_css url_img extension_img) ~% P8 W( t9 x" C: U
        default_backend dynamic! `3 Z0 Z$ t& ?! ?/ D

5 t+ D% V& g, z  See also : "use_backend", "reqsetbe", "reqisetbe"$ y! |0 p* X  e3 R; t* `

/ z' |2 e/ T6 ~  x! j" B3 Y3 H
* a' Q5 p% e. ]8 w9 }disabled$ e7 Q" U( l+ Q7 g7 L
  Disable a proxy, frontend or backend., \8 D! q# m# L1 \4 o
  May be used in sections :   defaults | frontend | listen | backend$ k, I+ G! N% d* _; G1 l& p3 `: O
                                 yes   |    yes   |   yes  |   yes$ {/ [6 Q9 T  F0 d$ m
  Arguments :6 k4 n. ~1 N. A/ ^% |+ g

9 z0 i- t+ z0 g4 I+ r4 |( r& G  The "disabled" keyword is used to disable an instance, mainly in order to" b; X; _$ ]) ]2 q
  liberate a listening port or to temporarily disable a service. The instance0 K# Z, [6 e1 H" l8 f* O
  will still be created and its configuration will be checked, but it will be% C' n* f# z2 G
  created in the "stopped" state and will appear as such in the statistics. It
  X0 c9 ]7 E1 F! i  will not receive any traffic nor will it send any health-checks or logs. It5 h7 s  _, B( @( [1 W
  is possible to disable many instances at once by adding the "disabled"; H  ^: p; J7 V5 d5 h
  keyword in a "defaults" section.- R: Z3 G! ]: f
1 E) j4 r/ f( W% T( v2 k7 g
  See also : "enabled"
- D' w0 q* L2 `2 s2 }% s8 j. [. L  W9 I4 r
8 P6 [/ F( C9 P  Q
dispatch <address>:<port>* q$ Y7 Q" B/ j7 f3 b) I2 x
  Set a default server address( T$ ~+ s( c5 p7 y1 a, M% n( [
  May be used in sections :   defaults | frontend | listen | backend
6 y. S+ l+ W" Q- o/ ^2 R                                 no    |    no    |   yes  |   yes8 N1 `' u0 `) {/ c
  Arguments : none
. _7 Z: `, y" v- o2 J# x8 G' h7 l& m1 X+ |1 @
    <address> is the IPv4 address of the default server. Alternatively, a
3 p% o  m: m8 Q              resolvable hostname is supported, but this name will be resolved
' h6 Y! _) u6 E7 w2 R              during start-up.3 \- @- f# K& {9 c. r  u

4 O/ T/ ?' v" r! w7 M    <ports>   is a mandatory port specification. All connections will be sent2 k* d3 R) _. R- s3 L$ I/ u
              to this port, and it is not permitted to use port offsets as is* z. N$ p0 [& F! Q9 b3 E( t( t
              possible with normal servers./ A/ t! n: d3 a3 s# A' B: z
4 i* C. f: B1 P' l8 o" z
  The "dispatch" keyword designates a default server for use when no other
! g! _% B! o5 T2 b2 U1 O% P- Y. R% l  server can take the connection. In the past it was used to forward non
; k! v$ F) d) l6 j! ^" p+ G4 H9 ]  persistent connections to an auxiliary load balancer. Due to its simple: Q. \) @3 h, o# e: H, m
  syntax, it has also been used for simple TCP relays. It is recommended not to
2 {" \1 }' N  L, F  use it for more clarity, and to use the "server" directive instead.: \, Q5 t& X6 D6 j" \2 q
0 k" J% ]+ s- I
  See also : "server"
/ }0 Q$ v0 j) [% P/ x' V+ E0 d1 m  Q" R% \& J$ @
, O% N* u  T% C. p# e) D! ~. e
enabled
8 q6 ~  D( y& ^1 @( ]0 [  Enable a proxy, frontend or backend.
  P2 N; R5 X+ n; g  May be used in sections :   defaults | frontend | listen | backend) o7 p& a, i6 k8 s' m5 M# [
                                 yes   |    yes   |   yes  |   yes% E0 X# F! I  |7 k! |* P
  Arguments : none
- Z( |) k7 r" C: `* M$ A: ^
6 X" A0 v$ h. n  The "enabled" keyword is used to explicitly enable an instance, when the
( _# b7 a5 V' d6 P4 [  defaults has been set to "disabled". This is very rarely used./ O  t9 \! v$ [* W0 o6 d# C

& E. {' h+ X0 `! J3 H& O  See also : "disabled"
/ ?& q2 F/ |, a0 S$ |
* A8 Z4 Q9 t4 {( Q9 G% B" ]6 a( d- N8 A1 T
errorfile <code> <file>
$ t4 r* B& X, i2 T* c2 }, X  H0 X  Return a file contents instead of errors generated by HAProxy
2 T: |8 M$ e8 l: b, G3 e  May be used in sections :   defaults | frontend | listen | backend
( u2 B* t- D! k& E  v& n9 k% ^                                 yes   |    yes   |   yes  |   yes
; k9 ~" s3 C& }( X, [8 T) r  Arguments :% t( |( c% z& j( c" j
    <code>    is the HTTP status code. Currently, HAProxy is capable of. v# {- M/ X) ?
              generating codes 200, 400, 403, 408, 500, 502, 503, and 504.
5 O& A) ~' a/ Y( }: ]* i* a: [, K" H
    <file>    designates a file containing the full HTTP response. It is
7 e  }5 H3 _6 L% J3 V              recommended to follow the common practice of appending ".http" to: I9 z  U+ g9 v" n! @" o
              the filename so that people do not confuse the response with HTML
0 N% o- P. I, u+ w* I              error pages, and to use absolute paths, since files are read
+ V5 a8 Z6 U9 p. G              before any chroot is performed.
! ]+ \) U. ^6 n+ L
3 S0 N% A+ `6 u; V9 U3 Z3 A* s  It is important to understand that this keyword is not meant to rewrite
" r# k* e( _* P; y  errors returned by the server, but errors detected and returned by HAProxy.
; }1 {) K) y6 e2 n8 l" s  ?' W  This is why the list of supported errors is limited to a small set." V( E* S0 F+ J

2 l; ?, S  J7 ~  Code 200 is emitted in response to requests matching a "monitor-uri" rule.
# h( V9 m) \/ Q) J3 T& E" i  p" I; @; t' I
  The files are returned verbatim on the TCP socket. This allows any trick such
4 r- W) V. K: z$ _  as redirections to another URL or site, as well as tricks to clean cookies,
6 C7 p  \& h: G% @( _' A7 D8 i  force enable or disable caching, etc... The package provides default error" a' G/ G+ c1 P1 Q# p: H
  files returning the same contents as default errors.# D) ~1 w& }$ |/ y% u/ K+ k  ~

/ ~. i4 F3 r- `' n  The files should not exceed the configured buffer size (BUFSIZE), which8 ~, B/ }2 F+ @9 M" z
  generally is 8 or 16 kB, otherwise they will be truncated. It is also wise
* ]+ J& C& w  n8 A  not to put any reference to local contents (eg: images) in order to avoid* {; t& C7 _! o, H% f0 h
  loops between the client and HAProxy when all servers are down, causing an
: X- Q, I+ V) W, _  error to be returned instead of an image. For better HTTP compliance, it is
9 M1 a, r- P; ?  recommended that all header lines end with CR-LF and not LF alone.
, m) x" [" H; b8 h% @1 S7 Q' Q" m" v" G, C" k. l; O
  The files are read at the same time as the configuration and kept in memory.
6 X6 J- R# a5 g: v9 V4 W: ]  For this reason, the errors continue to be returned even when the process is# W# T) ^& S4 B3 _5 ~) g
  chrooted, and no file change is considered while the process is running. A! k+ L; |7 F3 v* R8 J
  simple method for developing those files consists in associating them to the
1 F+ N" X: r/ n  403 status code and interrogating a blocked URL.
" w0 ^9 V: z* @6 L* `0 ~9 B
. i7 z- r0 H. x1 i2 d) a7 j  See also : "errorloc", "errorloc302", "errorloc303"0 U( H6 g- k2 |8 {9 [. v

; s: t4 n1 @' y# ~5 V* {( q  Example :6 E" n3 ?1 _+ p- a
        errorfile 400 /etc/haproxy/errorfiles/400badreq.http! M9 D0 o* X( ?, }- B( N
        errorfile 403 /etc/haproxy/errorfiles/403forbid.http+ Y0 ^, n! Q% a7 h2 N: G% d7 L9 g
        errorfile 503 /etc/haproxy/errorfiles/503sorry.http% E( T- V$ \& S" |, ]

2 C$ O6 `8 S/ S# r2 e+ a8 a! T3 T: [2 V; _
errorloc <code> <url>
' w, t( B- g7 T2 x! m3 lerrorloc302 <code> <url>
# s1 q2 ^' o& {3 m; o. i  Return an HTTP redirection to a URL instead of errors generated by HAProxy
- I1 u4 J6 x/ z1 d2 r2 V  May be used in sections :   defaults | frontend | listen | backend1 Z- V- R6 O/ ?" G
                                 yes   |    yes   |   yes  |   yes9 i9 M( B# p$ B
  Arguments :
. g  o) ^2 C; N6 z! n2 u- A" \3 M4 J1 d    <code>    is the HTTP status code. Currently, HAProxy is capable of: O( \6 `/ H' H; Q
              generating codes 200, 400, 403, 408, 500, 502, 503, and 504.' u( F4 t9 w- o* a
2 ?3 U7 q2 |8 E7 O0 H1 `* o2 r
    <url>     it is the exact contents of the "Location" header. It may contain
% N( o* h5 D) a% L7 O              either a relative URI to an error page hosted on the same site,
, o" a4 U+ n, e) G) G              or an absolute URI designating an error page on another site.) {9 L( Z  e+ Y4 m
              Special care should be given to relative URIs to avoid redirect  j  c5 Y9 |- t
              loops if the URI itself may generate the same error (eg: 500).* k5 d& a2 o% z! t
7 C% ]0 x# m6 P# _! N! n
  It is important to understand that this keyword is not meant to rewrite
& g3 o- |8 W; [; b# j1 j5 [& H( R* j  errors returned by the server, but errors detected and returned by HAProxy.
1 k, Q" k/ f* ]7 A- V! f7 L  This is why the list of supported errors is limited to a small set.# y# u& S- p! r/ z

" a" d( F2 i, B( \9 l+ x  Code 200 is emitted in response to requests matching a "monitor-uri" rule.5 k: k& `7 @+ @  j; U9 t
$ I" a+ x6 L+ M& b: e6 o; [! e3 n. x
  Note that both keyword return the HTTP 302 status code, which tells the3 ^: n/ I. \0 X, H' K2 s
  client to fetch the designated URL using the same HTTP method. This can be
. F2 g( I" ?7 `8 R/ N  quite problematic in case of non-GET methods such as POST, because the URL
- W8 P. p3 e+ Z! z% N  sent to the client might not be allowed for something other than GET. To
  f0 m$ X3 d! H& h8 p# D/ B& f) L+ a  workaround this problem, please use "errorloc303" which send the HTTP 303
7 P$ v' |' I; O) s! B  status code, indicating to the client that the URL must be fetched with a GET  b2 _8 K' g4 f! ~/ y) J: @3 W
  request.
9 W; I; Y2 f! a% r" ]  s3 P& y0 K. C9 A+ h, ]# I3 e
  See also : "errorfile", "errorloc303"
& a$ U1 z+ ]* ?! I9 t6 h5 b$ F# ~- O7 h9 b: R
6 |2 i& T4 C( ?, x; o
errorloc303 <code> <url>
4 `6 R- d2 F9 `; `  Return an HTTP redirection to a URL instead of errors generated by HAProxy4 e  \2 l+ ]& d% Z0 C! B! K& M# J
  May be used in sections :   defaults | frontend | listen | backend# {  s& ~$ ]3 @! \9 R
                                 yes   |    yes   |   yes  |   yes* _7 ]! x2 _6 k0 f/ l6 e
  Arguments :
7 t4 K. x  @$ P7 T& D4 [( ]    <code>    is the HTTP status code. Currently, HAProxy is capable of" [$ H* ?: H7 X% f1 B$ R; k
              generating codes 400, 403, 408, 500, 502, 503, and 504.# s& y  c) _9 g" F+ a
. ~. ]/ o( [( @- p  ]( h
    <url>     it is the exact contents of the "Location" header. It may contain) v# l) _/ q! h, e
              either a relative URI to an error page hosted on the same site,8 w9 j. \1 \9 Y" R3 d8 M
              or an absolute URI designating an error page on another site.
) P4 h; g" l. B; s5 b* [& C              Special care should be given to relative URIs to avoid redirect8 _- J. z7 {9 |1 m3 ^
              loops if the URI itself may generate the same error (eg: 500).
2 d3 x) v' y$ T( U, Y+ z" c( ?8 V/ {: F8 i
  It is important to understand that this keyword is not meant to rewrite
1 g! j6 \; n/ O  errors returned by the server, but errors detected and returned by HAProxy.% s/ P' d' ^- t1 `" m5 j- k8 X1 `
  This is why the list of supported errors is limited to a small set.
( S0 M' t& ~2 \2 `8 n" b5 q/ `4 V' F. M8 M4 x8 k0 Q; N) N- z8 I
  Code 200 is emitted in response to requests matching a "monitor-uri" rule.1 k" l  F1 V# \/ w+ y3 {9 p

1 t  W) X- l' c) f' N4 R9 C  Note that both keyword return the HTTP 303 status code, which tells the
5 o9 |+ \5 y. {2 Z  client to fetch the designated URL using the same HTTP GET method. This- V( t$ y4 i% p1 K# n4 n
  solves the usual problems associated with "errorloc" and the 302 code. It is
) r: ]5 I6 L) H  Q3 J( [& i$ e0 s  possible that some very old browsers designed before HTTP/1.1 do not support
6 m5 {5 R) f6 @8 Q- |. K  it, but no such problem has been reported till now.
8 b3 m( }# K& k8 M5 }- S1 G
! p2 ]( k7 Q) m9 a5 e  See also : "errorfile", "errorloc", "errorloc302"3 |6 D! `. |- a( J' o
- t3 L. C# E/ h5 i; P8 B/ [

: J( p* B7 O+ [5 @% ?force-persist { if | unless } <condition>
9 g) r; s' ~6 }& D2 h1 S  Declare a condition to force persistence on down servers/ ]' L+ e9 i- V' K& o/ m
  May be used in sections:    defaults | frontend | listen | backend, u. s6 t$ ^7 ^5 ]% {2 c( ^
                                  no   |    yes   |   yes  |   yes
6 i8 W  x" H4 S: p0 n' e
$ M- v+ D; }! Q- b. h( w0 y  By default, requests are not dispatched to down servers. It is possible to
; C  x, {* `4 B  force this using "option persist", but it is unconditional and redispatches
$ i- ?& `5 d- _9 F  to a valid server if "option redispatch" is set. That leaves with very little, X5 E: C0 T+ Q5 y
  possibilities to force some requests to reach a server which is artificially4 c7 W) }) P9 ]1 l9 e+ T1 Q
  marked down for maintenance operations.
( U/ i2 y' m, ?9 Y* l1 @1 B3 W
9 \9 o+ h, ]/ Z$ I  The "force-persist" statement allows one to declare various ACL-based
$ v  O* N) R. M  conditions which, when met, will cause a request to ignore the down status of( k* z7 U$ b! L. F/ {
  a server and still try to connect to it. That makes it possible to start a
, ^3 [9 w( m+ |4 K6 z- h  server, still replying an error to the health checks, and run a specially
: A5 k8 W, J6 c  z- a4 M9 r8 h7 @  configured browser to test the service. Among the handy methods, one could
+ p0 V' U+ C  b1 L0 D% e  use a specific source IP address, or a specific cookie. The cookie also has. W* U4 G& m' m0 H0 y3 |; o6 V
  the advantage that it can easily be added/removed on the browser from a test5 E, S3 N" I4 Y4 h2 q
  page. Once the service is validated, it is then possible to open the service
0 K7 t* i" s( n/ P: @% i) F7 `  to the world by returning a valid response to health checks.
0 D9 q3 R' K; i; y* e6 z) U
! i, W' ]0 O. d& W: o5 w  The forced persistence is enabled when an "if" condition is met, or unless an
& }, z- O$ n- f0 W* ]$ v( ]1 I  "unless" condition is met. The final redispatch is always disabled when this- A, \8 |7 r" o: c7 |( [6 U: I
  is used.
! i/ k7 \9 F* y
# X$ ^! c6 E  l, F; a0 v  See also : "option redispatch", "ignore-persist", "persist",
( g% V2 [- g9 P; H. N: y4 R             and section 7 about ACL usage.+ V( j1 s9 L8 d% @: [2 H* E. x

. u& l+ H" `" X, u# B3 }. I0 o. h, u
fullconn <conns>& {/ p+ Y( w2 c' ?* B/ i5 E9 A: @. {
  Specify at what backend load the servers will reach their maxconn
! J. E5 d1 U/ L) o+ w" |, M  May be used in sections :   defaults | frontend | listen | backend- I1 E$ `' Y5 p( |9 _
                                 yes   |    no    |   yes  |   yes
) r1 g- \: @" c: r- W  Arguments :) M" ], I+ G7 E, D( D+ ^
    <conns>   is the number of connections on the backend which will make the
6 M& e& W3 F  h9 s- v; b$ w              servers use the maximal number of connections.6 I$ S% L1 `5 c# l7 G
0 M- c, r# K$ R  C. Y/ w! Q4 |
  When a server has a "maxconn" parameter specified, it means that its number
( l( `8 f: _% Y0 B0 M: s  of concurrent connections will never go higher. Additionally, if it has a7 [8 q- i9 g6 I0 I% V6 E, u
  "minconn" parameter, it indicates a dynamic limit following the backend's
' x6 F+ E0 B& J7 G/ }4 |, I  load. The server will then always accept at least <minconn> connections,
1 |! y" G: H' o2 q9 }9 `, K  never more than <maxconn>, and the limit will be on the ramp between both1 H0 G  k6 k& e9 v0 t) K+ T
  values when the backend has less than <conns> concurrent connections. This3 p$ P! I; Y6 ^  H2 g7 [$ \2 Y
  makes it possible to limit the load on the servers during normal loads, but: e  P, O. z3 ^* V$ _; O+ j
  push it further for important loads without overloading the servers during0 W2 w  D6 C. L5 j/ n$ n
  exceptional loads.
3 N6 ?+ p/ t% C2 Q' @: ^7 C) h1 l2 v$ {0 K/ \4 T. q
  Example :
9 G+ ?! x# Z/ o     # The servers will accept between 100 and 1000 concurrent connections each
( l) }+ {3 K8 W9 x     # and the maximum of 1000 will be reached when the backend reaches 10000
" O) _6 o; A, s% w" d; P     # connections.3 S) A9 \2 j3 q) p: b$ ]! E/ N: C
     backend dynamic
) f6 U" }; v2 B" K4 p$ `        fullconn   100005 [$ P6 F* I( `2 |" n! w
        server     srv1   dyn1:80 minconn 100 maxconn 1000: Z2 J7 h0 i  \" T, k- n
        server     srv2   dyn2:80 minconn 100 maxconn 1000
5 P' O1 ^, H( _# X* M8 W" N  q0 M
  See also : "maxconn", "server"
& |4 Z3 E, O& B% `# ~  F, A
$ ~& x: v% n7 }& Q' I' ]% V+ X+ H# p) g6 p& }( \
grace <time>
) S; E' e7 |. L  G0 ~5 O: _; ^: P  Maintain a proxy operational for some time after a soft stop
9 }/ V  l/ G8 [8 y- W. A  May be used in sections :   defaults | frontend | listen | backend
! y" v! G+ B% b                                 yes   |    yes   |   yes  |   yes
+ X, x8 Y; l9 g& B, A' H1 N( D+ _1 Q  Arguments :9 G- A8 K" C0 @( G( a: X5 c* J
    <time>    is the time (by default in milliseconds) for which the instance1 v& _+ e5 t7 i" N- I
              will remain operational with the frontend sockets still listening- K+ e9 @3 X% p4 `$ Q
              when a soft-stop is received via the SIGUSR1 signal.
) c8 H* S7 J) B4 H
9 e/ w! j: u* x  This may be used to ensure that the services disappear in a certain order.
8 ^, z. H: h! t9 M: y  This was designed so that frontends which are dedicated to monitoring by an
: i' m# Y$ |! ^& ^5 H8 ?8 P8 M' b- [  external equipment fail immediately while other ones remain up for the time
, u6 h/ D7 E* D0 |# Z! y5 Q  needed by the equipment to detect the failure.& `2 @0 G" p8 c) Y0 T
( L3 q8 H5 a' s
  Note that currently, there is very little benefit in using this parameter,, f7 v/ m* s% i. e) S
  and it may in fact complicate the soft-reconfiguration process more than/ a% O' L; _) z+ Z8 ]$ ?
  simplify it.
. Y; K4 Q0 s& T5 X( e& L
9 K7 j5 b# \. ^+ K" w) z: u" ]7 \
& X6 o+ l9 }# H; t/ b/ k( bhash-type <method>
" H! g3 u4 Q$ O3 y  Specify a method to use for mapping hashes to servers. K: L) Y- P  I$ O1 @
  May be used in sections :   defaults | frontend | listen | backend
. X! `- E" r5 |7 [6 v                                 yes   |    no    |   yes  |   yes- m& a( u& j: ]2 J
  Arguments :, u( [2 p5 S% n# n8 r
    map-based   the hash table is a static array containing all alive servers.
4 E2 a8 |' ^; A9 }! P& a: E                The hashes will be very smooth, will consider weights, but will
0 S, a) G- T1 P  x) U" Z3 D* q                be static in that weight changes while a server is up will be- j; L$ Z* s$ }/ I' e. J
                ignored. This means that there will be no slow start. Also,6 E  l; s' ?7 [1 ]0 Q, l% M8 u
                since a server is selected by its position in the array, most! `4 ]1 O4 u  e) C
                mappings are changed when the server count changes. This means
; F/ j; w( V: v/ x  {+ i* R                that when a server goes up or down, or when a server is added
( `6 _8 `6 e' C1 m                to a farm, most connections will be redistributed to different, c* }: ~' F- J+ e1 R3 Z1 i6 K  r
                servers. This can be inconvenient with caches for instance.
7 C8 c8 h( r8 U9 M+ z4 k7 O7 N  [# Z1 `0 e; W" W& F. D9 p
    consistent  the hash table is a tree filled with many occurrences of each
, K. [% _& w$ o                server. The hash key is looked up in the tree and the closest
; k6 C& w$ M& P2 B8 \1 ~5 J+ {                server is chosen. This hash is dynamic, it supports changing
- n- t0 _' L) C+ R' h                weights while the servers are up, so it is compatible with the
5 u6 S) ^, ?2 L1 X                slow start feature. It has the advantage that when a server9 s7 W  @# R6 t1 r; r
                goes up or down, only its associations are moved. When a server
" w) H) Q. t7 A% \3 j                is added to the farm, only a few part of the mappings are
% r+ t& B# D; ^                redistributed, making it an ideal algorithm for caches.3 C8 m9 o2 f; Y, B: \
                However, due to its principle, the algorithm will never be very, }: _' Y% H/ O- {* a6 C% t
                smooth and it may sometimes be necessary to adjust a server's: o0 p2 Y, z# P  J* I  ~: C
                weight or its ID to get a more balanced distribution. In order9 A8 c/ @$ \3 R; Z
                to get the same distribution on multiple load balancers, it is) s6 t; M' T$ r/ Y
                important that all servers have the same IDs.( }' R) t5 H2 l

" T; _9 |% i$ |- d! M8 g& Z2 }  The default hash type is "map-based" and is recommended for most usages.
; d6 n% I0 |' g. d8 A8 G" Y, b' @' A
  See also : "balance", "server"- T: @. r& v) J2 p
8 L& O0 K3 J6 A/ N4 `

& p; \0 T. t2 d5 H6 Y3 hhttp-check disable-on-404
) u9 D7 X- O& k2 W1 B! H% q1 z  Enable a maintenance mode upon HTTP/404 response to health-checks
/ r: M' H! g, ~/ j- |  m' E/ t  May be used in sections :   defaults | frontend | listen | backend
+ X/ |1 r4 c, b- i7 y4 n$ Y                                 yes   |    no    |   yes  |   yes; E% K% j4 w  v6 i9 ^8 l: P- Y2 l* l8 f
  Arguments : none
$ t# O* Y7 d$ Y0 O6 u& }
& o- y+ b8 C5 p+ j9 e  When this option is set, a server which returns an HTTP code 404 will be& s; |' N  }3 [& ?
  excluded from further load-balancing, but will still receive persistent
2 u0 C: \# E3 ^( J6 r  connections. This provides a very convenient method for Web administrators5 g/ b# o( m7 q2 q% S; Y! H
  to perform a graceful shutdown of their servers. It is also important to note
; ~4 k# F6 |- K/ x  ?% s* J  that a server which is detected as failed while it was in this mode will not0 f5 Z3 [3 [3 L; k
  generate an alert, just a notice. If the server responds 2xx or 3xx again, it( v7 k- |) T' i5 H
  will immediately be reinserted into the farm. The status on the stats page7 \: v- e) _0 L* s3 M
  reports "NOLB" for a server in this mode. It is important to note that this
4 j/ s7 j, T7 W  option only works in conjunction with the "httpchk" option. If this option0 P' [; s! n5 f
  is used with "http-check expect", then it has precedence over it so that 404
; y8 q4 s. Y4 I( w# L$ g, t  responses will still be considered as soft-stop.
: {2 m; u8 y* F1 u  ?$ u8 H: [* r7 V  v' }5 r% ~# I; l& h
  See also : "option httpchk", "http-check expect"
6 ?6 ?% }# w: z. o% Z  a: ^
: H1 Q+ H! I# L8 K! \9 @' j
/ {7 |' Q# ?" h1 T; bhttp-check expect [!] <match> <pattern>
4 X% U, i, s6 p* v5 Z# G" [- U  Make HTTP health checks consider reponse contents or specific status codes2 Z. A+ w0 W: S: j' O: `
  May be used in sections :   defaults | frontend | listen | backend- T8 f6 D' ]+ A# s9 A. p1 {
                                 yes   |    no    |   yes  |   yes4 R4 T2 I  c% A# f5 S- [+ e
  Arguments :
5 }) @6 b4 ?, S9 J1 i    <match>   is a keyword indicating how to look for a specific pattern in the
' i7 _* `9 r; n6 }2 P3 ~# e              response. The keyword may be one of "status", "rstatus",. {9 q& J$ A8 P7 z
              "string", or "rstring". The keyword may be preceeded by an
7 q: T/ M: D" t$ y* a) I) J  a9 u4 j              exclamation mark ("!") to negate the match. Spaces are allowed( e+ l" Y2 T% e+ E' r( V  c7 D+ l# Y
              between the exclamation mark and the keyword. See below for more
  W) F/ y% y; r9 O              details on the supported keywords.
( k+ G$ A) i1 @1 ?- k% |7 f9 P4 U% D5 C  _1 O
    <pattern> is the pattern to look for. It may be a string or a regular
# [+ E) m1 `  x) R, C9 Y8 v              expression. If the pattern contains spaces, they must be escaped1 ]# o" Z" Y; {' Z
              with the usual backslash ('\').
- }5 U' A& {; G
' s  K8 t: r6 `# Z  By default, "option httpchk" considers that response statuses 2xx and 3xx* [1 M: ~) E9 x
  are valid, and that others are invalid. When "http-check expect" is used,; I. A6 U3 W% C; }% _3 r
  it defines what is considered valid or invalid. Only one "http-check"
9 ~  t( u) v# ]( i- L  statement is supported in a backend. If a server fails to respond or times
6 N6 s/ m/ v. l7 _. ]  out, the check obviously fails. The available matches are :
  C- c0 g; y! a, r2 z; f! e
0 S) A) a3 f3 z; {4 H    status <string> : test the exact string match for the HTTP status code.  m" Q% j' k/ U, Q. e& B
                      A health check respose will be considered valid if the# C* R% Y; W0 U  o- u
                      response's status code is exactly this string. If the8 e0 k# b* S+ {6 s
                      "status" keyword is prefixed with "!", then the response" q" f" }& I9 _2 M: y' X
                      will be considered invalid if the status code matches." m; M' v- j8 ~/ B% E7 c) h7 j3 j

5 F+ [5 I$ x% b/ H+ ~    rstatus <regex> : test a regular expression for the HTTP status code.
+ f/ \' d+ [, W                      A health check respose will be considered valid if the
7 u) [* N2 A' v7 ^% D- \                      response's status code matches the expression. If the
/ e3 a7 q7 I' T8 T                      "rstatus" keyword is prefixed with "!", then the response
5 @. ]/ U* f$ ]3 r2 X! W6 N                      will be considered invalid if the status code matches.9 M& J- b- l6 w( i
                      This is mostly used to check for multiple codes.& C- u# l) h- k9 W' r  S

" [9 U% g; H9 j" N0 b    string <string> : test the exact string match in the HTTP response body.
4 a1 p6 c- U% ^$ h                      A health check respose will be considered valid if the
+ w/ P' K5 {; ^( O3 C                      response's body contains this exact string. If the" B1 w3 J# {" ~6 j
                      "string" keyword is prefixed with "!", then the response" L& T0 Y; G. C. F8 A( r
                      will be considered invalid if the body contains this! E8 b) G4 I. ~4 K% ~
                      string. This can be used to look for a mandatory word at
& t% z1 B7 e4 g4 ^+ M                      the end of a dynamic page, or to detect a failure when a
; m0 ]2 G0 }8 ?1 l                      specific error appears on the check page (eg: a stack' B) x6 q, l& q
                      trace).
" `6 i/ s, n  ]& {: V' f( n2 t! T: t9 Y1 g; Z
    rstring <regex> : test a regular expression on the HTTP response body.2 h5 h  W% D% {3 G" Z" _
                      A health check respose will be considered valid if the
- L+ T( r% n, \5 o1 u' x3 e& _7 [                      response's body matches this expression. If the "rstring"
2 p- i& `* ]7 \6 Y( P, ~" u                      keyword is prefixed with "!", then the response will be
2 l7 I7 L# R3 t- p; ^# O                      considered invalid if the body matches the expression./ F* a/ g8 ]2 F1 j) X! n6 s
                      This can be used to look for a mandatory word at the end+ X1 m  U3 v1 j) {9 ?" s3 L
                      of a dynamic page, or to detect a failure when a specific* d4 g1 v* F& L0 n8 |
                      error appears on the check page (eg: a stack trace).6 Q/ b* F" g0 V% J/ P, [
$ C) V- P! c! k# q9 g
  It is important to note that the responses will be limited to a certain size1 I8 P$ N1 q+ Z" y+ \* _6 x$ ~
  defined by the global "tune.chksize" option, which defaults to 16384 bytes.
9 ?/ z5 j0 ^; Q2 v  Thus, too large responses may not contain the mandatory pattern when using
8 P+ B' F8 P8 h9 w3 y6 }2 m  "string" or "rstring". If a large response is absolutely required, it is
) P7 t/ I9 ]" ~  possible to change the default max size by setting the global variable.
6 j( M) w# m# I  However, it is worth keeping in mind that parsing very large responses can# y  X, a' a8 j4 _5 Y
  waste some CPU cycles, especially when regular expressions are used, and that4 I! e) ~, q1 f$ H9 ~/ Y
  it is always better to focus the checks on smaller resources.% [" L2 a: [& S7 l

9 P8 Q3 z4 F# Z1 _  Also "http-check expect" doesn't support HTTP keep-alive. Keep in mind that it5 k3 g( y% r& \0 Y8 v8 [; |1 [
  will automatically append a "Connection: close" header, meaning that this
' b, p2 ?" F! U9 \  header should not be present in the request provided by "option httpchk".5 O( ~4 Q) D& c0 I2 G

, H) m1 a; H+ J" N+ j& k1 v6 I  Last, if "http-check expect" is combined with "http-check disable-on-404",
7 \' Y$ k  x" G7 i  then this last one has precedence when the server responds with 404.
  N1 d2 c5 d8 f5 n. H& E0 |' Y
. e4 ]0 n1 l9 T4 z1 y  O- P# C  Examples :
( V3 Y2 U: z  E; h" W         # only accept status 200 as valid
% Z- w* M* W4 D5 u8 Q         http-check expect status 200# m& x- t/ p7 {

% }& E5 q9 K  }; V2 K+ M         # consider SQL errors as errors# b* A3 \3 Z0 ?2 O0 M& x8 A
         http-check expect ! string SQL\ Error+ s. R- s! y% E9 {

% E5 Q. K5 I; r0 C# G( g         # consider status 5xx only as errors* C4 p4 I" S* g+ l6 H3 P$ Y
         http-check expect ! rstatus ^5; L) ]( d' j9 J8 J

- o" ^9 N5 |2 |5 S# F* p5 I         # check that we have a correct hexadecimal tag before /html. Q3 L. K1 {, |7 G- T, X
         http-check expect rstring <!--tag:[0-9a-f]*</html>
: F# u9 Q0 k) Z1 E9 W( a- |, R$ C2 x9 D: w! U4 U+ W1 D% [6 m
  See also : "option httpchk", "http-check disable-on-404"
$ k' G, r! u5 F8 b+ e
" t6 X  t; b1 I2 p5 M* @% ?1 c# D% ~8 M5 d& @( y$ A8 W- O
http-check send-state
. r: f+ g/ `8 v' l5 L8 X+ N! a  Enable emission of a state header with HTTP health checks
/ @5 M$ [) H0 @7 Z  May be used in sections :   defaults | frontend | listen | backend; Z6 E1 T' O0 Y' H) ~. \' B8 M5 `
                                 yes   |    no    |   yes  |   yes0 S& Q( X, s6 H( O, ~
  Arguments : none
5 b* m) K+ i: `- y0 r; W+ S5 K5 H* h8 h
  When this option is set, haproxy will systematically send a special header7 c1 o* D) [8 Z0 h& y0 P
  "X-Haproxy-Server-State" with a list of parameters indicating to each server% ?0 L. S8 ^& I- I
  how they are seen by haproxy. This can be used for instance when a server is# b* l' M4 }) `
  manipulated without access to haproxy and the operator needs to know whether
+ z1 |$ B! E& u7 g/ d' f" i2 p  haproxy still sees it up or not, or if the server is the last one in a farm.
' w6 X  r8 r6 a# h4 |# R5 D% Q' Z, S
  The header is composed of fields delimited by semi-colons, the first of which
# J' L3 A5 [& \. I" i  is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid
7 h4 \: w4 F# p# m% h( R  checks on the total number before transition, just as appears in the stats
& N0 N7 @: M; o* j9 L; N  interface. Next headers are in the form "<variable>=<value>", indicating in- d8 U" g0 L0 q7 G) D$ l7 {
  no specific order some values available in the stats interface :) Q* A" R4 H& h
    - a variable "name", containing the name of the backend followed by a slash
0 m0 x7 s, P& n& [      ("/") then the name of the server. This can be used when a server is
3 f# j4 a+ \0 J, }1 G3 N5 h      checked in multiple backends.
; K: ]9 d# Q0 h( J" u5 H: j  l% w& b7 M1 z; r+ R6 E
    - a variable "node" containing the name of the haproxy node, as set in the; F. u$ L1 i+ v( e
      global "node" variable, otherwise the system's hostname if unspecified.
5 v% `$ B$ u: d* C6 ?' {6 {( B" T, p; b2 T0 L6 v: p* B
    - a variable "weight" indicating the weight of the server, a slash ("/")
" N$ F- y% X0 Y6 a      and the total weight of the farm (just counting usable servers). This
& l& h/ ~+ t( v/ s( s      helps to know if other servers are available to handle the load when this
9 M# c5 `8 t: G) n* A7 E      one fails.. \: q; X" @7 P" t) Z1 A
; ~* S; ?1 p; a5 X
    - a variable "scur" indicating the current number of concurrent connections3 A3 Z' }7 |, u: G/ `3 G9 l
      on the server, followed by a slash ("/") then the total number of  ]6 J- d- H5 q6 _6 |) i4 i6 Z
      connections on all servers of the same backend.
8 E6 C9 J1 i  M" x9 a; f5 b
# D- j# m2 A8 L" V1 M, K% I    - a variable "qcur" indicating the current number of requests in the% _9 Q* y9 J/ `1 F4 u0 U
      server's queue.
. `$ y7 ?7 k) b& L* I! W0 o
8 I1 L! t, [/ j# t1 l+ v  Example of a header received by the application server :
& Q6 l- [6 H1 N1 j( ?    >>>  X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \9 x2 j7 f/ a( _* k# \( E  y- s
           scur=13/22; qcur=0
% m/ h/ b! ^7 Y3 V, Y) k1 N8 q3 t  Z& m; Y' Z* ?  I' r
  See also : "option httpchk", "http-check disable-on-404"
% }6 U: y( R! @) S) q9 w
1 v4 K3 s% G: o- lhttp-request { allow | deny | auth [realm <realm>] }2 a7 h8 Y% ^2 e+ h% J! e4 n
             [ { if | unless } <condition> ]/ ?. S; \# S5 v. k
  Access control for Layer 7 requests
, N/ _' y. Y8 r. e& D" V3 Z" i+ H2 z
  May be used in sections:   defaults | frontend | listen | backend' s' \/ _, e8 P, G7 ]3 z6 ^- B
                                no    |    yes   |   yes  |   yes) t) f: F5 K9 G  P6 D
1 p# @- B' L  P9 v
  These set of options allow to fine control access to a& t4 Q1 W( p: }. ^( |
  frontend/listen/backend. Each option may be followed by if/unless and acl.
) o8 s+ f. ~! N% a  First option with matched condition (or option without condition) is final.& T# D6 q( u1 v2 o8 N# ?
  For "deny" a 403 error will be returned, for "allow" normal processing is  {$ U" ?1 ~# H: H2 M0 S) Y
  performed, for "auth" a 401/407 error code is returned so the client
  ~( E8 V+ [, f% A. O$ ~  should be asked to enter a username and password." q: l- G( h5 o/ A, I

% X0 a. m; m5 [7 e, f  There is no fixed limit to the number of http-request statements per( I' p% n+ O% s, H0 O
  instance.- j# j' p; y1 B4 I. F
/ f$ _. j2 B# h5 |- ?) w1 K
  Example:
) i+ c7 o+ I# ]& v        acl nagios src 192.168.129.3& `% q8 v( y0 H/ m% P. c& F
        acl local_net src 192.168.0.0/16- @2 F: d8 Y; _3 `- i% ?0 O
        acl auth_ok http_auth(L1)/ O. S: `1 [( x$ |, O5 b1 ^
; _$ J- l2 }0 S1 y4 k
        http-request allow if nagios6 e0 Z. c  d5 u. y" G2 |; |" C8 R
        http-request allow if local_net auth_ok
, u1 M# Z( U" c9 |0 b! I7 P        http-request auth realm Gimme if local_net auth_ok1 y- C9 H( o5 d2 ]* R, [4 H' O$ K+ D
        http-request deny
" U3 q4 h% f) w% `+ A( |' @) m, R/ G# p  Q% d+ u7 H' ^# |
  Example:: {) {) v  _. U( `2 M; X  a5 g+ Z
        acl auth_ok http_auth_group(L1) G11 i# m  D9 u6 G) g

7 N! U$ Q7 M7 ]        http-request auth unless auth_ok
2 \& W1 g8 F9 E, t  h- q+ w3 M, z; Q6 c( |; n) {) W: M& K
  See also : "stats http-request", section 3.4 about userlists and section 72 ]: }0 v* v' Y0 b* U* C
             about ACL usage.
  v4 m8 h* U5 J
( ?% q8 ?2 K. p/ fhttp-send-name-header [<header>]
% |( b- |5 ~) J7 P$ M1 |0 T  Add the server name to a request. Use the header string given by <header>5 f, G. @" o, ?: O+ c) C3 h
( K5 T9 s/ C" v5 a7 \. w9 n
  May be used in sections:   defaults | frontend | listen | backend
; h+ g4 D$ s2 \4 b# f2 Z                               yes    |    no    |   yes  |   yes7 v" Z- k$ Y( d5 T3 \
/ ^2 H% B, f) H0 R( s
  Arguments :
/ L$ ~/ T% i/ q' \  l1 g6 E4 S5 P: D1 T
    <header>  The header string to use to send the server name
$ j# K0 G$ t: m7 Z% V6 l
2 v% e- Y) m0 ]. [, m  The "http-send-name-header" statement causes the name of the target  p- I+ a9 A1 ]7 J2 y* y
  server to be added to the headers of an HTTP request.  The name
0 ?- X1 u! V8 S- t& |8 i) v  is added with the header string proved.6 |0 P5 E' Q5 v; b! `# W. z

. ?/ r! w  z% K, [! i# \6 K  See also : "server"
# e; }7 b0 y: k( |+ ^% S) D; E9 i5 q7 M0 I& i  o9 R$ r
id <value>
' \( a* V5 y9 y+ L: b  Set a persistent ID to a proxy.
% R2 S+ Q; u$ ]8 O! J4 J+ B2 N8 Z  May be used in sections :   defaults | frontend | listen | backend1 h! c/ }: r7 N& |0 @( B
                                  no   |    yes   |   yes  |   yes
0 t8 P1 Y& k% N% D  Arguments : none
( }; [& {" N  n, p& z4 {$ g( c8 h+ p
  Set a persistent ID for the proxy. This ID must be unique and positive.
, a6 g/ {/ J3 h  An unused ID will automatically be assigned if unset. The first assigned
' _' w/ q  {7 h5 F; b9 E  value will be 1. This ID is currently only returned in statistics.1 z) k  Q- }) }

: S5 Q% |9 u: D* t9 T! o/ J9 W/ V1 A+ h7 c" i
ignore-persist { if | unless } <condition># z' a# [- \2 d7 ^% l
  Declare a condition to ignore persistence9 Q. P2 z( }/ {* p- |* r
  May be used in sections:    defaults | frontend | listen | backend# |! f' b) V- C
                                  no   |    yes   |   yes  |   yes
; o* W8 h& l) x; L5 ?5 O1 P; ~8 i) P9 j4 x
  By default, when cookie persistence is enabled, every requests containing
& i8 I5 I" Q5 w4 ]  o  the cookie are unconditionally persistent (assuming the target server is up$ \" j4 A- `% u. n$ e/ q% h3 d
  and running).4 E( M3 K7 v% a/ |; z0 Z

" K  V" s- v5 r- r1 _, v  a  The "ignore-persist" statement allows one to declare various ACL-based
  B2 K2 y- X: y+ y) f! k  P  conditions which, when met, will cause a request to ignore persistence.6 I- z, t( @) ^8 _$ f
  This is sometimes useful to load balance requests for static files, which
5 r  v( T, x& l+ L. u  oftenly don't require persistence. This can also be used to fully disable5 L) j0 V' T0 h9 H( h0 }
  persistence for a specific User-Agent (for example, some web crawler bots).
. G& S4 l* ~* w& A6 r6 x' }7 I& v+ \0 `+ d
  Combined with "appsession", it can also help reduce HAProxy memory usage, as# t( H: b1 P( O# d' l
  the appsession table won't grow if persistence is ignored.+ o+ C% \9 l+ P. }* z: R! J6 |

& ?, Y, ]# S* U; x0 u2 D4 N  The persistence is ignored when an "if" condition is met, or unless an
4 s7 L# ]% L9 n8 }7 Q7 e  "unless" condition is met.
& }& ?, W. K, [7 r1 S6 J' W, N4 ^9 B& l6 q! M2 h6 z1 S
  See also : "force-persist", "cookie", and section 7 about ACL usage.2 P% q  l/ [' G; W$ {- _6 O
4 s; W; J; `' a8 l; ^7 @# A

4 J$ x$ G7 g0 `( Y+ Jlog global
9 q# ]8 j6 _; I$ R7 rlog <address> <facility> [<level> [<minlevel>]]" d  N0 I9 B& b  ^' M. d
  Enable per-instance logging of events and traffic.$ T9 M( e% z/ Y2 D. [+ z
  May be used in sections :   defaults | frontend | listen | backend! S- u2 @( @5 K1 {8 T& ]
                                 yes   |    yes   |   yes  |   yes! X; w9 _6 y5 i: A7 E
  Arguments :
+ F" p3 B/ ]$ b    global     should be used when the instance's logging parameters are the: x2 G9 i, G4 a; _/ O0 ^2 x
               same as the global ones. This is the most common usage. "global": L6 O$ ^. ~$ O9 o2 H
               replaces <address>, <facility> and <level> with those of the log7 e6 v! e9 S1 `3 p' W
               entries found in the "global" section. Only one "log global"% i1 U+ m1 t* t3 d3 f9 J. J' N( ]
               statement may be used per instance, and this form takes no other/ ^/ S& p. B; i* p3 j) `" Z8 W
               parameter.# A: s) e) P1 F# _2 O, B

3 S! X& O, D4 f    <address>  indicates where to send the logs. It takes the same format as9 t9 _/ J; k- m
               for the "global" section's logs, and can be one of :. T) k7 P+ C0 [0 N; x8 x
& u1 I7 k/ t( X& f/ d: U; {
               - An IPv4 address optionally followed by a colon (':') and a UDP
3 |# b- ?1 h* e4 n& n" w; ~                 port. If no port is specified, 514 is used by default (the
5 B7 p. d* A( D' ^  ^, G' s; w6 Y3 H                 standard syslog port).
# o/ `: K3 c  K) B% T4 R9 w$ n5 D- [# J) B
               - A filesystem path to a UNIX domain socket, keeping in mind
- V+ S7 t, k& i* J8 G9 P5 d4 k/ @2 H                 considerations for chroot (be sure the path is accessible6 C' F  P' f# Z# B
                 inside the chroot) and uid/gid (be sure the path is
" v$ X( D7 F' J4 O                 appropriately writeable).9 |1 q5 ^# K" G
9 H! d/ X& T8 E4 u! g
    <facility> must be one of the 24 standard syslog facilities :. O! q; Y4 [5 m3 F# G! q7 E
6 u6 W' M3 y2 l# s- M5 t
                 kern   user   mail   daemon auth   syslog lpr    news
+ {' f2 i+ ?$ k& w( I                 uucp   cron   auth2  ftp    ntp    audit  alert  cron2: a9 z& w4 k$ ?8 M5 o6 a
                 local0 local1 local2 local3 local4 local5 local6 local7# y; g& `; ~, N- Q& Q+ t3 b

% m2 l" S" i. J6 y/ g    <level>    is optional and can be specified to filter outgoing messages. By0 V* G$ G! I2 f
               default, all messages are sent. If a level is specified, only6 B9 g, s# U9 T* V, B
               messages with a severity at least as important as this level
3 _* x7 u" Z1 ]' |8 C               will be sent. An optional minimum level can be specified. If it7 z0 N% \: n- J2 D1 p' t2 g
               is set, logs emitted with a more severe level than this one will
' l6 S) ?. s8 }* q               be capped to this level. This is used to avoid sending "emerg"* L, d. w4 b0 a* B, @/ T
               messages on all terminals on some default syslog configurations.
9 u2 ^8 @+ x7 h5 ^7 D8 o; i" @               Eight levels are known :0 l4 D8 I; B5 L8 P, K

" Y! g7 U1 m/ Q- i: Z# O                 emerg  alert  crit   err    warning notice info  debug
0 ~. L. L5 Z6 Y  {5 m# L9 U" N+ I$ |
  Note that up to two "log" entries may be specified per instance. However, if
) }0 P# z6 P' K9 E$ D  "log global" is used and if the "global" section already contains 2 log
2 m( C9 _* l6 t  entries, then additional log entries will be ignored.! q2 h. X$ S3 B8 o- O$ P1 \
% t+ T/ f5 G( [5 x5 Z
  Also, it is important to keep in mind that it is the frontend which decides" ^' ]  x. m+ N3 c
  what to log from a connection, and that in case of content switching, the log
2 l1 A2 Z; E5 N; B; E* ~  entries from the backend will be ignored. Connections are logged at level) _: F: j0 p( `3 c% L  j% E( L
  "info".
3 l6 Y: o: F- _6 R7 G, H! p
; e4 m+ |7 d4 m5 ~  However, backend log declaration define how and where servers status changes8 m4 Q1 p) B/ [; p) Y3 P$ d+ a
  will be logged. Level "notice" will be used to indicate a server going up,4 f+ X" ^# x/ i$ Z# K, ^) I
  "warning" will be used for termination signals and definitive service2 I. X6 Y2 k! ^- ?" D. q. s" n
  termination, and "alert" will be used for when a server goes down.7 j9 R. Q7 ~/ b. a  P
) \/ d5 `' }$ H/ w% _4 F+ e: W
  Note : According to RFC3164, messages are truncated to 1024 bytes before) i6 [: ?" U3 J2 r
         being emitted.4 I6 X7 c0 }! H0 t. ?% p. L
' ^8 m# v# Y2 e* K* y; Y
  Example :# H1 i. e" u* n7 j: N1 a# G0 m9 h
    log global. W4 r8 C$ J0 n# \" K5 V
    log 127.0.0.1:514 local0 notice         # only send important events
' {' r3 ?5 s- H" Q* v    log 127.0.0.1:514 local0 notice notice  # same but limit output level
8 A+ s; F9 Y+ N) g  k7 a& ]; \2 T' w% D% E+ t6 b' O

1 h1 Q2 s* R* P; n' {' l" emaxconn <conns>& w% `' z6 Y0 R( i9 U" v
  Fix the maximum number of concurrent connections on a frontend* B! d. n/ A' \0 C) M7 c% m$ E6 ?
  May be used in sections :   defaults | frontend | listen | backend4 L3 k( N- d0 `
                                 yes   |    yes   |   yes  |   no
8 ?' P+ o! M. N; S- |+ a  Arguments :% H" P3 D& ~. ~8 i6 g( M
    <conns>   is the maximum number of concurrent connections the frontend will6 u! d7 j0 G; [0 a
              accept to serve. Excess connections will be queued by the system
- q* G; w& V' y2 x# P: ~- W              in the socket's listen queue and will be served once a connection! K, s& g- @! \3 S! W8 ]/ `3 l* S
              closes.- A8 Y& p1 l% z4 e/ {* w5 ^" y

+ f, F& _" q( v, _# q  If the system supports it, it can be useful on big sites to raise this limit# d3 s- M# g7 V
  very high so that haproxy manages connection queues, instead of leaving the
. x, I( n4 T. s) c) |  clients with unanswered connection attempts. This value should not exceed the* B/ V# ^, L+ L1 a+ u# o9 a; v
  global maxconn. Also, keep in mind that a connection contains two buffers
& l# T' p( B: \" I3 o3 f1 w  of 8kB each, as well as some other data resulting in about 17 kB of RAM being; }! K# i# x, S+ M$ \+ D2 U9 d
  consumed per established connection. That means that a medium system equipped
0 U0 F: n8 w" G  with 1GB of RAM can withstand around 40000-50000 concurrent connections if
, p; L8 c9 l# J3 D  properly tuned.% `+ c  P" X$ [

& C5 X' K# X9 l* F6 I0 t  Also, when <conns> is set to large values, it is possible that the servers9 I( a( m2 q8 w$ x, u9 T9 g
  are not sized to accept such loads, and for this reason it is generally wise
2 H; I. ?/ C5 i" m. |2 o# a  to assign them some reasonable connection limits.
4 j9 i; e) H0 A; ?* I% z% U" d5 u; x; P' j% e& m2 l
  By default, this value is set to 2000.
( n. j7 e5 M/ x, A& y( N# C: B, E* i; W
  See also : "server", global section's "maxconn", "fullconn"' ?9 `3 Y8 t9 x% _2 Z. g) A7 J
6 K5 v5 D* V& e) k
1 P; A8 d( e# ^% j. U
mode { tcp|http|health }
3 y4 M" l0 v! U2 o3 b$ V0 @) w  Set the running mode or protocol of the instance
- x& Y( a; {% X% V, {1 z- E  May be used in sections :   defaults | frontend | listen | backend/ b) I& x3 j9 M# @; P
                                 yes   |    yes   |   yes  |   yes
; i8 W) Z* q" I+ O! K9 B# D6 q  Arguments :* ~  Z& j9 O' j. b
    tcp       The instance will work in pure TCP mode. A full-duplex connection: e) Z( C) \" `5 H
              will be established between clients and servers, and no layer 7
/ ^! d- m4 J/ X: {8 h2 l              examination will be performed. This is the default mode. It
. ?/ `! S9 p. X6 H0 |+ @              should be used for SSL, SSH, SMTP, ...
, g/ m) ]! |! o  U4 p$ u3 I; t. g2 O
    http      The instance will work in HTTP mode. The client request will be
6 E$ s" D1 H8 u0 p. U8 b              analyzed in depth before connecting to any server. Any request
6 ^: ?+ |; x4 w3 Q& {% b7 }              which is not RFC-compliant will be rejected. Layer 7 filtering,
2 e$ a7 i& }; y# ^% X4 V              processing and switching will be possible. This is the mode which& @8 s+ O6 P! @" T+ D* ?
              brings HAProxy most of its value.9 ^8 M- X' I' y' F, F, D+ u
" J" ]( ^4 p! A
    health    The instance will work in "health" mode. It will just reply "OK"
. n6 P; ]; K" x% G4 o              to incoming connections and close the connection. Nothing will be8 f2 p) S) v9 k; ?3 u
              logged. This mode is used to reply to external components health
0 M$ j' a& D( K6 ~$ f) j              checks. This mode is deprecated and should not be used anymore as2 V7 ^/ J! I: w; D& `: B  f0 T, w
              it is possible to do the same and even better by combining TCP or3 F9 S, N/ h0 `- y! e. G5 v
              HTTP modes with the "monitor" keyword.3 P$ M; x" ?8 J( `

# V7 x1 _3 Q5 w. H% A) R( J  When doing content switching, it is mandatory that the frontend and the
6 z) n6 X: R) n4 a* U" O  backend are in the same mode (generally HTTP), otherwise the configuration' p8 `! G& }( z; G9 y
  will be refused.0 _' [) b- D3 f' n
( z- {. ~9 r3 H- O( c
  Example :* v. W: `; w: L( C
     defaults http_instances$ r0 M+ N+ r9 v0 {% v7 d- |
         mode http9 r& R. A1 K' L5 `

! b" t% E& _, N& Y& p6 d2 E( @  See also : "monitor", "monitor-net"
" _% @& L! a( J2 Y# {+ Y& L. O% F$ k1 r' g6 Q  `6 F3 n
6 R. p4 d$ p. A9 ]2 o" p5 {
monitor fail { if | unless } <condition>
+ }& N$ B( ~2 {1 Y8 D+ f  Add a condition to report a failure to a monitor HTTP request.9 m" k4 k, ?4 J: t8 x. _( Z4 I
  May be used in sections :   defaults | frontend | listen | backend' r  C$ n& u' s( j4 e
                                 no    |    yes   |   yes  |   no. K# q7 k) P1 R6 X& L. R% Y8 `4 C' i
  Arguments :
5 y1 e0 R) s9 V8 A' t    if <cond>     the monitor request will fail if the condition is satisfied,
; \  `2 z* C1 |* U& R                  and will succeed otherwise. The condition should describe a
0 x9 g) C5 Q, }, W+ ?$ @7 B                  combined test which must induce a failure if all conditions  l$ q  |7 s  m! z5 G6 K% \: ]- X$ O
                  are met, for instance a low number of servers both in a
+ {, ?- A3 s7 i( v8 A' d0 a                  backend and its backup.
- _' Z0 H9 H4 e3 C) q" C9 Q( K8 r, @- B
    unless <cond> the monitor request will succeed only if the condition is) c% I% e& Z2 |2 ?( a' I
                  satisfied, and will fail otherwise. Such a condition may be
/ N0 B1 p# \. `* K" T8 h+ h8 m                  based on a test on the presence of a minimum number of active
' Z) e# O( k9 t7 Y, k, f+ l+ K                  servers in a list of backends.
$ x3 X! P+ d# r, c' f3 \" m3 c4 M7 f+ \" O
  This statement adds a condition which can force the response to a monitor6 y5 K# o  i* o% A& k- S
  request to report a failure. By default, when an external component queries( d  |8 Z. n  s+ p, V4 S
  the URI dedicated to monitoring, a 200 response is returned. When one of the7 F2 Z6 G$ K) i$ R/ E
  conditions above is met, haproxy will return 503 instead of 200. This is
9 v4 w$ A; `6 B" n! [  very useful to report a site failure to an external component which may base' L% }8 c: i) m- p. U$ t+ J8 Q
  routing advertisements between multiple sites on the availability reported by
5 F8 |( `; x* j- X! L6 Z  haproxy. In this case, one would rely on an ACL involving the "nbsrv", i' W7 m& q4 [9 {7 w
  criterion. Note that "monitor fail" only works in HTTP mode. Both status
9 R- C! [  m5 Z. }" \6 s  messages may be tweaked using "errorfile" or "errorloc" if needed.6 }% y1 N. z8 P

: c2 u( `$ b# q6 e6 H6 S  Example:
) p- F1 e" ?5 y9 H0 f! n% q* T1 |     frontend www
, `$ Y8 v& B, p  A        mode http4 G1 C# o, r& u$ F, x1 U# B$ Y3 X0 Q
        acl site_dead nbsrv(dynamic) lt 2
/ Z  d( x3 q, J; r* i6 A3 K0 h  H        acl site_dead nbsrv(static)  lt 2* ?9 Y- B0 j3 N4 s
        monitor-uri   /site_alive2 S  l. c$ B" c7 X2 K. \1 z2 I. _- h
        monitor fail  if site_dead2 f) @  C+ F# g: M& o
3 \! Y4 ]% ]' W! Y* `" M6 }- y
  See also : "monitor-net", "monitor-uri", "errorfile", "errorloc"  b* a' X( z9 e
% o2 }  F: h- P4 x1 ]

8 o7 K8 A1 H0 r# z9 h3 Ymonitor-net <source>
% H, b! l- }7 M  Declare a source network which is limited to monitor requests' f! C( S  Z# ^. R6 Y" B
  May be used in sections :   defaults | frontend | listen | backend
# t( o: o/ W5 A* X7 o                                 yes   |    yes   |   yes  |   no
( H& Q5 E/ ?: ^  Arguments :* |- V: P% t$ ?2 C& c
    <source>  is the source IPv4 address or network which will only be able to
' Y; M+ D: j0 v0 o$ }              get monitor responses to any request. It can be either an IPv45 G7 _, Q, m- d7 ~7 [
              address, a host name, or an address followed by a slash ('/')
% G7 w0 y3 o# s# h  ?; {& r              followed by a mask.2 j$ k+ {' a0 P" ~, S
- F# r0 _+ n- Q+ v
  In TCP mode, any connection coming from a source matching <source> will cause
0 `7 K: y( v. @  the connection to be immediately closed without any log. This allows another
+ _0 N7 j  k- n, R7 U  equipment to probe the port and verify that it is still listening, without
8 o% V+ I# Q: |  forwarding the connection to a remote server.
( `: N' ^6 _  j' y2 w' X* K6 f( H1 X! W( A! X
  In HTTP mode, a connection coming from a source matching <source> will be! z+ k% S: K1 i8 i
  accepted, the following response will be sent without waiting for a request,5 |4 \/ z, [5 F4 N% x; D
  then the connection will be closed : "HTTP/1.0 200 OK". This is normally" U0 C+ W: e9 o# [# T
  enough for any front-end HTTP probe to detect that the service is UP and
. F( e- y3 H: r" \; r) V  running without forwarding the request to a backend server.3 O7 [! R/ l! N9 E8 r$ p) |

, k' t! N3 |0 h2 @9 @- ]: h5 `  Monitor requests are processed very early. It is not possible to block nor4 f3 m4 C& e0 n* B7 j" U
  divert them using ACLs. They cannot be logged either, and it is the intended
4 F8 b. b! z. X9 b0 @/ \: Q  purpose. They are only used to report HAProxy's health to an upper component,, k" k5 ^' [; i5 x
  nothing more. Right now, it is not possible to set failure conditions on) a4 c* t0 `" M; L" N
  requests caught by "monitor-net".# \; u0 r, Y, j: {% c) Z

' L2 M2 p( Q. J! y% V  Last, please note that only one "monitor-net" statement can be specified in% i$ |- Q0 H9 L/ j" u
  a frontend. If more than one is found, only the last one will be considered.$ M/ J9 L' L, w" o7 _& G

0 y2 h: O; q* [4 P  M# ?/ C, [  Example :
8 ]7 r/ T+ \5 \; B9 l' \    # addresses .252 and .253 are just probing us.
  }# n7 \# F: B& a. d( z+ `0 i# {: W    frontend www
' c% g& I1 p/ T0 M2 ?0 Y$ T" W. |* n        monitor-net 192.168.0.252/31) R+ j$ F. L4 Z4 r6 B7 p1 C
8 O. \, u7 C3 Q! m. \
  See also : "monitor fail", "monitor-uri"$ v* o- U% q* l0 ]

* C, Y1 X. j$ p4 b4 u3 F  R
  J2 U% T% D  k/ X4 \& b+ imonitor-uri <uri>
% t8 s" [4 c4 K2 I  Intercept a URI used by external components' monitor requests
  |+ s% f/ y2 P, e/ Y: N  May be used in sections :   defaults | frontend | listen | backend  U& p# z0 R, G" c+ X# ^
                                 yes   |    yes   |   yes  |   no
# H5 D( j4 _7 q" s' r3 M) S. F2 R  Arguments :
. X1 Z6 T% T( e4 I# o4 S+ c$ q    <uri>     is the exact URI which we want to intercept to return HAProxy's0 @# Y' g3 l5 s1 w9 V8 S$ r- P  i
              health status instead of forwarding the request.
) [( x6 a0 U" @) v
' l' D4 ]) N3 L1 h  When an HTTP request referencing <uri> will be received on a frontend,
  S1 P/ ]' w. ~0 w  HAProxy will not forward it nor log it, but instead will return either8 q- e0 `7 a* w  l
  "HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure
9 @4 k) O5 K# X1 ]! ^6 I' f" O# @  conditions defined with "monitor fail". This is normally enough for any7 u9 w/ a0 L% ?2 I
  front-end HTTP probe to detect that the service is UP and running without
" ]2 `* S6 ]0 J, W) r  {  forwarding the request to a backend server. Note that the HTTP method, the
+ A6 A6 g+ T5 n) u# `/ h. `  version and all headers are ignored, but the request must at least be valid* H3 [/ [2 A& o7 O; m# d
  at the HTTP level. This keyword may only be used with an HTTP-mode frontend.
% r$ p. c4 j: a2 }$ \
" ~: b% T& w/ @: K  Monitor requests are processed very early. It is not possible to block nor
; d, Y- c. T5 N0 H' j( ^7 m' F  divert them using ACLs. They cannot be logged either, and it is the intended6 T- E2 j- }. O; g- {/ R" X
  purpose. They are only used to report HAProxy's health to an upper component,
# B$ _% C! w0 w& U  A. \  nothing more. However, it is possible to add any number of conditions using+ i+ e" b! O% ]  {1 o* ^# k
  "monitor fail" and ACLs so that the result can be adjusted to whatever check
/ r9 }: }9 ?2 m$ R, F+ z" ]  can be imagined (most often the number of available servers in a backend).
1 H5 y/ g8 v9 G# x2 _  T* A- q2 x8 t2 `
  Example :
/ i5 f- c, }" n# X    # Use /haproxy_test to report haproxy's status9 e* U( r" `- b- H( }- E
    frontend www: R/ z2 w- G8 V' g  ~  b
        mode http
  t1 g. t" X" Q  i  m' P        monitor-uri /haproxy_test
& m9 N2 @. _: R
) J! d9 J, e- N. Y! C2 {5 Q  See also : "monitor fail", "monitor-net"
. X2 ~! T, ~3 r8 T: ^$ f( s& Y& S7 V7 @+ P9 J8 }
- r4 }2 ]: j: Z# t/ o
option abortonclose
( j0 L& i* j/ L8 g4 Y0 x( ?no option abortonclose
' s3 D% h6 z6 \5 f: Y  Z0 s  Enable or disable early dropping of aborted requests pending in queues.' z( W3 G/ R) U
  May be used in sections :   defaults | frontend | listen | backend1 _9 ~! }. D* u& e5 i. A2 L$ b
                                 yes   |     no   |   yes  |   yes
2 Q" J, x1 A* K# d& A  Arguments : none
/ B' [4 p1 a& a. E6 k. r+ B. g3 ^6 b+ l# ?+ _
  In presence of very high loads, the servers will take some time to respond.8 |8 L. F7 w; Q* S8 q" J" W
  The per-instance connection queue will inflate, and the response time will+ T9 b- p3 ^5 F- P7 n
  increase respective to the size of the queue times the average per-session# M. F: R7 J3 F+ X9 E6 Z2 |% _
  response time. When clients will wait for more than a few seconds, they will
- |: g' D- {# L* [6 R  j  often hit the "STOP" button on their browser, leaving a useless request in
! ^& `$ a) \# H  the queue, and slowing down other users, and the servers as well, because the' n6 L3 I  W! ?- P, `
  request will eventually be served, then aborted at the first error/ A8 W. j5 D% `6 q& W6 d  Q
  encountered while delivering the response.
$ f' a3 b0 `3 C; V1 w2 h  k, H/ Z' u: T4 \4 A
  As there is no way to distinguish between a full STOP and a simple output
4 X2 y. S. I. r+ L3 Z5 W9 l  close on the client side, HTTP agents should be conservative and consider
7 L7 f% O" i7 v  G' _- _  that the client might only have closed its output channel while waiting for" C4 q. g+ q2 m7 k3 f
  the response. However, this introduces risks of congestion when lots of users: m/ U& {) H# M5 G; o1 N  j
  do the same, and is completely useless nowadays because probably no client at6 n% x7 L- v" H* c/ j  M
  all will close the session while waiting for the response. Some HTTP agents3 j6 S# ^+ ~0 o* s) c9 ?4 i+ P% P
  support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most3 F( N1 [3 l0 ?! q5 G2 d! ?  n* E
  hardware-based load balancers). So the probability for a closed input channel
* g* R( O) C8 ^5 f8 F8 ]  to represent a user hitting the "STOP" button is close to 100%, and the risk
, K, Y* u( d* \  of being the single component to break rare but valid traffic is extremely
$ L; ^( p& o; V7 D5 g& S  low, which adds to the temptation to be able to abort a session early while7 l6 j# i' ]' J1 b+ n* D
  still not served and not pollute the servers.: b& r! i! V8 ]
% _  h. j1 A; d
  In HAProxy, the user can choose the desired behaviour using the option$ ^7 ^; Y8 ?! D! F( i/ }5 ^1 n8 B4 Y
  "abortonclose". By default (without the option) the behaviour is HTTP
, t- D7 H2 l9 E# ~: k* Q  compliant and aborted requests will be served. But when the option is
' Y! O' H  P; a0 v# F  specified, a session with an incoming channel closed will be aborted while
6 u: I) h# D. Q  it is still possible, either pending in the queue for a connection slot, or
& `9 j1 P4 j4 x0 b" o- P  _  during the connection establishment if the server has not yet acknowledged" O# V1 |! }7 a0 x3 [6 K
  the connection request. This considerably reduces the queue size and the load$ p( `. p; s. g4 p5 K
  on saturated servers when users are tempted to click on STOP, which in turn4 x# b# {8 f- e7 u/ e8 U, E/ B% Z
  reduces the response time for other users.  q, t" A2 r8 Z

( j9 d; y* S  S  C- f9 n1 ]& H  If this option has been enabled in a "defaults" section, it can be disabled2 ]0 D0 M* q; r% l( E7 h
  in a specific instance by prepending the "no" keyword before it.
! T8 r/ e5 V/ Y2 T7 L
6 _4 U' z4 o& U7 x  t) P1 |: P0 P5 B  See also : "timeout queue" and server's "maxconn" and "maxqueue" parameters
1 [9 z3 G/ b6 C+ @# G% o  V6 g1 d& w6 H/ X9 k( Z* G* x0 ?4 D0 V
3 H7 C5 n. f) U1 u. q3 L
option accept-invalid-http-request
- O# P: z  }. x# K7 E# H2 g, Xno option accept-invalid-http-request
/ g. _+ n% g% |% g& U8 y9 S" ~( ]  Enable or disable relaxing of HTTP request parsing
* q/ D& q3 c2 I6 \$ @- D2 ]  May be used in sections :   defaults | frontend | listen | backend
% w" M2 T3 X5 `                                 yes   |    yes   |   yes  |   no
3 L5 a% d* [( J$ s  Arguments : none
% z( |/ y( d# z! i9 R7 S  d
) q: ]  J# S* u8 w  By default, HAProxy complies with RFC7230 in terms of message parsing. This/ H/ \3 e- N7 r; S6 f$ ?) [
  means that invalid characters in header names are not permitted and cause an
3 [% j+ k( [# H+ ]$ E  n( [& p  error to be returned to the client. This is the desired behaviour as such
  D: A8 Y9 ~( D: k1 h# [( J# Z  forbidden characters are essentially used to build attacks exploiting server" |. k& o( F# t# I) h
  weaknesses, and bypass security filtering. Sometimes, a buggy browser or
$ o0 b8 R/ R0 ]. `2 R  server will emit invalid header names for whatever reason (configuration," v% o1 e5 E8 O: R) l' e
  implementation) and the issue will not be immediately fixed. In such a case,
) s! V( A0 U' \9 X0 c$ f$ q, t  it is possible to relax HAProxy's header name parser to accept any character
) Z" T4 A' E! \: u/ S  even if that does not make sense, by specifying this option. This option also
! x. l  z$ R  c2 j  relaxes the test on the HTTP version format, it allows multiple digits for
' x" I( T( r' c; b! _" Y2 W$ G  B# S  both the major and the minor version.1 D, e1 y' `6 N6 j4 {& n

! d' r. }# f& C, V  This option should never be enabled by default as it hides application bugs  x6 r# p7 @; W( O8 F4 S! W
  and open security breaches. It should only be deployed after a problem has9 I$ T; l  M. P4 X- [; k
  been confirmed.
2 S1 {7 f' M% c! p  V0 m0 _# Q3 i- X0 X0 ]9 a& `# Q
  When this option is enabled, erroneous header names will still be accepted in7 w; K+ C; T+ j; U# _( P9 b
  requests, but the complete request will be captured in order to permit later* \4 Z0 B5 Y$ V4 I! J
  analysis using the "show errors" request on the UNIX stats socket. Doing this
7 A$ s8 B3 W- f* F) W* u! ~0 Q  also helps confirming that the issue has been solved.% V+ {( `9 _8 B0 b/ ^) [) ?
( k* n# ^. P, y. O& f
  If this option has been enabled in a "defaults" section, it can be disabled
8 r& s/ a1 Y0 r6 D+ i  in a specific instance by prepending the "no" keyword before it.
: a& N3 C+ {, B4 V: @1 M' W2 Z0 c/ _+ o8 ^. |( e5 F
  See also : "option accept-invalid-http-response" and "show errors" on the* c4 d9 W7 L4 o7 _; r+ w
             stats socket.2 g2 h" k/ h& a$ _+ s, H

7 N$ C6 U6 h/ j. `9 k
$ P! P* \, E5 I+ A6 _2 Doption accept-invalid-http-response
: ]9 i$ k* K" i% {9 fno option accept-invalid-http-response( h/ o2 v9 \/ `& R: f, C
  Enable or disable relaxing of HTTP response parsing" s! N% e" ?: f8 M
  May be used in sections :   defaults | frontend | listen | backend5 X# p/ n+ r. T' C
                                 yes   |     no   |   yes  |   yes
; s+ r" `9 Y( S5 k$ q2 m8 \  Arguments : none
6 o0 |4 a# w! x) L$ |
+ X* a' L) N$ d" p( w8 I5 X$ ~  By default, HAProxy complies with RFC7230 in terms of message parsing. This
  K7 O6 ?* \$ K3 @) F7 P( Z" ]  means that invalid characters in header names are not permitted and cause an
' x! G- K# L' F. {  error to be returned to the client. This is the desired behaviour as such
1 Z% O/ B/ a+ _. M1 l5 H/ Y  forbidden characters are essentially used to build attacks exploiting server
3 v& h- R8 U7 ?  d. {1 f  weaknesses, and bypass security filtering. Sometimes, a buggy browser or2 P8 M- I1 A0 F+ `' g+ q
  server will emit invalid header names for whatever reason (configuration,
. z& G  X# J8 x! ?2 w% n  implementation) and the issue will not be immediately fixed. In such a case,& q! a- L. k# m, ^" U0 Z
  it is possible to relax HAProxy's header name parser to accept any character, ~5 g) m  c- M/ }, z
  even if that does not make sense, by specifying this option. This option also# D7 K. |0 V& F2 d7 G4 @9 j3 y. Z
  relaxes the test on the HTTP version format, it allows multiple digits for
' \0 U; \0 b7 q: G, n! E- f  both the major and the minor version./ V3 R# z! V: z, J; @$ T# b

9 L# ?3 i5 P8 w+ H5 r  This option should never be enabled by default as it hides application bugs* Z8 J: ]- C' a$ `3 A6 I
  and open security breaches. It should only be deployed after a problem has
8 U' C2 x1 Y- R  been confirmed.
7 ?: u4 w8 q0 _0 J& V  c  Q8 K9 @" L2 h; t
  When this option is enabled, erroneous header names will still be accepted in
3 k+ r/ {. Y2 k+ U; g& F8 v+ |  responses, but the complete response will be captured in order to permit
* W0 Y- L3 M& p  later analysis using the "show errors" request on the UNIX stats socket.  C( j9 A& c. Y: k) X9 W! h
  Doing this also helps confirming that the issue has been solved.
% A8 B3 w& {: c# Z" j7 E6 O' M4 I- q/ ?8 W1 t- S; a
  If this option has been enabled in a "defaults" section, it can be disabled
7 W$ ]% ~! x3 i% m& R* {# |  in a specific instance by prepending the "no" keyword before it.9 N8 v* I# U$ x! k; @
, U0 M8 p& Q. Q
  See also : "option accept-invalid-http-request" and "show errors" on the; Y4 M3 {9 m# r5 p# I! d) f# L
             stats socket.; W5 {* E# N/ [; y$ @

% i9 B! L5 D! M( K8 S' m: s/ w: S$ l4 u1 M' o
option allbackups
# F1 {9 e7 U3 |& J! cno option allbackups" j% e' Y' A) d
  Use either all backup servers at a time or only the first one- |* V9 q; x/ a2 s
  May be used in sections :   defaults | frontend | listen | backend
- v5 v; S( I+ Q9 X3 Y, l/ ]' }                                 yes   |     no   |   yes  |   yes
1 d9 r( K- g3 t  r! ^  Arguments : none2 r7 C% Q  Z( q7 _0 l
* ?* i+ [+ ~6 s2 X) R& [
  By default, the first operational backup server gets all traffic when normal! n& X( H+ _* M; U; c* [3 K0 ]
  servers are all down. Sometimes, it may be preferred to use multiple backups
6 B8 b7 u+ c5 c2 h  at once, because one will not be enough. When "option allbackups" is enabled,
& {6 {* B8 w4 I* O2 }: ?  the load balancing will be performed among all backup servers when all normal
4 B; A3 g' R3 z: V, A/ _' I& \# I8 @  ones are unavailable. The same load balancing algorithm will be used and the
: @/ W2 {  j# X2 D) c  servers' weights will be respected. Thus, there will not be any priority% i6 B+ V3 u) K5 ^3 b; _2 ^
  order between the backup servers anymore.
0 y+ q8 Y8 u" H2 E1 M5 s: N3 K8 D4 ]' `' a* Q) S3 r$ j, K
  This option is mostly used with static server farms dedicated to return a
5 A0 w) q. M1 L* G3 n' }/ D  "sorry" page when an application is completely offline.
! ^2 P+ l) K* U" }
. `/ M4 I5 x# ~% G  If this option has been enabled in a "defaults" section, it can be disabled
) j# Y( b0 R' K8 D5 M  in a specific instance by prepending the "no" keyword before it.
2 K. \3 A" _. X2 I6 [1 j+ H  K( x
3 t% @+ g/ ?% U5 v! N9 h1 w. j4 k) y- U5 C8 _, v
option checkcache
: f: K+ E  p& ~0 Ino option checkcache
) k* i; T) N* ]) K! t) f7 b  Analyze all server responses and block requests with cacheable cookies
% L3 p- d% u: N; @5 ?( E  May be used in sections :   defaults | frontend | listen | backend# b2 X, Q4 `+ D7 N4 _% m8 Y2 q. |
                                 yes   |     no   |   yes  |   yes
2 S( F* W! Y2 A( ^$ P& o  Arguments : none
+ J. o$ {. s- i3 H6 f+ u! Q5 \
9 Q) G1 \! r" \+ K+ g  Some high-level frameworks set application cookies everywhere and do not
0 Q+ O' }; }: I  always let enough control to the developer to manage how the responses should+ s! }4 X0 j' p* ~* o% I) ~# P
  be cached. When a session cookie is returned on a cacheable object, there is a7 k% [8 c2 a$ W. i3 s
  high risk of session crossing or stealing between users traversing the same
5 Y' Q/ S/ J7 f8 ^  caches. In some situations, it is better to block the response than to let
9 v1 a3 G9 l3 i- ?# @  some sensitive session information go in the wild.$ a; |& O" c( P& ^) H& |, o

7 x5 J8 s- T+ w  The option "checkcache" enables deep inspection of all server responses for
6 p; F4 _9 x2 Y- o7 J4 J6 I( O  strict compliance with HTTP specification in terms of cacheability. It4 p; W, u& E  J# S
  carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server
% _. M5 D+ M! j  V; L  response to check if there's a risk of caching a cookie on a client-side
2 |3 V7 c( Z6 v6 q- R  proxy. When this option is enabled, the only responses which can be delivered$ r6 b# J' i. t
  to the client are :; S: u5 B2 w; {8 D9 m
    - all those without "Set-Cookie" header ;
' s" g  ]2 o" E; t9 m8 G. y$ H    - all those with a return code other than 200, 203, 206, 300, 301, 410,
0 m6 A& z, J) P7 r  g, W      provided that the server has not set a "Cache-control: public" header ;
, C: a& A5 n2 u- _4 L& I( Q    - all those that come from a POST request, provided that the server has not2 S3 C, S: l; h6 K1 a  G8 i
      set a 'Cache-Control: public' header ;+ m+ y5 n0 f5 p; O3 g8 s
    - those with a 'Pragma: no-cache' header3 `' I2 ~: W/ q: Y+ p
    - those with a 'Cache-control: private' header/ O/ @1 D5 }" r
    - those with a 'Cache-control: no-store' header1 H* V$ g' Z; V) j% d& k
    - those with a 'Cache-control: max-age=0' header
$ g4 |( w4 X+ Z  n( v6 v    - those with a 'Cache-control: s-maxage=0' header, C8 r7 c4 A5 F! ~; N$ Y
    - those with a 'Cache-control: no-cache' header. }; X/ X4 A; }# D& J2 ]/ f7 S' f
    - those with a 'Cache-control: no-cache="set-cookie"' header
, `. u6 R1 `2 V1 g    - those with a 'Cache-control: no-cache="set-cookie,' header  b3 }/ M8 M5 u
      (allowing other fields after set-cookie)5 Y" J5 E0 \2 k" U- P4 h  U

) z9 D+ f2 \5 i% N4 m$ z0 q" A& G  If a response doesn't respect these requirements, then it will be blocked* h  f4 D8 H. y2 ?
  just as if it was from an "rspdeny" filter, with an "HTTP 502 bad gateway".
" T" n9 g6 R: n$ Q0 i1 ~' ^  The session state shows "PH--" meaning that the proxy blocked the response
' h  }$ y+ D/ B/ s2 u' l  during headers processing. Additionally, an alert will be sent in the logs so2 L, f9 T2 F- G
  that admins are informed that there's something to be fixed.
) b7 [+ T( u, a' @% g& f1 n& m! X1 A9 c) D7 d
  Due to the high impact on the application, the application should be tested
1 d3 ~5 o( `4 O! a  in depth with the option enabled before going to production. It is also a- l) _  g# g. k2 F% E- v
  good practice to always activate it during tests, even if it is not used in% F% Z1 s) H% @: u* E0 J! H) i
  production, as it will report potentially dangerous application behaviours.9 S/ {- _! _# p  @* Y  x

% l7 R7 W; O/ v& t( q  If this option has been enabled in a "defaults" section, it can be disabled
  r' m: B$ i1 j- {+ n1 k  in a specific instance by prepending the "no" keyword before it.
/ n. V/ T% U* s6 V$ S/ e4 F
; f. M+ p4 z* ^  O9 \2 b- s
" h/ l+ }. T) h6 Woption clitcpka
) g; p6 {# l1 c7 gno option clitcpka/ a" B4 }1 ^7 y. l) \1 a# M1 r
  Enable or disable the sending of TCP keepalive packets on the client side# O+ `5 I# Q; g, k+ r5 q
  May be used in sections :   defaults | frontend | listen | backend
6 W6 u  P- K- Z# B- D9 F9 M0 l                                 yes   |    yes   |   yes  |   no% B) T; G7 `5 |; e
  Arguments : none
: @5 I' t6 r7 e
7 [, `1 Y1 H: w5 e7 g* w& g  When there is a firewall or any session-aware component between a client and
) \' X" h) b, ?# n, f( V  a server, and when the protocol involves very long sessions with long idle' `4 h: E/ F; y  M
  periods (eg: remote desktops), there is a risk that one of the intermediate& @% H( X5 g' \* U( m9 y5 B: m
  components decides to expire a session which has remained idle for too long.& R3 F8 y9 P3 M
. O# g) g' ~! o1 |/ h
  Enabling socket-level TCP keep-alives makes the system regularly send packets
" c# @% R2 z2 l- I* C  to the other end of the connection, leaving it active. The delay between
0 J! K( B! I. H  keep-alive probes is controlled by the system only and depends both on the
; ]& u& ?6 F1 o) a) `) [8 |  operating system and its tuning parameters.$ g: ~) ]( |: ]) X% `
& N1 _* k' X- Y6 V( `) M
  It is important to understand that keep-alive packets are neither emitted nor
. c" }1 q$ M' S  ?* [& |  received at the application level. It is only the network stacks which sees7 P0 m5 t; m# _; A0 R
  them. For this reason, even if one side of the proxy already uses keep-alives' r  G' @. e( C% o1 q7 }
  to maintain its connection alive, those keep-alive packets will not be. ?  G0 e; ]' n6 g3 n( X
  forwarded to the other side of the proxy.( G( s. a0 h2 V4 g
" K( T8 Y' E  A  l; ?9 i' @* e
  Please note that this has nothing to do with HTTP keep-alive.7 A# A7 g1 @! D6 h! r- U

) @' G; _2 U# D' S/ y1 h) Q* y. ], R  Using option "clitcpka" enables the emission of TCP keep-alive probes on the
2 I7 Z# p( |# G, U  client side of a connection, which should help when session expirations are
4 A! Y$ e( i8 T% ~( r1 `8 ]" n0 L  noticed between HAProxy and a client.* \4 T; |3 B+ a0 c, ^7 g; R& O
% c4 x$ Z" M' S+ t1 ^# T- D
  If this option has been enabled in a "defaults" section, it can be disabled
, h* v" Q: e+ R# F2 G; v6 n" x, `  in a specific instance by prepending the "no" keyword before it.# P. I/ t6 q" B9 u- y
5 u: }! M4 h$ N
  See also : "option srvtcpka", "option tcpka", K$ C6 B; N* F& H
6 d# s: o) R0 y

- E# g# `$ a+ \8 r5 `2 B2 z, Q0 koption contstats
( l! N: z2 C) a% d3 c  Enable continuous traffic statistics updates5 Y: q6 k1 o  y7 w( K
  May be used in sections :   defaults | frontend | listen | backend* K. R0 [- Y! H  `/ j' @
                                 yes   |    yes   |   yes  |   no
! F* x& d$ p& x  Arguments : none8 c4 I: E7 }# b9 ]
$ l+ v5 j9 H2 h8 P' [
  By default, counters used for statistics calculation are incremented
( }: a4 h0 |2 V- C. O  only when a session finishes. It works quite well when serving small
- A' d" `* S& C+ [% |8 l+ ~  objects, but with big ones (for example large images or archives) or
' N& z1 a& M9 K$ Z: c8 _1 F  with A/V streaming, a graph generated from haproxy counters looks like1 ~  e; ?7 g8 ~5 z' \) o
  a hedgehog. With this option enabled counters get incremented continuously,
7 v; V* V8 h4 `* C1 V  during a whole session. Recounting touches a hotpath directly so
* k& \1 E+ P$ p* G3 Y: Q  l4 `  it is not enabled by default, as it has small performance impact (~0.5%).0 U. m0 K! n- @* p/ g9 ^* s
# Q% o6 E  P9 R" P( V
: Q1 C! _* Y* d1 l, C: [3 G4 V$ t
option dontlog-normal
( d/ I3 j+ ]1 n2 Vno option dontlog-normal; y* x' k+ E& ^! M5 D
  Enable or disable logging of normal, successful connections; g9 Z4 m1 l6 U8 [; z9 b- D
  May be used in sections :   defaults | frontend | listen | backend  B, T2 Y# p% W2 Q- `
                                 yes   |    yes   |   yes  |   no- r: ^7 u, x& t( `+ Z- v' S8 A
  Arguments : none
% w+ Z* f4 q: P/ U* K8 I( Y; G
$ G5 u8 [9 i& I" M) p! t  There are large sites dealing with several thousand connections per second
* E; G) Q, c& i* C% I  and for which logging is a major pain. Some of them are even forced to turn4 ~2 ~2 L" }4 a9 B- f
  logs off and cannot debug production issues. Setting this option ensures that* E2 Y# ~* c, v9 Z0 o
  normal connections, those which experience no error, no timeout, no retry nor
; n$ p! X% W# m  u$ T0 @  redispatch, will not be logged. This leaves disk space for anomalies. In HTTP
$ ]4 E5 ?0 M* O" {  U  mode, the response status code is checked and return codes 5xx will still be
& Q: A0 A8 c6 `1 {9 w  logged.9 D7 }  \4 j! E% Q9 w

/ j& h# s  T- \  It is strongly discouraged to use this option as most of the time, the key to* ^6 r- L9 j- G, L' {1 `
  complex issues is in the normal logs which will not be logged here. If you
2 E, T* b6 ?5 M8 H  need to separate logs, see the "log-separate-errors" option instead.) d9 X. f1 @! j* C6 Z& F; A
/ V- \& }! X! I# W* d
  See also : "log", "dontlognull", "log-separate-errors" and section 8 about
$ t; w( B+ ?6 R5 Z: B             logging.
0 d6 T; D# S, D1 e5 }1 [) ]
0 ]4 f8 i; i: T# [2 s& b8 b8 h) V- j, D2 ~3 _
option dontlognull
# x$ n* x8 B& {# g4 u0 jno option dontlognull
0 H5 \  H' q2 G! u6 o7 _7 f$ _+ C  Enable or disable logging of null connections& N' Y2 D& A& V/ K# L# X6 h9 d! ^
  May be used in sections :   defaults | frontend | listen | backend3 z& {# f" w* Z' |$ C6 i( U: ]/ p0 U
                                 yes   |    yes   |   yes  |   no4 p3 Z# O1 c% |+ g* z0 M! k# h
  Arguments : none
, }9 U  K, t' p- `
+ @# g. i* ]2 Z5 V  In certain environments, there are components which will regularly connect to
: ?- @- Q7 R  |- A" v/ R, J1 g  various systems to ensure that they are still alive. It can be the case from3 e; o2 F2 s: P9 p/ n: @
  another load balancer as well as from monitoring systems. By default, even a8 V* {8 n1 c9 y# M0 ^8 c% I
  simple port probe or scan will produce a log. If those connections pollute- I: q+ z# }$ F5 _
  the logs too much, it is possible to enable option "dontlognull" to indicate
5 D; w# X+ X+ K( J  that a connection on which no data has been transferred will not be logged,
( o7 w8 A& v* [. n3 \  which typically corresponds to those probes.) m% O" @* U$ C! i% E, K+ e
- ~& t7 U) ~/ n/ R3 H7 U
  It is generally recommended not to use this option in uncontrolled
* i) S3 D! w( ]/ ^1 k  environments (eg: internet), otherwise scans and other malicious activities
3 ?7 y" A+ i: T( ?1 w2 c% f0 |$ `6 U8 C  would not be logged.' ?6 y6 m4 |( T. k& F& p# Z
  X7 P$ M' M- O$ D: \6 ~
  If this option has been enabled in a "defaults" section, it can be disabled
8 p2 Q8 v4 v/ C" a  in a specific instance by prepending the "no" keyword before it.
% V) R9 D/ ^  H2 s5 V0 e( k1 Y5 y2 a6 K+ ^* H4 Q, \7 ]( C/ n0 F
  See also : "log", "monitor-net", "monitor-uri" and section 8 about logging.
, }8 \$ t. ]6 c) H. j. x. ]' y5 Y$ \
! e0 q6 F/ {) u# Y. ?: t8 {
9 D' ?6 V) q* a0 u3 ~option forceclose
: Q2 E5 s  d7 u7 D, l* Bno option forceclose
+ L) C9 w' }, }" A9 X; k  Enable or disable active connection closing after response is transferred.% @7 d- S+ B! b+ A5 n
  May be used in sections :   defaults | frontend | listen | backend
" }  f$ H, [" I! t8 y! n. ^                                 yes   |    yes   |   yes  |   yes! I. x, g: b/ h9 c, U) X
  Arguments : none9 V4 D# r  ?  r2 z6 }3 `
- |# a7 i( s) l1 g0 E5 W
  Some HTTP servers do not necessarily close the connections when they receive- V0 S( O+ G5 I; I( U
  the "Connection: close" set by "option httpclose", and if the client does not; B- d, l! f+ e. C
  close either, then the connection remains open till the timeout expires. This7 _$ i( E. o4 A* n* j/ E
  causes high number of simultaneous connections on the servers and shows high0 G6 @5 g2 Y( A5 K% B0 T% M
  global session times in the logs.1 l: {% f: Y+ O  `# ?  Z

9 u* x4 Z: f% U3 \5 m" p6 r* f  When this happens, it is possible to use "option forceclose". It will
- V! B1 C! q* a: Q$ @  actively close the outgoing server channel as soon as the server has finished9 Z+ c) m8 A, k* I/ H8 A
  to respond. This option implicitly enables the "httpclose" option. Note that7 j/ h* ]' Q; E. ]
  this option also enables the parsing of the full request and response, which5 F+ x8 i8 I/ _7 g( @
  means we can close the connection to the server very quickly, releasing some# z( k3 |/ K) }5 @( q7 l+ y2 P$ y8 v
  resources earlier than with httpclose.
: G8 S2 ~: N# y$ q
& f: h  L- w! c! E& E4 u5 Q  This option may also be combined with "option http-pretend-keepalive", which
  y( S- K1 K7 d1 ^3 V. b  will disable sending of the "Connection: close" header, but will still cause8 d# m2 M) M7 s
  the connection to be closed once the whole response is received.: V' Y* D" ^, L) A* V4 w8 k: l0 N
/ i8 ~- K' }) g7 I) Q
  If this option has been enabled in a "defaults" section, it can be disabled
1 b" t# E" g* {* b  in a specific instance by prepending the "no" keyword before it.
6 ?6 ?9 n5 n/ ^  C/ W) ?
: h% Y% q8 ?6 Z" O9 h5 f  See also : "option httpclose" and "option http-pretend-keepalive"' j2 A" g" f* X6 |: f( e

. {* c( a+ T! B
, b. _& t5 ~$ m" h! u0 Coption forwardfor [ except <network> ] [ header <name> ] [ if-none ]  z9 S6 n) }) }* e* Q2 q2 a/ K6 I. p
  Enable insertion of the X-Forwarded-For header to requests sent to servers
/ M" v# u- c% i  t  May be used in sections :   defaults | frontend | listen | backend
7 s" `8 j/ a# T! a5 w8 ~- y3 E& l                                 yes   |    yes   |   yes  |   yes, h$ o5 E8 j/ h0 s8 H# F
  Arguments :
) \1 a4 J( C+ F$ ~6 W+ n- c( o    <network> is an optional argument used to disable this option for sources$ [4 r, f1 n- F
              matching <network>8 m- l% k3 O9 B( [. B! p; y
    <name>    an optional argument to specify a different "X-Forwarded-For", Y5 J- G. m, n' `- ^
              header name.
& @$ g% Z9 S: y# H6 U; y0 q' Q% Y! `) g, |. L  t: s! T
  Since HAProxy works in reverse-proxy mode, the servers see its IP address as) i$ V1 M4 f- d7 n0 u9 Y
  their client address. This is sometimes annoying when the client's IP address( T! K5 Z5 ^, e. z7 n
  is expected in server logs. To solve this problem, the well-known HTTP header4 E) \/ T2 q2 c. \: B, U5 N
  "X-Forwarded-For" may be added by HAProxy to all requests sent to the server.
  D  C2 @/ T! `  This header contains a value representing the client's IP address. Since this1 _) _9 }8 A& @
  header is always appended at the end of the existing header list, the server
, B. O; c  T7 y! q& c  must be configured to always use the last occurrence of this header only. See
% x% u3 G( u. X  the server's manual to find how to enable use of this standard header. Note( k: \8 C5 |9 u3 h( |3 G& |
  that only the last occurrence of the header must be used, since it is really, b4 O8 s$ Y6 u) S0 |* D7 l
  possible that the client has already brought one.  L7 P  _" k" a5 P

- h) D. c  ~; E. s( w  The keyword "header" may be used to supply a different header name to replace' ?5 Z1 G" m: Y- T" x3 r, e  v
  the default "X-Forwarded-For". This can be useful where you might already
9 h% I; R6 q% H  e  have a "X-Forwarded-For" header from a different application (eg: stunnel),
$ A& W5 D) J1 m5 H4 `" X  and you need preserve it. Also if your backend server doesn't use the8 k0 r1 }) G; d$ L, C% r
  "X-Forwarded-For" header and requires different one (eg: Zeus Web Servers
- j% l, P# W0 \  require "X-Cluster-Client-IP").
+ j) |# G& C% s' B$ E7 b- H8 k/ Y0 S. M9 V" b0 f
  Sometimes, a same HAProxy instance may be shared between a direct client
6 M+ ~0 `0 x5 p5 \  access and a reverse-proxy access (for instance when an SSL reverse-proxy is% U# }. u; ~% h
  used to decrypt HTTPS traffic). It is possible to disable the addition of the
2 v5 M& j( v! a$ p# ]  o  header for a known source address or network by adding the "except" keyword
( F& O5 e  D. i' f8 B, I  followed by the network address. In this case, any source IP matching the
, R% _9 l( v* M4 _5 \  network will not cause an addition of this header. Most common uses are with
+ {, c& W- H; Y# ]" ^  private networks or 127.0.0.1.
' {9 Y6 n+ V7 L9 G' l1 {( t$ x
; R# b3 o5 C1 C  Alternatively, the keyword "if-none" states that the header will only be# Q2 O% o$ U3 \1 D' p8 h( t
  added if it is not present. This should only be used in perfectly trusted: D1 A- w6 @  [  E7 ]
  environment, as this might cause a security issue if headers reaching haproxy* [2 ]) [: m% i
  are under the control of the end-user.
! |! ^+ ~7 B0 [9 O) b8 X9 v2 `) G* P
  This option may be specified either in the frontend or in the backend. If at% [. k3 l: [1 @6 ^( A) J7 [
  least one of them uses it, the header will be added. Note that the backend's
, V% G  q# |. m+ Q  J9 m& O  setting of the header subargument takes precedence over the frontend's if8 H' i! H7 U, j$ ]3 Z2 C
  both are defined. In the case of the "if-none" argument, if at least one of
1 m/ B! p% z9 I  g8 t  the frontend or the backend does not specify it, it wants the addition to be
  C. y( N/ y% X3 L+ L  mandatory, so it wins.
( p7 H! D* R# t: N$ [7 ^7 }
1 R6 A$ {/ u  O  ?! G' o/ r  It is important to note that by default, HAProxy works in tunnel mode and
, ?& b! P9 v/ u& t( [  only inspects the first request of a connection, meaning that only the first6 t2 R5 \  y5 Y0 ~1 q0 G
  request will have the header appended, which is certainly not what you want.- \+ C  p8 Z# X$ x- r
  In order to fix this, ensure that any of the "httpclose", "forceclose" or& G1 N: l4 }, m/ c8 V; A
  "http-server-close" options is set when using this option.
' v+ B) s& I  ?+ m& Y! N4 ?# c" Z& v; }+ s" L# m
  Examples :* ]2 ?9 x: h: f1 K& P1 T: [
    # Public HTTP address also used by stunnel on the same machine
" s8 z5 E5 Q( B6 {8 U0 k: r    frontend www
2 J) N$ ?5 K/ Y1 o" S: D        mode http
1 o$ J& z  @+ k        option forwardfor except 127.0.0.1  # stunnel already adds the header
: ?/ @" N; @: b- v
' u& \( W; X5 t/ Q9 f    # Those servers want the IP Address in X-Client( `4 f1 i4 @* N
    backend www5 Y) ]4 c( S7 d: t' m% K9 }, q+ D3 T
        mode http) H0 ?& B  Y0 |6 j9 K' l
        option forwardfor header X-Client& k& X# c& s7 Z+ i  l) `0 u

. J8 T& O8 b  E% P  See also : "option httpclose", "option http-server-close",/ K' v: K2 `, O* k
             "option forceclose"
' }3 w6 v9 y6 C+ Y: ?4 z; U) z- Y6 d( {5 m) q& v% ^

: S; i& A$ F# @  c/ boption http-no-delay; D& y$ Q) k4 N/ |
no option http-no-delay
0 C1 m( I& i' g5 \  Instruct the system to favor low interactive delays over performance in HTTP
; |  y1 i* e' v# a; M  May be used in sections :   defaults | frontend | listen | backend' ?7 d7 P2 N  _  X4 f1 [& A
                                 yes   |    yes   |   yes  |   yes
  u( c! }/ B$ n% M, m  Arguments : none
. `' ^; h& W3 ^0 K- R) l9 O' M+ X4 Z7 {; X  h5 n
  In HTTP, each payload is unidirectional and has no notion of interactivity.9 V- Q: @9 q/ l# R% ^" N6 V
  Any agent is expected to queue data somewhat for a reasonably low delay.
8 _. V# z9 R" L  g0 q  There are some very rare server-to-server applications that abuse the HTTP
7 ~: V+ }3 r, W0 U; T( H1 W  protocol and expect the payload phase to be highly interactive, with many
# t# F  g, j' j, R8 W( s" w# v  interleaved data chunks in both directions within a single request. This is- n0 \, ]$ F' O3 o% N
  absolutely not supported by the HTTP specification and will not work across* }( Y* F1 `' O, ?) a
  most proxies or servers. When such applications attempt to do this through8 t- ]1 ?$ U+ ?! [& d
  haproxy, it works but they will experience high delays due to the network8 h  ]& V7 ?, b5 Y
  optimizations which favor performance by instructing the system to wait for
6 L; H$ z5 t4 d1 \, |5 `6 O; w  enough data to be available in order to only send full packets. Typical1 n' C* S3 ~5 p$ S' G- x& |
  delays are around 200 ms per round trip. Note that this only happens with
" j) r! t* e# ~0 k/ o. ^3 t5 q  abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
! ~9 U8 C; w: i( h8 j9 _  affected.
4 M$ n% X, i0 ~3 |% C3 K: F. M3 k8 y6 z' F  |" x& e  z, n
  When "option http-no-delay" is present in either the frontend or the backend
% ?4 ?- f- b1 }2 D$ m  used by a connection, all such optimizations will be disabled in order to3 A4 G0 G; k. R6 O
  make the exchanges as fast as possible. Of course this offers no guarantee on
8 A$ B! i+ e5 _, g; S% E  the functionality, as it may break at any other place. But if it works via
3 O6 V' m4 Z* P/ D  HAProxy, it will work as fast as possible. This option should never be used" |5 A$ [  m( c
  by default, and should never be used at all unless such a buggy application$ h& M* c) r- S" Q2 P* o, M
  is discovered. The impact of using this option is an increase of bandwidth
) f& e5 M/ y. l4 U5 W) f  usage and CPU usage, which may significantly lower performance in high0 W% ]' G5 M, t% P/ U9 N; c7 [
  latency environments.
6 E# m6 f2 v" {" y
& [. F- D& Q2 R1 K2 S' ~6 v4 `6 b! t7 E. f* c7 u$ @
option http-pretend-keepalive
2 `% S" H  ^$ ?9 f4 h, E# Qno option http-pretend-keepalive
8 n* j& s8 o) j% J' U1 d. Q4 O; s& z  Define whether haproxy will announce keepalive to the server or not: p5 D2 H! {' n5 c& ^; z6 j- l
  May be used in sections :   defaults | frontend | listen | backend# V: E; i9 \3 A2 W/ N
                                 yes   |    yes   |   yes  |   yes
3 W" `2 l' k6 {% x  Arguments : none
* p4 \* Q7 V6 V
# l2 z4 @8 J7 ]5 _' q0 D% O, z  When running with "option http-server-close" or "option forceclose", haproxy
5 h7 a, h" d0 [9 ?. p6 m  adds a "Connection: close" header to the request forwarded to the server.0 r0 t& F9 s( l7 i4 z0 w; C
  Unfortunately, when some servers see this header, they automatically refrain/ u9 M" Q! @% i5 B7 `, n2 V
  from using the chunked encoding for responses of unknown length, while this8 I/ o' u* X! o* g
  is totally unrelated. The immediate effect is that this prevents haproxy from* \- k7 O% J- p* G. v& I
  maintaining the client connection alive. A second effect is that a client or
& Z" ~: B7 i& _( ?  a cache could receive an incomplete response without being aware of it, and( y$ i- z+ G, P# w' v% z5 b
  consider the response complete.
& ?1 m1 U& E) K/ L5 ]- t# K; u' _3 }' D7 N" {
  By setting "option http-pretend-keepalive", haproxy will make the server7 {9 w  Z$ l( I
  believe it will keep the connection alive. The server will then not fall back$ B, f" E4 v9 ?0 B  R2 l% ]
  to the abnormal undesired above. When haproxy gets the whole response, it* w7 D" O7 [* Y, ]  x
  will close the connection with the server just as it would do with the6 P' L1 ^4 Z( J. b& R
  "forceclose" option. That way the client gets a normal response and the
& {2 A- Y/ c" r2 j- Q3 `8 h  connection is correctly closed on the server side.
% q6 U8 l2 [% @9 X, e' |0 I; D4 j- \# ~% s4 T2 n4 ^/ O
  It is recommended not to enable this option by default, because most servers, ^  G$ n4 |$ f7 a% L
  will more efficiently close the connection themselves after the last packet,
) _2 J2 F, V; u0 j0 h: ^  L  and release its buffers slightly earlier. Also, the added packet on the; j0 a' `- g) U
  network could slightly reduce the overall peak performance. However it is
' e0 K& w5 A) F0 M  worth noting that when this option is enabled, haproxy will have slightly
5 q3 W# \: Q- ^6 V% S# g) ^: a0 G  less work to do. So if haproxy is the bottleneck on the whole architecture,
" n- s7 g# G6 \$ j" q+ K: E" Q8 q# u  enabling this option might save a few CPU cycles.. |" p& L1 ^3 `! Q8 l/ Z" E

% i' {3 f; \& {% n/ ?$ T7 A3 Y$ x  This option may be set both in a frontend and in a backend. It is enabled if
$ y7 b8 ^# l0 w  o* E  at least one of the frontend or backend holding a connection has it enabled.$ H, S* n; g. L6 p  `" c: J
  This option may be compbined with "option httpclose", which will cause
  I' a/ V7 C3 P  keepalive to be announced to the server and close to be announced to the
/ E/ R0 y# j5 U. e( G! Z$ s  client. This practice is discouraged though.
# Q, Y+ {/ Y4 h6 ~: r2 S# Q0 G$ u
: X9 g' R! _; Y3 [% e# L  If this option has been enabled in a "defaults" section, it can be disabled) w/ r, Z* _. P+ B  a3 P" g2 @
  in a specific instance by prepending the "no" keyword before it.
+ P$ d# s3 r& k6 e2 {! O0 k- d9 k5 A: t/ d7 ~; t3 O
  See also : "option forceclose" and "option http-server-close"4 E8 r% s8 L" F. G2 C
. R+ w: f# ^" A' N: p- s

! }1 }/ {# X7 J) f7 Voption http-server-close
, D2 p: c( _* Wno option http-server-close9 q3 H' c- k: T. g, t& J' _7 v: X9 v
  Enable or disable HTTP connection closing on the server side
$ Y7 F9 P/ D( ]) [  May be used in sections :   defaults | frontend | listen | backend
% C: j1 m2 Y; s& y8 _                                 yes   |    yes   |   yes  |   yes# e& n0 e8 q( r9 y7 [3 z# M* }, |+ l
  Arguments : none
) N9 X) V/ u3 J1 h% U) k/ d, H6 Q  D" a( e$ u/ q& A2 i  U
  By default, when a client communicates with a server, HAProxy will only. D5 _, X  X- j3 a
  analyze, log, and process the first request of each connection. Setting
: S/ W7 e' \6 `/ |  "option http-server-close" enables HTTP connection-close mode on the server) R' g" u. }. k2 h8 [% @0 f
  side while keeping the ability to support HTTP keep-alive and pipelining on! F' I# \# K% n$ z6 q, I7 _, Q
  the client side.  This provides the lowest latency on the client side (slow9 O& O5 S' l  {3 b, m) t  `( Y
  network) and the fastest session reuse on the server side to save server
6 u; B7 L! D: A" w  resources, similarly to "option forceclose". It also permits non-keepalive9 O3 h* `% Y4 }) k; ?6 L. D
  capable servers to be served in keep-alive mode to the clients if they
0 u/ Q" |8 J+ n. B8 I  conform to the requirements of RFC2616. Please note that some servers do not1 P' o  w# ?7 m' m; g! B6 Q
  always conform to those requirements when they see "Connection: close" in the
. q+ x& E/ y) r9 ]% Q: X2 n6 f5 ^  request. The effect will be that keep-alive will never be used. A workaround
8 ]% a2 [+ z' ~$ m% v4 M  consists in enabling "option http-pretend-keepalive".
6 ]$ z  o) Q  ?. B8 d
* X8 Q" m; D! t& u8 E  At the moment, logs will not indicate whether requests came from the same
3 L% \* w  x; N( R+ C) L2 _3 n6 C  session or not. The accept date reported in the logs corresponds to the end
& Q3 e% Y2 ^3 I- _8 U  of the previous request, and the request time corresponds to the time spent0 N3 G! A* u/ M' b$ r+ Q
  waiting for a new request. The keep-alive request time is still bound to the! [3 ]1 v" Y; p& Q
  timeout defined by "timeout http-keep-alive" or "timeout http-request" if
8 M; n' `5 _7 k& q3 Z/ j  not set.( O. K: f- L5 E' }2 ]! p
/ R3 R" \7 q6 I/ h
  This option may be set both in a frontend and in a backend. It is enabled if0 h# Z3 h0 d* U
  at least one of the frontend or backend holding a connection has it enabled.
3 N; m1 s9 m% c+ X1 L  A  It is worth noting that "option forceclose" has precedence over "option4 t9 r( n, k) _6 s3 P1 M9 e5 o
  http-server-close" and that combining "http-server-close" with "httpclose"
% X  x8 F) X2 `4 j9 \  basically achieve the same result as "forceclose"./ A0 o! V! N' s$ O4 N8 v

' [# ^$ \7 {0 m% ^! x1 J* w  If this option has been enabled in a "defaults" section, it can be disabled, ^* }* G- c4 J; ]3 I
  in a specific instance by prepending the "no" keyword before it.
5 Z- u: h2 d8 N; k; H
% b6 b, x: n- e/ L1 Z: ~0 ?  e  See also : "option forceclose", "option http-pretend-keepalive",
: Q/ x: a% i! X& l5 o2 m* [             "option httpclose" and "1.1. The HTTP transaction model".
% Z6 l" _4 m# A/ t0 ?) X; ]6 e( x2 c7 z4 Z9 c
+ S9 y) ~' z" E. m3 W' Z
option http-use-proxy-header$ T# _( J) \9 R
no option http-use-proxy-header: r5 R& y+ ^7 ^# e/ T
  Make use of non-standard Proxy-Connection header instead of Connection* N& t$ p$ b0 O) c; R" D* [
  May be used in sections :   defaults | frontend | listen | backend
8 ], L% v9 w- G( }  v: ]  z                                 yes   |    yes   |   yes  |   no
, n; l* ~" a" z$ Z  Arguments : none
) A% S2 T! h* {  J+ d. N
4 h3 u* d, M* y# w  While RFC2616 explicitly states that HTTP/1.1 agents must use the
0 m! f! n' z* Y1 g: c% u  Connection header to indicate their wish of persistent or non-persistent
* v$ t( P& V) s9 a: \8 y: f$ A4 E) d* G  connections, both browsers and proxies ignore this header for proxied
7 a  Q: F9 M3 C. B/ z+ ^$ V  connections and make use of the undocumented, non-standard Proxy-Connection" j% _# p" r- A' B3 W- y
  header instead. The issue begins when trying to put a load balancer between' `9 e* l) n) J- i, a3 y
  browsers and such proxies, because there will be a difference between what
; k) M  s& C+ t, J- L* @  haproxy understands and what the client and the proxy agree on.
, ?7 F/ {" d  T; `# t) ]* A: t" d3 ~) W" f8 z9 ^% t
  By setting this option in a frontend, haproxy can automatically switch to use
0 }9 n/ [! W# L! ~  that non-standard header if it sees proxied requests. A proxied request is+ U' o3 w& H$ i1 w" Y. a7 V! y
  defined here as one where the URI begins with neither a '/' nor a '*'. The' F9 _9 C" }. W% q# P# e
  choice of header only affects requests passing through proxies making use of
$ K% Y# K1 E* y! i4 K4 {2 e  one of the "httpclose", "forceclose" and "http-server-close" options. Note9 Z; z& I* W; b; a$ C( f% L
  that this option can only be specified in a frontend and will affect the
8 t+ R0 \% t, g& o$ \6 Z/ H) v( j3 j  request along its whole life.7 E) J" [  g8 i/ I/ d/ }( X
/ {: @" z1 R2 x% P5 m
  Also, when this option is set, a request which requires authentication will( E( u/ I, W! l4 I
  automatically switch to use proxy authentication headers if it is itself a
8 n  V% H" a% V. x' s- M! C# P  proxied request. That makes it possible to check or enforce authentication in" u9 y& d& x" U7 N/ w. `1 D
  front of an existing proxy.& L, n4 v. [6 B: R( }0 f" ~1 X5 E

5 x+ Y# Y/ r# c1 V  {' e2 K  This option should normally never be used, except in front of a proxy.
2 U4 w# `; Q9 m$ }" z& t, l: G* x( u1 W  g0 J
  See also : "option httpclose", "option forceclose" and "option
' w8 ]8 p) l% j! [             http-server-close".) R5 d" \. s9 Z; x& O
& s% r" O, ^. N, `5 a! R

6 _( o! M5 P8 ?: Z# m$ c( |. poption httpchk
$ O. N  p. z5 A7 ]3 Q7 e( hoption httpchk <uri>* q. w" h& M, H" Y/ f* ~
option httpchk <method> <uri>
: K; L$ t  O2 _7 [+ u/ qoption httpchk <method> <uri> <version>
) Z! z% u' k1 D- {  Enable HTTP protocol to check on the servers health
$ d  }' B1 J% y% M  May be used in sections :   defaults | frontend | listen | backend# z: O  t# H$ \7 g7 T
                                 yes   |    no    |   yes  |   yes, A3 _. f* A) J  J: g
  Arguments :4 v' _; S8 O9 q
    <method>  is the optional HTTP method used with the requests. When not set,
6 j$ f8 C. y/ p* Q2 ]              the "OPTIONS" method is used, as it generally requires low server
. @: d% e, w0 ^1 _( X7 M              processing and is easy to filter out from the logs. Any method
7 b, a: o$ p, }9 |0 |' E7 W              may be used, though it is not recommended to invent non-standard
7 Y* U$ Z  q8 W2 k; l+ w0 j              ones.
8 x+ @+ F  m0 z* A2 ?6 p# x0 G0 y) R* ]' ]! H
    <uri>     is the URI referenced in the HTTP requests. It defaults to " / "0 l2 r/ G( t- t. z7 Q# R/ P9 P
              which is accessible by default on almost any server, but may be9 Y/ y3 M7 g6 S* C$ w& \1 m7 m
              changed to any other URI. Query strings are permitted.
) V  R$ L# S; Z
1 x8 A; c  V$ y9 O0 c    <version> is the optional HTTP version string. It defaults to "HTTP/1.0"
5 `, h$ I. X; t8 _, w6 t) B- M# g/ Q              but some servers might behave incorrectly in HTTP 1.0, so turning, R9 N4 i  U* D
              it to HTTP/1.1 may sometimes help. Note that the Host field is
' T, W# T& C2 e' W& G- \% f              mandatory in HTTP/1.1, and as a trick, it is possible to pass it
3 X  ]$ ]( O* X/ i+ M% [              after "\r\n" following the version string.
; b" b. ?) X9 V5 L3 U* S9 ?& Y. B2 x% p7 l& u% Q
  By default, server health checks only consist in trying to establish a TCP- c/ `, L9 Q0 ^3 w
  connection. When "option httpchk" is specified, a complete HTTP request is
( F1 P" N5 v- G8 m) h" `  sent once the TCP connection is established, and responses 2xx and 3xx are+ b2 C4 `' v+ J  a
  considered valid, while all other ones indicate a server failure, including
; c* L7 f+ K7 k& t. D  the lack of any response.
- @8 D. m9 y9 Q' J& c% H7 b$ L4 c) |4 v/ r# E9 m& k
  The port and interval are specified in the server configuration.
1 g. U" F* x+ ^2 c/ S. t( J  C! y8 y
  This option does not necessarily require an HTTP backend, it also works with
& g8 L  S$ N' G+ r" K  P: |" ]4 p  plain TCP backends. This is particularly useful to check simple scripts bound. x( Y' e" ~& ]/ E+ Z
  to some dedicated ports using the inetd daemon.
3 v8 w( S8 b) `- I5 E+ y
* ~7 U, N7 z" |2 c. b6 [  Examples :! [" Y* W1 L, {2 B# y' F
      # Relay HTTPS traffic to Apache instance and check service availability; c% [; [. j# g& d+ l* \  m
      # using HTTP request "OPTIONS * HTTP/1.1" on port 80.
7 B% r  C: c6 J6 P( N$ n      backend https_relay3 X: N9 J# s$ }$ Q8 t8 e5 T! V
          mode tcp
; g; O3 O0 S5 p# m7 o          option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
8 T$ s/ E: V* |. g2 r- I( `          server apache1 192.168.1.1:443 check port 80
; u4 Z; ^- U5 o- A. `$ \% H) u6 s% K- `# t4 Y! S3 @; [
  See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
. e$ [! {% d% {- A" _  |             "http-check" and the "check", "port" and "inter" server options.7 v  K, ]7 r- |0 O
2 J' Q! q4 p# t4 ~. }; O, |
$ {; \$ w' F+ b: M( m
option httpclose! ?# h) w9 f2 L
no option httpclose( ]9 s. o8 ?7 Z. T+ o
  Enable or disable passive HTTP connection closing
) }; v% e. I+ {8 ]  l) w! c  May be used in sections :   defaults | frontend | listen | backend# Z" Y! R7 g, E5 N$ h
                                 yes   |    yes   |   yes  |   yes# @9 K/ }7 y$ U  ]" Z, p: w6 m0 Q
  Arguments : none# Z$ V" C1 i4 ]6 u- M: M

7 [/ c0 I6 d0 V! \) ]  By default, when a client communicates with a server, HAProxy will only4 i5 m6 Y9 m' Y( {$ Z
  analyze, log, and process the first request of each connection. If "option6 d; `  n9 `+ b2 k/ c. T4 n
  httpclose" is set, it will check if a "Connection: close" header is already
; E  r7 U8 z9 J( k: R) F0 ]  set in each direction, and will add one if missing. Each end should react to# J0 S- I$ t( _$ F0 L- y
  this by actively closing the TCP connection after each transfer, thus  L+ M3 I7 s0 Z  l1 L( L2 `" V
  resulting in a switch to the HTTP close mode. Any "Connection" header) V$ N: c. i2 Q* Z, I8 Z
  different from "close" will also be removed.& X; A$ O! {- I; y3 Q+ q. Z9 b: M
# U" Y% ^% e8 [3 U; E1 o% P2 Y
  It seldom happens that some servers incorrectly ignore this header and do not4 U. g/ N" s( b& i, N! H
  close the connection eventhough they reply "Connection: close". For this
' l. ?$ N! ^/ i9 ^1 {5 N) b  reason, they are not compatible with older HTTP 1.0 browsers. If this happens9 c  a# G2 y/ q1 u/ K
  it is possible to use the "option forceclose" which actively closes the
' t1 q8 v, r9 ]4 ~7 Z' R  request connection once the server responds. Option "forceclose" also; f1 L# G7 F) Y7 y2 Z9 Q
  releases the server connection earlier because it does not have to wait for
8 t  R: K2 M; [! A. K, z* U' ^$ z  the client to acknowledge it.4 h4 x; x9 v# O( T/ D# g; J

. E3 Z: T4 d0 n0 U  M/ M! G7 }+ u  This option may be set both in a frontend and in a backend. It is enabled if- ]" ~' C* {% ~& @' F9 G0 Y( v
  at least one of the frontend or backend holding a connection has it enabled.
, K' Z) W# Y7 e6 L8 ?  If "option forceclose" is specified too, it has precedence over "httpclose".' j& D( X0 V! ^3 z' \' `
  If "option http-server-close" is enabled at the same time as "httpclose", it) F+ P0 [) R) b
  basically achieves the same result as "option forceclose".
. n) t7 E' p0 K! [3 _. F. r, Y
" O. Z7 N' E- `7 J+ q" u  If this option has been enabled in a "defaults" section, it can be disabled
6 A9 Y: _* g" q0 z  in a specific instance by prepending the "no" keyword before it.; J0 B) R, n$ x& b; g# C( ?! G8 L8 D
; E  V  V/ i+ k
  See also : "option forceclose", "option http-server-close" and/ P) A% R2 @$ M+ Z- I
             "1.1. The HTTP transaction model".. L" z* q) y1 e, P% V) q3 X
, I1 ?& S: V, E6 E0 q7 h' x

. ^$ d/ O3 {+ J2 K+ ]- \option httplog [ clf ]& U5 ~: \6 W" y+ L4 G6 B: o* @& d0 \9 G
  Enable logging of HTTP request, session state and timers# J: t) p2 R% X  r# \
  May be used in sections :   defaults | frontend | listen | backend
+ d2 v' Z' n* M' }, C                                 yes   |    yes   |   yes  |   yes# q% t7 [/ T0 R) m0 i+ c
  Arguments :
1 o" q* i* j+ @$ o9 J3 |    clf       if the "clf" argument is added, then the output format will be/ y+ s; Q, z; T
              the CLF format instead of HAProxy's default HTTP format. You can! q  ], R" }& B& q& Y
              use this when you need to feed HAProxy's logs through a specific$ C' a3 {3 s0 q  M0 B- J
              log analyser which only support the CLF format and which is not
! e5 C6 b& L5 O" j$ c5 |& s              extensible.
7 B9 q. f* B! @2 s8 _& t! ~9 e' J1 `8 ?: a
  By default, the log output format is very poor, as it only contains the# I7 C: z3 y1 W4 D! U
  source and destination addresses, and the instance name. By specifying/ X' j5 i! Q9 ^' m
  "option httplog", each log line turns into a much richer format including,
: S, _7 _9 L3 a1 X, c  but not limited to, the HTTP request, the connection timers, the session" `& B- P# U5 `9 x2 q; \2 q
  status, the connections numbers, the captured headers and cookies, the8 Q& \, Y( t5 U+ m& _
  frontend, backend and server name, and of course the source address and1 q, T  [( D" r0 Y, O
  ports.
$ C/ B) p- `; G; N  O$ w& C! s' m
% s3 n5 p+ @2 i* A6 ]: x  This option may be set either in the frontend or the backend.) H% w9 p  A( E5 n: J( K

  {5 i8 j7 D7 Q  I- q: A: P: z  Specifying only "option httplog" will automatically clear the 'clf' mode. Y3 m! @/ I% ?! `6 v
  if it was set by default.1 Q! J1 i0 Z5 j4 M& H: Z  t' Y

  n5 _$ Q2 T7 D9 y- E  F- @  See also :  section 8 about logging.; {2 d' U: {* w0 N# Q* ~' n, [
. A. T* A# x- Z0 ]/ d: x( d

. h) F$ Q; [$ Y* G5 a9 boption http_proxy
+ [4 q, H! ?6 ^- u9 X( R2 A* ?no option http_proxy& ?# ]. u& V( d0 ?7 P
  Enable or disable plain HTTP proxy mode& n; F+ w2 v0 s
  May be used in sections :   defaults | frontend | listen | backend
4 c/ D3 j( T6 M* o' n5 N                                 yes   |    yes   |   yes  |   yes7 ?7 I5 B7 @0 t2 L
  Arguments : none& U! }- Y9 B3 l  u/ o
, w/ ~5 H8 [' E, H! P
  It sometimes happens that people need a pure HTTP proxy which understands8 j7 C( |) b8 z, I, Z" y
  basic proxy requests without caching nor any fancy feature. In this case,9 c' X6 k; _5 f, p& ^8 n
  it may be worth setting up an HAProxy instance with the "option http_proxy"
- Z# e3 o! t7 B1 c8 t; O7 z- g  set. In this mode, no server is declared, and the connection is forwarded to& V' I+ A0 y( Q' t( H
  the IP address and port found in the URL after the "http://" scheme.5 _& I& \2 V/ q) r. a, [5 T1 v

) G7 O5 ~2 B" f  No host address resolution is performed, so this only works when pure IP: u; ~. P$ E0 ?& a
  addresses are passed. Since this option's usage perimeter is rather limited,
& ~/ x$ \4 S& S2 u  it will probably be used only by experts who know they need exactly it. Last,
0 Z, F; z2 e. G, \& C  if the clients are susceptible of sending keep-alive requests, it will be
( v& j' N9 z5 Z& n) Z/ J1 V, U  needed to add "option httpclose" to ensure that all requests will correctly! d$ f( I7 Z- i8 M
  be analyzed.
0 g4 @7 C% D5 o5 `' O* M4 s' d& R0 j- {8 ~
  If this option has been enabled in a "defaults" section, it can be disabled/ c' G1 X# T. {& ^; m
  in a specific instance by prepending the "no" keyword before it.- b' t* A/ t+ P" }- N9 G
; }, n1 B. y( Y- K5 y, j  C, U
  Example :
& c2 P0 j) I2 A; S; |$ h    # this backend understands HTTP proxy requests and forwards them directly.
+ h' `1 Q1 Q/ [8 G* w9 ]    backend direct_forward5 w3 P$ t( h% s1 b
        option httpclose
- ^* p8 b% |4 P# H: j4 t* s+ D        option http_proxy+ y4 p& a2 a: v% n2 k6 a6 E

. c4 L' p* E0 H  A( d- Y$ q  See also : "option httpclose"6 @8 w) [2 Z* C& h" W5 R& \$ r7 t* A; Q
/ u; K" ]# f  t) J5 W
4 K- i8 g8 V7 f/ \/ H- }3 L
option independant-streams
" e+ `9 h1 ]$ x1 O3 Z- q% ]no option independant-streams
5 b3 E, x  ^  y% Z+ f  Enable or disable independant timeout processing for both directions6 @5 j9 o: g+ ?5 {) J. Y3 k3 B
  May be used in sections :   defaults | frontend | listen | backend
6 K* J, e" q; Q  F                                 yes   |    yes   |   yes  |  yes
) h* s, `" p; t+ B$ E6 V$ J& \! v  Arguments : none/ \; J2 g5 E: F9 @5 Q
5 ~$ y2 N# R" ^0 K0 Q2 {+ `7 ?  W
  By default, when data is sent over a socket, both the write timeout and the$ f5 o' z/ s2 Q  K8 w
  read timeout for that socket are refreshed, because we consider that there is$ ?1 p$ w( E3 y" I
  activity on that socket, and we have no other means of guessing if we should  j3 d0 H* Z' u, B
  receive data or not.
! ~( e, L( H5 b/ `% t* h0 V% D& \& n! _' X8 c! R; |
  While this default behaviour is desirable for almost all applications, there& g5 |% r) [" V: y" K# x
  exists a situation where it is desirable to disable it, and only refresh the: T8 r0 {! K1 }) m9 h
  read timeout if there are incoming data. This happens on sessions with large
  e8 B6 O3 J- l  timeouts and low amounts of exchanged data such as telnet session. If the5 ~  _2 w# Y+ C5 A" V9 S
  server suddenly disappears, the output data accumulates in the system's% J# x' U0 N' v' |( k+ r; u5 ]
  socket buffers, both timeouts are correctly refreshed, and there is no way- \- H% b2 H1 U
  to know the server does not receive them, so we don't timeout. However, when
; D( `) I! S4 h2 z7 O# s1 w' a  the underlying protocol always echoes sent data, it would be enough by itself
* M# ]# D& @. M% t/ \  to detect the issue using the read timeout. Note that this problem does not
: t, x/ {9 |/ ?, Y$ r# r  happen with more verbose protocols because data won't accumulate long in the
( W1 r' y7 |$ Q) N! A, Q9 E' f9 T  socket buffers.
4 I! u; y- `& o/ @: B, d3 f% Z3 k. k1 C& y/ j
  When this option is set on the frontend, it will disable read timeout updates
. ]# b, ]( d9 \- X  on data sent to the client. There probably is little use of this case. When3 Z# p; m$ x6 E
  the option is set on the backend, it will disable read timeout updates on1 P9 f0 I: ~9 C/ q8 p% l3 Z
  data sent to the server. Doing so will typically break large HTTP posts from4 _8 |2 m' g4 H4 \, ?# v
  slow lines, so use it with caution.; X7 w, ?" G7 T9 D: n! f1 q" I

- J5 r. J0 c9 {6 t/ |5 M  See also : "timeout client" and "timeout server"
2 D0 f' @/ r; k9 Z' c& i2 S- V8 t( R. s$ p2 n' t) c5 W) R
( k' @9 M6 ~. }# V% V/ b0 r
option ldap-check
# a8 ^9 I& x% L: ?$ C  Use LDAPv3 health checks for server testing
3 l' y3 L3 a6 K( g; g  May be used in sections :   defaults | frontend | listen | backend! U; M2 u- X" c+ f4 _3 t# s- s
                                 yes   |    no    |   yes  |   yes
$ q. M7 s8 Z2 K: @  Arguments : none. G$ K% u5 o  a+ s, {1 q8 }' B
+ x5 w# G/ k9 b
  It is possible to test that the server correctly talks LDAPv3 instead of just" O- m4 X, d# J" J9 `! R5 g. d# K
  testing that it accepts the TCP connection. When this option is set, an, `5 O6 h* |& V" k
  LDAPv3 anonymous simple bind message is sent to the server, and the response
# _; w3 ?; J$ K0 D7 ~  is analyzed to find an LDAPv3 bind response message.
5 i- W% N7 r# F. n: u/ Z  H+ V2 G
) i  ]& I* X) M  The server is considered valid only when the LDAP response contains success
$ x1 W7 _* H1 w+ W  resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).
. I, k* p* l4 i1 r6 e. w
& d, {) N  c, R$ ]# x. `  Logging of bind requests is server dependent see your documentation how to' r% F1 h, y6 b7 ?) P+ u
  configure it.
& }( t, v& Z. s! m
: N4 x) }% g8 T4 x) {( J! Q2 }  Example :
1 N" ?4 O' H) w0 n+ B        option ldap-check& l3 m3 |) }' v: u6 c! r. `/ |
: Q* J" B+ D3 j: A1 [
  See also : "option httpchk"
% ?5 Y8 i# L# O
+ S2 B% C5 I: o# Q+ k# V& i& e1 M$ l, ~
option log-health-checks+ T: K7 P& ?9 E
no option log-health-checks$ K$ s$ [7 r  n% |3 \6 ?
  Enable or disable logging of health checks9 N" |: a+ N! C0 k
  May be used in sections :   defaults | frontend | listen | backend" R; Z1 D2 z) j, L* r6 \+ k
                                 yes   |    no    |   yes  |  yes
6 S6 @- }" c. g" `: L4 Z/ h. X, h  Arguments : none' K$ P+ a' C" _: K! |

+ n0 u4 B8 Z8 Y. Z5 @# t  Enable health checks logging so it possible to check for example what- f2 Y6 ^% N4 T. i" o+ `9 R: N
  was happening before a server crash. Failed health check are logged if
/ B. P. ], q/ i4 |  server is UP and succeeded health checks if server is DOWN, so the amount9 b+ P% Y' }8 _8 F
  of additional information is limited.& Q5 e( C3 z: M. `4 I0 U

! f* y0 n* Z4 K" A) B  If health check logging is enabled no health check status is printed
$ |4 P+ w; p8 }) T  when servers is set up UP/DOWN/ENABLED/DISABLED.
% Z6 p% x: A) G! O  W/ C. m) V0 |7 s" K3 \' C9 u6 M( e
  See also: "log" and section 8 about logging., ?6 \! i& q- H5 P
: B, R; _7 G2 K* Q/ w! B
) U1 A2 Q+ E& _+ V5 L5 E2 |% _8 q: M2 @
option log-separate-errors% {2 \* v: R4 D3 H1 ?
no option log-separate-errors8 H2 L/ D& h1 S! ]
  Change log level for non-completely successful connections
' C' b- g: u/ ]" Q  May be used in sections :   defaults | frontend | listen | backend) o0 u& g$ K) j  D& Y: d9 K# ]
                                 yes   |    yes   |   yes  |   no
/ ~- Q4 C8 V$ B" c2 \( g  Arguments : none  @9 R/ f" S% I8 G. _" m

1 Z* J9 o* N% H6 j- y! R  Sometimes looking for errors in logs is not easy. This option makes haproxy+ A. C) o. e# _" d- T: U
  raise the level of logs containing potentially interesting information such
% ^- D4 N4 s* w" H+ N  as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The. n' o* d8 O2 i/ j
  level changes from "info" to "err". This makes it possible to log them
0 L# o" j; D) V  separately to a different file with most syslog daemons. Be careful not to9 e3 N  ^, l# a$ h! F0 N8 R
  remove them from the original file, otherwise you would lose ordering which
  o- u8 E, w$ s& C' w4 R) g0 D  provides very important information.
! {' G% [: K0 ~. W# e- `6 \' T
3 [1 {: k( p/ Q( z  b' i  Using this option, large sites dealing with several thousand connections per
: m& ]" l8 s5 O  second may log normal traffic to a rotating buffer and only archive smaller
1 w' c1 b* f. l5 b$ f9 i  error logs.- K6 z+ I) V9 s2 F6 \# M4 }9 I+ z

( H0 a* N5 h2 |8 p% \% e  See also : "log", "dontlognull", "dontlog-normal" and section 8 about% H* @2 D7 S3 z4 E6 e5 m
             logging.
! ]: ]0 V( p' w; J3 ^4 u
0 L9 n* K) A: n3 j, c/ g: g$ a& u; r. l' g
option logasap
2 W  V. [+ G% m2 ~no option logasap
" x4 C' _4 m' S- D( F: K' ^# C3 u6 a  Enable or disable early logging of HTTP requests
) F. T6 ^' p7 ]* l* Y' P* {4 F* V  May be used in sections :   defaults | frontend | listen | backend
, D$ e" G. s# A! U' X5 J                                 yes   |    yes   |   yes  |   no
- Q' n7 ^; ^$ Y  Arguments : none) L, H9 D# [, B

# {& T( O, E3 A+ n! i  By default, HTTP requests are logged upon termination so that the total2 W0 ~) y% P+ h/ F
  transfer time and the number of bytes appear in the logs. When large objects
, c  b4 @! y% t; p$ _  g  are being transferred, it may take a while before the request appears in the# f# r& I5 x1 w, y
  logs. Using "option logasap", the request gets logged as soon as the server; ~" b- s- U# L& f
  sends the complete headers. The only missing information in the logs will be* m- K" g; v- F) b; l- L6 }
  the total number of bytes which will indicate everything except the amount, c( t- s/ _+ p! U, l
  of data transferred, and the total time which will not take the transfer
6 O4 L, r# c+ l9 m+ O* b- _  time into account. In such a situation, it's a good practice to capture the' n% \! g4 k: p5 T- q0 b
  "Content-Length" response header so that the logs at least indicate how many# z9 g# F2 \$ \0 C$ a. x
  bytes are expected to be transferred.
( K8 z- N" S1 f; X+ ^. I
9 i3 X  ?4 P# r6 u  Examples :
; S& g6 l, V' p' w! [      listen http_proxy 0.0.0.0:80
  `% F% q( T- i# S9 s          mode http
* R& i$ R. \. e& @          option httplog1 g( M& a  h) ?  K% F3 m
          option logasap5 x3 \# P0 H1 p; x: G) i0 `
          log 192.168.2.200 local3
4 N; h) j! v: O0 `% x( G- B
: Q% a5 m0 a. ^3 a& `4 h2 e1 `  J/ F    >>> Feb  6 12:14:14 localhost \
" S1 y7 l2 z( g7 Y  N# [- h# ^) C          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \1 u! F( Z* {8 ^3 `7 r0 e
          static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \: f# m  F& b% w. x
          "GET /image.iso HTTP/1.0"
4 }1 F, t/ Z2 ~: x8 E5 e  U% O9 C' t$ U! ~4 x
  See also : "option httplog", "capture response header", and section 8 about
; E$ q, y6 x% V+ z, l             logging.
; f# H# Y6 c, y# W4 J6 Q# d- z7 W0 u, d2 E* t8 Q

3 m9 a  \8 H0 u- z& uoption mysql-check [ user <username> ]* K; h8 X9 a. R8 v6 ~: X- B6 S
  Use MySQL health checks for server testing) F9 |: W9 i- P9 ]8 g" G' {
  May be used in sections :   defaults | frontend | listen | backend
7 x; I+ h& `5 E8 ]3 {  F                                 yes   |    no    |   yes  |   yes! F+ j- G* `: f& f  K
  Arguments :# n, o) Z3 Q! V# g) g3 o
    <username> This is the username which will be used when connecting to MySQL
+ K$ _& Y1 r8 x: T. G, a               server.  j5 \$ r! E6 ^0 g( z

3 y6 N6 x; Z. O9 P3 u! q. H  If you specify a username, the check consists of sending two MySQL packet,
% l6 r% `+ M$ f) w  one Client Authentication packet, and one QUIT packet, to correctly close
& b- c1 M/ v8 v( ?  q% a! p$ i  MySQL session. We then parse the MySQL Handshake Initialisation packet and/or
, `3 v, g  v% P3 P  Error packet. It is a basic but useful test which does not produce error nor
; s) p( a9 w$ n' B, t0 {, X3 G' U  aborted connect on the server. However, it requires adding an authorization) n4 k" N8 V3 L: }. }% k, `. k4 k
  in the MySQL table, like this :
: F9 ~: C* }% f
1 B' m* l6 b4 _0 ?, }      USE mysql;
* x) G( _& y3 H) H: F( n      INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
6 \9 Q: S) N# }7 i+ X      FLUSH PRIVILEGES;+ R% [7 h( S9 M7 n* u0 E

) m2 M1 Q. d& m  C; ?6 V7 F; J2 E0 D  If you don't specify a username (it is deprecated and not recommended), the
/ t+ Z5 S2 h: K. D0 u  check only consists in parsing the Mysql Handshake Initialisation packet or, i9 [# G7 l. v; k4 r& B
  Error packet, we don't send anything in this mode. It was reported that it5 u& s- j7 [6 T; @0 m2 W4 |
  can generate lockout if check is too frequent and/or if there is not enough
' k& U8 |3 C6 Z: f  traffic. In fact, you need in this case to check MySQL "max_connect_errors"
; T* ~( F, K- Y# R. Z  value as if a connection is established successfully within fewer than MySQL
% ]" T% v! \) b) d  "max_connect_errors" attempts after a previous connection was interrupted,+ w% J* D) ~+ D. d, `0 h
  the error count for the host is cleared to zero. If HAProxy's server get' T0 d% a4 w( f+ O+ E/ y
  blocked, the "FLUSH HOSTS" statement is the only way to unblock it.
9 h- m5 `9 K2 y& ]+ X7 z) g" c5 R+ S4 X! W  G8 _' L# v
  Remember that this does not check database presence nor database consistency., L2 u6 l' m% _+ `3 h
  To do this, you can use an external check with xinetd for example.
3 U7 y. [" [% |+ v4 o1 L$ ~: X! R! h# \) f* j0 p' _- @( w
  The check requires MySQL >=3.22, for older version, please use TCP check.* d3 a9 \5 d# A: [

- c5 O  G2 l( _  Most often, an incoming MySQL server needs to see the client's IP address for  o$ _: o# z; T( o! a/ _
  various purposes, including IP privilege matching and connection logging.
4 F0 i, v" V- {  When possible, it is often wise to masquerade the client's IP address when
1 r; E8 v) I4 B( i5 Z, {  connecting to the server using the "usesrc" argument of the "source" keyword,
5 }9 L8 x: A( D  which requires the cttproxy feature to be compiled in, and the MySQL server
# X6 e# t% P8 n1 j% Y8 ?  to route the client via the machine hosting haproxy.
/ B0 A$ Z' U: ~- Q0 @& O  k0 I  X  H3 a
  See also: "option httpchk"
' u9 B8 L3 {+ L: Q. A' ?
0 q0 ^2 O+ z' M3 h" Q% N; c! @( t7 [" v
option nolinger& b) F5 ~* h; j$ \9 n3 G$ E
no option nolinger4 @: @* Q4 a1 l! \3 p
  Enable or disable immediate session resource cleaning after close
- {( Y: D- v" ^! N6 W  May be used in sections:    defaults | frontend | listen | backend
4 p+ }/ A' L  r& E+ @8 i                                 yes   |    yes   |   yes  |   yes
" B( e" \3 `8 O9 [# a6 P5 ~6 L9 d  Arguments : none( V# v0 I+ ]$ ]3 b1 S9 W  B- b" Y7 F6 p, W
& I1 B2 K" S' r( |+ B. @, k
  When clients or servers abort connections in a dirty way (eg: they are
1 v9 E  B  L& Q1 _2 @  physically disconnected), the session timeouts triggers and the session is/ Q+ L- H& ]4 U8 T' q1 @. u
  closed. But it will remain in FIN_WAIT1 state for some time in the system,
  Z8 O1 o8 A. j. h% Y' P2 P  using some resources and possibly limiting the ability to establish newer/ ^) G! K( N6 I& o! q
  connections.
6 ^& D) G0 _' I% _# r
6 J7 Q- J2 }7 J9 F/ m7 z, U8 S  When this happens, it is possible to activate "option nolinger" which forces
8 R4 i# `. Q3 v) Q9 l  the system to immediately remove any socket's pending data on close. Thus,
7 y) |3 e; q1 [/ w  the session is instantly purged from the system's tables. This usually has+ ^% S  G) Y7 l
  side effects such as increased number of TCP resets due to old retransmits4 L# ~6 [5 p8 v% h* j/ |' l: ?
  getting immediately rejected. Some firewalls may sometimes complain about
% Y4 H* H: F2 w: i& y/ M% {  this too.6 I# l; p2 B$ b& P9 K& c
& m" M4 Q7 P8 u( K+ B) M8 r- Z
  For this reason, it is not recommended to use this option when not absolutely) M2 E0 G# O& r' i
  needed. You know that you need it when you have thousands of FIN_WAIT1
+ b2 l8 M0 g& u% a* _& ^% q5 R/ F  sessions on your system (TIME_WAIT ones do not count).5 T6 J7 X8 ~8 e( {% Y

6 [' e0 Z  _5 K, q. M% b  This option may be used both on frontends and backends, depending on the side
! ^) D9 C* M( x5 j& d" _% M) j& {  where it is required. Use it on the frontend for clients, and on the backend
% t% |3 z. r9 w  for servers.
2 R6 m4 R& r2 x* p$ a7 d' Z6 K. p4 o9 j6 \1 ^* ~
  If this option has been enabled in a "defaults" section, it can be disabled9 ^% x6 ?* I! b5 p- P; y
  in a specific instance by prepending the "no" keyword before it.8 r5 ~6 ~* X" f1 t: G
5 w' c* V' }  X# b

0 F: R2 Q/ w8 z6 `1 S0 `, {: poption originalto [ except <network> ] [ header <name> ]
+ G' K: }# m! g7 Y/ F+ X& [: m5 t  Enable insertion of the X-Original-To header to requests sent to servers
9 Z- p" Q5 ~9 u  May be used in sections :   defaults | frontend | listen | backend& j; c, F% ~% T0 v  w% n0 F6 ?
                                 yes   |    yes   |   yes  |   yes
6 t6 Q; {- K( V: ?, k  Arguments :5 p7 o+ I4 q# t; T1 y$ J8 E1 Z- `
    <network> is an optional argument used to disable this option for sources
' ~/ D( u6 w) t1 c  p6 u              matching <network>
2 l" W( R1 Y: ~    <name>    an optional argument to specify a different "X-Original-To"5 i1 p6 {+ b0 Y
              header name.
- [) d, e4 y8 C: @, W* Q, l& K- n1 j9 ]9 y/ R  Y# F
  Since HAProxy can work in transparent mode, every request from a client can
1 z& \, X( W% ]) @! F  be redirected to the proxy and HAProxy itself can proxy every request to a' v% R. R2 v1 J# k
  complex SQUID environment and the destination host from SO_ORIGINAL_DST will4 F- c5 X* G; y4 J/ Y
  be lost. This is annoying when you want access rules based on destination ip( w/ r3 [6 U! H9 @7 u+ o8 f- e% O. d
  addresses. To solve this problem, a new HTTP header "X-Original-To" may be+ [9 h+ X" g. ~& ~' h0 d8 t2 z
  added by HAProxy to all requests sent to the server. This header contains a
! _' X5 |/ P/ R$ S3 Y  value representing the original destination IP address. Since this must be
' w( z  m& ~8 ?" K, |% E+ x" O& z  configured to always use the last occurrence of this header only. Note that
- W, O5 w( C2 P7 O# h# v* N  only the last occurrence of the header must be used, since it is really
/ I1 W& q- C9 r+ v' X& Y9 p  N0 }  possible that the client has already brought one.
: s! g( [; }" ]* a
+ p, K3 H# J5 O4 p* R5 V( `, U' y  The keyword "header" may be used to supply a different header name to replace# \$ l% b3 g6 _+ W+ ^; V  n& G! t
  the default "X-Original-To". This can be useful where you might already
" F0 V, n# f. V. X  have a "X-Original-To" header from a different application, and you need
7 I# `9 l- Z0 g2 ?, n  preserve it. Also if your backend server doesn't use the "X-Original-To"1 c2 ^, A/ l( l
  header and requires different one.4 ]/ }  t6 x% z

! b1 D2 o! s4 H  Sometimes, a same HAProxy instance may be shared between a direct client
5 \' `2 K' S1 O0 `  access and a reverse-proxy access (for instance when an SSL reverse-proxy is
2 w: Q; N: _7 k' G; r1 @  used to decrypt HTTPS traffic). It is possible to disable the addition of the
( L( L  ]; {  h  header for a known source address or network by adding the "except" keyword. h. G/ e: A+ @" B* q6 ]( U
  followed by the network address. In this case, any source IP matching the
6 F; U  m  X7 W: u- P/ M" J  network will not cause an addition of this header. Most common uses are with2 Q! i. r9 b) A8 N
  private networks or 127.0.0.1.
( f  X/ E$ I8 H% L( D9 \  k2 v- K+ M4 g4 j4 x+ j- f' t
  This option may be specified either in the frontend or in the backend. If at
. N( J5 L* P9 @6 {$ V" h  least one of them uses it, the header will be added. Note that the backend's
2 h* y$ X- ], _/ y# J- y  setting of the header subargument takes precedence over the frontend's if
0 s7 y$ i' D" S  both are defined.( B) x, m4 C' q
! S( J/ }8 x2 M: h7 O" N
  It is important to note that by default, HAProxy works in tunnel mode and0 q) s6 R; ?7 `* M+ D6 l
  only inspects the first request of a connection, meaning that only the first( w4 @6 ^9 y0 [2 z5 Z" h' e. Q
  request will have the header appended, which is certainly not what you want.
8 Y" |! f4 c3 t) \: ?2 X- k, w  In order to fix this, ensure that any of the "httpclose", "forceclose" or0 ^$ y, A  g* w) U, F* o! D* P
  "http-server-close" options is set when using this option.
' x- K- n+ l2 X, R7 d, P, w
. C' q: O* V: u6 Y  d0 Z  Examples :
/ C8 [0 H' C' K3 g* I2 d* W    # Original Destination address: D4 V2 U# Z1 U- T
    frontend www
5 x8 H& r# |/ w2 k  H! H        mode http
6 ~3 b% ]$ J+ L        option originalto except 127.0.0.1! N( U) Z; ~; O' a5 i. Z

' L' x# o- p5 N. N  @5 B& O) l    # Those servers want the IP Address in X-Client-Dst
4 R" X: N  x9 L% `! E7 a% _  x    backend www9 @! W( ^' O# g! j
        mode http0 u, O2 a7 }. j8 ]5 }" N" d) Q% L
        option originalto header X-Client-Dst$ G& E# E9 Q1 m) V( v

: m) Z& n9 w  r( P! |  See also : "option httpclose", "option http-server-close",
: X6 C3 I9 {7 V+ k0 a1 t! o             "option forceclose"
" K  r8 c' j5 _/ H
3 r9 C( \4 s9 z" e) S% I. ^3 P) r/ J
; l8 X5 O1 }# z: n$ I( voption persist
( x/ u1 A( ?7 L" @9 }& ono option persist' H% E. O, F. S+ `  g. B3 ~
  Enable or disable forced persistence on down servers5 T2 P$ ?* A% Q' @1 P8 y: x. a
  May be used in sections:    defaults | frontend | listen | backend
# {6 L$ C, L( i) @! m& j0 j$ F5 P                                 yes   |    no    |   yes  |   yes
" S8 e6 r' o; o* r  Arguments : none" G% B7 C6 G; f/ F

- N' w- ~7 b3 z* D' O! x, X( \) [  When an HTTP request reaches a backend with a cookie which references a dead2 }; ?  Y3 m1 J# L- Y( O
  server, by default it is redispatched to another server. It is possible to
8 O/ P( ?# d  d1 P1 p2 Q6 n. B  force the request to be sent to the dead server first using "option persist"; p1 A& E/ t) H, c. }, B
  if absolutely needed. A common use case is when servers are under extreme3 ~, H7 |; s- ~0 o
  load and spend their time flapping. In this case, the users would still be
+ b( n. H( @. Q) u! V8 `3 q  directed to the server they opened the session on, in the hope they would be
7 a6 b% g/ U  e& S; O# g& ]  correctly served. It is recommended to use "option redispatch" in conjunction
% _# M4 u8 B  y  with this option so that in the event it would not be possible to connect to* ^" \! Q; n& P% O! n2 s8 t, X' a
  the server at all (server definitely dead), the client would finally be# C* m  s& V& K) S6 F
  redirected to another valid server.
5 x  j7 w, @5 I3 B2 |6 D8 C# x5 y2 ^' L1 P4 K4 a+ g
  If this option has been enabled in a "defaults" section, it can be disabled
: u6 b- N: F& P1 B# k' z7 Y& l  in a specific instance by prepending the "no" keyword before it.' a1 e; Y- v% _( D1 O5 [9 W
1 \6 [8 _$ K1 l2 P8 ^( f) M
  See also : "option redispatch", "retries", "force-persist"
: {- R( O9 X/ q0 t) l3 \) C, L9 p  J

, V3 c  B$ J* W  d, y7 Yoption redispatch1 P: U6 D* D/ j4 M3 g1 C: T
no option redispatch
" l) h3 f. `1 Y8 ]  Enable or disable session redistribution in case of connection failure
+ l  o) e$ X9 Q  May be used in sections:    defaults | frontend | listen | backend
  W$ ^/ k1 Q, C: G3 S% ~; V" w                                 yes   |    no    |   yes  |   yes# @6 C: r' j4 h5 D
  Arguments : none# U& |. s/ V3 L- Q5 ~3 V, W
- D& F* }, ]0 f. k1 F! c
  In HTTP mode, if a server designated by a cookie is down, clients may; b* v% H' L! @( Q: d5 v3 C( \
  definitely stick to it because they cannot flush the cookie, so they will not8 ^1 T3 N; N) k8 e5 I1 |3 V' R
  be able to access the service anymore.. ]; z( E& W+ o+ T- C$ v9 w
  x+ A9 K# V* x, e: O
  Specifying "option redispatch" will allow the proxy to break their
! h+ y0 L4 M1 x3 `3 G! T  persistence and redistribute them to a working server./ |2 D1 Z' T* J0 y

5 K( c: [: v7 m6 G, Z/ [" C7 l  It also allows to retry last connection to another server in case of multiple
8 c& `' r9 u$ s4 G  connection failures. Of course, it requires having "retries" set to a nonzero9 a+ P  Q" e7 ?& l# H. `: x( p' `
  value.
& ^. T6 D& e9 t* c# }5 n% [
% v; w$ `) n) u: t" l  This form is the preferred form, which replaces both the "redispatch" and! D9 |& t( {8 H0 x. b8 N+ l
  "redisp" keywords.6 B- W. r7 W! `6 C' K

& M3 y7 v# j4 G' |# O1 B5 S  If this option has been enabled in a "defaults" section, it can be disabled% A  s/ R$ y% S% l  m
  in a specific instance by prepending the "no" keyword before it.
  {2 n4 m* B) ]3 q  z. `' D
2 o5 k4 _+ }5 {7 X. ]' a$ `  See also : "redispatch", "retries", "force-persist"7 C7 C' e7 Q) }2 a- b& s% m5 A4 B

( X" ^- w8 ]7 Y2 b9 n# J+ |0 U/ K$ T" m
option smtpchk
. T# e8 Y0 i/ l* ]( S" Qoption smtpchk <hello> <domain>
2 y7 q( [3 J7 W  Use SMTP health checks for server testing
2 W1 W" k, h$ v* @, J: Q* v8 ~, V  May be used in sections :   defaults | frontend | listen | backend# ]1 [0 w- G, m# B
                                 yes   |    no    |   yes  |   yes
; F4 ~: o9 J. ^2 O; r' J  Arguments :
+ L! f6 }, A5 m( L! p7 s+ i    <hello>   is an optional argument. It is the "hello" command to use. It can: W, w3 g1 G$ d4 R. w( M
              be either "HELO" (for SMTP) or "EHLO" (for ESTMP). All other
  b  \$ E$ m- J# L* t/ L- o6 i              values will be turned into the default command ("HELO").0 V* v3 l' \7 u  l: w
! c) O  \' ~$ i) l
    <domain>  is the domain name to present to the server. It may only be; k; T0 f! F  _% s6 O$ _5 Y
              specified (and is mandatory) if the hello command has been: v& ^. y0 u6 o
              specified. By default, "localhost" is used.: H6 U) N; ]% s3 l5 i0 @6 w
* |! Y# l3 l. s/ J' A# w: U
  When "option smtpchk" is set, the health checks will consist in TCP
! C0 P+ G0 T7 }9 x5 x  connections followed by an SMTP command. By default, this command is
! g, Q4 g6 w$ ]: W% H: v! {7 R$ r7 {  "HELO localhost". The server's return code is analyzed and only return codes5 B/ V/ n( ^; k& W
  starting with a "2" will be considered as valid. All other responses,$ y8 s* Q* O3 E
  including a lack of response will constitute an error and will indicate a
4 \; K+ e. `; m, W9 ]  dead server.
* ?6 y2 ]4 q6 h8 ~: G
: D0 l! \* o/ r8 l8 L  This test is meant to be used with SMTP servers or relays. Depending on the7 E. K/ P8 |7 S1 `% R- {
  request, it is possible that some servers do not log each connection attempt,
! e5 f" F+ @# y3 l, l8 A4 j  so you may want to experiment to improve the behaviour. Using telnet on port" j! z/ u+ y" u' b
  25 is often easier than adjusting the configuration.) N9 ^  h" k& ^" m" ]; x
/ g0 D$ {2 A! I$ u3 r
  Most often, an incoming SMTP server needs to see the client's IP address for# K3 ?$ K* q% ^) F
  various purposes, including spam filtering, anti-spoofing and logging. When0 i. _% }3 F* G5 N3 M3 Y& J
  possible, it is often wise to masquerade the client's IP address when6 e; f# _  q6 r; c$ c' E! z9 D2 C
  connecting to the server using the "usesrc" argument of the "source" keyword,' C& h! A! E4 D) `1 q) y
  which requires the cttproxy feature to be compiled in.3 W% U/ n  h/ |( W/ v

3 c& L) L. |. Z: }6 k: s: h1 K  Example :2 w5 d- I( S0 c  J; ]& t
        option smtpchk HELO mydomain.org
. W/ p- P$ S% A; V+ S8 p* n1 v8 q+ Y% m7 @/ E# J" l! N# ^
  See also : "option httpchk", "source"
* b* P) a; X+ i2 q$ X8 d$ M* {1 q5 k2 y# [6 H" i  E0 ?
" r. I$ K1 A+ }9 B" Q
option socket-stats
, |9 d4 Y* _1 Ano option socket-stats
! a/ T1 X) o$ G% R+ h% k2 G7 U0 d: i9 S7 L; V
  Enable or disable collecting & providing separate statistics for each socket.' Z; W0 \% [% m) _6 o: t
  May be used in sections :   defaults | frontend | listen | backend$ W/ I/ |/ p/ `. Q0 W
                                 yes   |    yes   |   yes  |   no
* q# J; I9 G2 c( L" g0 w! H
( s  f/ T" c. F  @6 s/ d( A  Arguments : none. ^( x2 {' R! W2 k  ]( f6 J

% ^' k0 ~6 {( L% O
) Q& e% I4 m! g2 E( w1 v, w2 s7 Zoption splice-auto
* o0 {$ d. V1 f5 {no option splice-auto! u6 U% v8 b* M- N
  Enable or disable automatic kernel acceleration on sockets in both directions  s5 v( w0 w7 h5 c2 ~
  May be used in sections :   defaults | frontend | listen | backend
0 G4 ?* N4 Z, a6 `. U. A                                 yes   |    yes   |   yes  |   yes* q4 W9 r& D7 x$ t) D$ q
  Arguments : none
: V. m' Y' j3 i2 v2 j
3 f0 G; @, ~( ^  When this option is enabled either on a frontend or on a backend, haproxy# P( f6 e3 p: X( \' |6 c2 [
  will automatically evaluate the opportunity to use kernel tcp splicing to
" S3 ^+ r1 o) z$ J' A/ m0 E2 \( F  forward data between the client and the server, in either direction. Haproxy
0 \0 f% e/ {. }* }5 v% i( |- ^/ F1 J  uses heuristics to estimate if kernel splicing might improve performance or0 e( i/ N4 ~- V, V9 f3 z
  not. Both directions are handled independently. Note that the heuristics used
  w8 n1 s; s4 z8 }: o  are not much aggressive in order to limit excessive use of splicing. This
: A4 d+ V) s4 Y$ M; T: {7 ~6 o  option requires splicing to be enabled at compile time, and may be globally
2 S1 f9 b* z& a" s% O# Q8 R  disabled with the global option "nosplice". Since splice uses pipes, using it
) q5 W/ k1 A( |: D9 e- [  requires that there are enough spare pipes.
- v2 R/ i/ C% a; n+ A, _" t4 I9 ~% S5 |
  Important note: kernel-based TCP splicing is a Linux-specific feature which
$ `" {3 ]! `3 Y- \/ V0 ^5 Z0 Y9 @  first appeared in kernel 2.6.25. It offers kernel-based acceleration to2 s6 C- X% w/ X7 \+ b; X
  transfer data between sockets without copying these data to user-space, thus7 i) [6 p- ~0 b' @7 i$ I; z
  providing noticeable performance gains and CPU cycles savings. Since many' A+ J# V. m7 }8 n
  early implementations are buggy, corrupt data and/or are inefficient, this, A! F  r4 f/ p/ D* f3 j
  feature is not enabled by default, and it should be used with extreme care.
# g. J; g- W" @$ e8 I# R7 Y' [8 u  While it is not possible to detect the correctness of an implementation,
; g! L/ Z1 E. F. L% J/ e& \" }4 S  2.6.29 is the first version offering a properly working implementation. In' z, j$ Q+ }$ \9 T
  case of doubt, splicing may be globally disabled using the global "nosplice"
. N4 R8 M/ `, w  [  keyword.& t  X7 m: t5 t4 u  |! y
6 n$ Y6 m7 [- s; l9 q9 o2 z
  Example :3 p& p1 p9 f; J: d; j% p0 \
        option splice-auto  E5 d5 @* S& G% x1 _3 m

. k" I5 G6 `. W& x: x  If this option has been enabled in a "defaults" section, it can be disabled
/ q* i! K+ d1 @  in a specific instance by prepending the "no" keyword before it./ c9 ^3 p' }+ S' C

% N* {; S/ |, {6 e4 S  See also : "option splice-request", "option splice-response", and global. B  H  P, [; a7 N- U
             options "nosplice" and "maxpipes") l. a# m% j  `+ U. j2 o" A9 I
& Y" t2 x0 f5 B& {  K% E9 k% {
- C4 Y2 z- c/ N- J/ j- `
option splice-request
$ e1 O! t( P$ `5 J* k4 eno option splice-request
, T6 x4 X# t8 d1 i: X  Enable or disable automatic kernel acceleration on sockets for requests: ?  {/ O. ~: I, F' v7 R
  May be used in sections :   defaults | frontend | listen | backend
5 y" x( _. [" d                                 yes   |    yes   |   yes  |   yes3 O' G  S( e7 Q$ Z! @& R
  Arguments : none9 t2 D5 C, u  f  n, T  d/ r; N
: z8 B6 a* r- X- ]
  When this option is enabled either on a frontend or on a backend, haproxy- c0 l" r- l! {
  will user kernel tcp splicing whenever possible to forward data going from
. t& z7 q3 d) y7 V5 Z: J) j  the client to the server. It might still use the recv/send scheme if there7 s% s( _% T4 I( G
  are no spare pipes left. This option requires splicing to be enabled at
) V2 C' {& b' }, S3 }  compile time, and may be globally disabled with the global option "nosplice".
# Z+ G' u. s( o  Since splice uses pipes, using it requires that there are enough spare pipes.1 l# M# E: W- t3 o. s
" @& _* h7 _/ D& n/ `2 G! {) Q/ L
  Important note: see "option splice-auto" for usage limitations.% w- e* C: r8 G% ^0 p+ M, W  Q
2 i' {9 C' ~+ d" h% z1 |
  Example :& u, R0 e3 H; G2 C: L* V8 e6 F
        option splice-request
# g/ H& B6 {8 s3 {( d; |+ N1 ?. |0 |8 C3 t
  If this option has been enabled in a "defaults" section, it can be disabled
5 G, n0 q! L4 M. Q( B9 p% z  in a specific instance by prepending the "no" keyword before it.
2 ?" u9 f+ L5 |' S
- V3 t$ Q& a# D/ q# @  See also : "option splice-auto", "option splice-response", and global options
0 ]: A  r1 o( X9 H% z             "nosplice" and "maxpipes"
7 _9 S( a0 ], C7 d( N% ^9 C0 R4 M$ ]2 L- \$ j2 A% O! H

0 d( k3 N8 y, e* moption splice-response
* M, c& g8 q! ^4 X8 \* _$ Xno option splice-response. m1 Q( s; H  u  Y' p9 A! Z& y+ P; N
  Enable or disable automatic kernel acceleration on sockets for responses
6 F( I7 G* ]9 e: U7 b; S  May be used in sections :   defaults | frontend | listen | backend5 O6 r3 @7 J8 e9 K2 A
                                 yes   |    yes   |   yes  |   yes
' q& H- E/ l" B3 |2 T  g3 l  Arguments : none7 O9 Y( Y4 O; I5 ?

! F% B) f- a+ Y4 x4 f" Y  When this option is enabled either on a frontend or on a backend, haproxy9 V# g) Z  n5 v6 u0 t* u5 ~
  will user kernel tcp splicing whenever possible to forward data going from
) E. g0 g7 j% u3 a  the server to the client. It might still use the recv/send scheme if there
& X) e* A0 Q. x" f0 {) ^  are no spare pipes left. This option requires splicing to be enabled at4 B: u& a" Q7 l1 |7 `3 ~3 {
  compile time, and may be globally disabled with the global option "nosplice".
! _$ `' f7 r8 p+ G: r+ E  Since splice uses pipes, using it requires that there are enough spare pipes.- w" \) P; @4 e  Q% Z) N2 g

3 l3 A: ]. [' `# j* w  Important note: see "option splice-auto" for usage limitations./ a3 v7 y2 O# c6 B! R
/ m+ ~  m# d! k( V- k
  Example :: j5 B0 D: b: D8 D2 a4 X$ d* y
        option splice-response
" C8 C4 D* ?& f0 N2 I: Y5 o+ o+ p* R4 z
  If this option has been enabled in a "defaults" section, it can be disabled
  x9 P; w5 x2 Y6 ]  in a specific instance by prepending the "no" keyword before it.
# |* [3 f% J8 O  G. N
6 R) u: P( F& |: @  d  See also : "option splice-auto", "option splice-request", and global options
, ^, y& E. I5 t# P             "nosplice" and "maxpipes"  B- O3 z2 S2 x# b! E6 _6 [. ]- I

$ A/ A" ~9 C& ~9 V4 }  X6 F  ?) t9 x
" a" I, i/ ]  l/ F6 a7 noption srvtcpka
5 \4 R/ p% [4 ?. j. bno option srvtcpka$ j( ?+ A# s# B1 c1 y
  Enable or disable the sending of TCP keepalive packets on the server side" t7 V  X, ]9 ?) N6 L
  May be used in sections :   defaults | frontend | listen | backend- W- d$ C# o. f. x5 H! ~
                                 yes   |    no    |   yes  |   yes
' g1 @+ D0 F# A  }" g$ z4 U  Arguments : none
7 N" n" p) a! r! Q8 v7 [- U
0 f  }; m3 K: L1 e2 N$ r9 X  When there is a firewall or any session-aware component between a client and3 g3 t: B/ A$ \9 l
  a server, and when the protocol involves very long sessions with long idle7 P7 B  A! `! @0 W( a% H2 ?# q
  periods (eg: remote desktops), there is a risk that one of the intermediate
" _& c! q; G# I  components decides to expire a session which has remained idle for too long.* n% U6 ?/ k; Z; }% i' o

8 T) F' V6 G) V0 v  Enabling socket-level TCP keep-alives makes the system regularly send packets* I7 y: z4 x9 a4 {2 i! ~* P1 N) t
  to the other end of the connection, leaving it active. The delay between
! _( l7 z: N" X' l. `* C  keep-alive probes is controlled by the system only and depends both on the! x4 M) s: `5 u4 Z: A* H% Q2 V
  operating system and its tuning parameters., I" X+ H$ d8 s7 F  l; y+ I
" e- m  K  E( A) `2 F
  It is important to understand that keep-alive packets are neither emitted nor4 z' ~! e6 U/ {" U. c$ N
  received at the application level. It is only the network stacks which sees  ^$ n" S. B; S; K1 H4 p4 k7 D
  them. For this reason, even if one side of the proxy already uses keep-alives
2 T! r( y0 z. G( T4 K  to maintain its connection alive, those keep-alive packets will not be
0 X0 N9 j& t- A* j# U5 ^: e  forwarded to the other side of the proxy.) S. \. r4 E, n- s8 V; L) _& |

0 O9 B1 [0 i- q* r! z6 q  Please note that this has nothing to do with HTTP keep-alive.
8 M  ?& Y. x& S* a5 `/ g% W9 h0 U3 Q# m3 T/ B+ K1 g. f
  Using option "srvtcpka" enables the emission of TCP keep-alive probes on the
- j! `, I6 `3 T. x3 A3 ?  server side of a connection, which should help when session expirations are  \# g. V2 U# q# v$ ~
  noticed between HAProxy and a server.- Q- {5 H! p+ \: E, j

: u6 H+ u3 z3 o7 H7 i; i  If this option has been enabled in a "defaults" section, it can be disabled8 v2 v) P. T6 f; T" c
  in a specific instance by prepending the "no" keyword before it.1 D! z/ O, P5 f; R, u& X- l

4 ~4 H2 j9 z, |1 ^/ g  See also : "option clitcpka", "option tcpka"
1 n) d# A# F2 v
0 Y7 g7 B% a2 R$ y3 }6 H) r/ I. r" A
option ssl-hello-chk, N9 i( g# n' ?; v6 W/ o% M
  Use SSLv3 client hello health checks for server testing2 y7 ], I) ]2 F% ]" r  J$ f- t
  May be used in sections :   defaults | frontend | listen | backend
& f, e2 L! Q$ z% s                                 yes   |    no    |   yes  |   yes
' @2 ]6 M) Y7 u* x" ~- M3 s; r7 S5 ~& \  Arguments : none% a* a/ L& S3 K$ F
. _. m" B, z. l! o
  When some SSL-based protocols are relayed in TCP mode through HAProxy, it is
# x7 S# D" h5 s1 I8 ?  possible to test that the server correctly talks SSL instead of just testing# _* I4 L4 F/ e# X7 [' [
  that it accepts the TCP connection. When "option ssl-hello-chk" is set, pure; J4 g( Y2 `' Q# O
  SSLv3 client hello messages are sent once the connection is established to0 x; l7 O: ^" j( ^  r
  the server, and the response is analyzed to find an SSL server hello message.
5 A9 ]( T$ Z; n5 ?  The server is considered valid only when the response contains this server( Y$ t9 n- M+ O5 g: W# F& ^$ q
  hello message.
% L7 j0 ^9 z- z! @& X
. L1 w0 Z6 |: P8 E1 `& S  All servers tested till there correctly reply to SSLv3 client hello messages,
8 o- T& Z) `5 H  and most servers tested do not even log the requests containing only hello
- l" `3 E8 Y) {  messages, which is appreciable.) e1 b& F/ I8 ~/ v7 s- ]# b' J$ H
/ q3 ]3 R: S/ l! ]" Z5 s. Q- b
  See also: "option httpchk"
8 V5 H; @; P2 U" c8 T5 c8 D/ F& O# d! M9 j$ |% ~

+ j+ ?2 j& i5 r3 S& @option tcp-smart-accept
2 i) T+ `" H# D3 }6 w, Wno option tcp-smart-accept6 K( h% {4 K, u& k5 Q  E2 h9 B& V
  Enable or disable the saving of one ACK packet during the accept sequence
4 c1 I: d8 v) b! Q  J/ U" b  May be used in sections :   defaults | frontend | listen | backend
/ T( o8 c, J& Q* y( \- h                                 yes   |    yes   |   yes  |    no
2 u! y: y+ A# c9 D5 M1 f  Arguments : none  F5 o/ r6 e; q6 t/ V! w

+ i- \( t$ h8 [. P4 z1 y  When an HTTP connection request comes in, the system acknowledges it on4 M: L5 c. y; K/ O3 y' v& h+ H
  behalf of HAProxy, then the client immediately sends its request, and the: k& d/ Q$ |- g0 c
  system acknowledges it too while it is notifying HAProxy about the new/ w0 `' z6 w3 O4 s7 Q' B( k
  connection. HAProxy then reads the request and responds. This means that we
: `. w! L8 H9 V) y  have one TCP ACK sent by the system for nothing, because the request could8 e6 Q3 G# i1 {: r8 J7 T& P
  very well be acknowledged by HAProxy when it sends its response.
4 ^4 J# N/ E6 ?' s5 n2 Y7 [$ X, V3 F0 t$ u+ [" i, M. z
  For this reason, in HTTP mode, HAProxy automatically asks the system to avoid
  L9 v, t( g% h  sending this useless ACK on platforms which support it (currently at least
, g. z. M8 H% b  Linux). It must not cause any problem, because the system will send it anyway
7 Q# b4 [( p( I  after 40 ms if the response takes more time than expected to come.
: L% X8 E% q: [6 S  e' H* z: e. P$ |+ j. e  s% k$ X7 j, o" h8 z! O4 e" y
  During complex network debugging sessions, it may be desirable to disable
& }# b- f, P4 d; l9 G' g  this optimization because delayed ACKs can make troubleshooting more complex* v4 |) P* E; c7 J
  when trying to identify where packets are delayed. It is then possible to
" f: u0 z2 A# A% M* f, K* N  fall back to normal behaviour by specifying "no option tcp-smart-accept".' \4 V. @7 Z/ h5 ~! \" _
8 h; q3 X' _: D
  It is also possible to force it for non-HTTP proxies by simply specifying
: T) M2 A8 A" S6 e, t$ E  "option tcp-smart-accept". For instance, it can make sense with some services0 i: K- M6 p- k7 c; ?3 Q; ~
  such as SMTP where the server speaks first.
" ?! {4 j/ W. }, I3 }' e5 o8 m- |- L6 u. j: i8 k3 l2 p
  It is recommended to avoid forcing this option in a defaults section. In case3 I$ L: m1 f! Y- u9 G
  of doubt, consider setting it back to automatic values by prepending the
3 Q/ r! ^2 @8 K0 J  "default" keyword before it, or disabling it using the "no" keyword.' D% G4 Y7 Y: s1 C

/ d% ~0 ^& l; V" p/ Q3 o7 x' j  See also : "option tcp-smart-connect"
- P* j* \" M) F* k$ o9 E! _7 \" ~5 z9 [( _$ r4 K# G' [
3 G; K* O9 X( O0 y6 o4 }
option tcp-smart-connect
0 z& q6 O: \5 P# I! Rno option tcp-smart-connect3 u- V& s% d  n+ Q3 O
  Enable or disable the saving of one ACK packet during the connect sequence- P1 a. `+ d: n8 ?) E
  May be used in sections :   defaults | frontend | listen | backend
% Z  O6 g8 o6 I. K/ ^                                 yes   |    no    |   yes  |   yes
- e) J$ u# j8 L  Arguments : none
* }3 \* O3 e) y1 @( w: @
- |& @3 a6 R: ?  \3 O6 K  On certain systems (at least Linux), HAProxy can ask the kernel not to
0 \; _0 a* c3 e5 ^; K  immediately send an empty ACK upon a connection request, but to directly) O& M# k+ [% a# O, Q& E# |
  send the buffer request instead. This saves one packet on the network and
) V3 F- {5 B  H0 c- o: r  ?  thus boosts performance. It can also be useful for some servers, because they( b# j! o6 b1 P
  immediately get the request along with the incoming connection.
5 U+ H- R; Z& R1 y" J, s3 t1 l4 G8 @+ E; J1 O# |$ i8 h/ q9 V8 |
  This feature is enabled when "option tcp-smart-connect" is set in a backend.
* T* E: R: {: g6 `: Z+ K; O, ^  It is not enabled by default because it makes network troubleshooting more
! m6 X( z& H) t; _$ Y  complex.- k( O$ N0 ], l0 _
$ {% }0 o* p9 y; B/ }$ t: ~
  It only makes sense to enable it with protocols where the client speaks first
6 a, V& i, Q/ x  I, f/ r  such as HTTP. In other situations, if there is no data to send in place of
' V. ?) d8 Z3 |3 h  ~4 F  the ACK, a normal ACK is sent.
, g  [) ]6 m  Y4 U4 F; F5 r
; b8 F. Q+ H3 u3 C5 H; B7 q1 i' s, c0 d  If this option has been enabled in a "defaults" section, it can be disabled
( v1 w" d* m2 E7 j  K  in a specific instance by prepending the "no" keyword before it.
' ^! L4 k) J  L' g: h0 c# o
+ m9 |$ j8 @7 j& }" q+ o, C  See also : "option tcp-smart-accept"
& B" T* v5 K. s: C* Z& |# Y" ]- e- a( s

+ F& W; F, p5 ?6 E' Woption tcpka8 b" S% \# W9 \% T, ~6 p
  Enable or disable the sending of TCP keepalive packets on both sides
3 ~) a$ O' b( r! ~. [* ^# s  May be used in sections :   defaults | frontend | listen | backend* c9 c9 ?& A2 `9 H
                                 yes   |    yes   |   yes  |   yes. P# [- Z2 v8 O) z+ B5 H, t
  Arguments : none
5 o! s' O9 w5 B3 T) L9 h( v% K( K& x# J: ~/ a) O7 f6 S9 t' a* V$ T
  When there is a firewall or any session-aware component between a client and
: S8 O7 a) N& W3 f- a* S  a server, and when the protocol involves very long sessions with long idle
0 ]! y' {! s& d2 [4 n4 F  periods (eg: remote desktops), there is a risk that one of the intermediate
8 e' D9 [$ b* M* y  components decides to expire a session which has remained idle for too long.& o* C+ q. U* L$ p3 Y# n

/ |: E0 o, u* _8 B& y9 p  Enabling socket-level TCP keep-alives makes the system regularly send packets
0 K! o2 z5 y$ Q# l3 ^. {# n3 W2 |  to the other end of the connection, leaving it active. The delay between
7 R+ R/ u! ~3 ]" R( @  keep-alive probes is controlled by the system only and depends both on the# G( I/ @9 t& _# v7 @
  operating system and its tuning parameters.
9 r+ b2 f# {% }. K; y; X1 `+ X- G' B' O/ V% f2 E, ^: \: \3 [
  It is important to understand that keep-alive packets are neither emitted nor
0 N. o  [/ n! R) J' [  received at the application level. It is only the network stacks which sees
. o% W1 ~5 W& n7 o4 [$ G3 p  them. For this reason, even if one side of the proxy already uses keep-alives
% |* X7 P5 I. r  P/ @9 n4 L  f& n  to maintain its connection alive, those keep-alive packets will not be
, V, S4 [; y: Q+ M! J  forwarded to the other side of the proxy.
" O5 X2 p5 G, d1 c% f* [' z( s/ i: v2 R) R: S* p! H* F" |# @, L
  Please note that this has nothing to do with HTTP keep-alive.
6 K8 n0 C4 Z7 ]/ E' r- _- \+ R0 x* z* t" z, w# @3 M8 p3 W0 P3 G) I! @, a
  Using option "tcpka" enables the emission of TCP keep-alive probes on both, d8 N! q% h. c# I
  the client and server sides of a connection. Note that this is meaningful
4 k0 L! S& i4 k" T) F2 |& c/ [  only in "defaults" or "listen" sections. If this option is used in a
6 t  O4 w8 M5 D2 j$ v1 n" }  frontend, only the client side will get keep-alives, and if this option is1 z( H) X5 N* K+ S
  used in a backend, only the server side will get keep-alives. For this) a. m) [/ _( g' e+ @, Q
  reason, it is strongly recommended to explicitly use "option clitcpka" and
7 _% M5 N# D. o0 m% B; P  "option srvtcpka" when the configuration is split between frontends and
" |8 z* e( ~: D1 ~  backends.: n2 x$ n( l3 Z9 ]% |1 ~9 C
; A# A0 W0 x% M% s! N& t
  See also : "option clitcpka", "option srvtcpka"% e% l, m1 R9 Z1 z) ?1 }1 _

* |, u$ B) j: }
1 n/ ?7 G* _' q/ Y3 ?: S7 `; c7 q# Toption tcplog3 @7 _7 d+ X" b
  Enable advanced logging of TCP connections with session state and timers
  @5 H$ Q1 \5 P  May be used in sections :   defaults | frontend | listen | backend% U8 @9 ~$ D* ?4 H. p! n
                                 yes   |    yes   |   yes  |   yes
/ Y6 E3 j, I8 n  Arguments : none
- h; a! f6 i; a9 g3 k7 `) H# _. m/ o. O' r& @. i! {# a
  By default, the log output format is very poor, as it only contains the# \' u5 U. U3 ]6 ^
  source and destination addresses, and the instance name. By specifying# r3 Y: M4 d1 p; c8 E2 W& a( j) X
  "option tcplog", each log line turns into a much richer format including, but" d5 D; X' g1 u3 x
  not limited to, the connection timers, the session status, the connections
# z4 p" g, m8 g5 ^, R0 B, R5 m  numbers, the frontend, backend and server name, and of course the source
6 g  j" B  J8 f. E5 J  address and ports. This option is useful for pure TCP proxies in order to
, }8 V2 r# ~* S7 V  find which of the client or server disconnects or times out. For normal HTTP
( D  d) }* |( I$ R) O9 a  proxies, it's better to use "option httplog" which is even more complete.. e2 O3 Y8 N+ g% z, A3 {
5 t. Q/ Z: T: ^5 m8 s4 |& n, F
  This option may be set either in the frontend or the backend.# W8 @% z* {. i+ Z4 |

  s- F$ r0 a2 I  See also :  "option httplog", and section 8 about logging.
% ~& e! G7 W  S5 O& M
. o% N/ b* v( r# Q. ]/ I9 l0 |0 z0 h. `* N6 c
option transparent
  z- i) }& Z1 P! n( a0 Dno option transparent' @4 f/ X; w8 D6 O  O1 P
  Enable client-side transparent proxying
9 P" u7 f% o+ l" f  May be used in sections :   defaults | frontend | listen | backend
5 Z% N. q/ {' q                                 yes   |    no    |   yes  |   yes. n, U8 s- @* u% p* C9 ]
  Arguments : none
7 G5 N: p/ f' t+ a( y0 V, v# U
! @* T! V% a$ i; L  This option was introduced in order to provide layer 7 persistence to layer 32 T* m+ f  ~+ y9 [" Y1 p6 r9 b
  load balancers. The idea is to use the OS's ability to redirect an incoming
/ j8 r  w$ V/ a* k8 w! |0 S  connection for a remote address to a local process (here HAProxy), and let
4 R$ m' }0 I5 y0 @. Y( R* ^. Q) T  this process know what address was initially requested. When this option is4 w" r3 Z& l9 [3 I2 g( Y
  used, sessions without cookies will be forwarded to the original destination3 k3 P- i) n; q7 Z: j
  IP address of the incoming request (which should match that of another& ]# u  V- t# N3 s( A
  equipment), while requests with cookies will still be forwarded to the  \) q" H3 _7 G- x# x. U
  appropriate server.
- D( ~; m& H7 H( U+ _" ?! Q" L$ I+ j- v
  Note that contrary to a common belief, this option does NOT make HAProxy4 U/ S; ^5 c# g% k, `+ p3 a
  present the client's IP to the server when establishing the connection.
& [. l* Z" K1 G9 E' M) u, c5 X# [2 c% x" a
  See also: the "usesrc" argument of the "source" keyword, and the  J" F* i( J8 y. T3 S4 x, }
            "transparent" option of the "bind" keyword.
  d* n! d) o- z) p0 [: K% M* r, y5 }. D6 m3 P: e
0 n" N1 D1 ]% A- M9 u5 y; W
persist rdp-cookie4 K  O  J. N! b1 M0 _
persist rdp-cookie(name)
' N1 {* `7 s" R3 r  Enable RDP cookie-based persistence
# x) Q* q! @# {/ y2 U: C- g  May be used in sections :   defaults | frontend | listen | backend
7 B% H6 P0 D+ p3 u" u                                 yes   |    no    |   yes  |   yes
4 z2 m- l% ~0 t/ h% y- w  Arguments :0 P4 |0 J" ?' V" G
    <name>    is the optional name of the RDP cookie to check. If omitted, the" q0 D8 q+ `0 W, `; ~/ r. e6 `
              default cookie name "msts" will be used. There currently is no7 B1 ?3 l$ v4 C
              valid reason to change this name.
# A% L7 F9 E6 x/ x+ }% W( a, V) M( R# Y9 R% \8 `. l
  This statement enables persistence based on an RDP cookie. The RDP cookie
/ l, T) c- c6 m0 d( A  U  contains all information required to find the server in the list of known/ k/ ]! b& g, K1 ~4 Q9 w
  servers. So when this option is set in the backend, the request is analysed
9 b. F  c( x+ P. A! z  and if an RDP cookie is found, it is decoded. If it matches a known server
" O' v, C& l2 D; X/ B( x& H  which is still UP (or if "option persist" is set), then the connection is
, f: M7 p+ |! o0 N8 {0 @3 B  forwarded to this server., X0 e+ E3 C7 O/ y

6 H9 N. K3 J- z5 N  d* V* l5 ~* g. W  Note that this only makes sense in a TCP backend, but for this to work, the5 k- t1 J" z, |
  frontend must have waited long enough to ensure that an RDP cookie is present
# b# `1 b3 u' d5 D4 T0 g  in the request buffer. This is the same requirement as with the "rdp-cookie"; @7 y1 O! b. V8 v6 R! }
  load-balancing method. Thus it is highly recommended to put all statements in' @( v$ k  ^' k1 n& Q& \) U  g
  a single "listen" section.
# w0 [, D( R; ?1 V: x+ Y5 Z; {
! B$ a0 F  {. i. _# ~, B1 B  Also, it is important to understand that the terminal server will emit this5 V* D! w8 b: `$ b/ p+ @4 w* q
  RDP cookie only if it is configured for "token redirection mode", which means
6 f' K- Q6 H5 o# ?  ?/ U  that the "IP address redirection" option is disabled.
0 F, o0 U& z% l$ l! [9 e" ]5 w2 W& B& M0 L
  Example :" n$ t. h- l+ L6 D( D& |% v' |
        listen tse-farm
) k* Z) o: ?! s$ k+ i            bind :3389
; c  Y0 w( s- z8 I            # wait up to 5s for an RDP cookie in the request% p: x8 s( g( @% i% w, p5 z
            tcp-request inspect-delay 5s# Q- V& D3 ]# l  {+ {' \
            tcp-request content accept if RDP_COOKIE
' o1 ^; d% p, y$ v$ F            # apply RDP cookie persistence( a$ p' C1 t# o# c9 s
            persist rdp-cookie
) i+ m6 {( D; c8 c* d& V& ~7 i            # if server is unknown, let's balance on the same cookie.
- S8 ?$ E3 b% T8 U            # alternatively, "balance leastconn" may be useful too.
1 Y- q0 T) y0 t$ p            balance rdp-cookie7 I$ i+ a6 {9 {# W
            server srv1 1.1.1.1:3389
( x; s3 b' A! v            server srv2 1.1.1.2:3389  ~2 d8 e# M# |
( X* r+ }, e; b9 p9 l
  See also : "balance rdp-cookie", "tcp-request" and the "req_rdp_cookie" ACL.
$ s; ?/ X/ K/ u! E6 P
: A- z# H" V; L& ~" [8 D8 b% g4 z
rate-limit sessions <rate>
+ U8 L. K6 R' }7 s" H# ^  Set a limit on the number of new sessions accepted per second on a frontend
- s$ n3 u* x4 l" N$ ^; {  May be used in sections :   defaults | frontend | listen | backend" ~3 Q+ H" d& C
                                 yes   |    yes   |   yes  |   no) r/ ^) x* T1 }- k' l; M" n
  Arguments :
  i( e6 p1 |7 i* `5 X% L    <rate>    The <rate> parameter is an integer designating the maximum number
! {, |# S: J. u: O$ o! K              of new sessions per second to accept on the frontend.
4 E$ \# Y( h" L& _2 B
2 j, K6 U" H* c  When the frontend reaches the specified number of new sessions per second, it6 J8 ?! ^4 N/ y- E
  stops accepting new connections until the rate drops below the limit again.3 U, B* j7 s; H9 `8 `# D
  During this time, the pending sessions will be kept in the socket's backlog
" |: U2 G( w+ N+ W" W2 y  (in system buffers) and haproxy will not even be aware that sessions are/ l4 W" s7 m4 w1 l/ Y
  pending. When applying very low limit on a highly loaded service, it may make- k% S5 E' S0 R
  sense to increase the socket's backlog using the "backlog" keyword.: C: c2 z1 ]& u8 n8 S
3 v* r) X9 r2 d5 G$ E* v- z
  This feature is particularly efficient at blocking connection-based attacks
* \, d2 i7 }" W. j  or service abuse on fragile servers. Since the session rate is measured every
, J9 ^  k3 f% I- b  millisecond, it is extremely accurate. Also, the limit applies immediately,
) v& ]4 }. f2 ?' d  no delay is needed at all to detect the threshold.4 W' x  o) f- u/ ~5 j: D

. _* @  T& f0 S4 c' k) G; M3 n  Example : limit the connection rate on SMTP to 10 per second max
7 C: S0 Y8 @- `7 a        listen smtp6 q5 e9 }2 [; G% S& A" z3 }: Y
            mode tcp7 a2 E4 ?1 j  |$ W0 o% ]# {
            bind :257 O. L: ^* C' u; y
            rate-limit sessions 10
) O4 U. V$ J* n            server smtp1 127.0.0.1:1025' r; H( M) t2 ]

9 |2 X5 \8 Z  C: H  Note : when the maximum rate is reached, the frontend's status appears as
% F$ L; s( D8 x2 m* o) N         "FULL" in the statistics, exactly as when it is saturated.( F7 Z  t+ R! m* h% \! k# A

1 Z4 G8 k$ P. k' K0 s, K: T  See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion.0 \2 e/ Q. w3 f8 Z$ p
% z  V. w2 e. y& Z7 J# j  p

! s0 `5 {& E9 R& t' L* a7 lredirect location <loc> [code <code>] <option> [{if | unless} <condition>]/ g, @/ e* S6 p# P( H
redirect prefix   <pfx> [code <code>] <option> [{if | unless} <condition>]
/ g% Q% y6 z) U: Z8 predirect scheme   <sch> [code <code>] <option> [{if | unless} <condition>]
6 x. P6 D& ^  K9 x  Return an HTTP redirection if/unless a condition is matched- K" o/ u# g* B4 V7 n1 }' n* b
  May be used in sections :   defaults | frontend | listen | backend
" c4 R8 V' {2 s3 n' M                                 no    |    yes   |   yes  |   yes; D& E  A) @' E& K! g1 B

/ a, {- c1 V& G# K, r, H3 c) D. j+ R  If/unless the condition is matched, the HTTP request will lead to a redirect
+ f4 M7 J1 |$ e9 c& M9 B) i  response. If no condition is specified, the redirect applies unconditionally.
. L) [3 d1 @  O% `  W" ^  S1 {4 M$ }, Q  a9 n+ x+ h
  Arguments :4 V5 w2 J5 w  y' l! n) [0 V
    <loc>     With "redirect location", the exact value in <loc> is placed into( U0 |% H# |; A  {& z# e$ V( a
              the HTTP "Location" header.$ g7 f5 R: G/ J4 _1 ~, M$ J( |! |+ c
$ g( e5 D7 Z3 n
    <pfx>     With "redirect prefix", the "Location" header is built from the
# z; K7 g3 B7 ^              concatenation of <pfx> and the complete URI path, including the: c  K& n3 D5 {! }7 t9 L
              query string, unless the "drop-query" option is specified (see  B! R5 Z6 M! A; d( X# I2 g2 {
              below). As a special case, if <pfx> equals exactly "/", then# ]* v. i/ p0 H) Z3 Q
              nothing is inserted before the original URI. It allows one to
+ g/ p& f( J' D$ j              redirect to the same URL (for instance, to insert a cookie).  V7 L" E5 u- `: N
# O, v! P& P) f7 B0 a
    <sch>     With "redirect scheme", then the "Location" header is built by3 E8 A& o6 ~0 Q! P. v
              concatenating <sch> with "://" then the first occurrence of the
' [' w- K( [4 R6 A. w' \* A              "Host" header, and then the URI path, including the query string# x, r, D9 S1 z. v& s% Q- U: @% H
              unless the "drop-query" option is specified (see below). If no
7 F- N: R. ?' s& i; k              path is found or if the path is "*", then "/" is used instead. If
: g/ _; |4 |- O1 {              no "Host" header is found, then an empty host component will be. ?0 G3 W$ N! K4 l- r, [7 C. n; n
              returned, which most recent browsers interprete as redirecting to- [" {5 D' R( q
              the same host. This directive is mostly used to redirect HTTP to
2 ?% J0 a. F+ q  B              HTTPS.4 h! r/ t+ v! ?% x4 X3 A+ }
% t* j! m2 x% e- K4 E, V; t' M
    <code>    The code is optional. It indicates which type of HTTP redirection
# P: O5 w3 J1 R1 ~5 F' s  k              is desired. Only codes 301, 302, 303, 307 and 308 are supported,0 d2 i, o5 }9 ^& Z: a  n; `
              with 302 used by default if no code is specified. 301 means; w5 F3 p3 y  M- e3 g( |8 y  K" i
              "Moved permanently", and a browser may cache the Location. 302
0 V& a5 J& H) c              means "Moved temporarily" and means that the browser should not3 I. j! e# ^5 I) ?- U. o) w2 l
              cache the redirection. 303 is equivalent to 302 except that the
  ~. o% B+ `- J* ?" E1 A              browser will fetch the location with a GET method. 307 is just% T+ E0 b$ y! h: L9 @' ?" s; _# S9 s
              like 302 but makes it clear that the same method must be reused.
+ `- e: y& n. \2 g              Likewise, 308 replaces 301 if the same method must be used.5 J. r( p1 n; G+ X

8 F, L" X+ O1 G$ J3 i    <option>  There are several options which can be specified to adjust the
9 r: t8 Z& Y& i: |              expected behaviour of a redirection :$ [# ?- p; L& m2 h& P4 p! Z+ @( `

2 l/ g7 T3 t9 W5 a5 E4 @! ~4 k& w! V      - "drop-query"' ]) i$ d# g: `( O8 Q. e% ]
        When this keyword is used in a prefix-based redirection, then the- B" X+ C8 d2 Y3 E! K' y# O+ ^' F# f
        location will be set without any possible query-string, which is useful' b, j- t! }* |0 [6 [6 {* W: a8 Y$ B
        for directing users to a non-secure page for instance. It has no effect4 A( L; k1 O% S: \
        with a location-type redirect.
/ ^% u: k: G0 F; M7 O. x% ^$ j- T0 g+ M" i9 }
      - "append-slash"4 q& X" _1 |1 D, U& h( _' F. H  W  A
        This keyword may be used in conjunction with "drop-query" to redirect
6 N- r: e& A! J( N# E- c2 H# Y4 ~: Z        users who use a URL not ending with a '/' to the same one with the '/'.
) Q7 M# b; M9 x, g  n7 O0 i6 C        It can be useful to ensure that search engines will only see one URL.
' L0 J& N) E5 e/ d2 A# i        For this, a return code 301 is preferred.
9 G8 o+ M+ B  w! J( }% F( S6 ?; l0 k' x- G* j
      - "set-cookie NAME[=value]"7 {1 G# T' B$ j. K
        A "Set-Cookie" header will be added with NAME (and optionally "=value")
8 n% M  I: m4 p3 v- b3 u4 h+ z        to the response. This is sometimes used to indicate that a user has
5 T8 g  B; T, Y  h        been seen, for instance to protect against some types of DoS. No other
5 Q4 }" ?% o" K% ]4 x  o        cookie option is added, so the cookie will be a session cookie. Note
9 Q8 l% w! m6 \# |+ T9 Q0 {        that for a browser, a sole cookie name without an equal sign is
) |  M5 r2 ?' W: q        different from a cookie with an equal sign.
, R( o5 ^5 @. I5 B9 I9 B( ?* E* t
, J/ x* V# U' a! |0 h      - "clear-cookie NAME[=]"  ?; J( G" U6 ~
        A "Set-Cookie" header will be added with NAME (and optionally "="), but
, D1 N) D2 O7 ^7 n- V( K# x        with the "Max-Age" attribute set to zero. This will tell the browser to
2 G- u0 @" S, D        delete this cookie. It is useful for instance on logout pages. It is
- g* q* l7 C7 }6 x        important to note that clearing the cookie "NAME" will not remove a3 k" I4 o  s, t+ k' v. k
        cookie set with "NAME=value". You have to clear the cookie "NAME=" for
5 L" G3 J2 X8 y5 R        that, because the browser makes the difference.  v. |0 W5 N6 y
2 U% s7 N1 `. R& M2 F$ E
  Example: move the login URL only to HTTPS.- O# ^+ f# X- u1 q1 ^7 Y
        acl clear      dst_port  807 ^# Y3 C+ _7 o) N' ]
        acl secure     dst_port  8080( }0 E* X/ H+ K9 f& K
        acl login_page url_beg   /login" z0 p9 e+ P' A- [5 x
        acl logout     url_beg   /logout+ ]: P. K! h+ r% K8 Q4 M& ]
        acl uid_given  url_reg   /login?userid=[^&]+/ v- s! s0 w# b4 m5 ?$ Q
        acl cookie_set hdr_sub(cookie) SEEN=1
# W) e; G4 A" Y9 A
8 p2 h: V& q: \. N        redirect prefix   https://mysite.com set-cookie SEEN=1 if !cookie_set+ M! d; [4 w6 U6 }9 I4 I) {" j
        redirect prefix   https://mysite.com           if login_page !secure
. X& n/ l" Z- A$ P        redirect prefix   http://mysite.com drop-query if login_page !uid_given/ G2 U4 z$ ]" K% C- w
        redirect location http://mysite.com/           if !login_page secure( s0 \7 B+ |2 ^# @
        redirect location / clear-cookie USERID=       if logout, `$ N) o* r) t- v

: X. U" m! g: f% S- |  Example: send redirects for request for articles without a '/'.
* u3 `4 G8 i. p, Q  p        acl missing_slash path_reg ^/article/[^/]*$
. I. }& m+ \; Q2 f( r) a% K        redirect code 301 prefix / drop-query append-slash if missing_slash" E. e% S- K+ i' z# x6 O
8 g0 `2 K+ N0 [" \
  Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.& o: M  V/ m; @8 A7 w5 u
        redirect scheme https if !{ is_ssl }# f, w) W3 m5 ], q+ x2 p5 G
0 y  {1 L" U2 D& T
  See section 7 about ACL usage.
! F! f# Y( _& r" c7 U
! U0 R/ n+ x4 K+ S2 q, w# N, {. C6 f
redisp (deprecated)' W3 s& P# S# J) i5 i
redispatch (deprecated)$ s: w- }. ^: Y" {& B* Z
  Enable or disable session redistribution in case of connection failure
" \1 r6 w0 Z5 X% W0 `  May be used in sections:    defaults | frontend | listen | backend% T; w  s/ v2 [7 Q; D
                                 yes   |    no    |   yes  |   yes
2 x8 w  H' D- H8 J+ u! `  Arguments : none$ b# u0 k: r7 f- _% l
9 M% c" y) ~# \0 w
  In HTTP mode, if a server designated by a cookie is down, clients may" I! c2 g$ l. a8 E: o0 o7 X
  definitely stick to it because they cannot flush the cookie, so they will not1 B5 A; N* a- \3 r3 J
  be able to access the service anymore.
2 w4 L% x0 N) {) G" H  W2 e7 }+ C/ Y5 C$ S' h
  Specifying "redispatch" will allow the proxy to break their persistence and, \& G# j% w2 L+ B7 D7 ?' `
  redistribute them to a working server.
; v7 _$ J/ X3 F* |6 L/ n4 e9 J3 s/ t/ o
  It also allows to retry last connection to another server in case of multiple+ ]+ J9 Q! ]9 a: R
  connection failures. Of course, it requires having "retries" set to a nonzero+ m' `3 K9 P# b; o) R* v2 w
  value.
' v! ?* C- g8 t$ j
$ E) R$ _8 X! G* ?& B  This form is deprecated, do not use it in any new configuration, use the new+ p& [# e  L" B* j! z7 i% x
  "option redispatch" instead.  d/ z8 |. S" s+ D4 n- R, c6 E9 B

7 }! }8 C# ?; j$ V4 j  See also : "option redispatch"0 a/ `) d: B6 X0 X' l
- h8 x. }  Q0 l' Z

' k6 x* m0 T9 Preqadd  <string> [{if | unless} <cond>]3 u) E% t6 h9 @& {' m
  Add a header at the end of the HTTP request
) }6 Q# e' a6 u9 y) b5 K. c# F  May be used in sections :   defaults | frontend | listen | backend
9 l1 C4 V. ]+ r                                 no    |    yes   |   yes  |   yes
* x  L4 A7 Y* g  Arguments :
- U  K6 u! K6 h. C5 w    <string>  is the complete line to be added. Any space or known delimiter, w0 |; q1 B) x* F' [, X
              must be escaped using a backslash ('\'). Please refer to section
3 [* \) U4 _' b/ I              6 about HTTP header manipulation for more information.
4 ~# B4 O) A  Q6 `
" B. h* s- Y4 O8 {    <cond>    is an optional matching condition built from ACLs. It makes it9 S% F9 z* }! {% B: v
              possible to ignore this rule when other conditions are not met.
. h( I/ U6 B( ], k& O$ h, w! W# v0 z/ _/ J' l
  A new line consisting in <string> followed by a line feed will be added after2 B$ l$ M/ @% Y" E1 A: V; A/ `
  the last header of an HTTP request.- K, Q3 A* ]& U8 d

9 u1 `$ l# x. _6 o( ]5 H  Header transformations only apply to traffic which passes through HAProxy,
* @+ {- v* P/ z' c% f7 y  and not to traffic generated by HAProxy, such as health-checks or error
$ C0 x+ F* M( X  responses.
7 ~6 O# E" k' S8 H. [+ s. m7 {) r) L
  Example : add "X-Proto: SSL" to requests coming via port 81
' d% c( [* [1 Y2 i     acl is-ssl  dst_port       81) \5 [7 q; Y9 M% q/ Y0 M1 Q
     reqadd      X-Proto:\ SSL  if is-ssl+ Y) c+ S8 M8 H* Y3 e- @
8 @+ w! j- f0 J, P
  See also: "rspadd", section 6 about HTTP header manipulation, and section 7
) q: E) v0 I0 X8 ^            about ACLs." b( B; d: U8 l% S

  Q, D; n$ {* B6 g1 K% X* I: D8 F0 K/ \( z
reqallow  <search> [{if | unless} <cond>]' |/ u  N% d' Z; ?) E
reqiallow <search> [{if | unless} <cond>] (ignore case)( v- o. L' ?1 l% f! r  k
  Definitely allow an HTTP request if a line matches a regular expression
3 z5 v7 C+ E" ?2 @5 v/ e  May be used in sections :   defaults | frontend | listen | backend4 D. {, V& {- o  f% Y. s
                                 no    |    yes   |   yes  |   yes2 E* O  W. X  E* v: T7 ^
  Arguments :
6 C" m7 Q7 M% C4 L$ S4 W/ R9 ?    <search>  is the regular expression applied to HTTP headers and to the9 {8 t9 m& i! Y; @: h3 y; k
              request line. This is an extended regular expression. Parenthesis( X1 q; a6 n3 k
              grouping is supported and no preliminary backslash is required." }% ?, [* E0 X& O/ M$ A
              Any space or known delimiter must be escaped using a backslash
/ ^) ^. d1 a: l* {              ('\'). The pattern applies to a full line at a time. The
0 Y7 [  w% t8 w/ n0 u( [              "reqallow" keyword strictly matches case while "reqiallow"/ I! `) k% ~) U& E* e
              ignores case.
" z' c+ Y/ {3 n: `7 d( f4 h* c/ G5 W2 M! c, j3 n  x
    <cond>    is an optional matching condition built from ACLs. It makes it
( A& Y* P9 m% C2 n0 i& t              possible to ignore this rule when other conditions are not met./ c! p/ U; i7 Q) p: J/ i3 K

: G! o4 `7 n( d9 D2 M! n% p1 o  A request containing any line which matches extended regular expression, i% Q/ D$ r! d4 t7 \0 k
  <search> will mark the request as allowed, even if any later test would
, {' f% x. g7 F1 q0 g) H& W2 E3 }  result in a deny. The test applies both to the request line and to request
+ r% h& t; p/ F- K  headers. Keep in mind that URLs in request line are case-sensitive while9 s- S# g+ s8 A* `7 U, \, |/ k
  header names are not.9 P2 }3 M# V% z# g$ t
0 N; m0 P% h$ y7 S7 r, ~0 w$ k
  It is easier, faster and more powerful to use ACLs to write access policies.3 Q# y( q% W  B1 }8 M( e
  Reqdeny, reqallow and reqpass should be avoided in new designs.
' V; @3 a) j) j0 B
* _9 T! U7 j2 ~7 p  Example :
+ L; I  c% I; L4 A" n, ?# Q9 w     # allow www.* but refuse *.local
1 T. M& u  F' j3 j     reqiallow ^Host:\ www\.: r) |4 [7 e) E6 e
     reqideny  ^Host:\ .*\.local# n- H- M9 S1 D, P  L
& h3 E) k; z( N- c7 S' k
  See also: "reqdeny", "block", section 6 about HTTP header manipulation, and" ]9 r8 E0 @" R' [
            section 7 about ACLs.9 s1 i- ]% e* H* i1 G! c: c) O3 G
- x. Q; R% K1 G4 m# _; d/ K  }

. c0 B" C; k! ?reqdel  <search> [{if | unless} <cond>]
# b' E5 x( p3 lreqidel <search> [{if | unless} <cond>]  (ignore case)
/ `- N4 V* j" K$ ^0 N$ N- m* n% L  Delete all headers matching a regular expression in an HTTP request
! K5 z% G) ?2 ?% F8 H  May be used in sections :   defaults | frontend | listen | backend
3 G) g2 O' g, b7 c' N4 S                                 no    |    yes   |   yes  |   yes- p0 d& V" n# |- F2 x. |
  Arguments :
* c! p; M5 C4 C  v* x    <search>  is the regular expression applied to HTTP headers and to the
" Z# _0 J. a+ }5 O5 ]              request line. This is an extended regular expression. Parenthesis
. u& Q8 q: X4 r( i9 k              grouping is supported and no preliminary backslash is required.( R, Y% X" [0 t- u
              Any space or known delimiter must be escaped using a backslash
: }7 S) I' i: P8 |2 D              ('\'). The pattern applies to a full line at a time. The "reqdel"" {* b- Y; p: N( n
              keyword strictly matches case while "reqidel" ignores case.( O; g  B  @) b8 ^
1 d5 `& G3 M. M4 j+ S' v
    <cond>    is an optional matching condition built from ACLs. It makes it; W3 k- e+ [: B8 b. @7 S
              possible to ignore this rule when other conditions are not met.
( R& x( L1 N2 q. M5 f* j$ h$ `& U: N  Q0 {3 i5 ^7 u
  Any header line matching extended regular expression <search> in the request: c" I' z: z6 L7 U5 m: N; ]
  will be completely deleted. Most common use of this is to remove unwanted
* L8 v1 p0 ~# p  and/or dangerous headers or cookies from a request before passing it to the
( c' c' m! X& x) H. R* P9 C  next servers.
% s9 C; U5 {9 d1 \4 Y4 ^# d7 i1 P2 k9 x7 Z  [# B1 [, j
  Header transformations only apply to traffic which passes through HAProxy,
  M6 v+ D0 |" J- z  and not to traffic generated by HAProxy, such as health-checks or error
' \" l# d. M7 Y' {: L: E# ?  responses. Keep in mind that header names are not case-sensitive.9 l7 I% E" \4 f: k( X9 G3 _

- `* v, C8 ^5 O  Example :2 U4 }! c% c& v* X( A
     # remove X-Forwarded-For header and SERVER cookie. [- n; t1 N# c. K) `  C
     reqidel ^X-Forwarded-For:.*
5 X# Y1 Q" x2 k6 n! L( Q     reqidel ^Cookie:.*SERVER=8 J; l$ ^+ R# z+ m! m# R0 S
$ J. V6 v4 P; M1 h
  See also: "reqadd", "reqrep", "rspdel", section 6 about HTTP header- p8 h& t- _( `* |; Z: C$ @
            manipulation, and section 7 about ACLs./ k' }3 C  F( _
$ l1 [  r$ e1 u8 L# l+ _

7 W% H6 T" u( d) `0 dreqdeny  <search> [{if | unless} <cond>]
' [5 m- L- E7 Z0 O% Breqideny <search> [{if | unless} <cond>]  (ignore case)) `+ A1 _4 j; C' E1 w
  Deny an HTTP request if a line matches a regular expression& p4 p# X. b, a2 G( a/ I: w" `  |
  May be used in sections :   defaults | frontend | listen | backend8 \9 k% [( K/ D4 c
                                 no    |    yes   |   yes  |   yes
0 w# @# _  `; {  Arguments :
, i; d+ X# N) S3 z- R, V    <search>  is the regular expression applied to HTTP headers and to the
- L- c7 J4 Q& ~' X0 a7 q              request line. This is an extended regular expression. Parenthesis
- Z7 U. K  b8 g# z6 Y- m: n              grouping is supported and no preliminary backslash is required.+ U5 m+ i7 O. x" {3 w- P/ d5 g
              Any space or known delimiter must be escaped using a backslash
% J0 `# p& Y! S# `              ('\'). The pattern applies to a full line at a time. The9 ?2 y3 O& n* g! L  Y) Q0 p
              "reqdeny" keyword strictly matches case while "reqideny" ignores
+ ]$ p" |6 z. b& @; i0 ?              case.
' j+ ~  x9 D0 q) E1 ?  u$ g; v* I
/ n' l: J: x- `7 d& |! ]    <cond>    is an optional matching condition built from ACLs. It makes it
; D8 y5 ]3 g1 @9 d5 @% S              possible to ignore this rule when other conditions are not met.& p4 P: h% L) z! |5 X8 L0 z- T
$ G+ ~5 P5 I: S; K
  A request containing any line which matches extended regular expression
( A5 G5 i, \; x; b9 J" n  o  <search> will mark the request as denied, even if any later test would
6 E) k- m  V- l$ a# d7 V  result in an allow. The test applies both to the request line and to request
1 p' v$ i- q' z3 g6 r/ }  headers. Keep in mind that URLs in request line are case-sensitive while! f& t" T- B* r$ f* B
  header names are not., Y. u0 C0 L4 z* s1 [" h

  c' f4 @  y' k# f( q* N  A denied request will generate an "HTTP 403 forbidden" response once the) [, r/ Y" `5 Q' V; V2 `
  complete request has been parsed. This is consistent with what is practiced
0 V# ]1 o( c. F  using ACLs.
$ T2 ]' _  N2 Q% m) c$ N
3 l. ^" \# m& h: X: X0 i  It is easier, faster and more powerful to use ACLs to write access policies.
" K1 [( u8 u4 B; V' O) u  Reqdeny, reqallow and reqpass should be avoided in new designs.6 |  W& J/ {' `* e6 Z  ^& D$ W% }; i
+ X' d. ~' k8 A
  Example :7 ]! H" E% ]* y
     # refuse *.local, then allow www.*
( @6 {5 x2 ^5 Q/ y# n; ]     reqideny  ^Host:\ .*\.local( k" _+ t7 w! R  {4 I. D- F% d$ O
     reqiallow ^Host:\ www\.
8 @! s/ b8 j) Q% s( X# z$ B8 K( x  Q: N, _9 O  ?1 Y* ~
  See also: "reqallow", "rspdeny", "block", section 6 about HTTP header
1 _, _& ^6 a% E& l8 x  t& i. G) M            manipulation, and section 7 about ACLs.9 E" Y' Z0 \3 c7 s: g

  r) z9 W2 y' e" f6 O" o' [
' X2 r. @5 s& Preqpass  <search> [{if | unless} <cond>]
* D. l9 S4 v) i% |2 U$ g2 Jreqipass <search> [{if | unless} <cond>]  (ignore case)2 T3 S8 d% A. ]: t' x2 `! q" }
  Ignore any HTTP request line matching a regular expression in next rules
4 V, r$ X- }0 O0 f6 O  May be used in sections :   defaults | frontend | listen | backend0 I1 X3 C3 o. |
                                 no    |    yes   |   yes  |   yes; F% U! V1 H% w$ x  ~$ i
  Arguments :
  Q& f3 z1 n" b" ]; e    <search>  is the regular expression applied to HTTP headers and to the
2 _1 h; }# n4 ]9 q( X( i              request line. This is an extended regular expression. Parenthesis
9 O" p  x7 P! S# G& V8 B              grouping is supported and no preliminary backslash is required., @, u( y7 Y, F5 F) l) N
              Any space or known delimiter must be escaped using a backslash
& B% w2 b' ?# O/ O9 ~! z              ('\'). The pattern applies to a full line at a time. The
, U+ ?6 ^; e1 e+ b              "reqpass" keyword strictly matches case while "reqipass" ignores7 t( g1 X. e& r
              case.
6 T/ [/ I" y% {8 x" ~0 d5 Z' R# g2 w* g
    <cond>    is an optional matching condition built from ACLs. It makes it
* T9 ?' ^- ^5 ~+ n* f. R+ p. i              possible to ignore this rule when other conditions are not met.
& \. F/ o' H7 G# y  ~6 V3 `0 U0 }! D9 x
. e4 o2 R) w2 v/ d& `) y& E& U7 B  A request containing any line which matches extended regular expression9 \1 z5 V7 k% Q2 h$ O* ~/ l+ O
  <search> will skip next rules, without assigning any deny or allow verdict.
+ X( ^& J, }/ c# k" ]/ N/ d  The test applies both to the request line and to request headers. Keep in
8 o: A' C1 U, \7 I7 P& @/ i2 Z0 H6 w  mind that URLs in request line are case-sensitive while header names are not.+ y0 U4 ]& ~9 [" K

- A# \, p6 [& R  It is easier, faster and more powerful to use ACLs to write access policies.! u$ i  o& C# X& ~
  Reqdeny, reqallow and reqpass should be avoided in new designs.
5 Z* D0 Q2 q) t6 [  F) [9 F  A3 N) \5 u+ C/ i! W+ I9 f! f
  Example :
" ~; O3 @& Q0 m1 c$ D     # refuse *.local, then allow www.*, but ignore "www.private.local"  U/ _. l/ i$ A. ^8 k. E" ~
     reqipass  ^Host:\ www.private\.local4 q8 N% }# X( I1 B& Y
     reqideny  ^Host:\ .*\.local
4 t1 a+ n- a6 ?2 G5 g, h9 t9 S     reqiallow ^Host:\ www\.# L( `1 o- H. u* ?
6 I" L  x. _9 G4 R; x
  See also: "reqallow", "reqdeny", "block", section 6 about HTTP header- F7 B/ u" R9 P
            manipulation, and section 7 about ACLs.
5 l: B9 q' x+ y1 [- I; C  T" @: T3 r( y5 f# {& m. u' {6 `; z  b/ ^
! S; A6 b0 Y+ H( ~5 @) V3 S
reqrep  <search> <string> [{if | unless} <cond>]
4 E* C! U% B7 ]2 v1 i; greqirep <search> <string> [{if | unless} <cond>]   (ignore case)8 C+ Y1 q; Y" t+ f
  Replace a regular expression with a string in an HTTP request line
9 ?9 g- M# P; k# J: w9 B% ?+ N  May be used in sections :   defaults | frontend | listen | backend+ D9 h: k* d2 P
                                 no    |    yes   |   yes  |   yes8 f$ ?3 i0 f" |  p% t* K. }
  Arguments :
* Q# L* @5 u* i  K% q% f    <search>  is the regular expression applied to HTTP headers and to the
3 B: ?0 t8 X* N, A9 X1 n% d3 N              request line. This is an extended regular expression. Parenthesis! M; h2 _* _4 ^
              grouping is supported and no preliminary backslash is required.
  C% A2 j, T1 i; h4 A              Any space or known delimiter must be escaped using a backslash4 a8 ?- ^+ h+ ^) S
              ('\'). The pattern applies to a full line at a time. The "reqrep"
6 @& D$ g) U2 o" K) _              keyword strictly matches case while "reqirep" ignores case.
, ~# O. _, @, c6 a! N% f, c% Y
7 T7 v+ `# n$ I& Q, t    <string>  is the complete line to be added. Any space or known delimiter+ v+ C& r/ W( _3 {" r4 V5 c
              must be escaped using a backslash ('\'). References to matched% ^8 {, F+ s$ ?: u
              pattern groups are possible using the common \N form, with N
7 Y. c) F. @' R# o              being a single digit between 0 and 9. Please refer to section2 K6 w9 W" b. @) Z5 X
              6 about HTTP header manipulation for more information.. h* ^. @% q" N9 D
8 L1 [+ I" t7 ~* x7 Y& J2 h4 j
    <cond>    is an optional matching condition built from ACLs. It makes it, |/ Q% ^( s9 }/ s" E3 c( X% D
              possible to ignore this rule when other conditions are not met.
* e& {! R$ `6 F) o' `" R& S; n' ]: G7 J8 o/ [
  Any line matching extended regular expression <search> in the request (both( |9 K' x( y: f+ _
  the request line and header lines) will be completely replaced with <string>.
) ]! t3 r$ I/ {  }  Most common use of this is to rewrite URLs or domain names in "Host" headers.
2 v+ [* u: v/ f7 M5 n) p: @
0 Q2 Y4 u6 ^+ H2 W: D: u' b  Header transformations only apply to traffic which passes through HAProxy,6 T0 t' h3 W9 |1 g8 o! K# r
  and not to traffic generated by HAProxy, such as health-checks or error- A# V4 q' o7 L8 _
  responses. Note that for increased readability, it is suggested to add enough$ Y, G% ~9 c" M( S0 P
  spaces between the request and the response. Keep in mind that URLs in
; g4 T( v- k" w0 _  request line are case-sensitive while header names are not.
0 S; A, u$ A+ C- M  k2 b1 Z& k' T; ~, N/ n
  Example :: K, a4 h7 j8 k' @
     # replace "/static/" with "/" at the beginning of any request path.6 N% F9 a: U3 [9 s* X
     reqrep ^([^\ :]*)\ /static/(.*)     \1\ /\2
6 W  h: [. U, }3 D     # replace "www.mydomain.com" with "www" in the host name.4 e5 ^1 }6 k2 K' ^1 m- X% {6 [6 U
     reqirep ^Host:\ www.mydomain.com   Host:\ www1 I1 w( w7 V: |0 P

- n! N, \; l3 d  {; U; _% U% C3 p8 G5 q  See also: "reqadd", "reqdel", "rsprep", section 6 about HTTP header! ~8 y, l2 I' H3 F0 _- @7 U
            manipulation, and section 7 about ACLs.
, j+ ?+ O) r6 W4 F0 w# Z9 Q1 m
2 D, ?: |9 w  H6 m: F# }  L- }3 o3 m" G. V5 r6 M5 {" ~0 h
reqtarpit  <search> [{if | unless} <cond>]
9 E6 U' z) B  M; T4 creqitarpit <search> [{if | unless} <cond>]  (ignore case)
: Q' d! H' K* h- }  Tarpit an HTTP request containing a line matching a regular expression
7 H" h$ b: H0 O& Z) T" n8 `" l  May be used in sections :   defaults | frontend | listen | backend
! D) o( [7 @0 @6 g                                 no    |    yes   |   yes  |   yes, R) n! O; ~7 K3 I
  Arguments :
. W) D/ q3 i  l$ d    <search>  is the regular expression applied to HTTP headers and to the. c# ]" m9 i, W2 z$ T% G
              request line. This is an extended regular expression. Parenthesis( O" K3 U# l8 A& D4 |
              grouping is supported and no preliminary backslash is required.) g7 g& e& k( m! d+ _8 o
              Any space or known delimiter must be escaped using a backslash
* Y! A; F& r  D              ('\'). The pattern applies to a full line at a time. The, @. I: @% d. o$ d- D
              "reqtarpit" keyword strictly matches case while "reqitarpit"
. I" x1 @: A' a8 R, ^0 D              ignores case.
& W5 ]9 y: c& y8 ^& _  y+ o! {
' q9 R$ @* b+ P* K: `    <cond>    is an optional matching condition built from ACLs. It makes it) t! T6 {7 Y" u. ^
              possible to ignore this rule when other conditions are not met.0 F4 i3 M% O6 v' y7 w9 U7 _
/ A% I9 x% G% P& N! H2 T# F
  A request containing any line which matches extended regular expression
0 L1 r: z% b! u# i  <search> will be tarpitted, which means that it will connect to nowhere, will
" s9 H# a& E7 S& {+ q' [. Y  be kept open for a pre-defined time, then will return an HTTP error 500 so1 e# v# t1 @" y$ _. U! I
  that the attacker does not suspect it has been tarpitted. The status 500 will# g0 _) A. P' m: p
  be reported in the logs, but the completion flags will indicate "PT". The
$ O% _7 V! }; M$ j6 f. n  delay is defined by "timeout tarpit", or "timeout connect" if the former is8 k* q3 |( }- W7 P
  not set.
: W) b0 ~" y& B: C6 A, V
5 r" U$ I+ _! n3 J  E  The goal of the tarpit is to slow down robots attacking servers with
% \, C4 |4 d8 n$ E) h+ y  l' j  identifiable requests. Many robots limit their outgoing number of connections
3 N# j. J1 q! k" Q" a  and stay connected waiting for a reply which can take several minutes to
2 [# M4 R5 K# Z+ F- m  come. Depending on the environment and attack, it may be particularly- q) s% D  p! P  W
  efficient at reducing the load on the network and firewalls.
. \4 s% W0 d; D$ B( r) [  E8 X+ x
  Examples :) N2 E- @, `5 ]  g9 G
     # ignore user-agents reporting any flavour of "Mozilla" or "MSIE", but, m" M* F1 @4 x) f' Y
     # block all others.( N8 f9 E) E1 r, f. ?7 r/ t
     reqipass   ^User-Agent:\.*(Mozilla|MSIE)! _  \  b0 e& l, P5 B
     reqitarpit ^User-Agent:' i' y) W( m& _! g9 N- u
1 |2 k1 G* }( u
     # block bad guys
# }( \" P/ C4 ]" x     acl badguys src 10.1.0.3 172.16.13.20/28. F: ~' V/ w4 S! Y& S& Q3 u
     reqitarpit . if badguys
. F* T9 _6 U; S
* T, W/ Q* m4 b' O  See also: "reqallow", "reqdeny", "reqpass", section 6 about HTTP header- C. h9 q7 ~3 k9 x8 Z
            manipulation, and section 7 about ACLs.
1 S$ g/ V$ k; |
, h% m9 c( V- A7 [9 W* \0 E# m% `
7 o9 f1 `: P- @/ L8 b) fretries <value>$ ]+ O" [, F. P5 L5 y8 _
  Set the number of retries to perform on a server after a connection failure7 E6 e/ d7 i- V2 R) {" w
  May be used in sections:    defaults | frontend | listen | backend
; q7 t  w7 S& X+ g$ L                                 yes   |    no    |   yes  |   yes
) m, Z7 S/ O' d/ B; S% r* q0 K  Arguments :
2 m) K" {8 f  N" |* F    <value>   is the number of times a connection attempt should be retried on
' I7 Z: U! Z8 g( p- V/ C4 v              a server when a connection either is refused or times out. The" u' P0 J7 {  J% ^& x% t! |
              default value is 3.
4 q: t* R* |$ P  T+ u  D2 t: l
! \6 z9 W! P9 {8 f( w7 _+ }4 g  It is important to understand that this value applies to the number of2 T4 {/ y3 e1 ~8 T3 ]) r
  connection attempts, not full requests. When a connection has effectively
! F1 c* Z- J: P$ E4 E  been established to a server, there will be no more retry.
1 p5 P. a# I' F8 G1 X  y+ S  S+ S
  In order to avoid immediate reconnections to a server which is restarting,
6 X) S/ Y  Y2 P5 S) S8 y8 `  a turn-around timer of 1 second is applied before a retry occurs.
3 J$ }. M( k9 j: ~' c5 @- S; G# P: [( Y% F% Y- Y; j, [) p
  When "option redispatch" is set, the last retry may be performed on another$ q9 H* {! T9 ~% i- x+ _- X
  server even if a cookie references a different server.
: Q! \  r! T1 Z+ @3 x" g6 Q/ T, o  M* C; d+ J
  See also : "option redispatch"/ A7 f2 A/ x( r" ~* L
- u+ h8 \# O% H; x5 b, J! Q. }: r3 k

' q+ a( O3 V5 e" Qrspadd <string> [{if | unless} <cond>]  Y& O+ ]8 Y! z7 r
  Add a header at the end of the HTTP response
' N! ^) k; L" R% I  May be used in sections :   defaults | frontend | listen | backend
$ f# K9 N* i; l. D  C7 e# i                                 no    |    yes   |   yes  |   yes
4 y. M; u0 F# b* K1 \: R: ]  Arguments :+ Z3 k# y: Y  s9 i
    <string>  is the complete line to be added. Any space or known delimiter! N) {- Q$ A6 B* b
              must be escaped using a backslash ('\'). Please refer to section0 O* c( h" k0 ~, \
              6 about HTTP header manipulation for more information.4 H9 w# g" C2 v% M: o( W4 @
5 V4 ?3 l' Q$ |
    <cond>    is an optional matching condition built from ACLs. It makes it
; R' g# s6 o' E3 ?% \5 p              possible to ignore this rule when other conditions are not met.
0 f7 ~/ P; ^8 T- E2 t$ M- Q! O( ?% q  N) D/ }: w
  A new line consisting in <string> followed by a line feed will be added after
) b' R+ `0 ?7 R! k- U7 M8 y  the last header of an HTTP response.4 G; F6 h  M; q+ n  C/ t5 l1 {

3 z$ j) g6 |& j/ m# P  Header transformations only apply to traffic which passes through HAProxy,1 r/ o5 C  v6 N5 q2 u" C
  and not to traffic generated by HAProxy, such as health-checks or error
) ?5 M& G9 Y3 k  t3 a5 x0 C$ ~$ K  responses.: S- P: X2 U5 ?; \, e' `
& g3 [8 g* [: A0 y! U
  See also: "reqadd", section 6 about HTTP header manipulation, and section 7
/ E$ F' K7 T2 m) u/ Q% c8 Y            about ACLs.) R  q$ O/ u* T2 O* c* A) i9 }
. }1 G$ K$ M" x# X$ C; m

3 U; u( U; ?( Y" a8 D5 x: M$ R: srspdel  <search> [{if | unless} <cond>]
* N3 e; ~: b) D. e% _rspidel <search> [{if | unless} <cond>]  (ignore case)
% ~9 K2 {. s5 x% M+ u  V" M  Delete all headers matching a regular expression in an HTTP response$ ^8 {: c7 W. h/ Z/ K$ L
  May be used in sections :   defaults | frontend | listen | backend. v3 O5 c& B8 O# R9 u  y
                                 no    |    yes   |   yes  |   yes% q9 @# p8 y+ ?  M) H
  Arguments :
/ Y6 j3 d0 I: L, T5 @' b    <search>  is the regular expression applied to HTTP headers and to the3 v: q! a. M. b% R
              response line. This is an extended regular expression, so
- B! K5 {- y+ a7 o5 p; T              parenthesis grouping is supported and no preliminary backslash
7 L( g! f; f" u, ]" ~2 L              is required. Any space or known delimiter must be escaped using
  n7 A( l3 {6 y, e* p3 U              a backslash ('\'). The pattern applies to a full line at a time." y8 F, W1 d' n8 _4 Q, i0 f
              The "rspdel" keyword strictly matches case while "rspidel"" P& k8 p4 U/ ~5 [( c3 Z
              ignores case.
6 ]+ B* ^8 G5 D  ]* _# A9 A) R
6 I: L* r. |2 T0 U, F7 W! l    <cond>    is an optional matching condition built from ACLs. It makes it
% S) ?3 [: f% N/ \: b5 \  y              possible to ignore this rule when other conditions are not met.+ N+ ~0 a& W( o6 B* J* y6 y
" Z$ A9 ~3 F3 w0 F" h
  Any header line matching extended regular expression <search> in the response6 M9 X  }( O# @2 K
  will be completely deleted. Most common use of this is to remove unwanted
% g- c8 R3 y( h) q/ ]/ R2 ~3 Y- A  and/or sensitive headers or cookies from a response before passing it to the- T5 Q6 y2 `# y, C8 q
  client.
; {. \3 u# R7 M! p( H# K; v% D  h; @; \3 W
  Header transformations only apply to traffic which passes through HAProxy,
# T( U& h) c( D6 T! k/ W% A' W9 Z9 ?  and not to traffic generated by HAProxy, such as health-checks or error
& a2 i& o: G6 d3 a5 h  responses. Keep in mind that header names are not case-sensitive.
/ [" ]$ n9 v4 P8 ]1 H) H
8 t1 E4 L, W2 Z+ Z7 L: A: [5 W8 O9 }  Example :
* [$ o5 U3 r( @& G$ N. p1 |     # remove the Server header from responses
+ i) g) W5 _6 \2 c5 `6 a     reqidel ^Server:.*
; J! P4 E# n$ }/ j! m# E1 ^8 `  Q, N5 g) Y* P3 x1 t5 V
  See also: "rspadd", "rsprep", "reqdel", section 6 about HTTP header5 ?1 j  T$ ~" e) O6 s$ F  Y
            manipulation, and section 7 about ACLs.
/ Y* G' r& l/ l& v
7 l/ l2 z' `, ~  n/ ?1 T
: X" h. F( [$ N8 R( }rspdeny  <search> [{if | unless} <cond>]
" D8 Y* `1 m* y8 J, Arspideny <search> [{if | unless} <cond>]  (ignore case)
, A. Z6 A9 g6 H4 r5 I  Block an HTTP response if a line matches a regular expression  r4 }: s4 ?* @9 S  D3 I+ ?' p
  May be used in sections :   defaults | frontend | listen | backend3 a1 i6 P5 K2 G  w
                                 no    |    yes   |   yes  |   yes7 F# t+ [) ]* V, i  M' p7 p' v7 R
  Arguments :& S; q6 _; [7 C8 W
    <search>  is the regular expression applied to HTTP headers and to the- D# ~& O7 E3 |0 q6 J
              response line. This is an extended regular expression, so1 q  Q' x. R3 ~' ^5 z
              parenthesis grouping is supported and no preliminary backslash2 B' h& r# l/ B; p; C  G
              is required. Any space or known delimiter must be escaped using
; H1 w) I" `' `; m: v% u+ v' N              a backslash ('\'). The pattern applies to a full line at a time.
* i% x# [7 P9 y( ~              The "rspdeny" keyword strictly matches case while "rspideny"
4 U7 F7 g4 x5 M1 P              ignores case.
6 r7 |3 t/ W1 U- |. \) ~* w5 K4 F, s  o4 X+ t
    <cond>    is an optional matching condition built from ACLs. It makes it
# F6 C, b3 G' Q9 U$ t              possible to ignore this rule when other conditions are not met.
9 S$ C: j; V2 h9 v: s% O/ U& b! _
& D- j. O! p. p" |! S& O  A response containing any line which matches extended regular expression
! Y/ N: f( E, A  N  C; W1 ~4 h7 |. t; ^  <search> will mark the request as denied. The test applies both to the* z, c( C) s5 i
  response line and to response headers. Keep in mind that header names are not* X, T4 K' h" k
  case-sensitive.
! D! F8 X3 {+ {; a: F* Y) r# i8 L1 [/ w
  Main use of this keyword is to prevent sensitive information leak and to4 U9 `' [% q0 C. [
  block the response before it reaches the client. If a response is denied, it
8 z4 I' ]1 x+ `& H, M5 S2 I5 M" M0 l& [  will be replaced with an HTTP 502 error so that the client never retrieves
% ]* t6 Q- o6 p  k  any sensitive data.0 L& Z. Q" U7 S' N& G* Q& {
1 T. H7 M# n' b- w+ q; {
  It is easier, faster and more powerful to use ACLs to write access policies.
8 \9 i5 E% \  [7 t' U0 ^+ W  Rspdeny should be avoided in new designs.
! ]' _9 s. r) A' ]1 W" n" Q  K8 a5 i5 t1 S8 m
  Example :( k' B/ H7 Q( a/ j, H
     # Ensure that no content type matching ms-word will leak
2 R7 ?* ]- d" g- F+ c' }/ ]     rspideny  ^Content-type:\.*/ms-word0 O/ `3 W$ w, B+ L; h$ J
+ f4 S9 ~" n& K
  See also: "reqdeny", "acl", "block", section 6 about HTTP header manipulation
/ U8 Y2 v2 T6 D& j            and section 7 about ACLs.
. [( l" u4 @$ X  ^* V9 z! a2 o1 S7 e& T; d6 U" D  A
4 z5 j! R: ]! O+ v6 I7 T
rsprep  <search> <string> [{if | unless} <cond>]
2 J+ O$ @9 |1 ]8 w5 H# ?; brspirep <search> <string> [{if | unless} <cond>]  (ignore case)
; ]0 G  g& f# D5 D- W  Replace a regular expression with a string in an HTTP response line
  _& V# S8 N0 Q& P! |; ~  May be used in sections :   defaults | frontend | listen | backend
  Z/ ?9 g1 K3 {: z                                 no    |    yes   |   yes  |   yes
8 g: Q/ B# Q5 W  Arguments :1 B5 F% ?# V' n. x; P, X/ j
    <search>  is the regular expression applied to HTTP headers and to the
! o8 w. t' l2 k              response line. This is an extended regular expression, so
1 w( j2 W3 a% h# Z3 k% ?7 N              parenthesis grouping is supported and no preliminary backslash
8 w3 f7 E8 a* ]              is required. Any space or known delimiter must be escaped using& _+ k8 s! Z+ B0 h
              a backslash ('\'). The pattern applies to a full line at a time.: u& R0 [" b* n1 V
              The "rsprep" keyword strictly matches case while "rspirep"
- a- {5 D$ [' Z6 ^              ignores case.8 l% q: X- I  C) t7 [$ x1 a
* n/ w# k+ B  D* u- ?# e
    <string>  is the complete line to be added. Any space or known delimiter: Y, t0 i6 u9 l" V" _9 b2 Q4 M
              must be escaped using a backslash ('\'). References to matched
' F0 e* S, c1 b) J2 n6 v              pattern groups are possible using the common \N form, with N
4 ?+ ~9 x4 V! W& g- i" T3 |              being a single digit between 0 and 9. Please refer to section( w: v! Y8 F9 _0 {9 W
              6 about HTTP header manipulation for more information.
% A4 U; z# Z: }3 X; I4 U  O: B
3 o% n4 Y  n6 W5 Q3 _: `( \2 l    <cond>    is an optional matching condition built from ACLs. It makes it) L# D. `; L+ C1 I
              possible to ignore this rule when other conditions are not met.. V9 U$ m& i8 O( l. S+ l; J

! g: q+ L; u% ?# n' x  Any line matching extended regular expression <search> in the response (both
$ Z# f6 q. D5 p6 I  the response line and header lines) will be completely replaced with
3 P) B' O. I% [  v  @. Q7 M  <string>. Most common use of this is to rewrite Location headers./ d& |7 z+ E' B

2 R2 z* F3 q% K7 H- _& \, [( i0 O  Header transformations only apply to traffic which passes through HAProxy,
1 I  k7 X4 V+ z( G9 t  and not to traffic generated by HAProxy, such as health-checks or error
% l2 d# I( [' |  responses. Note that for increased readability, it is suggested to add enough2 P2 x; |) G0 i+ ?( Y
  spaces between the request and the response. Keep in mind that header names
) `0 I, I5 K0 U  are not case-sensitive.7 P$ _1 @' F% Z$ }
. h& R* G8 l4 i* e" }3 C
  Example :
7 E' d- b7 D$ y$ W# @. L/ L. j, k& \     # replace "Location: 127.0.0.1:8080" with "Location: www.mydomain.com"
$ O3 b0 L2 R* i8 s: I     rspirep ^Location:\ 127.0.0.1:8080    Location:\ www.mydomain.com
( ?7 Z# J$ F+ x3 M3 m. S1 m' X! _  `- v0 d
  See also: "rspadd", "rspdel", "reqrep", section 6 about HTTP header% D% R7 ~& l% U8 H
            manipulation, and section 7 about ACLs.3 s  C! g; n3 _( [4 v+ D8 L- c

- x0 m- N4 u8 E9 p' a# d) i. a
server <name> <address>[:port] [param*]
+ t4 J/ i. ?# o# {  B  Declare a server in a backend
3 D& o4 g5 r6 Q2 `' d! `; c8 m  May be used in sections :   defaults | frontend | listen | backend
' J8 ^% S0 A6 P; F& {( m- E1 `                                 no    |    no    |   yes  |   yes
. y3 c! _4 r$ J9 _  Arguments :4 t8 z& V& g& ~# J
    <name>    is the internal name assigned to this server. This name will
( _) P2 ~: `0 v) B2 Q7 s( X              appear in logs and alerts.  If "http-send-server-name" is. X& K* L; \% h5 X
              set, it will be added to the request header sent to the server.' o# ]2 W; V( T" R. J

3 y# e+ B4 P8 U0 y6 a# K& t    <address> is the IPv4 address of the server. Alternatively, a resolvable" ]" J; z' g; R: w7 W
              hostname is supported, but this name will be resolved during
3 n0 K  ^6 v6 z2 _" z' |& M              start-up. If no address is specified in front of the port, or if- c6 A* s, @1 X, y) F
              address "0.0.0.0" is specified, then the address used will be the, Q0 D( e" l8 W. P  x+ z
              same as the one used by the incoming connection. This makes it
* z& p2 w! L0 Y1 N: ]              possible to relay connections for many IPs on a different port or
3 @* {! w6 B. Q. K; E              to perform transparent forwarding with connection limitation.3 }7 O9 W/ f6 q0 z/ b. o% O

5 X1 G2 X( J' f! b    <ports>   is an optional port specification. If set, all connections will
! u* J! R) |( ^& N3 B3 D' k              be sent to this port. If unset, the same port the client
( i# L% ]7 h) l9 Z, f' T: b              connected to will be used. The port may also be prefixed by a "+"
$ N- d, p" p; d% Q              or a "-". In this case, the server's port will be determined by
, o, C0 X) A7 U8 {" X              adding this value to the client's port.; B7 Z3 G( b- Y+ O- ?
' C0 U: U3 S, L0 Y9 o/ }+ E
    <param*>  is a list of parameters for this server. The "server" keywords: Y4 {" w7 f) g  A( S! v, ?- L( A
              accepts an important number of options and has a complete section( m: o: B' x1 U% [1 V6 G2 c4 e; v
              dedicated to it. Please refer to section 5 for more details." B" R3 S2 q1 L3 i2 w& d  M" P
* H& @) \3 w) E' T. S
  Examples :
- X! j1 y; H: ~0 \! u2 w/ B        server first  10.1.1.1:1080 cookie first  check inter 1000& y# K8 }7 I; [5 p
        server second 10.1.1.2:1080 cookie second check inter 1000* Z3 Z( G. M( H! `1 H
9 D; L) Z6 E( U
  See also: "default-server", "http-send-name-header" and section 5 about
6 C/ R2 D  @" h  Z             server options0 o! D& X; ]7 Z9 v
2 C2 b& l1 n1 O+ o) Q3 M: b

3 `" E* Q! z8 c7 Esource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
( K: q; y( g$ N# T4 L# C* tsource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
& a1 X( I( Z6 k- z6 ]/ u% b5 bsource <addr>[:<port>] [interface <name>]
7 ^! c9 t  Y4 P  Set the source address for outgoing connections
' d- ^  |+ T2 ?1 a  May be used in sections :   defaults | frontend | listen | backend
# S6 S- T3 B4 n3 e                                 yes   |    no    |   yes  |   yes, W# v9 @' u5 E9 }
  Arguments :. m& [* l! k% U( }: Y
    <addr>    is the IPv4 address HAProxy will bind to before connecting to a, f2 G  x* L, Y' w1 @. G
              server. This address is also used as a source for health checks./ B. ^# E; j/ h% p! S
              The default value of 0.0.0.0 means that the system will select
! Q. o/ W  K. A              the most appropriate address to reach its destination.$ Q7 b" k, J: p* I" @  \& Q( D: Y6 D0 q2 Q

+ X6 L9 g5 `, t+ k! T# T% q    <port>    is an optional port. It is normally not needed but may be useful1 F% t2 R5 D$ ]
              in some very specific contexts. The default value of zero means
( f( T) U8 p  c9 k8 ?              the system will select a free port. Note that port ranges are not, ^; j( J9 Q9 m. Z( H- @6 R
              supported in the backend. If you want to force port ranges, you4 |% Y7 o! s# l2 ^& u
              have to specify them on each "server" line.
5 Q6 g5 O. h( z; Q
8 U  W1 h0 f" t' u7 L1 j+ D& M    <addr2>   is the IP address to present to the server when connections are
2 }0 f' A2 c2 D. j! [              forwarded in full transparent proxy mode. This is currently only; L9 Z2 `# k+ I: D0 e* M
              supported on some patched Linux kernels. When this address is$ ?6 c$ _4 O/ i: q8 G$ ^
              specified, clients connecting to the server will be presented8 X7 M9 ?; R% H
              with this address, while health checks will still use the address( }1 D" o* k: ^1 D) N8 R) }
              <addr>.
# p% M5 q( h5 c5 y: C" {3 L3 U: l- w4 h9 G) D5 U
    <port2>   is the optional port to present to the server when connections1 m* O, ^, p9 U) o) L( H
              are forwarded in full transparent proxy mode (see <addr2> above).
) ~7 n- @5 h- _& v5 i              The default value of zero means the system will select a free7 o: ^% M6 j4 H, x0 A
              port.1 d/ x1 `* s; }- r/ y
9 j/ _3 t1 E: x4 R  N" x9 C
    <hdr>     is the name of a HTTP header in which to fetch the IP to bind to.* v& Q8 V2 `/ z/ f( ?9 f
              This is the name of a comma-separated header list which can+ j6 e% F( T( o
              contain multiple IP addresses. By default, the last occurrence is' s0 E+ D$ i& O! A1 @9 Z
              used. This is designed to work with the X-Forwarded-For header; b2 ~7 x, \2 j# z
              and to automatically bind to the the client's IP address as seen
9 v0 F. \' Y+ x% M( y              by previous proxy, typically Stunnel. In order to use another8 |* L( F9 r  p% B2 F' y
              occurrence from the last one, please see the <occ> parameter2 i- l2 S% K4 A" N$ @; ~
              below. When the header (or occurrence) is not found, no binding
1 v# c2 y7 M1 v8 b' {              is performed so that the proxy's default IP address is used. Also
( b4 h4 h. Q6 r; m$ y$ g: b0 R              keep in mind that the header name is case insensitive, as for any
+ o4 t: H# Y$ {8 g7 B              HTTP header.
, \( E- R, i6 `  Y: r/ T( D
( t8 R7 s, |! P) a  R8 C2 H6 }    <occ>     is the occurrence number of a value to be used in a multi-value9 I. @! s, ^! n( r+ ^
              header. This is to be used in conjunction with "hdr_ip(<hdr>)",
% e" H/ C  M4 h              in order to specificy which occurrence to use for the source IP
* Z! X" s9 M% P              address. Positive values indicate a position from the first
6 H# s) ~7 q4 p# @0 a% ?! D2 i              occurrence, 1 being the first one. Negative values indicate
8 C& U1 Z" z* r  i1 B+ R              positions relative to the last one, -1 being the last one. This7 {# z, W  A" Y5 N8 T% d9 `6 `- ]8 h
              is helpful for situations where an X-Forwarded-For header is set
: X6 s4 R" [5 _0 j! H. Z              at the entry point of an infrastructure and must be used several
5 L7 W9 L: |: H              proxy layers away. When this value is not specified, -1 is
' ]/ i* y2 U9 P" v* o6 V              assumed. Passing a zero here disables the feature.
# h: L) h5 B2 n$ B  t; K4 y8 a$ i( t, D& b1 s8 T/ r) l* B$ y
    <name>    is an optional interface name to which to bind to for outgoing
- A7 Y: w) A8 v; i4 \              traffic. On systems supporting this features (currently, only8 {$ G8 Y8 A4 g, O
              Linux), this allows one to bind all traffic to the server to: r% ^" A( G# p) m/ }
              this interface even if it is not the one the system would select
  i9 A% O* f4 [# E# W( g              based on routing tables. This should be used with extreme care.
. G: Y; C- R2 H* N! q7 k* [: y, ]              Note that using this option requires root privileges.
' ~$ M3 C: t5 d( E  W3 l, k: A6 R9 ]  t/ H
  The "source" keyword is useful in complex environments where a specific
  I/ D- L' m. C% }9 p: r. E" l  address only is allowed to connect to the servers. It may be needed when a0 G( Q- \% Z5 Q/ a& t/ l) Y( ?
  private address must be used through a public gateway for instance, and it is
" n' @& e- p, ~# d% |  known that the system cannot determine the adequate source address by itself.
- J0 n4 Z1 n, Y' Z
8 ^$ f, j# K2 g, B. g  An extension which is available on certain patched Linux kernels may be used1 V$ S' V0 S0 T( t! C9 Z
  through the "usesrc" optional keyword. It makes it possible to connect to the
- c+ p0 g; b* \7 m  G8 }  servers with an IP address which does not belong to the system itself. This% U2 ]4 S4 b' m$ o$ ]+ i
  is called "full transparent proxy mode". For this to work, the destination/ a, @% w7 u; c1 P& P
  servers have to route their traffic back to this address through the machine
1 f# s7 R) m1 b* [! F% M, y  running HAProxy, and IP forwarding must generally be enabled on this machine.
8 H3 p5 V6 j! A# Z( }% }. D9 w. X* R% x& x
  In this "full transparent proxy" mode, it is possible to force a specific IP6 H8 C2 Q5 O) \% g2 c' P/ F
  address to be presented to the servers. This is not much used in fact. A more
; s' A; ], _" ]: s  common use is to tell HAProxy to present the client's IP address. For this,
$ r  E: Y, {+ G3 Q9 ]  there are two methods :
9 k3 N4 V3 \7 z' S+ h; a$ |/ k' k7 h, D5 b" o. F' i
    - present the client's IP and port addresses. This is the most transparent
( N8 o, }, J; G      mode, but it can cause problems when IP connection tracking is enabled on
5 E( K% `! _' A+ L      the machine, because a same connection may be seen twice with different8 s5 v9 X! X8 x0 B4 U4 P! P  I' R
      states. However, this solution presents the huge advantage of not. a2 n5 a& s2 y6 j' B# |4 l+ p4 H6 v
      limiting the system to the 64k outgoing address+port couples, because all# _" m) k4 Q9 i! n$ r$ e
      of the client ranges may be used.
5 u6 L2 N* u; F) p$ C
# C' y8 @- q( K* t6 ]: m- u! I% l2 ~    - present only the client's IP address and select a spare port. This
. ~, n5 i4 ^  ?      solution is still quite elegant but slightly less transparent (downstream
* D# q! J$ o6 x1 ?0 X      firewalls logs will not match upstream's). It also presents the downside* {/ c& o+ D% H  E9 k- B
      of limiting the number of concurrent connections to the usual 64k ports.
2 W! Z  Y( `" T! U, O1 h" L      However, since the upstream and downstream ports are different, local IP8 W5 Y0 g$ d/ k; K9 t) r) w
      connection tracking on the machine will not be upset by the reuse of the+ G4 h& c# y* z
      same session.
  H% m1 B0 x( C% S, b4 D7 Q- R; [, n, I- P6 F# b0 x, d0 B- C( X
  Note that depending on the transparent proxy technology used, it may be$ W( K; X( b: R! x3 ?# v
  required to force the source address. In fact, cttproxy version 2 requires an1 M9 y+ A8 y9 [; p: f) Q  l7 b
  IP address in <addr> above, and does not support setting of "0.0.0.0" as the
5 t- u1 P$ ~5 c' r1 P7 Z4 v  b  IP address because it creates NAT entries which much match the exact outgoing" B( V' O; |$ u7 o% U
  address. Tproxy version 4 and some other kernel patches which work in pure
# e- H1 U, N1 B% y3 k) V  forwarding mode generally will not have this limitation.
& B- ^, F$ ~! w& R
. g0 a: P; m, c9 I. O5 ]  This option sets the default source for all servers in the backend. It may
) E* H9 G1 S3 a6 i9 f  also be specified in a "defaults" section. Finer source address specification$ E4 p3 l8 W5 l5 P3 b
  is possible at the server level using the "source" server option. Refer to
0 w: V7 s! F' H/ R8 o# `. d  section 5 for more information.
/ f/ @9 p7 R1 ]; o9 }+ P* C4 _% }9 r; J+ @0 d
  In order to work, "usesrc" requires root privileges.3 u- l) `" e: {; p# m3 Q. ?

9 x8 l5 U. o7 w: |; u5 t$ M& }  Examples :5 Y+ D4 K# W8 D$ V( n
        backend private' [. g, `2 T. @
            # Connect to the servers using our 192.168.1.200 source address
: M2 w" s5 S: H, L            source 192.168.1.2005 ?) ~- _: r' W! f0 y) y' |
# ^# ^! }2 n  x6 {) A, n% T6 @5 g
        backend transparent_ssl1
) }# Q2 E' O! ?$ h' h. [            # Connect to the SSL farm from the client's source address9 A2 o/ e- n; s* I+ V" \
            source 192.168.1.200 usesrc clientip3 r( x8 q3 B: G& N: C
: H( K! C3 U5 j) P+ P+ T
        backend transparent_ssl2( s$ T( [7 \( O. U. v0 [3 Q/ q
            # Connect to the SSL farm from the client's source address and port# E& k) s) @$ a0 u& Z
            # not recommended if IP conntrack is present on the local machine.
( l7 @7 z7 d, K' i) Y" u& v( A5 Q            source 192.168.1.200 usesrc client* w7 ^1 E! |/ V" Q9 I7 c+ k# d( j
- u& j8 c! T  L% t
        backend transparent_ssl3
, N" H. ]5 t# ^: G+ Z9 k0 v; d            # Connect to the SSL farm from the client's source address. It
: |2 F. {% F% n8 ^7 n            # is more conntrack-friendly.! I: b! [6 e. e; O3 ^7 M- L; r
            source 192.168.1.200 usesrc clientip, J" C/ w8 b4 r/ ^" {# V

5 ]$ x# z3 O& }( i7 k        backend transparent_smtp! K; O/ V3 ]! \) f7 e% Q  w
            # Connect to the SMTP farm from the client's source address/port' w5 Q- y. f& S9 o
            # with Tproxy version 4.( Q( W/ m; j4 A5 z/ K+ e
            source 0.0.0.0 usesrc clientip
3 ~, V! m7 a# ^7 q0 Y
3 C6 t$ }% l% e0 Q4 S, b' Z        backend transparent_http& o. C1 a5 g% q2 B
            # Connect to the servers using the client's IP as seen by previous; O, e3 i. S  _3 m- Z
            # proxy.  l' _! T# [% R1 \
            source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)
2 y" z" J* T9 n. A0 p; u* l. s) \5 E: y# c6 w% N8 |& I
  See also : the "source" server option in section 5, the Tproxy patches for+ v, l+ R$ H, l7 j  g' L4 k
             the Linux kernel on www.balabit.com, the "bind" keyword.
+ @# S# _' h6 }7 B) s/ g* @6 r
% h% i/ t% z/ B' ~8 `* o  D& V: B/ n4 O
srvtimeout <timeout> (deprecated)
/ e- X. Z$ ]( W" H9 c, r  Set the maximum inactivity time on the server side." e3 l( P$ I  Q
  May be used in sections :   defaults | frontend | listen | backend
0 M2 o  ?8 H% c( b                                 yes   |    no    |   yes  |   yes+ S* T4 x) B& S/ j4 j5 I0 o
  Arguments :
9 S! D& f" W. }$ R, ^( x    <timeout> is the timeout value specified in milliseconds by default, but3 F' v/ f6 v  l3 f
              can be in any other unit if the number is suffixed by the unit," c/ E, S# o4 M8 V9 o0 h# A9 H
              as explained at the top of this document.( P; V/ Y+ J) S' T# h  h4 y+ J7 o# x9 U
) }5 z- d3 J  Q3 J) y: }9 }! A
  The inactivity timeout applies when the server is expected to acknowledge or2 [! [# W3 o  |& s7 T, M4 B
  send data. In HTTP mode, this timeout is particularly important to consider
, l+ g9 k- A8 D5 j2 M) z. T  j% [( m  during the first phase of the server's response, when it has to send the
4 h" Q" `1 u3 n! O6 F5 v. ]  headers, as it directly represents the server's processing time for the
. {* {, t$ s  u  request. To find out what value to put there, it's often good to start with7 @( o  v$ c* }5 `8 J+ p
  what would be considered as unacceptable response times, then check the logs, d( W9 ~4 ~0 O6 i/ B( i+ ]
  to observe the response time distribution, and adjust the value accordingly.
$ G3 `9 P& V$ Q; o3 `5 O* D( T
, B" ?# {! G  x  The value is specified in milliseconds by default, but can be in any other& Y; _+ R: h6 y: w& d6 k9 U
  unit if the number is suffixed by the unit, as specified at the top of this
( y6 r5 I1 i$ s4 I2 N  document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly- g$ u; }! C/ R
  recommended that the client timeout remains equal to the server timeout in
6 v+ Y! l8 a+ j2 z$ p  order to avoid complex situations to debug. Whatever the expected server% u% w6 _& k  P8 D* W
  response times, it is a good practice to cover at least one or several TCP( p& a& M8 J3 L+ O
  packet losses by specifying timeouts that are slightly above multiples of 34 m- {4 S+ ^, G3 `
  seconds (eg: 4 or 5 seconds minimum).
. R1 a, c' P' o4 Q' v
$ A3 m/ Z0 v7 G0 O' `- }5 G  This parameter is specific to backends, but can be specified once for all in2 H6 O2 v7 A# @; d2 `
  "defaults" sections. This is in fact one of the easiest solutions not to
; G4 _1 K4 E7 t$ T; i  forget about it. An unspecified timeout results in an infinite timeout, which
: @* m: N" ^/ a* T  is not recommended. Such a usage is accepted and works but reports a warning4 l+ p1 F) |2 y
  during startup because it may results in accumulation of expired sessions in% e2 X* @! M/ \; h# z( w! a
  the system if the system's timeouts are not configured either.
. z$ ^& N. G3 f
  B' o: y: }9 r  This parameter is provided for compatibility but is currently deprecated.
0 ~) g+ L0 {* B$ A8 @( |  Please use "timeout server" instead.: o. F3 W' E+ ]& }7 x% T
" G( ]6 I  W4 I! d2 \! e# ]
  See also : "timeout server", "timeout client" and "clitimeout".* f/ A+ R+ m: }" S3 H! I; ?
! l* P2 m5 A( L! b" r9 W, Q
3 U5 j5 C1 v# o' z" A
stats admin { if | unless } <cond>
, J) k3 r1 Z& h( d/ O7 z4 f  Enable statistics admin level if/unless a condition is matched7 X  ]) o) ?8 a  d) n0 d! n
  May be used in sections :   defaults | frontend | listen | backend! x. W  F/ l' |! y8 Y  N6 p3 v
                                 no    |    no    |   yes  |   yes, c! j7 A! u" v$ m

6 m' d) u: q8 _. w  This statement enables the statistics admin level if/unless a condition is
$ H5 [7 o+ ?" \# V  matched.5 ?3 x% v% i# c  {
; ?: s5 k, |+ t% r
  The admin level allows to enable/disable servers from the web interface. By. j( t% ]( i* Q1 X& C0 o/ X
  default, statistics page is read-only for security reasons.
( L8 [4 z9 t5 j9 V4 t: H2 J: h3 Q7 [3 _( A6 p+ c( |
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
! z1 J+ X, o4 C# f+ P: v3 z& O9 p         unless you know what you do : memory is not shared between the
6 b& e1 {8 \: K         processes, which can result in random behaviours.* Y7 g7 S& T& G0 X
2 A4 {! A7 Z+ k1 i* A4 u
  Currently, the POST request is limited to the buffer size minus the reserved
9 Y7 r" ^; e7 i0 _  buffer space, which means that if the list of servers is too long, the; G4 m% H7 X' [% y# y9 r7 ~3 z
  request won't be processed. It is recommended to alter few servers at a
/ ]/ Q* Z5 |; I, {  time.
+ F8 b3 ]- C- R( h! @0 i: l: E- w: i2 d% P* L3 J
  Example :
; N- [' W5 ]6 }' P8 L3 \    # statistics admin level only for localhost, W* g; g6 J. D- e4 S
    backend stats_localhost/ J* m. b/ J2 {5 ^
        stats enable1 |8 f  n9 b* c( q" `  o* Y6 s# ?
        stats admin if LOCALHOST
3 H- S1 o9 J9 H1 z% N8 g$ |& r. a8 P6 M: x/ F: A2 s( r
  Example :; Y2 [) k! l7 i& G, h0 z
    # statistics admin level always enabled because of the authentication; W8 T' ^; E7 x  v
    backend stats_auth
# w5 m1 j: `5 _/ Y2 z8 {3 U        stats enable: y/ P5 ?  M) Q- G4 ]
        stats auth  admin:AdMiN123
" ?' k" ^6 m/ |. q5 c6 A2 D        stats admin if TRUE
* j( j2 e5 v9 \- y
! [6 N3 B+ B: V  Example :
: Q3 `% \, z" J7 W2 p* n0 A* p    # statistics admin level depends on the authenticated user
. e1 u# J" n6 Q+ c    userlist stats-auth
; H2 m" q% [- J0 T        group admin    users admin
! i7 |# o' M, v4 Q; ^        user  admin    insecure-password AdMiN123) R- I  S, W9 N6 N& A
        group readonly users haproxy
) e3 G. @9 z6 s) E& @& o0 ]5 v/ q        user  haproxy  insecure-password haproxy
. _% i% l& b, G, `4 a* T+ ?
6 b, h  u) e: A- [8 Y    backend stats_auth
0 {/ X' l$ r: f; F/ j        stats enable9 i6 X9 W8 \% C/ |
        acl AUTH       http_auth(stats-auth)
# j4 ^8 Y4 ]6 o) T; k: V# _* W        acl AUTH_ADMIN http_auth_group(stats-auth) admin
2 D# X* `$ B' i! E! k7 u$ u$ d        stats http-request auth unless AUTH3 x9 m; ~& b$ A' s
        stats admin if AUTH_ADMIN7 T. r% Y  K! n1 J# j

& ?: _4 s; A  f" v2 ^0 i/ U* W: t  See also : "stats enable", "stats auth", "stats http-request", "nbproc",
8 E$ o4 k* e& u( f. l  y             "bind-process", section 3.4 about userlists and section 7 about, r" e9 j8 r# C
             ACL usage." d4 j6 J" p, k5 b' ?, q9 c
9 A; u! Y. c' c7 X* w! C2 g

2 q7 L' r; k/ g! K4 Sstats auth <user>:<passwd>
; K  q: W3 P. T  e  Enable statistics with authentication and grant access to an account1 B" Y& V5 `4 Z1 e6 K
  May be used in sections :   defaults | frontend | listen | backend
9 w# _, P) v( s2 M6 g3 o2 P                                 yes   |    no    |   yes  |   yes
; h! x7 ]% K& N* r6 L8 w  Arguments :
! Y6 l6 T4 G' R  T& o% e    <user>    is a user name to grant access to) D4 t- J8 }$ R% H

& U1 H7 A( r8 n5 d. Z# Y    <passwd>  is the cleartext password associated to this user: b7 ]1 L  g/ z& g1 F+ [( [# s
0 X5 W  n0 S* X
  This statement enables statistics with default settings, and restricts access( O* c' a8 v' v" c
  to declared users only. It may be repeated as many times as necessary to
  H* g  o0 L$ s0 Z# m: Z5 M  allow as many users as desired. When a user tries to access the statistics
9 i6 T3 L4 J2 K  without a valid account, a "401 Forbidden" response will be returned so that
: U* _0 g# ]+ h, {; k  the browser asks the user to provide a valid user and password. The real
" w+ ?0 E; q7 v1 }' V' m& ]; W( e  which will be returned to the browser is configurable using "stats realm".
3 m9 \* q, B: |
$ o: ~6 y  [+ t# w4 s' n  Since the authentication method is HTTP Basic Authentication, the passwords
; {% D4 N+ b  {7 t; G  `  circulate in cleartext on the network. Thus, it was decided that the
3 Q9 d0 S9 T9 U' n8 i  configuration file would also use cleartext passwords to remind the users
& e5 X2 w1 M& N/ y* w  that those ones should not be sensitive and not shared with any other account.7 }' b! p8 f5 z

: F% T4 \, d* i9 s; W& z& S. @' a  It is also possible to reduce the scope of the proxies which appear in the
* U5 }1 e5 U/ j0 G2 g  report using "stats scope".
. \; |# F6 n  K) m. q, J- T# W) v1 A$ b( ^0 v9 }0 F1 d$ u, |
  Though this statement alone is enough to enable statistics reporting, it is
6 E- x' H" ]' f/ S4 @3 t  V! c  recommended to set all other settings in order to avoid relying on default  B5 u0 p* d3 }* E1 V& k8 K
  unobvious parameters.8 C8 M. P+ l0 x7 k/ E/ e

/ u: q8 I2 Y/ A: E6 g9 e  Example :
5 L( K, f+ @) L' u2 b7 \    # public access (limited to this backend only)
, b  ^& K" u" ?7 R' U- c: N    backend public_www
. ?' e" n7 h/ j- E1 B        server srv1 192.168.0.1:80
5 y' n7 H. ]5 F; n        stats enable
$ J9 J- O; T- o  [% h* A) u% S        stats hide-version2 H; \5 P. n. w  D
        stats scope   .$ L( s- ]8 f4 ^
        stats uri     /admin?stats
! z( b+ C4 x& N, e+ b* R! Y        stats realm   Haproxy\ Statistics
; v; S4 T: o2 k5 t) _) j) y3 E        stats auth    admin1:AdMiN1239 K+ A3 R) A! w1 z6 s1 X9 y
        stats auth    admin2:AdMiN321
. m# z5 ~$ d2 C4 A& o' U3 N) q( x7 p" x5 @" d
    # internal monitoring access (unlimited)
! ]+ Y1 T7 F" k. ?( Q" B$ u- o0 T    backend private_monitoring, D5 M1 J# R3 H, l# c5 m
        stats enable! Y$ p3 b3 S* i& C
        stats uri     /admin?stats  H9 D3 k, N3 w3 s: N
        stats refresh 5s  n' ^3 u, n8 M, b
$ U/ D9 w0 ]  L" E/ h! Y" J
  See also : "stats enable", "stats realm", "stats scope", "stats uri"
4 \. q' W% K% W& X- k+ r
- _$ a5 g7 _2 o2 F/ d6 q7 B1 l$ B; T3 K$ H- }
stats enable
! G, m6 y" E" A) d  Enable statistics reporting with default settings
  ^$ @( n, @1 P$ K4 F  May be used in sections :   defaults | frontend | listen | backend
3 q1 R, f, |0 X- \; y5 N                                 yes   |    no    |   yes  |   yes
! J3 u& @& e& q) C  Y. g8 q  Arguments : none
9 Q: p' g; k) j
/ P6 B6 p! d. a5 ]4 u* l. N5 x% M  This statement enables statistics reporting with default settings defined
$ x% X4 A8 f* {) F  at build time. Unless stated otherwise, these settings are used :
; S1 J: p# w1 O+ F7 \    - stats uri   : /haproxy?stats7 N/ x5 Z2 ?8 O2 _3 W
    - stats realm : "HAProxy Statistics"% Q1 f, e, x7 O# A+ j7 c
    - stats auth  : no authentication4 M* ?; @# U! V
    - stats scope : no restriction3 f0 w. p* E1 l# X& C! Q

* }  S9 ^2 [  O# z) m7 |  Though this statement alone is enough to enable statistics reporting, it is
8 m2 @9 p# `) r9 C' M1 p# P  recommended to set all other settings in order to avoid relying on default& D* _. s& l; V. a! J
  unobvious parameters.1 S3 X, z0 Y9 m
" ]( _  r0 i/ t+ P- T: `- `
  Example :
! N  [+ U: g& J; [    # public access (limited to this backend only)  n. L4 |- Y3 P4 r# g
    backend public_www: B& Y: m! r3 G$ F
        server srv1 192.168.0.1:804 F" G6 A* K$ A( x* S9 M: G9 `- N4 Z0 k4 W
        stats enable
1 V; H( |- H& n        stats hide-version
0 O. F4 s! B0 u        stats scope   .1 r5 z1 _1 F+ Q& l/ D1 Y
        stats uri     /admin?stats
. \) r5 ]$ x% @- [        stats realm   Haproxy\ Statistics
& c# F- i9 G8 c) m" d        stats auth    admin1:AdMiN123( ?& b% ^9 N+ m: z4 C! y' T# O
        stats auth    admin2:AdMiN321
6 b2 K' C5 _: n% d7 y
8 w2 Y& d$ h  N5 J% f( \- x# p; l    # internal monitoring access (unlimited)- l2 Y/ K2 a7 x( W
    backend private_monitoring
: A& y1 E2 F. R6 L9 E2 I- |        stats enable. R# S2 p5 o6 V( l
        stats uri     /admin?stats% Y( \" F# u* P
        stats refresh 5s
6 w8 T. G# U& d* b
7 W9 ^' w5 y7 f3 v  See also : "stats auth", "stats realm", "stats uri"  g1 u' d  ?+ u9 `, `! L8 j& x

' s9 s4 K. D8 u
( V1 w( J( k, \1 v) j2 e& d& O9 W) e% Ustats hide-version
0 i+ z3 L* d" q& _5 r; I# N  Enable statistics and hide HAProxy version reporting6 }  s+ t: {2 W
  May be used in sections :   defaults | frontend | listen | backend
$ r/ Y) B$ f3 h4 c                                 yes   |    no    |   yes  |   yes6 p* e+ l, h6 T0 Z
  Arguments : none4 W* L) s' v% k, o$ y( h/ W
: O) j2 x6 f3 G. ?# W- L  _; _
  By default, the stats page reports some useful status information along with
8 \! \5 O* G. E  the statistics. Among them is HAProxy's version. However, it is generally
$ J- B* T- ?+ ^2 X7 n7 ^. c5 \  considered dangerous to report precise version to anyone, as it can help them
  @9 G  i! J# H0 v  target known weaknesses with specific attacks. The "stats hide-version"
% ^1 |3 m2 C- c2 M: Y+ ^6 }/ G) o6 R  statement removes the version from the statistics report. This is recommended
0 J( y5 l" @# e  for public sites or any site with a weak login/password.
( A8 C" }6 l; F! j4 ?& ~0 h7 ]2 F# k3 F, i7 L" e
  Though this statement alone is enough to enable statistics reporting, it is
; v8 O6 H( y1 g; I2 E6 K  recommended to set all other settings in order to avoid relying on default
. V- a  t) b  ^3 h$ y" C) o, N8 E  unobvious parameters.
3 P" S3 ~; o$ x. v: K$ h& l: x& z& T5 J2 P* B  L8 P
  Example :# |( L, L: I/ c( I, f* a& \
    # public access (limited to this backend only)
0 B! B/ J) J6 Q* |. T. f+ T8 G    backend public_www
! Y8 l' U8 ^! g5 y9 |( C" }7 ~! F        server srv1 192.168.0.1:80" M8 O0 z" h3 W  S* y& E
        stats enable+ k5 f" _8 f- S8 E
        stats hide-version
! j% h) _' I7 Y0 K* I        stats scope   .. z, y6 a5 x' E5 G
        stats uri     /admin?stats. A5 o# J- ^, l5 i( n
        stats realm   Haproxy\ Statistics/ H& \  q* J9 \3 w  y. b
        stats auth    admin1:AdMiN123
0 D: l$ ]( y( F- ?. [: `        stats auth    admin2:AdMiN321
8 }8 m% W3 `. v  ~
2 L+ d7 Q# P; ?) N    # internal monitoring access (unlimited)5 N$ M& H: P7 Y5 D7 \- _8 y
    backend private_monitoring- b- I" p; m+ Q9 D5 y
        stats enable, L0 R1 S7 }) g
        stats uri     /admin?stats) e1 f% l* X# i8 ]/ L3 q
        stats refresh 5s
' @2 J- l" V" B+ X! v" Q' ~6 g# j: ^8 D, y
  See also : "stats auth", "stats enable", "stats realm", "stats uri"
' n) O  V3 ?, q  p
0 s: K% ^, N# X! Q" Y' G1 Y0 u& Y: [; p3 A+ q
stats http-request { allow | deny | auth [realm <realm>] }
, Y6 X/ d" [  X             [ { if | unless } <condition> ]
5 f' d. {/ t" I: S- y$ h  Access control for statistics. p; ]0 t9 k: I1 L
# W& f& R# t' g
  May be used in sections:   defaults | frontend | listen | backend9 f! q' S( i- c* g
                                no    |    no    |   yes  |   yes
) i5 B6 p$ {* o. v4 D7 u5 ?
6 V2 W! Y. ^3 B& P, s( f" \8 O  As "http-request", these set of options allow to fine control access to, _3 H# s' |( o; e/ z
  statistics. Each option may be followed by if/unless and acl.' G+ \5 l$ m- t% t  }: ?; P
  First option with matched condition (or option without condition) is final.
7 |; r& j9 M% C' A) O: ^  For "deny" a 403 error will be returned, for "allow" normal processing is
/ T# t9 i! Z9 U; J7 ~! D  performed, for "auth" a 401/407 error code is returned so the client
4 E  _2 O; y1 O5 |5 B4 [5 h" x  should be asked to enter a username and password.
/ R5 j; ~' }  H. Z. W0 V+ w  E5 H
; @% e1 b( A( o( O$ i  There is no fixed limit to the number of http-request statements per
( M! C* r6 U; ?. E' I* }0 Z  instance.
9 O. N" `/ P7 f2 u1 ~! F
' Z5 [6 P3 @' ?  See also : "http-request", section 3.4 about userlists and section 7
8 g- C8 R6 S. }7 a& c" A             about ACL usage.& c* S( u! c  m" s' p5 i

5 S% k7 i2 v" L& J7 p% ~
( `' T5 Y, q9 gstats realm <realm>  a" B. Q* c) ?# A8 u; H
  Enable statistics and set authentication realm
* F/ L* h+ V$ Y+ g  May be used in sections :   defaults | frontend | listen | backend
  W+ V" N. O: Y9 t0 r. J                                 yes   |    no    |   yes  |   yes) k: V1 r1 [( f0 r% W+ g
  Arguments :
' E$ y( E- q* D. ]1 u    <realm>   is the name of the HTTP Basic Authentication realm reported to  Z+ O% y, T. G& O$ [* \. f& E
              the browser. The browser uses it to display it in the pop-up
3 g* Y) U& {2 i% X% p* K. r. R              inviting the user to enter a valid username and password.
) w' A! H; B5 `' E, o. M6 m7 C
  The realm is read as a single word, so any spaces in it should be escaped6 f4 m! ?$ L1 u4 {6 h& Y' _( c
  using a backslash ('\')., Y1 C. g1 R1 a+ Y. x9 Y' p- c9 x

3 z& m7 D6 \6 u5 W  This statement is useful only in conjunction with "stats auth" since it is4 f) M+ x0 B& {& Q. N
  only related to authentication.2 _2 O6 l- ~6 {( B& A( g- X
* i9 J' [5 l1 i& _$ }9 G" ^
  Though this statement alone is enough to enable statistics reporting, it is: s9 \3 A6 M9 _! |; h6 T& }: }' ^
  recommended to set all other settings in order to avoid relying on default; e6 V; \: c' F- N
  unobvious parameters.9 a! x: V( E! Q0 C6 p
  M0 ], P4 _' m% U1 S. @
  Example :
7 b6 a% t6 S, w, I    # public access (limited to this backend only)' t; c1 R1 V+ J- Z- f, h( z, w
    backend public_www
! Z0 F% z5 }9 D2 I        server srv1 192.168.0.1:80
& s! N% N1 @4 \+ b, l$ q        stats enable
" O% d5 B: A$ f0 z8 {4 Y4 t        stats hide-version
: h& R4 ?# U9 o' E! n5 a* c        stats scope   .
  v& p# k  M- x        stats uri     /admin?stats: l$ H; S" z  j! T6 N" y& a
        stats realm   Haproxy\ Statistics
5 Q" c# y. G+ W        stats auth    admin1:AdMiN123
& y# X8 E; p! P        stats auth    admin2:AdMiN321
" O* Y4 t% Y" ]2 B8 l4 C9 ~' q- H1 \2 @8 T) t6 X1 p
    # internal monitoring access (unlimited)
, ?# q3 C. ^5 }, K2 O    backend private_monitoring' s" e- H- w) U* ~$ b. e. ]/ _# N
        stats enable
! A& n. B! F0 |* A        stats uri     /admin?stats
4 y' g! \+ e  Y+ M, z        stats refresh 5s
  l: J5 f: q7 S; O# }) L5 V+ W/ j' r8 h. K6 i  s  p, `+ V
  See also : "stats auth", "stats enable", "stats uri"0 Y+ S& ~6 d- O, H2 Q) G2 e

" q% X- s/ ^0 e7 m& t2 g
9 e' w; r0 l! x* Hstats refresh <delay>/ W: J  e) H, R. s$ B  B
  Enable statistics with automatic refresh
8 Q( ~0 l) @( O2 ?! n+ ]; M0 B  May be used in sections :   defaults | frontend | listen | backend/ s' l% b# j/ Y# }" M  E: M
                                 yes   |    no    |   yes  |   yes
7 X3 E( \, m0 k2 Q8 v: _3 J4 N6 n  Arguments :
% E7 ^; y6 T: n+ j( a* f    <delay>   is the suggested refresh delay, specified in seconds, which will
8 r$ n: {) T0 E4 T! y: y              be returned to the browser consulting the report page. While the( B0 `9 T$ {  o1 y
              browser is free to apply any delay, it will generally respect it
2 A8 |1 [# r" @: V% G! S              and refresh the page this every seconds. The refresh interval may
( @- m  W0 Z1 x8 L; p( D              be specified in any other non-default time unit, by suffixing the
! V7 L* B# N: W( {, I              unit after the value, as explained at the top of this document.: M8 q2 g0 o/ g+ N  r- M& f
% m" O. [! }6 J
  This statement is useful on monitoring displays with a permanent page
. N  z$ V3 A$ T; V( O  reporting the load balancer's activity. When set, the HTML report page will
( |# ~2 R' n5 M  include a link "refresh"/"stop refresh" so that the user can select whether
  P1 L. C; ^9 e; F  he wants automatic refresh of the page or not.( J8 ?* C2 j, m4 [

4 J. E# E+ p' ?/ P3 H7 f  Though this statement alone is enough to enable statistics reporting, it is/ f, @6 V, {4 d: o) j: Y  ^' f$ T0 h
  recommended to set all other settings in order to avoid relying on default
) ]: d$ g6 m1 [4 a  unobvious parameters.1 E2 g- b! S$ Z8 r* b8 L, r5 f
5 b  q5 a% s$ ~+ _& }! Z; d) t
  Example :
/ ]  k- L4 W) m3 @6 N, \/ Q5 |) B  d, m    # public access (limited to this backend only)# }, [: J; Z1 e  V
    backend public_www
% S: O- W4 a, R( v5 Y& S        server srv1 192.168.0.1:80
2 _. j/ g9 Z! o# Y4 Y6 t% ^        stats enable% M6 l0 o) v7 ?4 L* r' V; X
        stats hide-version
: k! H6 i) g" d        stats scope   .
3 l7 g/ d$ L# Q# h2 p        stats uri     /admin?stats  W% ?) c* G7 t& J$ j" l; R. I( v
        stats realm   Haproxy\ Statistics- A: o- z) \; _$ }
        stats auth    admin1:AdMiN1233 R$ Q$ o2 l: B; O- I6 M. B
        stats auth    admin2:AdMiN321
* Z+ g! W% c6 o7 E& O) O2 A$ H* _+ Q. X
    # internal monitoring access (unlimited)
6 S7 r; W6 e1 N3 v    backend private_monitoring
+ ^) y+ Y1 o- B) Y6 o/ W        stats enable' |1 N  A1 G4 O7 x; q; ^
        stats uri     /admin?stats/ q* T) e5 J7 h! O) l
        stats refresh 5s
+ {+ D& c# b' S" Y- U- Y; t
5 w- i7 E& g$ H' I  See also : "stats auth", "stats enable", "stats realm", "stats uri", p' x) S+ O( C' r6 R+ i% g
' U3 O- ^# z" t2 X0 D+ q  i

. o4 d. r1 }0 y) k, \stats scope { <name> | "." }: P1 z$ O5 d/ A2 h9 P7 a% K( v
  Enable statistics and limit access scope+ F! N# N* {3 p  b; [- X2 |* j
  May be used in sections :   defaults | frontend | listen | backend* }6 i6 z& E. q# V3 b6 S8 @4 C, a
                                 yes   |    no    |   yes  |   yes# G8 p) r" R! x" G2 m% P; T* }/ i
  Arguments :
  n/ ?2 Q* m3 i. B* _) C4 ^    <name>    is the name of a listen, frontend or backend section to be: O1 v! {: _5 Y2 @
              reported. The special name "." (a single dot) designates the7 x# k# R; m$ }
              section in which the statement appears.* N0 g8 [: p8 s, `$ u% `3 h

" l5 W4 T* V; F  When this statement is specified, only the sections enumerated with this
  c2 c* J( S( O9 f- ]1 J8 Y  statement will appear in the report. All other ones will be hidden. This' E9 D4 T" N8 c+ e+ Y
  statement may appear as many times as needed if multiple sections need to be
' I( r, a! G5 S& S7 Q& i  reported. Please note that the name checking is performed as simple string. t  C4 c8 ?1 {; I2 g% }
  comparisons, and that it is never checked that a give section name really
) B* J% ^$ j8 n$ ?  exists.& n/ i7 s; J. z- K- g, X5 V- H

9 H% ^+ P0 [1 v1 e7 B) F  Though this statement alone is enough to enable statistics reporting, it is0 u7 I$ C% g7 A" R/ L3 W
  recommended to set all other settings in order to avoid relying on default' q0 [, k+ w; }. c" h
  unobvious parameters.
4 A+ i. o) h- n8 G" V+ |2 M0 I- s  x* i; T5 J3 v
  Example :
8 v- e" ^' |( C' [    # public access (limited to this backend only)5 f; }& T$ N7 Q! [) r) J5 s- h0 p
    backend public_www
4 {6 B( r& R/ z8 s& g7 y4 D        server srv1 192.168.0.1:80
: n6 G7 l& @8 L9 A) F$ g' v7 ^* W- f        stats enable
) d- v( p4 \# C        stats hide-version
( ?3 Y2 b! `; O( w. j        stats scope   .
8 G5 T. R6 K4 R        stats uri     /admin?stats  u% o  O# b7 g8 Q5 ~6 o- K
        stats realm   Haproxy\ Statistics
6 Y1 B% W5 g( R! b        stats auth    admin1:AdMiN123
/ _9 c% `& S2 ]% y3 W        stats auth    admin2:AdMiN321" {) p% i; ~, k" H* Q- A  q

5 D- ^, i# w2 H3 D    # internal monitoring access (unlimited)
8 F8 H4 P1 n+ A" f* n7 z    backend private_monitoring& f7 S2 s8 _' d
        stats enable
; {. f5 K) _: Q( T; `- ]        stats uri     /admin?stats, l+ k. K8 M2 z' }
        stats refresh 5s
  I* f4 `5 E& P
, {# t8 }  a+ w; ~2 J) O! Z/ r0 y  See also : "stats auth", "stats enable", "stats realm", "stats uri"/ H3 o) E. l- M' L( ^$ r7 N7 r
1 w" q, H7 k- b" I) ^  T- X
( J/ W' z4 a) w* v$ h
stats show-desc [ <description> ]& ~, q2 N3 w/ c/ n: f5 I
  Enable reporting of a description on the statistics page.0 F' t  a0 D* x# D" U
  May be used in sections :   defaults | frontend | listen | backend0 P5 O" L& R' m
                                 yes   |    no    |   yes  |   yes. _/ K& V$ t$ m/ H& Y( q( i7 n

  J3 I; \6 a5 G4 s& n    <name>    is an optional description to be reported. If unspecified, the
& g2 \' U" R. Y( Z. Q/ j" f              description from global section is automatically used instead.# S( ]5 M  q/ G7 h$ S4 e
7 D/ W" J  @( Q/ l; F
  This statement is useful for users that offer shared services to their
- ?; \- k/ G0 P7 ^) E( p  customers, where node or description should be different for each customer.
+ \+ L  C! @3 s; Z' a) x, w% A- t6 k' S8 ?( t
  Though this statement alone is enough to enable statistics reporting, it is
" Z8 |+ m: W9 h  recommended to set all other settings in order to avoid relying on default
1 P2 Y% i! i1 i, G  unobvious parameters.  By default description is not shown.
! U1 F, Y. l# d" ?( n( |! f( D3 q3 ?  }% d4 D
  Example :
2 E, p8 e: o* o" I    # internal monitoring access (unlimited): C8 t. Y* ~1 I* N' d8 D. h
    backend private_monitoring' D( S/ x) h7 C* i( {3 ]. H
        stats enable! c# l7 ^. ~* Z( w9 b
        stats show-desc Master node for Europe, Asia, Africa
  H  f+ E8 l! g* L9 p        stats uri       /admin?stats) [. Y8 j3 Z$ m4 G; K7 L
        stats refresh   5s
( e1 K# M& D& f6 N  c2 v1 {# y, j1 y9 N$ T$ l0 R* f
  See also: "show-node", "stats enable", "stats uri" and "description" in( ?, n1 Z* Q1 w2 w, \
            global section.! ^# Y7 ^( a% T
' f9 w) _) q. V$ S" y$ l+ P
7 v1 j) T  Q* n& s  A( R
stats show-legends1 b9 l) z, F5 O: U- D
  Enable reporting additional informations on the statistics page :! O% V1 X/ h) a. O  ?
    - cap: capabilities (proxy)
/ _6 I  ^8 U- `2 p( }1 f3 w7 y) ]1 @    - mode: one of tcp, http or health (proxy)4 s- d" E* B' Q- \- y' q
    - id: SNMP ID (proxy, socket, server)
( K+ y9 \+ p9 V7 K# B    - IP (socket, server)8 W; ]" L9 Z# Z0 e8 ~0 G$ m3 _
    - cookie (backend, server)
$ z* |! [- x, c, o0 H! `
8 L; c9 m  O1 G: a  Though this statement alone is enough to enable statistics reporting, it is. K/ L2 D) T6 `5 u' _
  recommended to set all other settings in order to avoid relying on default
' t2 u+ G  y2 [1 h# G4 g& B3 ^  unobvious parameters.  Default behaviour is not to show this information.& O+ Z1 u/ o( p
$ J  h: C" V: w3 K: F  j# s
  See also: "stats enable", "stats uri".4 H# a! T' o( \! u) _( O/ K5 p
; M! @7 V' D- s6 u
4 M  A9 }% F, p9 M+ k# M
stats show-node [ <name> ]! u9 o/ y1 O5 X2 ]
  Enable reporting of a host name on the statistics page.1 e2 |2 y$ S% v- b
  May be used in sections :   defaults | frontend | listen | backend$ \# b# W4 s: D4 W2 M9 g
                                 yes   |    no    |   yes  |   yes4 K4 ?) x' p  U) U/ B5 U8 Q
  Arguments:( D/ i0 V5 Q& @( |+ M
    <name>    is an optional name to be reported. If unspecified, the+ {, ]* w1 p1 h3 E6 J
              node name from global section is automatically used instead.
+ O  O, I9 ?; H2 L# G$ L4 O  w- H( y4 Z+ ~" ]' a, N$ `
  This statement is useful for users that offer shared services to their4 O9 T/ r. Y' w. Z( H. @9 J
  customers, where node or description might be different on a stats page
4 a, h3 S4 ]: T: B0 ?; O( i" k3 e  provided for each customer.  Default behaviour is not to show host name.
, h7 ?) f8 z3 T% s) Q- z! p. u- _- j. A2 s& I4 s6 E
  Though this statement alone is enough to enable statistics reporting, it is
4 [6 V/ W: h; v: z. D  recommended to set all other settings in order to avoid relying on default
8 J" _) o. r4 \1 L) x1 D  unobvious parameters.3 P7 k  S) E* ?4 u5 _, {# h
. k' D$ j! ^$ Q
  Example:6 Y3 P$ C$ D( s  N7 s) U  M
    # internal monitoring access (unlimited). E' d! ?6 m3 i! J$ j- q
    backend private_monitoring" A1 T' l* s( S6 E* T+ H# F) N# V
        stats enable$ A9 N; n  {2 g3 k8 P; ]
        stats show-node Europe-1
+ M, ]+ e/ Z# ?9 h        stats uri       /admin?stats
# t" O5 Q. j  l8 W7 i0 D5 w0 @& Q        stats refresh   5s
  z' V) X; n5 h1 o  [% M8 q  C# B1 [: R" N' x6 S1 H0 o
  See also: "show-desc", "stats enable", "stats uri", and "node" in global
: m1 {8 W2 J* _1 C9 C0 h4 Z$ M8 O            section.
  \( c2 @. p9 E4 S& W* R& ?* R8 o# I2 t: Y

; b: M5 O: X9 fstats uri <prefix>, ^6 n! b$ S. P7 U+ l& X
  Enable statistics and define the URI prefix to access them
5 i$ q+ }+ n* q3 o9 L9 J  May be used in sections :   defaults | frontend | listen | backend
0 i  d- V* ]/ Z5 _* a                                 yes   |    no    |   yes  |   yes
" ?3 `, {5 h( f3 M  Arguments :
7 a% k! ]5 _0 c& v    <prefix>  is the prefix of any URI which will be redirected to stats. This
1 a# b; ]$ l/ H7 X! y  C              prefix may contain a question mark ('?') to indicate part of a
* t6 J# `- b7 s4 f9 r# B2 A+ e( A              query string.
( F, q, x2 {# |
. Z% Q; x. a4 y# e  V9 j% h9 [2 k  The statistics URI is intercepted on the relayed traffic, so it appears as a
8 g; W/ R4 t0 _3 J, u( f8 x  page within the normal application. It is strongly advised to ensure that the
8 K+ k! o7 G4 H- g4 ?9 \" E  selected URI will never appear in the application, otherwise it will never be/ e* `0 N1 [* @2 B
  possible to reach it in the application.
+ x3 j% H. m* s+ `" p8 c
6 R) c+ y% J$ X  g& k  ?# M/ v  The default URI compiled in haproxy is "/haproxy?stats", but this may be+ a  ^! w! }  t) x
  changed at build time, so it's better to always explicitly specify it here.
2 t1 m( I- v, J) i6 Q  It is generally a good idea to include a question mark in the URI so that
, H, G" x& l& S. N' }  intermediate proxies refrain from caching the results. Also, since any string) n% V6 o. ?* \# A
  beginning with the prefix will be accepted as a stats request, the question
1 x' j0 r% Q+ p  K( Q  mark helps ensuring that no valid URI will begin with the same words.
- f5 I6 K0 z7 @3 N  k
6 O: S" Q! |* ?$ u" \0 F5 B& d; I  It is sometimes very convenient to use "/" as the URI prefix, and put that
  u( M5 J: K4 r8 P5 {9 a( b  statement in a "listen" instance of its own. That makes it easy to dedicate
1 F2 a" Z6 @8 C7 ?) D  an address or a port to statistics only., f0 u! J- |* i, @
" `, G+ m: l% s& K- ~
  Though this statement alone is enough to enable statistics reporting, it is
7 ]( E5 F$ u% ?1 E# O: r: J# k  recommended to set all other settings in order to avoid relying on default  T6 h& l" a( ]1 t. l( _1 u) m
  unobvious parameters., N4 j  G) F2 t2 M1 v2 m6 r
+ K. y3 ^# y2 A2 A; S) u+ o5 d
  Example :
* y4 G. A; u5 _; r4 M. n    # public access (limited to this backend only)
5 g: O6 h3 R- Z, s- A    backend public_www
' @, v3 J  o$ T" j6 {! R        server srv1 192.168.0.1:80% U* [* K% Y3 r
        stats enable
/ Q; v' B8 T0 d9 M% |9 U$ E2 e0 h6 `        stats hide-version  [& D+ F. c/ h; j6 U, B
        stats scope   .
0 E# V* M8 z8 U6 z' Y        stats uri     /admin?stats
& M5 k" ]: ^4 O4 y- X% f        stats realm   Haproxy\ Statistics
* e. l( n. i6 x/ L8 A# \  c1 H        stats auth    admin1:AdMiN123
0 B0 i/ O, b! t        stats auth    admin2:AdMiN321
9 O0 _4 F( K6 o: l  S: A) d5 d2 n( _' w) p) U
    # internal monitoring access (unlimited)) b3 w/ W7 V) }% A) |
    backend private_monitoring/ j; I. n; ^* r8 p! A! c
        stats enable
+ ~6 a& r2 _: o, p        stats uri     /admin?stats
2 ~$ q6 b: V5 a7 J9 M        stats refresh 5s9 V( }3 c+ C/ u6 a9 T

3 `1 l0 Y2 M8 B, g* b1 j  See also : "stats auth", "stats enable", "stats realm"- Q  v" m; \3 P) O" j1 f

! n3 a- f) Z: O8 u) Y( c9 |' o- S: j* ^
stick match <pattern> [table <table>] [{if | unless} <cond>]
! v, H1 h7 E0 z  Define a request pattern matching condition to stick a user to a server
7 C( a9 ~. j9 F) b: k8 D0 ?6 Y8 t0 B5 C  May be used in sections :   defaults | frontend | listen | backend3 m3 O2 }1 X& q: D' J0 j
                                 no    |    no    |   yes  |   yes
! d! D& d9 E% p2 {8 [& B! f9 G5 c. u$ v4 R+ q- ~2 y6 a
  Arguments :3 |7 y: ?3 a' f/ ~
    <pattern>  is a pattern extraction rule as described in section 7.8. It
+ K8 |. Y$ |- q0 U7 E9 v% L5 C: W               describes what elements of the incoming request or connection; H! n& v: g1 C/ b: t( s  h
               will be analysed in the hope to find a matching entry in a; D  i6 F) @7 ^+ C
               stickiness table. This rule is mandatory.
3 R' ]9 F9 L$ {# x+ Y, l7 i6 i
    <table>    is an optional stickiness table name. If unspecified, the same
' h3 m8 e( `& f  i2 [6 q1 m               backend's table is used. A stickiness table is declared using
& T3 e1 e/ U( e+ i; w               the "stick-table" statement.
+ Z) A; p7 m: H! R" R9 @: Z  A; {- O& x0 \+ P2 h
    <cond>     is an optional matching condition. It makes it possible to match
. e# e* x  a$ S; j/ I, S# |2 i               on a certain criterion only when other conditions are met (or7 G* g5 ^/ k8 }% @3 Y2 ]# `$ H
               not met). For instance, it could be used to match on a source IP2 r& R3 h( ?" p/ d" R+ Y
               address except when a request passes through a known proxy, in' y2 y, k7 m* j& h% p
               which case we'd match on a header containing that IP address.' }' _4 Z# I, F- V# Q. Y3 s
; C/ R* B$ I# |& Q$ T
  Some protocols or applications require complex stickiness rules and cannot* c$ t2 b8 k9 j) `. H: Y2 |* a* z
  always simply rely on cookies nor hashing. The "stick match" statement
8 S' X: c) r7 l# C$ b- r  describes a rule to extract the stickiness criterion from an incoming request
- b+ h2 s, R" J9 n# C( N  p: x$ U5 d  or connection. See section 7 for a complete list of possible patterns and
) a1 ]. N% x* [. Z/ E  transformation rules.) }( y( t* l: Q* B
! ~" ?0 T, x+ p7 K* T
  The table has to be declared using the "stick-table" statement. It must be of
4 \6 N% Q# `' G8 x  a type compatible with the pattern. By default it is the one which is present
# ]9 h* x2 |; z* P- q  in the same backend. It is possible to share a table with other backends by
0 f' K6 o5 \  v. }9 O  referencing it using the "table" keyword. If another table is referenced,
+ i5 E, y6 ^+ n. w$ \. V: P5 d  the server's ID inside the backends are used. By default, all server IDs
9 _# ?/ S* [$ m* P8 m! L5 n* ]+ g  start at 1 in each backend, so the server ordering is enough. But in case of: p, y; r0 F+ I4 v& b# y) G
  doubt, it is highly recommended to force server IDs using their "id" setting.
7 l6 V+ K2 I) Q6 T" ?6 z8 |( |! A# I" z' G/ n
  It is possible to restrict the conditions where a "stick match" statement
5 Z  V# N5 U$ {' O  will apply, using "if" or "unless" followed by a condition. See section 7 for
% T7 I- \- K  k  ACL based conditions.9 m; g* A3 m3 S; K+ N$ s  l0 c
$ ~! H$ h- E. H4 C8 w: H7 i
  There is no limit on the number of "stick match" statements. The first that! h& B7 T$ M2 F1 J& t/ h
  applies and matches will cause the request to be directed to the same server
4 _! z: `' O' |2 b) U# B, k3 S  as was used for the request which created the entry. That way, multiple
* L  N) G4 ]# E  matches can be used as fallbacks.3 J1 `( q1 A  G5 D7 ^
' p; ]6 w7 l! m# \* D' w
  The stick rules are checked after the persistence cookies, so they will not# s; b: J6 O( P& _$ [; \5 U
  affect stickiness if a cookie has already been used to select a server. That' p- J& u- v) X9 ]! B; W
  way, it becomes very easy to insert cookies and match on IP addresses in
0 Z0 p( ?( ]  B/ b3 d  order to maintain stickiness between HTTP and HTTPS.
# U5 g/ b. Z# T
3 e$ p3 p+ C) u$ [$ C  Note : Consider not using this feature in multi-process mode (nbproc > 1)- o1 m$ K$ V2 I" l. Z4 m: e
         unless you know what you do : memory is not shared between the
4 B  ]/ R6 \; ]7 E: C         processes, which can result in random behaviours.$ R# b) n0 D. O( |0 g$ ~1 k

4 x! B: b- R% u9 R, \; E, u4 A$ q  Example :
6 }& l: r- U, C# R+ p$ A9 U' j    # forward SMTP users to the same server they just used for POP in the2 S+ a6 R9 S1 t  v' _
    # last 30 minutes8 Z. I" i& E9 L) U% m
    backend pop
; G: h- F# r! R        mode tcp3 Z% {0 j1 C/ {/ E* f% `
        balance roundrobin- h5 q* a% |/ J* b7 ]8 |
        stick store-request src
5 I4 }4 [2 Q. Q6 ~        stick-table type ip size 200k expire 30m5 l$ l+ F% U' ?, L/ Z9 c% L
        server s1 192.168.1.1:110
; }* m  {* Z, v- w2 \8 t" a5 ]        server s2 192.168.1.1:110  `7 |- x" }: W0 r( t# C! W

4 A* t; U/ R6 ~- M7 F; s7 g    backend smtp0 p$ ~' P# D8 X$ Y; K+ O* G+ C3 j2 g
        mode tcp  K' z2 V8 V  J+ S# h
        balance roundrobin
' z$ P) b7 y4 J/ I, s2 z) z( p& Q9 `3 E. g        stick match src table pop
, q2 l& P  H5 {0 v9 r        server s1 192.168.1.1:25
, M$ U( B4 Y9 \- @- j4 R        server s2 192.168.1.1:25
) A! [6 \6 K. A
( \3 X1 G3 @. |  See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7+ P7 c3 |7 ]- y* I
             about ACLs and pattern extraction.: |( h& Z& z- r5 f' A1 z" I

9 q% ]9 i2 [% d4 G7 U3 |; j+ ^. I8 t! ^" C& O& X% I
stick on <pattern> [table <table>] [{if | unless} <condition>]5 ^! u+ Z: s3 U( w
  Define a request pattern to associate a user to a server
2 O7 L  ^1 S; [' F! a, s9 s  May be used in sections :   defaults | frontend | listen | backend
4 R8 i( U, b. ]$ U: Z  t                                 no    |    no    |   yes  |   yes/ f; l1 i' |$ M5 L
. q9 Q5 B3 t+ Q* x* ~& a
  Note : This form is exactly equivalent to "stick match" followed by5 b7 K" S$ @( x& T
         "stick store-request", all with the same arguments. Please refer
* V2 n: o; z  {) N6 V7 z* v$ Z6 R4 i         to both keywords for details. It is only provided as a convenience$ l2 }- x3 M( k
         for writing more maintainable configurations.* u5 q: c  {/ e, F/ f% @) M: t1 ^

5 t/ }6 H/ O, z5 \) ~/ q8 D  Note : Consider not using this feature in multi-process mode (nbproc > 1)
. p3 C# e+ W4 u! {         unless you know what you do : memory is not shared between the" w! `  y. f$ ~% E
         processes, which can result in random behaviours.
8 i+ W* C% H4 M+ T1 D2 L" t# G$ m% B% g, g
  Examples :+ E$ z+ E2 T% N
    # The following form ...+ c$ g6 A5 X& o# ]% B
    stick on src table pop if !localhost4 q, B& R- M& t  e, y! y. Y/ S' e
! \& C( a1 }+ o
    # ...is strictly equivalent to this one :* ]: v" `, S% t+ U6 g  {$ v5 J1 L
    stick match src table pop if !localhost
% Y( r" F* I, w8 o( q2 ?    stick store-request src table pop if !localhost
* X* l6 P& V3 J9 f8 J7 F+ E* n8 x5 }6 `% A$ V$ W

) m6 U* N+ T( }* C    # Use cookie persistence for HTTP, and stick on source address for HTTPS as
7 Y( E* F0 I/ G  _& r    # well as HTTP without cookie. Share the same table between both accesses.1 a1 I- ^5 @0 t( t5 f
    backend http! X' |+ n) F3 c( p, {$ _
        mode http
) o- m& E7 f& ], H6 u5 n" A        balance roundrobin
! M$ P" V- Q  d2 K        stick on src table https* {* G+ `5 w# r/ T' c9 p1 q
        cookie SRV insert indirect nocache
8 z! R: x! \# h- }        server s1 192.168.1.1:80 cookie s1
1 X& g. @# u% }# G4 V6 _8 g        server s2 192.168.1.1:80 cookie s2. M1 [" V0 c+ Q( |# J, |2 t- H
1 A" b; d5 g# T; p5 c! \
    backend https# n5 B, I( K5 M8 J" i! F$ r
        mode tcp
! G0 _; G( C( L$ G        balance roundrobin
: z; j# Q4 o7 K5 K- L$ p        stick-table type ip size 200k expire 30m& ?, A9 s0 J6 O" j# t8 [5 Z' ?) t: k
        stick on src+ O) T1 R9 y% c' _
        server s1 192.168.1.1:443
1 F5 u; R" d( V        server s2 192.168.1.1:443
" Q5 I' I# H! K3 M7 m+ T+ k+ X9 O4 O$ k3 m1 p1 v1 `4 c
  See also : "stick match", "stick store-request", "nbproc" and "bind-process".$ L  z, n' n2 u# g
; B, B! [  R" l, t8 v* w
$ c" k" Y5 A% E1 F  z
stick store-request <pattern> [table <table>] [{if | unless} <condition>]; j" c$ q& I3 _, E. O- z% c' A
  Define a request pattern used to create an entry in a stickiness table
, P3 ~5 y! s$ h: Z4 s* Q  May be used in sections :   defaults | frontend | listen | backend
; V3 }# ]- D' ~/ g( U+ V0 V% N                                 no    |    no    |   yes  |   yes" @) e  D. ]8 _# l4 G; ^- Y$ h

7 l* j" L, w" H' j* g9 E  Arguments :: }3 r9 G. P1 U, L7 j9 C2 V
    <pattern>  is a pattern extraction rule as described in section 7.8. It2 s) Z  [- ^2 C5 [# R7 s
               describes what elements of the incoming request or connection
4 D5 V: M7 g* y/ j1 u: k; |9 S               will be analysed, extracted and stored in the table once a
: }$ _: D: l( J2 ^               server is selected.# X: i, X" K6 a" I& u

/ X8 @) E' N) a; n$ \/ [    <table>    is an optional stickiness table name. If unspecified, the same* t& o, {# V, f( d
               backend's table is used. A stickiness table is declared using
* y$ `4 o' h8 R! T# V               the "stick-table" statement.
  z2 R4 M, B8 L& g( m
5 |7 H4 \8 X1 ]1 S/ S  L2 p0 t" a* n    <cond>     is an optional storage condition. It makes it possible to store
% j9 ]8 x% ]3 k" Z               certain criteria only when some conditions are met (or not met).
* I4 @! R! E6 x               For instance, it could be used to store the source IP address
/ V5 n/ g8 [1 z, @- D9 z$ i               except when the request passes through a known proxy, in which) M/ M( P* d! e6 z7 Y
               case we'd store a converted form of a header containing that IP
. E+ _/ j6 r: V               address.5 E9 l* ^  ?3 D5 O$ S
( y( M( i" ^" m+ k
  Some protocols or applications require complex stickiness rules and cannot
5 |/ P; o0 U9 b9 ]+ a- E& {' c/ b& \  always simply rely on cookies nor hashing. The "stick store-request" statement- C1 d' ]* J2 q. C4 y: }# _
  describes a rule to decide what to extract from the request and when to do) [; t( M  w" C$ p# b
  it, in order to store it into a stickiness table for further requests to
0 {$ C7 j0 h) ]3 m/ ]  match it using the "stick match" statement. Obviously the extracted part must. m: W$ h! j4 G! {9 q  H6 V; m9 k
  make sense and have a chance to be matched in a further request. Storing a
3 j7 ^& W! e7 ]: M+ ?* s  client's IP address for instance often makes sense. Storing an ID found in a% e- q+ D% b* k$ T) s1 d
  URL parameter also makes sense. Storing a source port will almost never make
3 B) n3 q1 Z" F  U  any sense because it will be randomly matched. See section 7 for a complete) p2 u8 o3 q) g
  list of possible patterns and transformation rules.
; ?$ y" T, {: I' F$ g) Y( W
$ M8 ]4 S  f- P8 B6 E  The table has to be declared using the "stick-table" statement. It must be of# K: c$ T& G( B1 u& l
  a type compatible with the pattern. By default it is the one which is present. u+ D0 M- a' k: m% n/ @2 r( R* n* V' V
  in the same backend. It is possible to share a table with other backends by
! a4 H7 j# N: _/ D6 d  @5 P* Q& O$ g  referencing it using the "table" keyword. If another table is referenced,) d' N7 i# m& ]3 t+ g' B% c
  the server's ID inside the backends are used. By default, all server IDs
/ Z) f9 _! ~# p9 O. Z  start at 1 in each backend, so the server ordering is enough. But in case of
& w' U! g! n7 D! v  doubt, it is highly recommended to force server IDs using their "id" setting.( n/ d/ I1 z% z$ Y7 Y5 J

2 W( `' E( E' T. D. V! @% g  It is possible to restrict the conditions where a "stick store-request"0 `) F6 @: R2 I; Q
  statement will apply, using "if" or "unless" followed by a condition. This' h+ I4 Q9 Q. U5 Q
  condition will be evaluated while parsing the request, so any criteria can be3 n) k& O, G, G; l3 v9 l% ^
  used. See section 7 for ACL based conditions.. I0 v: ~' g; o
8 U; H2 K& _; B/ X# ^5 r6 }: R
  There is no limit on the number of "stick store-request" statements, but" d8 |$ c% Z% f: [
  there is a limit of 8 simultaneous stores per request or response. This% i- w( T% [9 b+ Z
  makes it possible to store up to 8 criteria, all extracted from either the
; H$ t# k& G* J, w  request or the response, regardless of the number of rules. Only the 8 first
, t4 w8 r( q$ Y5 y) M  ones which match will be kept. Using this, it is possible to feed multiple* o' i% L4 s( U5 J
  tables at once in the hope to increase the chance to recognize a user on
" X4 Z+ E& l9 d1 V  another protocol or access method. Using multiple store-request rules with
; G2 G' `0 R1 M' |4 B  the same table is possible and may be used to find the best criterion to rely
& f8 e  f# U$ w7 D/ [) d! p+ n  on, by arranging the rules by decreasing preference order. Only the first9 T9 O4 p- F% F) J
  extracted criterion for a given table will be stored. All subsequent store-$ ]; U% z! w  L# ^: j9 t
  request rules referencing the same table will be skipped and their ACLs will: y* ?7 ?4 w. |! w6 C
  not be evaluated.+ d9 s4 z1 ~0 s! ]: }  s6 X
* ^6 [! [# T+ F% H# i& N. E" k0 @( V
  The "store-request" rules are evaluated once the server connection has been
9 G- I- F( W/ ]$ b8 s  established, so that the table will contain the real server that processed
; |* K2 ]0 Z- M/ H& I  the request.
+ S0 r( h! @5 T' }$ h; d
5 s8 z* [% n8 D6 z  Note : Consider not using this feature in multi-process mode (nbproc > 1)
4 x1 {) M9 d0 M* V' f6 U* t6 C         unless you know what you do : memory is not shared between the
$ q* S& j. Y- W, V9 Q* L         processes, which can result in random behaviours.
2 ^7 R( C) D+ L! M& ?
3 l+ h. K! a. W: i7 Q/ r  H9 j  Example :3 K! i4 d) e% j6 P% @4 p
    # forward SMTP users to the same server they just used for POP in the
, u8 a; ~: x6 w  W: U+ Y' W4 n) [+ l    # last 30 minutes
" a: O- k( o( ?9 n    backend pop
4 f# K. j) z1 E3 W        mode tcp+ H5 G) x! s) @
        balance roundrobin: `, h# t. S6 i. Q9 e, Z3 _
        stick store-request src
6 p5 O$ X' ]8 K0 o8 W. N( {2 k        stick-table type ip size 200k expire 30m
7 K! o% p: ^4 e" ?        server s1 192.168.1.1:110/ z6 T. ]% [: Q: u8 U
        server s2 192.168.1.1:110" J( O( I! k( {3 N; e
( `  ?6 U# w1 [5 }# }
    backend smtp- J1 x& J( z6 D$ F
        mode tcp
" G) L* s; L% S5 H        balance roundrobin# H8 \4 W4 f, V7 K
        stick match src table pop6 T4 A' \( D# ^* }& }0 o" e+ O
        server s1 192.168.1.1:25
* _7 {, J& `0 s% T        server s2 192.168.1.1:25
- W7 \0 Z4 h* z" q% I: e# I! [$ ?1 \- v0 w
  See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7
9 u0 \/ n# ~+ T' M$ v! n7 h             about ACLs and pattern extraction.2 J6 `) ^+ l& b  T: d; r$ Q6 h
1 o3 R3 d- G% @
1 n, {: b0 J" c! O" p
stick-table type {ip | integer | string [len <length>] } size <size>
% n3 x7 B# m' Q: ~9 r3 x, c* H            [expire <expire>] [nopurge]* _5 \' V0 ]" A* ?# |- S1 m5 n& ]
  Configure the stickiness table for the current backend4 \, p* v) |+ Q
  May be used in sections :   defaults | frontend | listen | backend
% n! D. u, L4 I" s( M                                 no    |    no    |   yes  |   yes) [! o! P2 d# f3 x  h* c& m3 j

- c, {7 k$ Z$ Y+ z- [6 P  Arguments :
& h. k+ n3 F1 h5 q    ip         a table declared with "type ip" will only store IPv4 addresses.
+ m/ j8 V8 Y5 o' v/ f5 V' `               This form is very compact (about 50 bytes per entry) and allows* Z8 n, q& S5 ~4 Z* [
               very fast entry lookup and stores with almost no overhead. This
, q: S" r8 Z! l. l               is mainly used to store client source IP addresses.
1 N( p' f/ o1 B" m& b
7 K, Z, [4 B4 w6 a9 D4 ]3 [    integer    a table declared with "type integer" will store 32bit integers
/ m5 j+ O5 v. y6 A               which can represent a client identifier found in a request for
6 W' o% J3 q- }9 j4 ~  Z$ F               instance.1 B1 B( p8 _9 B$ w
6 x' @& y/ d! }% h0 T$ \0 o9 k
    string     a table declared with "type string" will store substrings of up
, @: q+ f5 K+ ~: G9 C               to <len> characters. If the string provided by the pattern8 e0 v. A9 Z" j. X" J
               extractor is larger than <len>, it will be truncated before
# t5 J4 v4 Y  S               being stored. During matching, at most <len> characters will be
3 D" J% L8 c5 o% z0 v) `0 O               compared between the string in the table and the extracted
9 _! Y" e4 T4 M- T4 i2 a  R( z               pattern. When not specified, the string is automatically limited
6 A5 r7 X7 E5 ?% A( |               to 31 characters.
. e" d/ _7 P+ g- B5 d- ~9 i9 C$ E  R) Z, L3 L/ `$ w0 d
    <length>   is the maximum number of characters that will be stored in a
# I" d: {7 r. u; U* O% a) q               "string" type table. See type "string" above. Be careful when* W5 o1 K$ A: l% ~3 O& }/ b
               changing this parameter as memory usage will proportionally
! p+ P8 P1 J. Z6 J* I+ m               increase.* t  k# k6 ], w  E" c* @/ z
; V, }9 [% q* Z' d- P: R/ y* H
    <size>     is the maximum number of entries that can fit in the table. This
$ l+ f5 m* G% N; Z+ U7 I2 r               value directly impacts memory usage. Count approximately- C( y5 z. R: P' X" X. z
               50 bytes per entry, plus the size of a string if any. The size4 C+ m/ c" e+ u& o4 ^
               supports suffixes "k", "m", "g" for 2^10, 2^20 and 2^30 factors.
; j0 W9 `' \" o/ X3 a( X2 k* ?  P3 G
    [nopurge]  indicates that we refuse to purge older entries when the table, j* n7 u7 M6 c7 ?+ ]
               is full. When not specified and the table is full when haproxy0 u- V* w2 z" I0 U) o8 Q, x
               wants to store an entry in it, it will flush a few of the oldest
, {3 W) B/ p8 ]* p$ ?& r               entries in order to release some space for the new ones. This is3 Q9 ?6 G) d/ [; {
               most often the desired behaviour. In some specific cases, it
1 @2 W# ~9 J; j, q, D' _               be desirable to refuse new entries instead of purging the older
7 S0 m8 ^/ U) T" l0 @               ones. That may be the case when the amount of data to store is
7 b3 B# x2 c! O3 d" T1 F% e               far above the hardware limits and we prefer not to offer access
- e0 c0 h3 S: }4 R$ R/ G5 `               to new clients than to reject the ones already connected. When) @- H, s2 y$ ~. g/ I/ a8 U: P4 u
               using this parameter, be sure to properly set the "expire"1 Y2 L  w0 K/ s# ]
               parameter (see below).2 Y5 ~7 C6 ^3 J& ~
( M1 p$ v2 r5 g: D/ I7 V& ?
    <expire>   defines the maximum duration of an entry in the table since it  ^3 J. F1 h7 e$ \
               was last created, refreshed or matched. The expiration delay is* a# l* C% x2 o
               defined using the standard time format, similarly as the various7 R, S- Y, ~- }- `1 ?
               timeouts. The maximum duration is slightly above 24 days. See
5 M3 A; H& u+ O  |               section 2.2 for more information. If this delay is not specified,* M+ r1 p( A- M6 t  x
               the session won't automatically expire, but older entries will
" I( ?+ c" S* z5 w& }               be removed once full. Be sure not to use the "nopurge" parameter) a# k6 Z' U3 Y. M& L$ l
               if not expiration delay is specified.2 F! [& o/ h$ O/ D2 ]6 R

) \% t1 s) U2 U9 T9 a2 o1 O* n  The is only one stick-table per backend. At the moment of writing this doc,
& g9 r1 `; V. z) Q  it does not seem useful to have multiple tables per backend. If this happens$ v* J4 Z: E% I  y+ d
  to be required, simply create a dummy backend with a stick-table in it and3 t# U( }& p' {( i  r* t& b6 }# Q( Z
  reference it.* d( C. C& Y4 h) |+ \

, p+ {) ?( L  z/ B  It is important to understand that stickiness based on learning information" d5 K+ n! L+ B# p' r
  has some limitations, including the fact that all learned associations are
7 @  a/ p* f" u- C  lost upon restart. In general it can be good as a complement but not always& m, Y" h( j! D7 h7 b4 f5 K
  as an exclusive stickiness.! Z6 W6 V% Q& @9 W$ n5 ?

  h% r( y0 K* K) e3 L9 c  See also : "stick match", "stick on", "stick store-request", and section 2.2
( E6 |( O: p! n$ X1 O. \$ }             about time format.) L- y+ A* K5 n  G& Z: _
2 V' ^5 ?* X7 b9 [4 |) Q

5 O. J5 E2 W( }# u$ T9 `3 Ytcp-request content accept [{if | unless} <condition>]( y- }, l' i& ]/ E/ Z
  Accept a connection if/unless a content inspection condition is matched
$ x! C) L, @, s  May be used in sections :   defaults | frontend | listen | backend
+ R- Z5 q. X" V$ R                                 no    |    yes   |   yes  |   no
5 t2 f- d+ w6 A$ K/ L7 F
- M$ s3 E$ M' ~0 B  During TCP content inspection, the connection is immediately validated if the
4 p; z, f  x& h4 {5 l  condition is true (when used with "if") or false (when used with "unless").; n5 H) X+ f" N2 \: d/ q
  Most of the time during content inspection, a condition will be in an8 \( C$ `* k$ e; e( w+ A
  uncertain state which is neither true nor false. The evaluation immediately
5 l5 @& z3 C& @" c2 O5 W, ]! H  stops when such a condition is encountered. It is important to understand2 U6 l4 _( h& K9 X/ f8 H5 q, @& w( |
  that "accept" and "reject" rules are evaluated in their exact declaration7 j, ^1 `. t  z) d$ Y
  order, so that it is possible to build complex rules from them. There is no0 t4 b7 I% }2 B* w( J$ K0 K
  specific limit to the number of rules which may be inserted.
2 E) l9 C  h7 X
. u5 T$ Z; a0 {! ]* |  Note that the "if/unless" condition is optional. If no condition is set on$ ~3 P" U* o$ d5 U
  the action, it is simply performed unconditionally.* Q0 X& O5 K: q- I0 @% J
/ L6 d5 W+ D& s: w2 ], Z
  If no "tcp-request content" rules are matched, the default action already is
1 l* z3 m! Q* `4 s) k, O; r  "accept". Thus, this statement alone does not bring anything without another0 t! Z9 ?' V1 a- M2 B
  "reject" statement.
% e4 w0 j& f" h/ Z
) b1 C0 a# Y# p  See section 7 about ACL usage.
! v7 P& V# W8 w- c2 ?$ r# S$ P3 h
1 u3 N* M7 r8 |7 ]# H) u' d  See also : "tcp-request content reject", "tcp-request inspect-delay", J2 ]. j4 V8 |8 P

9 X2 W# E( A: B/ t" d$ h* a. ?1 l$ O7 E9 z# M
tcp-request content reject [{if | unless} <condition>]3 U, \9 H# e+ C3 O0 T# p# D
  Reject a connection if/unless a content inspection condition is matched+ O9 k1 ~: Q. e' P7 c. Z2 Q
  May be used in sections :   defaults | frontend | listen | backend
$ w6 [. f' j! q- A+ }7 s                                 no    |    yes   |   yes  |   no
$ S6 b2 O. G( S2 @
: O% l7 A& _- H  During TCP content inspection, the connection is immediately rejected if the
3 h  [) |  [: M3 m* _  condition is true (when used with "if") or false (when used with "unless")." _  R4 H, g- J2 ^
  Most of the time during content inspection, a condition will be in an
$ |7 f+ W6 f  t2 F  uncertain state which is neither true nor false. The evaluation immediately
  z' ]% B, |4 ~! D  stops when such a condition is encountered. It is important to understand
+ B; A- X$ M  f; v  that "accept" and "reject" rules are evaluated in their exact declaration
0 ]& H4 e0 r, @: P, ~  order, so that it is possible to build complex rules from them. There is no' {( b( ?! [5 s0 e8 b( o( Z% h
  specific limit to the number of rules which may be inserted.
: D3 t1 P$ O* R, }5 q+ ^7 y% e5 E2 o7 Z( j& Z3 a
  Note that the "if/unless" condition is optional. If no condition is set on7 Y% C5 J& q$ F% \! `; o" e
  the action, it is simply performed unconditionally., G* J4 @( d% O4 I; N' Y$ D1 t; S+ G
% x, F/ b8 t' J/ K
  If no "tcp-request content" rules are matched, the default action is set to
/ J$ c2 {6 b& o# d/ r5 ?# ]  "accept".9 e) [8 h7 j3 B+ A

( o2 B. i0 \, }- p! Y! j: F* T  Example:( Q. j- R. Y4 c2 J# \( ]7 k
        # reject SMTP connection if client speaks first% e6 ^! V# m- N- ?/ A7 F% n
        tcp-request inspect-delay 30s
3 @" ^/ s2 y$ F7 O; [! s) v        acl content_present req_len gt 0
% Y9 F  O3 _6 V# H7 ?        tcp-request reject if content_present
1 J! Q2 k' u& t+ Z2 H9 `5 d
$ O7 J" `% f* z7 b# k) t        # Forward HTTPS connection only if client speaks3 I5 {1 u5 Q, m" D9 F7 c' G) G: o# Z
        tcp-request inspect-delay 30s3 z! }! v7 u, Z" P2 K" `1 t) C& ]
        acl content_present req_len gt 01 K) S/ J6 Y  D/ U0 \3 {
        tcp-request accept if content_present* z( ~  V: W6 Y/ K: H7 z' T& p
        tcp-request reject
- [: {! i" V" X* a6 m9 S/ F6 b0 C# s; B! v1 ?
  See section 7 about ACL usage., t! N% H0 m7 H$ P# `, ^, N
. W& A, M% W1 @7 T7 E2 D
  See also : "tcp-request content accept", "tcp-request inspect-delay"
' S6 j/ \1 |0 J
$ {# I+ l/ e: L& r, e
5 k8 X$ u; {2 y2 E9 e. ^9 X; t& z8 Ntcp-request inspect-delay <timeout>
5 n) A# I' i7 y( q5 g  Set the maximum allowed time to wait for data during content inspection9 Z# ?  s5 D/ D. T
  May be used in sections :   defaults | frontend | listen | backend
/ C1 o, J( O; O% M* j; G5 e& l                                 no    |    yes   |   yes  |   no$ |) b: A  G% t
  Arguments :
$ Y0 Q- p4 x/ H0 V+ v. B    <timeout> is the timeout value specified in milliseconds by default, but
/ T. C- P$ l: l8 m: q: X0 Z              can be in any other unit if the number is suffixed by the unit,
! z* N3 c  S: A' T4 w# y7 j              as explained at the top of this document.
! N/ ~8 o( T" `2 `4 P; }: }: E! w7 U3 Y
' W& W" _/ H! `0 V: a  c5 I  People using haproxy primarily as a TCP relay are often worried about the
' Q, C9 C9 U2 W! Q& H; i  risk of passing any type of protocol to a server without any analysis. In
8 H/ C9 s) C/ x5 c8 i0 G  order to be able to analyze the request contents, we must first withhold% F/ ^! g' Y' }" ^- ]( l2 J
  the data then analyze them. This statement simply enables withholding of2 Z5 t7 J% _2 _1 h" N0 c/ Z
  data for at most the specified amount of time., s2 o; N. ?: `7 T7 \1 ]

+ N! @% z: {. u  G7 G% T- s4 c1 W% z  Note that when performing content inspection, haproxy will evaluate the whole& O. `9 x, R& m, ]" V
  rules for every new chunk which gets in, taking into account the fact that
9 V+ U7 S4 r/ g1 Y! g: ?+ Y  those data are partial. If no rule matches before the aforementioned delay,
4 ~# x, r1 X: B1 v4 ]* C0 w  a last check is performed upon expiration, this time considering that the
/ e9 d  l2 c5 q$ D- U  contents are definitive. If no delay is set, haproxy will not wait at all
1 A: G- B# Q) d+ t4 S8 B" \  and will immediately apply a verdict based on the available information.
* t0 w) F5 Q  u; g, s. q  Obviously this is unlikely to be very useful and might even be racy, so such& @, d& O7 H( u4 ~
  setups are not recommended.! @( d! F' U0 o' ]& i# }# Y* K

( Y; n: M% C% E% u% ^+ P6 }  As soon as a rule matches, the request is released and continues as usual. If! N$ I: ~5 F1 F' y- w, J
  the timeout is reached and no rule matches, the default policy will be to let
" F  i' K' o! x( S7 ]$ D9 @  it pass through unaffected.# F. e5 k  [2 \2 N; j* i/ ]
- t* h5 Z: z9 b) Y. p) V, N3 T! q
  For most protocols, it is enough to set it to a few seconds, as most clients
) l1 d! V9 F5 z  Z# V+ r" s0 k6 e$ a  send the full request immediately upon connection. Add 3 or more seconds to
3 Q8 c' w" U4 r8 D; P) d% D% A2 i8 I  cover TCP retransmits but that's all. For some protocols, it may make sense
  ?8 h" o, k% b* H3 C" f8 q  to use large values, for instance to ensure that the client never talks: ^$ v2 X& E* W9 t! _
  before the server (eg: SMTP), or to wait for a client to talk before passing  c6 G6 B: t- G  r% a
  data to the server (eg: SSL). Note that the client timeout must cover at& q! g0 w8 @0 p5 @
  least the inspection delay, otherwise it will expire first. If the client. I4 ^9 x7 d5 G
  closes the connection or if the buffer is full, the delay immediately expires
2 }5 k8 B  U; ?  X6 ~5 Y! v  since the contents will not be able to change anymore.
0 B; t" e5 d( G3 t; P8 `  R  f& r  X6 H4 F% f1 I
  See also : "tcp-request content accept", "tcp-request content reject",
$ D1 ?5 ~8 h& n1 p5 g7 F             "timeout client".' x! x, u4 ?6 H- c

( @" n& P& O0 q, K( k7 d2 u. y  K% X" u7 r0 h0 @: q
timeout check <timeout>
& d, b1 U( `: ]$ {( b% N  Set additional check timeout, but only after a connection has been already
9 x% e0 C  n. c5 P( ^4 p  established.' H, B3 ~$ ^0 W/ q( s' J1 H

' F4 [- |. G( n0 p  May be used in sections:    defaults | frontend | listen | backend/ L  ~4 t1 f9 S0 ~/ {- m  M
                                 yes   |    no    |   yes  |   yes
; C7 i. o- o0 t/ ~) ^1 d( ]0 p  Arguments:! T8 U3 `4 X' g
    <timeout> is the timeout value specified in milliseconds by default, but
- d& e+ Y% n8 ?: @( `( n6 G              can be in any other unit if the number is suffixed by the unit,0 F4 T& H3 `) N% L7 }# E( {
              as explained at the top of this document., a; E7 T; M! _$ O/ Z. P2 i! \

8 B' @0 q8 }8 y5 J2 G+ @  If set, haproxy uses min("timeout connect", "inter") as a connect timeout& u' i3 w0 D; U/ `2 V$ [6 x$ |
  for check and "timeout check" as an additional read timeout. The "min" is
/ F, q( S- Y* P8 U7 |9 c" G  used so that people running with *very* long "timeout connect" (eg. those, m: F4 S+ X) ]3 e/ Q& b5 a
  who needed this due to the queue or tarpit) do not slow down their checks.+ u' _/ D9 R3 s0 [+ {5 z6 l3 r
  (Please also note that there is no valid reason to have such long connect- ^) w0 t* V; `
  timeouts, because "timeout queue" and "timeout tarpit" can always be used to
$ I. N5 L1 N# k  avoid that).
, m; Z! Z( [/ c2 |0 v* g
" w+ F4 v7 l# a) q7 n4 n$ S  If "timeout check" is not set haproxy uses "inter" for complete check
) G7 Y; `% @' n  timeout (connect + read) exactly like all <1.3.15 version.& T* o( ^' [- Y9 E$ {+ [4 _
7 i# K$ P, X# K' [  @
  In most cases check request is much simpler and faster to handle than normal/ Y( Q$ E$ M1 s8 O
  requests and people may want to kick out laggy servers so this timeout should) I8 ]) w9 g" S! z7 R. Y
  be smaller than "timeout server".
% ]& O) K: S# ^. P+ y+ o3 V) V! J9 i3 `- v( d' }& C7 n
  This parameter is specific to backends, but can be specified once for all in0 [; L) G3 a9 e8 u8 d% o. s+ J8 R
  "defaults" sections. This is in fact one of the easiest solutions not to
; \. u6 X( u# }# R# |  forget about it.
8 l6 x. v/ F9 H
1 \* G- k7 s" l; {  See also: "timeout connect", "timeout queue", "timeout server",
3 \  d6 ]9 E# l9 ^            "timeout tarpit".% P9 U& O  A, V* q* H
% X0 `0 ?0 Z2 b- F  b5 P( m9 j
4 x# Q0 ^+ c$ O! E! j
timeout client <timeout>
9 _" l+ O. `% \3 C. g- C& Ttimeout clitimeout <timeout> (deprecated)+ f0 R9 W6 i4 [3 W3 ^) k: y5 t4 I
  Set the maximum inactivity time on the client side.3 i; k$ ^8 c0 j7 e
  May be used in sections :   defaults | frontend | listen | backend
8 Y9 y% D( @" b7 r# O& D! U                                 yes   |    yes   |   yes  |   no
0 p# y! \% }) @  Arguments :$ o" p( L& f. ]  Z1 I
    <timeout> is the timeout value specified in milliseconds by default, but
! T' J. Q1 Y( x( e* u) w4 X6 I/ S              can be in any other unit if the number is suffixed by the unit,
; @, ]; r! e& h2 s              as explained at the top of this document.6 ~" A0 k! ]* q/ {- T7 R7 I

% P9 j( t' d* l  The inactivity timeout applies when the client is expected to acknowledge or  w. U* b( C' B3 A
  send data. In HTTP mode, this timeout is particularly important to consider
' W/ R# |$ d# c  during the first phase, when the client sends the request, and during the' l/ e; G( X9 m) B2 ^/ R
  response while it is reading data sent by the server. The value is specified
# F2 E$ K* R- d" b. q  in milliseconds by default, but can be in any other unit if the number is
8 y0 F& F$ k# [4 h0 r  suffixed by the unit, as specified at the top of this document. In TCP mode. P% p3 F8 G0 ~- w, Y. G
  (and to a lesser extent, in HTTP mode), it is highly recommended that the
- ?) c9 V: I3 I- p3 x# [* E  client timeout remains equal to the server timeout in order to avoid complex
) a0 E9 F; z$ X; ]( a  situations to debug. It is a good practice to cover one or several TCP packet
" N7 f# X( Q* j5 P& C( e: {7 |  losses by specifying timeouts that are slightly above multiples of 3 seconds6 }4 [4 x  k6 d) x
  (eg: 4 or 5 seconds).5 U# D% n; b0 C" j( O+ \4 k, \

4 m1 @3 n- q( F- S0 k9 J# A  s9 B  c0 x  This parameter is specific to frontends, but can be specified once for all in1 m9 X$ V+ P% N' `# {
  "defaults" sections. This is in fact one of the easiest solutions not to
  ~) K/ d7 A  H( o: p. @  forget about it. An unspecified timeout results in an infinite timeout, which: F( C/ N+ c& R- P2 n' z; O
  is not recommended. Such a usage is accepted and works but reports a warning7 w  j: [6 O+ p4 k. q9 l: B
  during startup because it may results in accumulation of expired sessions in' t5 k7 D! d1 K% `# X' d
  the system if the system's timeouts are not configured either.
3 j1 L3 f" _/ p, c& ?6 U
7 ?- V7 U# {0 u5 k" D+ j* E) r  This parameter replaces the old, deprecated "clitimeout". It is recommended, c! ?& p  }7 H  W. }
  to use it to write new configurations. The form "timeout clitimeout" is
; L0 I- d; T$ M8 K$ M5 ~4 T- ~  provided only by backwards compatibility but its use is strongly discouraged.
1 J: R* J0 [9 N4 W8 _# N1 C
- |4 k& z/ X  M; @4 c7 P/ j  See also : "clitimeout", "timeout server".$ p. N# A; u* V4 ^. m" e% n
, A+ o, S# g; _2 Q# p

: g# a+ r2 `& S) |& ^$ E8 `# gtimeout connect <timeout>
( L1 i* a5 R' w" J4 q1 mtimeout contimeout <timeout> (deprecated)7 s" ~) _* _0 z- {
  Set the maximum time to wait for a connection attempt to a server to succeed./ s/ c6 V! T5 s" k
  May be used in sections :   defaults | frontend | listen | backend
1 K& C: D! P0 F0 c2 |0 P# `- o                                 yes   |    no    |   yes  |   yes
- y  A0 F) p5 I! A  Arguments :' g8 L- i- ]1 {
    <timeout> is the timeout value specified in milliseconds by default, but
; ~7 x4 E, ]0 E              can be in any other unit if the number is suffixed by the unit,! E5 I/ m8 I' d" R) z
              as explained at the top of this document.
' I% e# e0 v+ W: @7 L& o# c& v# D" P2 Y8 S- H7 z
  If the server is located on the same LAN as haproxy, the connection should be3 B, j' [* ]% I0 Z
  immediate (less than a few milliseconds). Anyway, it is a good practice to
; D0 P& Y) \: w2 _  cover one or several TCP packet losses by specifying timeouts that are
8 a: j9 h9 x( W& W- }( ?/ s  slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the
, W( z* o" T# Q  connect timeout also presets both queue and tarpit timeouts to the same value
" x& ?. P6 b4 Q; c4 W4 S# a  if these have not been specified.
' R; |" _9 I* L2 X
' u- w  w9 p1 |9 J) a  This parameter is specific to backends, but can be specified once for all in
2 _7 T' M4 i; L: Z7 A  "defaults" sections. This is in fact one of the easiest solutions not to, o$ A6 h3 }: Z8 x' B
  forget about it. An unspecified timeout results in an infinite timeout, which4 ^" B& X; t- f0 o7 ^5 z
  is not recommended. Such a usage is accepted and works but reports a warning  W: ?/ b3 U- o8 M
  during startup because it may results in accumulation of failed sessions in) b: h! {+ C+ j1 \. {/ k' p
  the system if the system's timeouts are not configured either.- ^7 ]& X% H% \& |8 o! P0 L% l
; r/ B. a8 W" C$ x* P, M2 [) w
  This parameter replaces the old, deprecated "contimeout". It is recommended
) ]* ~% A" X/ @  to use it to write new configurations. The form "timeout contimeout" is3 o! Z1 i7 N' A
  provided only by backwards compatibility but its use is strongly discouraged.
- ]( t: E  k) n) x! ?, m* Z
2 A2 m- U& N" h' Y( W. V3 _  See also: "timeout check", "timeout queue", "timeout server", "contimeout",4 i1 C2 c. v( H; E
            "timeout tarpit".
7 l6 D! [! f5 M! D& b
* V/ D( X$ I% {& {4 y( p! v$ ~+ Q
timeout http-keep-alive <timeout>8 o# \* E" H! }! H: @8 |
  Set the maximum allowed time to wait for a new HTTP request to appear8 P- J1 `+ `; b7 J; p/ O1 |1 R
  May be used in sections :   defaults | frontend | listen | backend
( _9 U2 l5 A9 L. j+ k  F8 v8 h0 b                                 yes   |    yes   |   yes  |   yes
9 l/ P2 r. \  G0 b. `, E  Arguments :3 x( y6 `3 p; d; q0 _% G
    <timeout> is the timeout value specified in milliseconds by default, but3 b9 b; }) F. r2 F
              can be in any other unit if the number is suffixed by the unit,
: [6 y9 C. m7 q$ o$ c              as explained at the top of this document.! w8 D9 o6 z* v& n9 F

9 O6 b! g- i, Z. L  By default, the time to wait for a new request in case of keep-alive is set# ~) n9 O9 [/ [( L
  by "timeout http-request". However this is not always convenient because some
4 O! I# o2 o+ K+ m5 ~7 ]' k5 _- z2 _  people want very short keep-alive timeouts in order to release connections0 T6 e& a# A1 [1 q  d
  faster, and others prefer to have larger ones but still have short timeouts0 S% e% M7 m- {, k1 _+ Y% |
  once the request has started to present itself." Q7 C* e# G  |% }* B: T# H
! @5 V& ~- R, Y* c; i. M0 Q7 D
  The "http-keep-alive" timeout covers these needs. It will define how long to4 Y+ `: t- H$ C! V; ^4 d
  wait for a new HTTP request to start coming after a response was sent. Once
7 u8 K  X0 q7 T! J- S6 ]  the first byte of request has been seen, the "http-request" timeout is used
  Y4 p3 V- f6 F; }: @( R  to wait for the complete request to come. Note that empty lines prior to a2 u6 E: `: ~& G' |
  new request do not refresh the timeout and are not counted as a new request.  r0 T( c6 q* G

- b& I+ {) X3 v# q  There is also another difference between the two timeouts : when a connection
$ E, w# z, Q' }& Q! a) O7 _9 v( z  expires during timeout http-keep-alive, no error is returned, the connection1 O. l4 u7 s4 h- g2 {; |
  just closes. If the connection expires in "http-request" while waiting for a6 K' P5 L7 V8 C) C4 s
  connection to complete, a HTTP 408 error is returned.
$ D0 P9 {1 @2 ~9 @: a) ?" u# {6 \  I
  In general it is optimal to set this value to a few tens to hundreds of
# o& Q8 ?- I/ |! a! z' W- @6 K  milliseconds, to allow users to fetch all objects of a page at once but
) e9 ^; W9 |! W! z3 y) `  without waiting for further clicks. Also, if set to a very small value (eg:6 V' Z: t1 c9 C. O& e. T
  1 millisecond) it will probably only accept pipelined requests but not the0 f% l" E1 X  G+ r5 K
  non-pipelined ones. It may be a nice trade-off for very large sites running
# j5 G' j0 J# z- i0 _# d  with tens to hundreds of thousands of clients.
8 ^3 _+ O* |  M- b- v' [, O! `! q( _& q- v. P. q# Z6 t
  If this parameter is not set, the "http-request" timeout applies, and if both
9 O7 u) x4 }3 k# `" y* h  are not set, "timeout client" still applies at the lower level. It should be  ?. \# ]0 \! u" @2 E) e
  set in the frontend to take effect, unless the frontend is in TCP mode, in
( J- u9 A/ r# _3 l  which case the HTTP backend's timeout will be used.
; r0 ], D& G4 O; `4 O% H8 f1 ]& ~$ `. S
  See also : "timeout http-request", "timeout client".: H( _4 i3 V$ Z2 _

% k) b, @6 ^0 l% a' S: |4 `4 K1 o; f" K. p* }0 q
timeout http-request <timeout>
. p, [. K, C( B  y' g3 k  Set the maximum allowed time to wait for a complete HTTP request
+ {8 e# C9 }+ q+ i: n3 E; j  May be used in sections :   defaults | frontend | listen | backend
! R: r& B9 m* u) c4 X5 g                                 yes   |    yes   |   yes  |   yes
2 y  c2 D% J% w  Arguments :
) q+ b1 T+ n/ J2 W7 }" k    <timeout> is the timeout value specified in milliseconds by default, but$ ?0 T$ ]0 C! `4 S# y- C
              can be in any other unit if the number is suffixed by the unit,
7 l% O+ H; l. c% V              as explained at the top of this document.
9 {* I% `! K2 f1 z2 y) \
( u: [- S, d: l  ?" b% D* S3 V- }  In order to offer DoS protection, it may be required to lower the maximum
# X3 H" y" G" d, s9 x2 h  accepted time to receive a complete HTTP request without affecting the client
% u9 x7 i, W; K: I  timeout. This helps protecting against established connections on which5 f' }+ A7 {; o
  nothing is sent. The client timeout cannot offer a good protection against
8 L1 Q& B& ^2 A1 Q+ E& J: ]- \5 y  this abuse because it is an inactivity timeout, which means that if the
( Q9 C, Y% C! P/ M$ d$ _% ]6 }  attacker sends one character every now and then, the timeout will not- M6 s# z' A; {5 P! C5 H
  trigger. With the HTTP request timeout, no matter what speed the client
& k+ ?; q5 `2 c, W: H( ?% D+ v  types, the request will be aborted if it does not complete in time.( h& i3 }  j2 j4 R! Z6 c3 y2 f# i% J

8 u; K. x. W7 m* m! B+ {6 {  Note that this timeout only applies to the header part of the request, and
# D" ^/ c+ B4 R  M  not to any data. As soon as the empty line is received, this timeout is not- D- \; [+ K. |
  used anymore. It is used again on keep-alive connections to wait for a second7 }) r9 F+ I; T4 F8 T% j" j
  request if "timeout http-keep-alive" is not set.$ m+ X  `- ?) D1 g) V2 ]

  G2 q2 O4 d; h$ t) A; L6 m  Generally it is enough to set it to a few seconds, as most clients send the
% j/ U! q% V1 ^4 s* y  full request immediately upon connection. Add 3 or more seconds to cover TCP% o  r4 L$ L8 A( a
  retransmits but that's all. Setting it to very low values (eg: 50 ms) will
) @! V8 r* l4 H4 b, ~% Z. _  generally work on local networks as long as there are no packet losses. This
5 U$ f/ @, D/ u) G. K  will prevent people from sending bare HTTP requests using telnet.
0 }7 _/ J' S. Y. K( h" c$ \5 K2 g* F" X: D* d' }3 f
  If this parameter is not set, the client timeout still applies between each7 A' L2 E1 b) ^* T3 f
  chunk of the incoming request. It should be set in the frontend to take
2 l8 B. l2 F# J& g- U  effect, unless the frontend is in TCP mode, in which case the HTTP backend's
. ~$ H5 w7 |$ S; G  timeout will be used.: q7 d; y$ r: R/ b2 G. Z

* e. m' n" e  w$ m/ C0 `  See also : "timeout http-keep-alive", "timeout client".# A" _1 I7 P$ R& \

: v3 i, g" K' D, [& a' I
5 k: `0 q3 ]0 W4 O- S2 c' r  i8 k* {timeout queue <timeout>
6 l  b( h3 V( j) A2 C  Set the maximum time to wait in the queue for a connection slot to be free
* p, J* R7 L- t' ^, y4 w4 }  May be used in sections :   defaults | frontend | listen | backend! E" j, {0 d4 H) q- A( E7 S
                                 yes   |    no    |   yes  |   yes
' U( _3 U3 b0 _7 P  Arguments :
6 r: |8 m/ W- z# t/ k    <timeout> is the timeout value specified in milliseconds by default, but. f; Y$ `, F2 X+ ^! R, J8 q
              can be in any other unit if the number is suffixed by the unit,- J9 [+ b" c& Z: S) @
              as explained at the top of this document.
  {: j( S0 |; v$ ?
- t# g' U" F! g  When a server's maxconn is reached, connections are left pending in a queue+ g' O5 I) K% q# v5 S# }6 z
  which may be server-specific or global to the backend. In order not to wait
" D7 e  j! q1 H7 r. z1 _  indefinitely, a timeout is applied to requests pending in the queue. If the& d& V% r5 Z. g( d( z- [" {
  timeout is reached, it is considered that the request will almost never be
' \, ]7 V4 X( V8 z/ `% y+ B  served, so it is dropped and a 503 error is returned to the client.
6 f+ Q8 U8 Q( |
3 R0 e) a- `: K, y+ i( @  The "timeout queue" statement allows to fix the maximum time for a request to( s  w$ Y0 i) _* ~
  be left pending in a queue. If unspecified, the same value as the backend's
/ l: K& c( L5 P4 U  connection timeout ("timeout connect") is used, for backwards compatibility
8 A9 h4 {4 \- J6 p2 ]  with older versions with no "timeout queue" parameter.3 X) t% J6 d+ B& s  K. Y
( i/ n8 f& ~8 J; Y
  See also : "timeout connect", "contimeout".( M9 @% P! W7 U: R1 N, \; l

! i, O5 I. g- b% q# j4 Z1 X+ M! G( z4 S& [; @
timeout server <timeout>3 x3 |* S$ W) }3 ^
timeout srvtimeout <timeout> (deprecated)" K1 G. Q, x1 m) b& \
  Set the maximum inactivity time on the server side.
% R0 E# t6 y. t; F7 M9 L  May be used in sections :   defaults | frontend | listen | backend$ L$ G3 e5 w3 q9 S9 N8 \, q. f
                                 yes   |    no    |   yes  |   yes  ?) ~/ ]% q" {. B- z
  Arguments :
% e5 s9 V/ C4 {% b7 @    <timeout> is the timeout value specified in milliseconds by default, but
4 B( c9 r9 b6 W+ R              can be in any other unit if the number is suffixed by the unit,6 A& ?  ^( @9 m3 N1 c
              as explained at the top of this document.
, U  |3 f( X3 M1 ~) T% e* [! }4 e- F' H7 o; C3 j+ `. D' W
  The inactivity timeout applies when the server is expected to acknowledge or0 ]" `4 h0 w5 t
  send data. In HTTP mode, this timeout is particularly important to consider1 w  ?7 P6 ]+ I; A! v
  during the first phase of the server's response, when it has to send the
1 k( J. y2 @# W' }$ i( i- \  headers, as it directly represents the server's processing time for the4 j6 d, o  w3 v  F3 B2 b
  request. To find out what value to put there, it's often good to start with
. N7 @3 D# t8 ^3 Z  what would be considered as unacceptable response times, then check the logs
! x- Z. @, |. I+ k$ a  to observe the response time distribution, and adjust the value accordingly.3 A; E  [2 _: @: F
  G4 z, V5 [6 h- x
  The value is specified in milliseconds by default, but can be in any other4 Z  |, q7 N" v9 f3 @! v4 y( ]) {
  unit if the number is suffixed by the unit, as specified at the top of this
  M- B/ A/ D  x3 u/ a  document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly5 W1 g% X3 h# x+ J6 y
  recommended that the client timeout remains equal to the server timeout in* s' x  p/ b1 `: a
  order to avoid complex situations to debug. Whatever the expected server8 A. `3 R. A% r
  response times, it is a good practice to cover at least one or several TCP5 W! r$ C7 y% M
  packet losses by specifying timeouts that are slightly above multiples of 3
) N4 V+ g$ {: `4 _$ G  seconds (eg: 4 or 5 seconds minimum)." C" j' K8 E2 U0 e1 v/ I4 {
; U# |9 i: _0 F* c, @+ t) e
  This parameter is specific to backends, but can be specified once for all in
7 L1 }1 q5 k) i3 g) d9 A  "defaults" sections. This is in fact one of the easiest solutions not to
$ B9 o  }$ Y& ]  forget about it. An unspecified timeout results in an infinite timeout, which, V0 H8 O; s: h9 E
  is not recommended. Such a usage is accepted and works but reports a warning
  @5 s. G4 n( b2 D, {  during startup because it may results in accumulation of expired sessions in
3 `  `4 d" J8 t- h, c  the system if the system's timeouts are not configured either.4 u" ~' d& O! f9 f* A4 z' h' z

9 O* n# L9 p* |7 a% S+ T9 G# m  This parameter replaces the old, deprecated "srvtimeout". It is recommended
3 X5 F4 L; W" f. `6 m) _& E  to use it to write new configurations. The form "timeout srvtimeout" is
1 T9 \  G) G0 x3 a  provided only by backwards compatibility but its use is strongly discouraged.6 w% _  w0 R; j+ r- l7 D

% g, S! ], }" K/ x+ r  See also : "srvtimeout", "timeout client".
/ Q5 g9 D& n  G+ g( V5 u+ i( ~8 y1 ?. V7 J/ W% Z) ]4 \5 p  |& d
+ N. n. q* t& ]: ~8 J1 @( X9 t8 q
timeout tarpit <timeout>
4 a* W$ R5 K& K8 D( n  G  y  Set the duration for which tarpitted connections will be maintained  w0 g% n7 |# x
  May be used in sections :   defaults | frontend | listen | backend
) L  \, K0 K- U( @2 ]                                 yes   |    yes   |   yes  |   yes  j% S0 \* o9 b9 ^# l
  Arguments :8 K) ?2 d% G! b
    <timeout> is the tarpit duration specified in milliseconds by default, but2 y+ }5 h( E  |/ t3 ^
              can be in any other unit if the number is suffixed by the unit,. N/ @/ h, p3 v. Z
              as explained at the top of this document.
  u- c- W. a; ]) G
, @: g9 c# z- u$ R& ]8 P: k4 S$ G  When a connection is tarpitted using "reqtarpit", it is maintained open with
- m; X+ v4 a6 m9 M, y# n  no activity for a certain amount of time, then closed. "timeout tarpit"
! M' `' c8 {( {% V  A. g  defines how long it will be maintained open.
) u: h$ \0 w7 ?# l! N8 [5 Y7 a/ e" {" O: {  T# b
  The value is specified in milliseconds by default, but can be in any other. G5 s4 u" d/ P: f, a. }
  unit if the number is suffixed by the unit, as specified at the top of this9 c* A2 r4 Q& E& ?( K( p1 [
  document. If unspecified, the same value as the backend's connection timeout' x/ e! q* D! O3 K4 w: n2 j; _/ z$ X
  ("timeout connect") is used, for backwards compatibility with older versions
! y) T. g+ X4 G  T  with no "timeout tarpit" parameter.' ^& ]/ [. _- X/ Y

0 P' N" {' l1 j/ R  See also : "timeout connect", "contimeout".
9 l7 x/ ]: x6 I' v# P6 c9 b5 `/ ^* C) U0 A6 A* W" H
# y' X! F; o. O0 R6 e, Z1 |/ u- E
transparent (deprecated)5 l$ a; C% U# k
  Enable client-side transparent proxying
3 @* R) h8 ]' `  @/ a( G: @  May be used in sections :   defaults | frontend | listen | backend. e# ]! E* B6 @( k+ f8 e- v
                                 yes   |    no    |   yes  |   yes
6 L4 O; L$ T( \2 F0 i) N/ c  Arguments : none; t9 m, y& j: l9 b

7 R7 Q0 d3 n2 H/ p  This keyword was introduced in order to provide layer 7 persistence to layer
2 R% v  m- Z  U* {  }% r  c  3 load balancers. The idea is to use the OS's ability to redirect an incoming# Z, V8 ]) z: z
  connection for a remote address to a local process (here HAProxy), and let
! p5 a* z7 \4 h4 o. x& c  this process know what address was initially requested. When this option is
, D  V: g0 [: E. r6 I  used, sessions without cookies will be forwarded to the original destination
) ]& g) w) A4 m( y  IP address of the incoming request (which should match that of another
1 u* z4 y* d) b2 G7 K6 `; a  equipment), while requests with cookies will still be forwarded to the/ I/ P4 D, O: G' n& W. i# s
  appropriate server.# O- O1 R5 J. V9 E- [8 i; D* \
# J. V# I9 l1 o# {" I; U4 {' c- B
  The "transparent" keyword is deprecated, use "option transparent" instead.
% S0 z5 Y/ f* ^
! {$ [  X2 S3 `5 k: m  D7 e  Note that contrary to a common belief, this option does NOT make HAProxy
' c7 r+ S& {0 a6 }( h. F  present the client's IP to the server when establishing the connection." Y9 {1 Z5 A5 c

5 W( H! G" p$ E$ D" n  See also: "option transparent"' a* [. M  J" D3 p# X/ b2 v

3 B5 k; ]) P/ s8 b: L
2 k4 K6 ?4 Q3 E% D' Cuse_backend <backend> if <condition>3 Q6 ^7 J! L- F( Y% l  Z
use_backend <backend> unless <condition>
$ Z" w) z! a+ b& k  i% p  Switch to a specific backend if/unless an ACL-based condition is matched.- m2 Q) d. y( T8 B8 [
  May be used in sections :   defaults | frontend | listen | backend
7 [1 R# d5 ]! J; h3 l' {                                  no   |    yes   |   yes  |   no5 N' R+ n$ g- o0 b
  Arguments :( b+ @, s* r1 O5 {# E2 ~
    <backend>   is the name of a valid backend or "listen" section.! V5 a1 C# m, d8 v0 F% i  q

/ z- U5 c: E+ ]: h" j2 w' I0 D    <condition> is a condition composed of ACLs, as described in section 7.
4 m. ~3 K5 k* H; p; ?1 {; }9 L, F2 x
  When doing content-switching, connections arrive on a frontend and are then
1 U1 W- w1 Z7 k8 \+ x0 f" M  dispatched to various backends depending on a number of conditions. The6 n3 V+ c; u' P# q
  relation between the conditions and the backends is described with the: W' S( B& N( I6 p- b; G0 `$ A+ E9 A6 [
  "use_backend" keyword. While it is normally used with HTTP processing, it can
0 x/ q9 ^" g5 x" h) l7 i  also be used in pure TCP, either without content using stateless ACLs (eg:, k* A6 f5 w9 Z1 J; ~# ^: w
  source address validation) or combined with a "tcp-request" rule to wait for
6 w& E+ ]$ G; J% A+ U" w7 o, O  some payload.: ^" W8 ~/ r* u, z) p
7 E3 m) \% b$ x$ s$ Y# f* @
  There may be as many "use_backend" rules as desired. All of these rules are# w3 g# _/ `: k& n
  evaluated in their declaration order, and the first one which matches will& W' L7 m0 _* u' O
  assign the backend.+ h8 q. a: G7 y9 G$ I, u

, r$ \7 Y( S* G$ }  In the first form, the backend will be used if the condition is met. In the9 D( R  Y; Y$ G3 Q0 u8 m
  second form, the backend will be used if the condition is not met. If no! y5 x& J2 y3 n) K) }4 Q& Q
  condition is valid, the backend defined with "default_backend" will be used.
  s; C' K( J& w  If no default backend is defined, either the servers in the same section are9 M, y0 d. c; p  O  V) P- H
  used (in case of a "listen" section) or, in case of a frontend, no server is
5 h/ Z$ h: P- l  used and a 503 service unavailable response is returned.$ w2 H0 V1 n  m9 \: C  K. E
1 W. b7 l& M& X; ~
  Note that it is possible to switch from a TCP frontend to an HTTP backend. In9 F. c" V9 i9 b2 ]5 D% E
  this case, either the frontend has already checked that the protocol is HTTP,
- C  R+ u0 F' k3 b  and backend processing will immediately follow, or the backend will wait for6 @. m6 p& O$ l0 g5 K0 Y) j
  a complete HTTP request to get in. This feature is useful when a frontend
9 a1 ]% v, [1 v1 Y$ w$ E  must decode several protocols on a unique port, one of them being HTTP.
9 n7 ?  T1 D" C0 |
/ d9 i4 Y3 Y  W2 A& [  See also: "default_backend", "tcp-request", and section 7 about ACLs.
( U# m" a( k7 i, ]8 E; F) H+ z" ~8 B, X( \. D* q# o8 Z7 ]
9 S1 Q4 G0 f5 B. T8 |; q
5. Server and default-server options
  l: S* H9 S! ^/ N; N------------------------------------& s7 A% w0 R! |. X( n

7 S# k& n3 }+ B' [2 L8 NThe "server" and "default-server" keywords support a certain number of settings) j4 W8 [3 R5 Z5 ?8 k9 w! u
which are all passed as arguments on the server line. The order in which those4 Z% Y* z* f- s7 o2 ?+ v/ I: y
arguments appear does not count, and they are all optional. Some of those
2 J/ o) s! {7 R4 \. \  X4 ]4 Msettings are single words (booleans) while others expect one or several values
7 a: i& I5 n- W% G7 P$ i/ Jafter them. In this case, the values must immediately follow the setting name.
  I4 }" j) j% V! D3 k) H& s. gExcept default-server, all those settings must be specified after the server's0 I2 E& r1 G1 E% p1 v
address if they are used:
& j, s/ e- c( N: A9 |/ n! i( E: s" {! Q7 l! q7 A* ?
  server <name> <address>[:port] [settings ...]
0 c- @% A" ]7 z% W: m: }  default-server [settings ...]5 _* Z$ k- _) Q6 h
' M+ J: i1 W: X
The currently supported settings are the following ones.
- E+ R( n* u( Z; A4 f' D5 i0 C3 ^
& ~$ u$ G8 Q" E' ]; Gaddr <ipv4>: ?# K6 k9 J+ ?( x
  Using the "addr" parameter, it becomes possible to use a different IP address
% d, z) |/ u; K+ v* w1 s  to send health-checks. On some servers, it may be desirable to dedicate an IP
* ^- A( p: H1 C) g: |2 u8 p  address to specific component able to perform complex tests which are more
& P$ `, R9 v$ q/ \: @8 O  suitable to health-checks than the application. This parameter is ignored if
4 S; s9 z. W0 z# T  the "check" parameter is not set. See also the "port" parameter.9 W% c8 P; c% u+ R0 G: N' }
6 \6 c* g8 c$ K  r: b
  Supported in default-server: No
8 l" I) ^0 p3 y7 o8 M/ S, U
3 L; e, h/ _4 }7 X9 H0 Qbackup; q) W# w) h( d( v" L) [
  When "backup" is present on a server line, the server is only used in load
, n6 b3 p) b" Q- p& h# @5 A  balancing when all other non-backup servers are unavailable. Requests coming
& L4 Y# \, U9 d6 r' i$ T  with a persistence cookie referencing the server will always be served
$ F) h. j8 _$ L/ D$ `" i  though. By default, only the first operational backup server is used, unless0 Z! z- I- [! f8 D: |
  the "allbackups" option is set in the backend. See also the "allbackups"
" u' u4 i# p; Q3 T  option.+ C* h4 x) x# d7 a0 Q

( \  _+ M0 m. |# c  Supported in default-server: No
' m9 ^1 s& E( r# g% U5 F
* ?/ l% w8 \% a; u1 Q3 W+ o& l7 _3 ~check
% \+ W' _! P$ @, i  This option enables health checks on the server. By default, a server is$ f9 ?. W. ^' S2 e
  always considered available. If "check" is set, the server will receive% ~7 e1 m3 {- P0 P' C
  periodic health checks to ensure that it is really able to serve requests.+ U' b7 B6 p2 g! A# m+ S
  The default address and port to send the tests to are those of the server,- G6 h2 ~# V" s
  and the default source is the same as the one defined in the backend. It is
* d6 k* q; @6 d% @6 F8 F: U  m& V  possible to change the address using the "addr" parameter, the port using the
+ N; b2 v6 n6 P9 U" N% O# s* |  "port" parameter, the source address using the "source" address, and the
6 @1 p& {) z2 u4 y2 x  interval and timers using the "inter", "rise" and "fall" parameters. The7 D# m1 W/ Q0 `) F- z( {
  request method is define in the backend using the "httpchk", "smtpchk",: |/ Q# o6 e" |( R9 C
  "mysql-check" and "ssl-hello-chk" options. Please refer to those options and
0 U5 D$ o9 o- n7 a  parameters for more information.
- O& L" d' M; R6 O4 Q% U* {7 ?: ^. c# |
  Supported in default-server: No
4 Q- u+ o& q, s" u* x9 |% W0 G$ ]8 m4 @/ J3 W* x8 a6 y% ]
cookie <value>  _# s# B3 s# ?7 z4 h
  The "cookie" parameter sets the cookie value assigned to the server to+ ]% k0 b; o' E9 K+ W8 j
  <value>. This value will be checked in incoming requests, and the first2 B, y4 \/ n' h- X1 g& c
  operational server possessing the same value will be selected. In return, in
! Q4 p- N! X- ^: P& H  cookie insertion or rewrite modes, this value will be assigned to the cookie' B- ], I5 O$ a8 i) Q8 S
  sent to the client. There is nothing wrong in having several servers sharing( d6 _# o/ y# n9 ^
  the same cookie value, and it is in fact somewhat common between normal and
1 [6 Z: n0 a! U" J/ Z9 G  backup servers. See also the "cookie" keyword in backend section.) ]" f$ K. W) {5 W, i4 Q

# L# S, b" J9 k, ~/ m  Supported in default-server: No/ Q+ A/ f/ G$ W( S; X5 C/ c
1 c- l4 c9 G$ J% w
disabled, ^" P7 q3 P$ I1 w: E+ P
  The "disabled" keyword starts the server in the "disabled" state. That means
  h, c- p- \5 i6 M  G& V' [) O  that it is marked down in maintenance mode, and no connection other than the
; @# S/ Y6 n- s" f! }  ones allowed by persist mode will reach it. It is very well suited to setup, B6 q& ]9 [* B0 y
  new servers, because normal traffic will never reach them, while it is still3 v/ t5 l+ \4 s( j
  possible to test the service by making use of the force-persist mechanism.; T2 I( H7 L: g7 ~; f# {: w, Q, ~9 o! Y
7 i/ |6 u/ J1 G
  Supported in default-server: No: V3 U  v0 I+ f0 q* h2 {- z
0 B9 s( c' }2 r; i) i) n0 V& X+ O
error-limit <count>
/ u6 O' ^$ r! F2 M. D  If health observing is enabled, the "error-limit" parameter specifies the1 a4 W( T& t" [; {4 W
  number of consecutive errors that triggers event selected by the "on-error"- y# ~4 k( P1 c9 h
  option. By default it is set to 10 consecutive errors.% `9 N5 ~" ?+ G8 E1 X* `

' A/ c8 \3 k2 y/ r- B3 w' f7 ~  Supported in default-server: Yes, ~: y+ [% ?( n' [7 a1 T

; o! T! n. T4 d" Z* D! G+ J  See also the "check", "error-limit" and "on-error".3 @! v. g4 I) \8 a. B

. W3 A: W4 E$ X! F7 e3 X- L! E8 jfall <count>$ H# V2 T0 O& t( g8 ~2 z# `
  The "fall" parameter states that a server will be considered as dead after0 [& ]; y& v( s7 X2 N+ K
  <count> consecutive unsuccessful health checks. This value defaults to 3 if( i: B5 }8 V" R7 H1 Y1 r
  unspecified. See also the "check", "inter" and "rise" parameters.% [6 l* u  h5 v2 g" L8 v* d
6 ?" I! Z. I- N; P; r; q
  Supported in default-server: Yes
4 r. q& q0 g' ]; s/ V- c
2 p) B# a) z& n& c3 j4 Kid <value>
5 M. g4 J8 f/ o- }1 \. Y1 i  Set a persistent ID for the server. This ID must be positive and unique for  ~* q6 U7 W& @+ q, v5 C
  the proxy. An unused ID will automatically be assigned if unset. The first; U- Y4 |+ Q  U: `# V5 F1 m: h! `) p
  assigned value will be 1. This ID is currently only returned in statistics.
; f5 `: W, _% W1 ]! T- I9 P0 Q; `5 ]$ n% z9 l: V% i2 `2 Y
  Supported in default-server: No7 \7 Z/ l( e% M" w3 a$ g
& T$ V  p5 X  X2 l( O" R! n; _
inter <delay>) ?& L% K. ^0 `9 a# f" M& ?9 N
fastinter <delay>
7 i% Z' a* r* V+ Xdowninter <delay>' z  t: M8 a' w
  The "inter" parameter sets the interval between two consecutive health checks. V- q& k5 ~# X# R; D6 D
  to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms.
& g$ e8 E. |2 C2 v* O, A  It is also possible to use "fastinter" and "downinter" to optimize delays
9 V5 n/ }( a* S2 t3 ]4 Z# F  between checks depending on the server state :% R) G( H6 j4 {! `2 y% u7 Y# o' b

- `) I3 p& C" y$ K' Z8 Q& L             Server state            |             Interval used
" @! ?' E$ n& e7 p0 {    ---------------------------------+-----------------------------------------1 [! a# F* n( T6 {$ m; o! ~- r
     UP 100% (non-transitional)      | "inter"
) W( w, O* I1 @    ---------------------------------+-----------------------------------------6 n7 B; Z( F/ C! q9 F9 X
     Transitionally UP (going down), |- X/ K/ y* U. x, E) t, k9 x4 A
     Transitionally DOWN (going up), | "fastinter" if set, "inter" otherwise.! s5 k% Q) R. G) l" S/ @
     or yet unchecked.               |) V2 C2 p0 y: F: K
    ---------------------------------+-----------------------------------------
( b# ^2 C; I6 A, Y2 y" @" B! F  ]     DOWN 100% (non-transitional)    | "downinter" if set, "inter" otherwise.
8 P9 z: H* a. z8 D    ---------------------------------+-----------------------------------------: R9 K) d1 z' j( t  ^6 t- F
0 N& n: _% B: {
  Just as with every other time-based parameter, they can be entered in any
) ?6 b5 ^+ g; i$ }' X1 U  other explicit unit among { us, ms, s, m, h, d }. The "inter" parameter also
( P- ~; v. N0 ^* Y/ i  serves as a timeout for health checks sent to servers if "timeout check" is0 J$ l/ g5 x6 g8 ~; {
  not set. In order to reduce "resonance" effects when multiple servers are+ P+ i. q" R2 r! Q8 r
  hosted on the same hardware, the health-checks of all servers are started
2 [- n% [$ A3 E  i, W9 g  with a small time offset between them. It is also possible to add some random0 I0 ^2 J: Y* m6 b- E5 q& |2 Y
  noise in the health checks interval using the global "spread-checks"' k; J8 O. }2 W/ F& g6 g( \
  keyword. This makes sense for instance when a lot of backends use the same
0 K! ^1 E8 X* I1 N  servers.
4 h' i  P1 N3 c0 y" C* a
& S! R( p+ A# Z0 b, w8 L) t! X  Supported in default-server: Yes! [( q$ Q8 a& J
" X8 s0 K. T3 W) ?  e
maxconn <maxconn>
) g) E0 A- R( n. P0 }6 _  The "maxconn" parameter specifies the maximal number of concurrent
& |7 g: u% Y7 w  connections that will be sent to this server. If the number of incoming
: A$ h2 d. g3 s2 \1 b7 p  concurrent requests goes higher than this value, they will be queued, waiting
5 p! A5 F) Z. |5 s2 @! J  for a connection to be released. This parameter is very important as it can
  Q4 J" v9 w+ U) A9 a5 b* m3 n  save fragile servers from going down under extreme loads. If a "minconn"
. u. u9 ?6 q/ J  parameter is specified, the limit becomes dynamic. The default value is "0"* S6 X! Q& K( z; R; r5 J/ K
  which means unlimited. See also the "minconn" and "maxqueue" parameters, and/ Z  a3 V4 ~8 l. U# [0 q: M* D/ P4 W
  the backend's "fullconn" keyword.4 U& x8 u. l4 i3 L8 P, t

3 O9 H; @$ Q7 H# {: v1 x1 J, N  Supported in default-server: Yes! P% ?3 C( R/ X1 \& D0 s% S2 [
5 e& c4 r. m  N1 e  P$ X
maxqueue <maxqueue>1 D1 h2 }( a' S9 ]  D
  The "maxqueue" parameter specifies the maximal number of connections which/ L% U2 f1 Q+ A* R
  will wait in the queue for this server. If this limit is reached, next
9 e2 h+ g* v) }* g/ b  requests will be redispatched to other servers instead of indefinitely
1 C+ m) W4 H+ y# {; K5 a+ w# d  waiting to be served. This will break persistence but may allow people to4 B2 r, S# P3 c; {
  quickly re-log in when the server they try to connect to is dying. The# ~4 u9 ]" O. F. o* `5 D) K
  default value is "0" which means the queue is unlimited. See also the
" m( s1 L. Q2 p$ D, i' W9 {  "maxconn" and "minconn" parameters.
+ @( [' O! z) @7 Z% n8 E3 ]. {! Z4 H: Z- V* w, c" O/ J* H
  Supported in default-server: Yes
: O& y$ x7 z1 ?8 O2 Y. b
7 L4 }0 _& S% ?! V, Gminconn <minconn>9 a/ U6 ]) v* F( r8 C. t) h
  When the "minconn" parameter is set, the maxconn limit becomes a dynamic
' y. q$ Q6 E7 b' m  limit following the backend's load. The server will always accept at least
( a$ Y0 F2 U+ P* g  <minconn> connections, never more than <maxconn>, and the limit will be on
* m( T5 W; u" \! E  the ramp between both values when the backend has less than <fullconn>
, d5 o6 g; I- z4 p* k. A  concurrent connections. This makes it possible to limit the load on the' D, s6 b5 T, D) r: V* n$ z& M
  server during normal loads, but push it further for important loads without1 k& Z7 S6 c- |8 {+ N3 s
  overloading the server during exceptional loads. See also the "maxconn"
( s' {; P# N, y1 s' u% x  and "maxqueue" parameters, as well as the "fullconn" backend keyword.
) H  Y3 @, g5 j! U% e
6 m6 X4 ?1 W" E; T7 u& v( Z  Supported in default-server: Yes0 G9 j& w' w' k/ c& c- K* n

9 i# P. k+ h1 s: c& r; K" `observe <mode>, y# _1 V) P" A. b
  This option enables health adjusting based on observing communication with! z6 ]& L# N; {5 W. B
  the server. By default this functionality is disabled and enabling it also: Y+ R4 `/ n  D7 ]  |/ n
  requires to enable health checks. There are two supported modes: "layer4" and
/ x) c' ^# H! V/ G# t) X  "layer7". In layer4 mode, only successful/unsuccessful tcp connections are
: Y" V! |3 ~* o  k$ w  significant. In layer7, which is only allowed for http proxies, responses% m3 r- O/ ^, G. `, v* u1 Y
  received from server are verified, like valid/wrong http code, unparsable
+ l# Y0 p* h- P& k, |3 E  headers, a timeout, etc. Valid status codes include 100 to 499, 501 and 505.6 t) `, {- P6 C$ Y

1 Y( _/ U" y+ x" X- |4 _6 `/ x/ r  Supported in default-server: No" S6 H) H# K/ c* e( L$ o$ ^

# l* H+ G0 }0 j  See also the "check", "on-error" and "error-limit".
: C; H! C4 N  ~4 `- E5 u. r* l* S
) i8 u" b5 b* P& Pon-error <mode>: R' @: @9 G4 N
  Select what should happen when enough consecutive errors are detected.
2 p" X, l  Z6 W- S" s# K' C( ~# T6 T  Currently, four modes are available:
9 m1 i1 I( L$ @+ _5 K6 S0 |1 m  - fastinter: force fastinter
3 G) q/ g. ^: a& @$ |4 |# r  - fail-check: simulate a failed check, also forces fastinter (default)
; B! M/ O! V4 E6 z5 D  - sudden-death: simulate a pre-fatal failed health check, one more failed
3 S9 X! e" E7 o; Q/ D    check will mark a server down, forces fastinter2 @2 k$ B& e! p! R+ N- l/ H* Y
  - mark-down: mark the server immediately down and force fastinter
5 g  ]/ A* J/ X" c5 p4 n8 q6 X1 Q% D9 |) Z% @
  Supported in default-server: Yes8 S! {, p, Z- B5 D# y% I# L- D

1 @1 _7 i) o0 ]  See also the "check", "observe" and "error-limit".
7 `3 c; O& ^5 q  W6 m1 O% W
7 F8 M" q( g# Fport <port>; _' }2 i3 H, d% w+ S0 w) k& A/ _
  Using the "port" parameter, it becomes possible to use a different port to* {" l/ Q% {2 G
  send health-checks. On some servers, it may be desirable to dedicate a port' `9 u9 |! G7 G
  to a specific component able to perform complex tests which are more suitable* D/ ]  s; V& n
  to health-checks than the application. It is common to run a simple script in% W& }! m" @! ^
  inetd for instance. This parameter is ignored if the "check" parameter is not% M: g2 \5 B7 I) O5 @
  set. See also the "addr" parameter.
' T4 d* D! [4 n( }; \. S0 P( R; v7 k' b, c  _9 A
  Supported in default-server: Yes) z5 v  \% F( }1 h1 W9 K9 S4 V

% w+ N( K' u- O$ K' G7 eredir <prefix>
" b4 L4 P2 a2 D) C$ X+ }  The "redir" parameter enables the redirection mode for all GET and HEAD
" C3 V) |4 o* v2 ~2 ~. _+ J  requests addressing this server. This means that instead of having HAProxy" ~4 x) l: D) n# K4 F/ D& I
  forward the request to the server, it will send an "HTTP 302" response with( C' f5 r5 I5 c5 W0 }& [
  the "Location" header composed of this prefix immediately followed by the
# c. r' @( e( |3 ]& m* v: q3 k  requested URI beginning at the leading '/' of the path component. That means9 I4 z& K- j/ Z1 w! t6 N
  that no trailing slash should be used after <prefix>. All invalid requests
. L% x9 h) o3 u. g' R  will be rejected, and all non-GET or HEAD requests will be normally served by8 _4 w! I) b4 }. `" S* [
  the server. Note that since the response is completely forged, no header% m) @& }9 K& J
  mangling nor cookie insertion is possible in the response. However, cookies in
7 l5 a; f; y& E9 w7 _  requests are still analysed, making this solution completely usable to direct1 C5 i0 x) p5 E( D- ^! q
  users to a remote location in case of local disaster. Main use consists in: K3 v( ?# Q/ j( v5 |0 I, Z
  increasing bandwidth for static servers by having the clients directly
! U! u1 o( x9 t  connect to them. Note: never use a relative location here, it would cause a, M- t& c/ ~& u' \/ u9 j; Z: ]
  loop between the client and HAProxy!# D! ]+ G5 [1 K! I; q8 X) D
8 l, K( {4 g0 v* }+ j
  Example :  server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
4 a, c( R" n0 R* E2 Q$ A) Y. H' s2 ^7 w
  Supported in default-server: No
: H9 `* S2 N) h6 ^1 e
1 y" i& Q' n" b0 R% ^9 K" Lrise <count>0 ^/ E+ [0 {( w  a# H+ \9 F
  The "rise" parameter states that a server will be considered as operational
) |7 }3 h- y% U+ N% z6 U  after <count> consecutive successful health checks. This value defaults to 2
/ _9 B& L* l* T" T- ]/ z' N* Y  if unspecified. See also the "check", "inter" and "fall" parameters.
2 t0 X$ _" P  I
5 ^; l$ S3 g) Y; V# L; y  Z% V  Supported in default-server: Yes
8 q+ ^, T$ a3 o; i  K
$ Q8 q- f' E' N3 [' xslowstart <start_time_in_ms>" j. r* Z- F7 k/ f- {  [& ~  F! _1 W
  The "slowstart" parameter for a server accepts a value in milliseconds which
$ m% Y4 D7 a. x) v- M# `5 ^  indicates after how long a server which has just come back up will run at
/ ?- ~! y& K+ _6 S. I  full speed. Just as with every other time-based parameter, it can be entered
4 M3 u1 A  h7 q* u  in any other explicit unit among { us, ms, s, m, h, d }. The speed grows
4 Q7 _" }3 x$ W: P% Y- H  linearly from 0 to 100% during this time. The limitation applies to two" Q8 l4 ?" l! y2 s0 c: g
  parameters :2 m7 Q6 S9 m% _4 w8 Q

9 o( F: F, p, |* `3 a  - maxconn: the number of connections accepted by the server will grow from 1
& H* E2 O& [) y, _4 ^  K) m* {    to 100% of the usual dynamic limit defined by (minconn,maxconn,fullconn).) }: H$ E! o4 }1 t& k: c* l

& m9 C4 @' g- s+ j# ?* P  - weight: when the backend uses a dynamic weighted algorithm, the weight
, h" j9 d3 D  o5 l% I  ?    grows linearly from 1 to 100%. In this case, the weight is updated at every
# F% @! P* S) M$ t, Z+ J1 p% ?    health-check. For this reason, it is important that the "inter" parameter& g+ v0 M' @! d  Q+ c
    is smaller than the "slowstart", in order to maximize the number of steps.
# t# U; g! F6 W$ v
# W( K/ Q3 ~& V8 W* g8 g  The slowstart never applies when haproxy starts, otherwise it would cause, R5 S- r/ O8 F1 e& |
  trouble to running servers. It only applies when a server has been previously
# E- t- h8 }8 W2 h3 @0 [  seen as failed.
+ ~+ d& S* U* {2 ]8 I$ X7 _% c" e2 |
  Supported in default-server: Yes
5 f$ w4 [1 ?. @2 {
* A# R& @8 n$ o' \  I5 zsource <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]( E- r, P! p8 l) \; L% T
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]/ g8 J' c3 N7 [. }! v3 {, w
source <addr>[:<pl>[-<ph>]] [interface <name>] ...
6 O2 P7 ]# I9 K' ]" a4 T, a. f7 N  T( _  The "source" parameter sets the source address which will be used when
: K# L' v; O, t  connecting to the server. It follows the exact same parameters and principle% L/ o5 b4 w5 V! W
  as the backend "source" keyword, except that it only applies to the server
2 P; I$ g/ P$ W3 h1 ^; M* @  referencing it. Please consult the "source" keyword for details.6 O& L( Q+ o+ l/ ?

6 a8 ?$ I3 z9 s( x' d  Additionally, the "source" statement on a server line allows one to specify a) i, @% f& H6 `$ \7 ?
  source port range by indicating the lower and higher bounds delimited by a3 K! `7 Q' D) K/ z
  dash ('-'). Some operating systems might require a valid IP address when a- p, P" K' m$ E2 C
  source port range is specified. It is permitted to have the same IP/range for7 e! D6 y% }' V/ k# e
  several servers. Doing so makes it possible to bypass the maximum of 64k6 r* ]# c6 M" w$ ]6 [, k
  total concurrent connections. The limit will then reach 64k connections per
# I9 Y: G  d  p8 \: X4 B  server.$ p2 d% z6 K# H" s+ Z, [) i
5 x/ R0 D4 Y& x0 c7 W* M. q- X
  Supported in default-server: No
6 B. m/ h# ?, J; b* Y9 {1 T; L
+ C  e2 C, [$ d$ Vtrack [<proxy>/]<server>4 F$ E9 |4 W* L4 P
  This option enables ability to set the current state of the server by
. l# k- J$ P4 P8 g$ ?( s1 P! _% E  tracking another one. Only a server with checks enabled can be tracked
+ N0 v+ L4 O# Z$ _" {% d+ e* R  so it is not possible for example to track a server that tracks another
  a1 k7 y6 b5 A) o# h) X; Q% \" P  one. If <proxy> is omitted the current one is used. If disable-on-404 is
6 u8 F5 F5 X- @2 }8 b  used, it has to be enabled on both proxies.
& D3 e% f7 v% p1 P; B0 I- ]
' w( A% o8 @  j5 l% O, D  Supported in default-server: No
5 f/ A8 r* y$ f4 N+ n3 l8 E6 _- _0 m% n2 m# g
weight <weight>
$ X0 Q7 U1 S- k- l  The "weight" parameter is used to adjust the server's weight relative to
% N4 @6 J1 c5 z0 I3 b) }+ B* ]8 R  other servers. All servers will receive a load proportional to their weight
1 ~! H, ~9 h. f  w' `6 s( m  relative to the sum of all weights, so the higher the weight, the higher the
% ~' |1 ~3 y7 p+ |( W! b8 m+ ^% X  load. The default weight is 1, and the maximal value is 256. A value of 0" E* K# B& E# N* B! W& c7 s. M; B
  means the server will not participate in load-balancing but will still accept
( ^0 K+ G' }. V: f0 C  persistent connections. If this parameter is used to distribute the load4 g/ w+ o# W; W! X. q  S( c
  according to server's capacity, it is recommended to start with values which
* h0 x9 w# B7 E! B" w8 [' M. i  can both grow and shrink, for instance between 10 and 100 to leave enough- N# l6 o- A- S  u) Z
  room above and below for later adjustments.
! N1 C7 n& h( r! z* S6 I1 R9 d/ W. r
  Supported in default-server: Yes! @$ g! g2 l5 E: a6 M
* V/ W& M0 `) u  G

  x, q6 R) F5 {( R. C) [% k) f6. HTTP header manipulation$ \4 j, Z/ m  ?' v& p' _
---------------------------
' d, y5 T' `9 p: `7 S; h. W$ m: Q; I2 M5 h* g  J
In HTTP mode, it is possible to rewrite, add or delete some of the request and
, x+ w- A2 {- h/ M  [0 ^response headers based on regular expressions. It is also possible to block a
2 q8 C* b. F# w* \; h& n1 Nrequest or a response if a particular header matches a regular expression,
0 [# A8 E# g* P0 p7 Uwhich is enough to stop most elementary protocol attacks, and to protect/ X- I& g. x; t2 B2 a! M6 n
against information leak from the internal network. But there is a limitation
  c$ {7 n: H; m6 g% U+ eto this : since HAProxy's HTTP engine does not support keep-alive, only headers4 H* s6 r% ^3 c( I
passed during the first request of a TCP session will be seen. All subsequent
- r# W$ u; T- Y" S( I$ zheaders will be considered data only and not analyzed. Furthermore, HAProxy6 E6 V% q" Q% M. F# o8 l
never touches data contents, it stops analysis at the end of headers./ d) S* Z2 A/ F# q$ G, }' N
2 K8 ?1 z5 Z8 z: }
There is an exception though. If HAProxy encounters an "Informational Response"; d- v$ X' [# {, H2 N9 g  }$ \
(status code 1xx), it is able to process all rsp* rules which can allow, deny,
* ?, [2 ]0 H6 erewrite or delete a header, but it will refuse to add a header to any such1 x& @. g& `3 P, n3 l( o7 x
messages as this is not HTTP-compliant. The reason for still processing headers
3 ]0 u, o6 t# N9 g# Qin such responses is to stop and/or fix any possible information leak which may9 B! Y" M/ Z# r- O5 q
happen, for instance because another downstream equipment would unconditionally! L7 H/ N0 Z$ X
add a header, or if a server name appears there. When such messages are seen,
  ?2 L# a+ ~6 P- S1 h# Qnormal processing still occurs on the next non-informational messages.$ J3 X, T# E4 @* y5 r

( Y/ f& Y  t* A) xThis section covers common usage of the following keywords, described in detail
; E: B" `. y! p- m; [" c- ?$ |in section 4.2 :  D0 u; y& _$ E$ q. |
4 Q" N2 K/ U% p: f- c! x
  - reqadd     <string>4 s8 a8 N' j+ |! c# J  n0 C
  - reqallow   <search>
) ?$ U% O+ f9 F! M5 }6 X  - reqiallow  <search>
5 E+ F2 o% ^% g+ J, ^% A  - reqdel     <search>& \: E: Y& M3 z1 a  \
  - reqidel    <search>5 g$ }+ T3 T# a# B/ v% Z) L
  - reqdeny    <search>
. N5 C3 Q! \) z" b4 I# W  - reqideny   <search>
- C) L; ^" y6 w9 o+ f: s8 L0 X( s. \  - reqpass    <search>
4 j& w/ o) m' x6 A# I. a  - reqipass   <search>! V$ Z, _: l6 F0 a6 ?* F: v4 R
  - reqrep     <search> <replace>. w4 U: E* x' j4 \$ F
  - reqirep    <search> <replace># Y% D, D" f# ]& j
  - reqtarpit  <search>
* v. ~' N) E2 I2 {% a  - reqitarpit <search>
% o! ~% \, H+ m) r  c6 }7 d! G  - rspadd     <string>
9 j& Y/ c8 f$ W2 Y4 Q+ ~- Z  - rspdel     <search>/ f2 \5 I! E) c
  - rspidel    <search>4 s2 E: y. T/ `; x5 ^: V
  - rspdeny    <search>& ~9 u! r0 R: j5 Q: |; R  K
  - rspideny   <search>
# Q. A- K: S7 U+ u/ w  - rsprep     <search> <replace>( ]/ g8 n, U. p, z
  - rspirep    <search> <replace>
( t7 U7 X! |7 Q: Q
. e) r) L4 b! a9 V* fWith all these keywords, the same conventions are used. The <search> parameter/ R6 {7 S9 ]+ e( M9 l1 @( ^
is a POSIX extended regular expression (regex) which supports grouping through
; c' z8 Q- \3 b' Nparenthesis (without the backslash). Spaces and other delimiters must be
$ T. S! d6 H4 w; L. A. @prefixed with a backslash ('\') to avoid confusion with a field delimiter.
, z# b* K8 ~0 t# m4 W2 ]Other characters may be prefixed with a backslash to change their meaning :, X! }* A0 U1 ?( O* |
# M" u: f) S' a, Q+ u8 b# p" B
  \t   for a tab2 f: x' i/ N1 K, V# Q) _% z+ S
  \r   for a carriage return (CR)
# P+ _( L3 O/ X5 z, T- {& |  \n   for a new line (LF)
& ^/ d  ^, E1 B: T$ ?% m- v  \    to mark a space and differentiate it from a delimiter6 V( C* j- W* {" m: A$ r6 ]0 P1 P
  \#   to mark a sharp and differentiate it from a comment
7 k" h* F! h7 T, V+ E, k  \\   to use a backslash in a regex6 U% T9 B) ~0 ^+ }, t  W* v4 Z
  \\\\ to use a backslash in the text (*2 for regex, *2 for haproxy)
: u% T3 s# S9 E( ~. V  \xXX to write the ASCII hex code XX as in the C language
# T" P& O- X' d$ v' n( j
0 a& k, L. R+ I3 O" Q( F) d6 t/ P3 a6 XThe <replace> parameter contains the string to be used to replace the largest
5 o/ i; H2 F' pportion of text matching the regex. It can make use of the special characters6 r. M9 ?+ @" e- O
above, and can reference a substring which is delimited by parenthesis in the) u% B: Z; t7 Z5 e$ D+ a2 O. Q: ~1 U
regex, by writing a backslash ('\') immediately followed by one digit from 0 to- P0 T1 B. ^* k' B1 f
9 indicating the group position (0 designating the entire line). This practice
1 f* t: _. N! P# i+ i7 xis very common to users of the "sed" program.
( ^6 R1 n7 u8 Q! b- a$ {' @2 n* F$ B5 q2 W2 b
The <string> parameter represents the string which will systematically be added
# I! F/ p3 P9 ~. |after the last header line. It can also use special character sequences above.
0 K" h* i: K4 G4 L3 ~1 `# X' o: s" W. Q" ^  b9 c
Notes related to these keywords :
2 f4 }& ?  Q" V" Y& Y* [; G---------------------------------
) Y3 h" t1 |1 ?5 [: [8 `# s  - these keywords are not always convenient to allow/deny based on header
+ S$ ~( F5 W# a4 }7 C$ |, {    contents. It is strongly recommended to use ACLs with the "block" keyword
  u+ E. V0 m. K( v) J# M    instead, resulting in far more flexible and manageable rules.
! H# z/ G' k5 G
/ ]$ Z* M. z( b! i( N  - lines are always considered as a whole. It is not possible to reference  e& O5 J/ u* P, G/ P2 H
    a header name only or a value only. This is important because of the way
; ?) u! z6 ~0 m6 ^) f    headers are written (notably the number of spaces after the colon).% s( s8 Y# V  F
( ]. x  z3 O) O
  - the first line is always considered as a header, which makes it possible to) q; k+ a. v0 r( H( E$ F# c6 R& ^/ J0 l
    rewrite or filter HTTP requests URIs or response codes, but in turn makes
( F. a- k4 o# p    it harder to distinguish between headers and request line. The regex prefix# [  R) v4 C* ?! S# \2 j5 }. ?  m
    ^[^\ \t]*[\ \t] matches any HTTP method followed by a space, and the prefix3 _9 c1 A, ], l, t4 g) s6 x
    ^[^ \t:]*: matches any header name followed by a colon.
5 v& ^6 j3 a/ b8 v: g2 D7 _, e; v8 ]; p" |1 x
  - for performances reasons, the number of characters added to a request or to
5 g7 A4 L' {* ^$ Z    a response is limited at build time to values between 1 and 4 kB. This
  h5 m- ^# W0 t% m    should normally be far more than enough for most usages. If it is too short
& I5 c  N+ J( S    on occasional usages, it is possible to gain some space by removing some
: L- B& G" I' m" s    useless headers before adding new ones." q" Y( m7 C/ Y# y
5 @) j  L; Y2 \5 [1 S  R
  - keywords beginning with "reqi" and "rspi" are the same as their counterpart
9 Y/ ?/ A$ a( i. l) ?1 F    without the 'i' letter except that they ignore case when matching patterns.* |9 M8 `7 o& m0 B( j
8 I' v  h' g& @" X, W. k4 E
  - when a request passes through a frontend then a backend, all req* rules
0 q3 B; x& o1 F+ M! l: Q    from the frontend will be evaluated, then all req* rules from the backend
) f. t; J7 I8 \) m2 E: Z7 C    will be evaluated. The reverse path is applied to responses.0 `' t# l: Z; B, L5 b: p+ b* k
) F' A2 l5 v: v0 {; G+ x5 g
  - req* statements are applied after "block" statements, so that "block" is
3 R/ k0 s3 a. ]: h    always the first one, but before "use_backend" in order to permit rewriting; t% w/ \/ Q$ W; j' o7 V
    before switching.
9 B0 R* h8 U  ?4 d5 ?
% M6 u0 s7 B2 i/ q3 z8 R, P3 d2 v5 }; A) g2 u1 i% A
7. Using ACLs and pattern extraction
7 h- n% u- \9 P/ v3 ~. L7 _8 l* z------------------------------------
1 H/ n) h3 H7 [. g/ Y  r" P. e
6 e/ h# d# Q9 }, `( }+ ^( F1 ]The use of Access Control Lists (ACL) provides a flexible solution to perform$ n! d: h% {/ K, _
content switching and generally to take decisions based on content extracted
: X& I% U( N5 M: n0 Z2 W) u4 Bfrom the request, the response or any environmental status. The principle is
: X2 d& K+ C2 |* s. ^) O. Vsimple :
8 s% n4 k& y# S; F
$ ]  G% f! n) d4 z$ {4 M# z  - define test criteria with sets of values# |6 u& l; ?: ~6 u( `. ~
  - perform actions only if a set of tests is valid3 @" s' n6 [, `; z% l) g

9 ^( d4 {2 _; S) UThe actions generally consist in blocking the request, or selecting a backend.
( `3 i/ D+ {) V0 F& l- g1 X
8 P; z. V6 Y7 PIn order to define a test, the "acl" keyword is used. The syntax is :; z; }6 a. v5 l: u* z# q
6 r" v6 h+ q; q; I0 D
   acl <aclname> <criterion> [flags] [operator] <value> ...
4 N; K/ E: z* D1 C) y6 K& q% n9 E0 J
0 K- f1 U* T$ ~$ Q0 p8 j3 uThis creates a new ACL <aclname> or completes an existing one with new tests.
" i7 g- V! G1 N6 }3 ]Those tests apply to the portion of request/response specified in <criterion>
4 [+ Z" l# I  h/ S' u. ^0 land may be adjusted with optional flags [flags]. Some criteria also support9 l5 b+ k) Z( ~* d3 l: z% b' t
an operator which may be specified before the set of values. The values are  B! Z! M1 E* F  O6 p
of the type supported by the criterion, and are separated by spaces.
& H  R' V, o% @) I1 \* S+ j9 f. x$ b; d/ y( j$ O/ {% L; k
ACL names must be formed from upper and lower case letters, digits, '-' (dash),
+ F. u4 \$ R, p0 |1 k- t8 O'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,
, I8 r; X; w$ R; F/ b8 V$ Gwhich means that "my_acl" and "My_Acl" are two different ACLs.
1 Y' A, J: f2 Z! i6 }
1 P# g" s3 x! S, `There is no enforced limit to the number of ACLs. The unused ones do not affect
# U+ T8 X2 ~3 ?! `9 Zperformance, they just consume a small amount of memory." j  N- g5 }  F2 G% e

- d* w# q+ J7 j- n! e; ?The following ACL flags are currently supported :+ a! M! ]2 U- s$ [! c2 y; ?
3 N3 \7 E3 M3 I9 j' D# p" R* a
   -i : ignore case during matching of all subsequent patterns.
+ x* F/ S& ^4 h* C% Y   -f : load patterns from a file.2 I; C& Q9 z0 e0 b' N& C: I
   -- : force end of flags. Useful when a string looks like one of the flags.
' c  c2 _* F! P; i1 y
8 L. K- r) s, k- K7 CThe "-f" flag is special as it loads all of the lines it finds in the file7 B2 F" \- ?; l, c2 r3 p
specified in argument and loads all of them before continuing. It is even) _. {, G' B8 n; f
possible to pass multiple "-f" arguments if the patterns are to be loaded from
7 }5 p) o4 L3 E. _multiple files. Empty lines as well as lines beginning with a sharp ('#') will
5 h. E* P! I5 a) e$ |8 U/ l. Gbe ignored. All leading spaces and tabs will be stripped. If it is absolutely
5 a: C, S8 M, H7 d. vneeded to insert a valid pattern beginning with a sharp, just prefix it with a8 P+ V1 P" z2 q9 @! [% S# E3 \9 q/ j
space so that it is not taken for a comment. Depending on the data type and
8 Z( I# I1 G! p, G0 j2 Kmatch method, haproxy may load the lines into a binary tree, allowing very fast
0 w' k2 l2 `& ~4 blookups. This is true for IPv4 and exact string matching. In this case,
! Y* a) w$ a3 s7 d7 a. wduplicates will automatically be removed. Also, note that the "-i" flag applies
) D8 T3 S1 ]) _  R. P' }to subsequent entries and not to entries loaded from files preceeding it. For
- S3 R9 ]9 S# d2 j! ~8 E9 linstance :
  k3 h; `" e! Q% U6 o# L  P6 y* i! @& F* G- C/ o5 T
    acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst  test5 r/ A- s( t( k+ A

4 `! R1 J) N! I0 ^- U; I$ h" yIn this example, each line of "exact-ua.lst" will be exactly matched against8 R4 e, L5 m; I1 ?/ f
the "user-agent" header of the request. Then each line of "generic-ua" will be1 M' k7 F  K' X7 B. N
case-insensitively matched. Then the word "test" will be insensitively matched8 e. f( X. K4 V" a5 _5 V
too.# N" v% v! b8 U! v8 S! |
4 F* t3 C5 F5 ]& [4 m
Note that right now it is difficult for the ACL parsers to report errors, so if
/ p) T( G  {4 A6 H1 P- K  Za file is unreadable or unparsable, the most you'll get is a parse error in the
) a0 }  G  b% [$ `ACL. Thus, file-based ACLs should only be produced by reliable processes.
* [3 j3 N" x. p! F3 ]
* E  }: ?6 g* z) mSupported types of values are :
% |$ Q1 N( p9 A9 ~5 m/ L" p) k
  - integers or integer ranges; z) n4 U' K$ B4 [  G
  - strings
% D& ?4 |$ X7 q7 s0 F  - regular expressions- h: D3 O2 v! C: A# f- J1 B
  - IP addresses and networks' N" y, U3 r% O' V7 d& e; V

: O, F% U7 i- s$ x2 O  l8 p  s# C) L( T0 M1 O, e7 ~( T/ G  F
7.1. Matching integers6 o5 a* b5 T1 K9 {
----------------------7 G0 I6 b# O% J
& a& I, S3 O' Z
Matching integers is special in that ranges and operators are permitted. Note
! m) n# }* ~: |, I9 ethat integer matching only applies to positive values. A range is a value5 a* X! {' z) X9 J) a
expressed with a lower and an upper bound separated with a colon, both of which
( |: V& S2 W( ~8 e- U3 O6 \may be omitted.
1 E7 @; {4 @* ~: y2 x( R/ r
( |  E9 ^; D% sFor instance, "1024:65535" is a valid range to represent a range of( y: u/ M8 F' }% l3 v) s# K
unprivileged ports, and "1024:" would also work. "0:1023" is a valid$ z3 M2 K/ a* c" k" C: @5 N
representation of privileged ports, and ":1023" would also work.. x! j* \7 e* P' m) g  ~
0 Q) L; N% J1 O/ P" E
As a special case, some ACL functions support decimal numbers which are in fact- \1 G& _( l" t7 o+ x5 Q; x
two integers separated by a dot. This is used with some version checks for5 b9 z" Y/ Y9 J
instance. All integer properties apply to those decimal numbers, including
2 e4 Y, q, D) X) _% x% X4 U( N! franges and operators./ |' `+ e7 c: K7 T& m) k
3 B* `7 Y( }) l+ E5 y
For an easier usage, comparison operators are also supported. Note that using7 I/ W# m* c( b3 u' v1 i2 d
operators with ranges does not make much sense and is strongly discouraged.0 s$ J. ~+ B0 X+ ]' j- A
Similarly, it does not make much sense to perform order comparisons with a set
/ y6 }2 ~4 [& z/ g, ?of values., o' E0 s6 S7 d, J/ h
/ O$ t; ^" D' _+ K
Available operators for integer matching are :
" W- z( o$ ], o0 \* ]6 ~) j+ L5 X0 [
  eq : true if the tested value equals at least one value4 _! {+ C# \, {0 H% ~
  ge : true if the tested value is greater than or equal to at least one value
7 c5 e# J% y$ g1 R- [, Z# Q  h4 u; g4 F  gt : true if the tested value is greater than at least one value
0 e; Z7 V. r# R# M  le : true if the tested value is less than or equal to at least one value
& Q) c4 g. Z: i( M8 D; n8 J  lt : true if the tested value is less than at least one value
4 S1 a) W# ?2 K% U5 n
: {6 D, P8 @  F) x: y5 x5 t/ u( b& tFor instance, the following ACL matches any negative Content-Length header :
8 M( N  G* ~6 D9 v6 A  C: N# M# d9 c9 m/ N7 D
  acl negative-length hdr_val(content-length) lt 0
0 x6 x5 @  e0 m2 q' A9 k
, B' Z7 N* r" M/ j: o9 KThis one matches SSL versions between 3.0 and 3.1 (inclusive) :
- G$ p) L% v% s$ k; c, v7 s0 C- |6 n7 P- a7 m8 t& z' L! Q" [2 [7 C
  acl sslv3 req_ssl_ver 3:3.1* v; x) H; u1 Y
8 D6 u  f+ U' K- }

+ _" d. V/ L1 J% l& q7.2. Matching strings
5 D) p, Q  d3 E( k---------------------  L. L5 s9 T9 h6 V2 B

! c: H; W/ Q  x9 H) w5 lString matching applies to verbatim strings as they are passed, with the, O" b! D" m( C5 x1 r/ ~/ y
exception of the backslash ("\") which makes it possible to escape some# u9 ]( D1 y+ v0 x( c& f
characters such as the space. If the "-i" flag is passed before the first! ^, |8 B7 j2 O7 ~% W; }8 f
string, then the matching will be performed ignoring the case. In order, z7 {* w* E7 j) @# n
to match the string "-i", either set it second, or pass the "--" flag* Y+ B' J: R- O6 j
before the first string. Same applies of course to match the string "--".3 p) B$ ]6 c- p, i' p' t
7 W5 ]& D1 i5 l0 M$ L

' B# j3 t, l8 l7.3. Matching regular expressions (regexes)7 p5 H5 q( `% n! Z. p( _
-------------------------------------------
+ x( }" d1 b. |/ o* Z; V& e" k+ S+ Z" A
Just like with string matching, regex matching applies to verbatim strings as% C: d7 e8 T! T6 |7 R2 i
they are passed, with the exception of the backslash ("\") which makes it, v1 i1 `+ |9 y' ?+ q
possible to escape some characters such as the space. If the "-i" flag is$ g9 e" o! \6 }8 N/ h! ^* E0 D
passed before the first regex, then the matching will be performed ignoring
3 q+ @" o/ ]. v. a6 Z. uthe case. In order to match the string "-i", either set it second, or pass7 S$ u1 Z" p" }4 [5 e. p- M
the "--" flag before the first string. Same principle applies of course to
, }. j: T  O9 wmatch the string "--".
0 R' a; n' K4 m5 b, T+ r' g; L) M% [  G; w  v# v

! E% i( `- b( b: A8 l" }: ]8 [7.4. Matching IPv4 addresses7 a" w# m# ^/ H, J3 \
----------------------------
7 Z2 Y6 {  x  g; I
1 C- E: F+ K9 I' Q  NIPv4 addresses values can be specified either as plain addresses or with a1 }# y! t; I. L6 I# L9 f2 v
netmask appended, in which case the IPv4 address matches whenever it is) i9 J" _9 [( b' @# m- d+ v0 m
within the network. Plain addresses may also be replaced with a resolvable
( G# y$ s# W/ chost name, but this practice is generally discouraged as it makes it more" K( Y1 X" ^/ x
difficult to read and debug configurations. If hostnames are used, you should
# G% Q6 A& y) Jat least ensure that they are present in /etc/hosts so that the configuration2 }1 w2 y2 M! d8 P
does not depend on any random DNS match at the moment the configuration is. I. P* z6 I9 J4 }: T; E
parsed.
  s$ `( \- l) g0 T0 l2 P5 @5 H9 Y# G' V, k( j0 n! ?
+ Q7 f4 O7 U2 j+ z1 s# K
7.5. Available matching criteria
6 I' c0 M' U/ ?8 k5 h8 a--------------------------------
" e7 U! k: ?" Q* U* N
6 N% B: O# y1 F) k7.5.1. Matching at Layer 4 and below
; O# d$ y1 Y/ m' V------------------------------------
9 ^% }  L4 d: p; t; {( ~& i
5 m" C: T( G0 C% _6 ?A first set of criteria applies to information which does not require any
: q$ C- k( |4 f# \& w4 Wanalysis of the request or response contents. Those generally include TCP/IP' \( K) w1 C" H" _1 D' O
addresses and ports, as well as internal values independant on the stream.$ W4 @) U, ?& @' ^0 y7 V9 R

/ c5 P$ [; U0 l1 C. Talways_false8 W5 B! N) H" D
  This one never matches. All values and flags are ignored. It may be used as
  W, b$ q/ K2 T6 e4 c* {  a temporary replacement for another one when adjusting configurations.2 j) ]& \+ r* t2 Z: X% j
6 X+ p2 ?5 m; O' J4 C& v
always_true* t' {" U) r, W+ W  _2 o. U
  This one always matches. All values and flags are ignored. It may be used as
% l- k3 C! E& C; n6 B3 v. H9 h; ?5 J  a temporary replacement for another one when adjusting configurations.
# G/ ~, X# M4 ^% x
' O  Y4 W9 a! }7 Mavg_queue <integer>& {/ J- \- v* q% C3 f
avg_queue(backend) <integer>+ t7 C9 k' ?( M, L" i9 p5 a
  Returns the total number of queued connections of the designated backend+ A# @7 r& G' o: l8 A) L$ g3 P+ R# Z& e
  divided by the number of active servers. This is very similar to "queue"
( z4 b! \" _$ U$ y8 q9 E  except that the size of the farm is considered, in order to give a more
0 A+ U" L. ~+ i; H' C3 v- ~1 d+ N  accurate measurement of the time it may take for a new connection to be
$ O( M0 S, C0 M' l/ g2 _. V: p  processed. The main usage is to return a sorry page to new users when it
: [  y4 U0 v9 \4 F- ^  becomes certain they will get a degraded service. Note that in the event, r9 t. ?8 @2 v$ D( N
  there would not be any active server anymore, we would consider twice the
  z5 B# ?6 F8 Q  T' ~  number of queued connections as the measured value. This is a fair estimate,# S7 l. X' \/ @1 B" b
  as we expect one server to get back soon anyway, but we still prefer to send
. B5 V6 i) N9 M6 P  new traffic to another backend if in better shape. See also the "queue",
  B) W" K2 ]  q: m  "be_conn", and "be_sess_rate" criteria.
9 Z0 D( O) w4 U+ H+ r( ?) u- Q
* _5 p5 Q: J% ]: l4 fbe_conn <integer>( \# ?( V  [) ]5 A; d
be_conn(backend) <integer>! m2 [6 a+ [+ y2 J+ z6 j7 P5 U" l
  Applies to the number of currently established connections on the backend,
4 H/ F- m. W" P  possibly including the connection being evaluated. If no backend name is
5 h$ U; F; j" h0 Z  specified, the current one is used. But it is also possible to check another
  B3 N7 N' Z5 B% o8 K7 p  backend. It can be used to use a specific farm when the nominal one is full.; ]+ L# {/ m; R( o
  See also the "fe_conn", "queue" and "be_sess_rate" criteria.+ k$ P+ J4 m: I3 o  O1 G+ V4 w
2 S# `- E9 M; w! ?& D. O3 b
be_id <integer>2 t% B5 n9 r0 e" L
  Applies to the backend's id. Can be used in frontends to check from which
; X: h/ a1 d- \0 q: r2 p  backend it was called.
5 T  Z' b# X( m/ Y" X
1 T+ R/ Q5 H9 x1 i5 ^be_sess_rate <integer>
  j, V) K& ~6 l/ Dbe_sess_rate(backend) <integer>
- M# i; o. i4 S1 d  Returns true when the sessions creation rate on the backend matches the
4 X. C/ _% \2 a. N  specified values or ranges, in number of new sessions per second. This is
3 [" i4 P* N) |0 T& Z5 D  used to switch to an alternate backend when an expensive or fragile one
% q0 z$ b( j7 H) e* O+ p  reaches too high a session rate, or to limit abuse of service (eg. prevent' h- h  {/ K0 a, [/ E
  sucking of an online dictionary).
4 c3 n, E" X. y) k+ Z  ]: Z
3 ^- p2 [2 d$ A* k1 Z1 ^) ~; U  Example :# Q8 s8 L! o$ r% N% a7 E
        # Redirect to an error page if the dictionary is requested too often7 _2 V8 G6 P" z3 R2 r9 U5 R( ?
        backend dynamic
9 h" j# S, y6 P. |4 u            mode http
/ f" R8 b6 ^5 m; I/ U            acl being_scanned be_sess_rate gt 1001 O# j) I1 q3 o2 X# Z
            redirect location /denied.html if being_scanned
' I, z' L( u* [. M. @1 Y
) i: C+ O5 l$ C' u  U7 U; n" @$ f& E/ @& Cconnslots <integer>, V+ f5 k) b$ L# J4 x" _
connslots(backend) <integer># `- X# R! i  F7 ^, E( X$ p
  The basic idea here is to be able to measure the number of connection "slots"
" R8 [* L8 a& D: s  still available (connection + queue), so that anything beyond that (intended0 {6 H" R. |1 j" i9 d
  usage; see "use_backend" keyword) can be redirected to a different backend.
5 B3 E0 v+ ^! E3 |7 A% P/ J8 X! u' ?) v! `
  'connslots' = number of available server connection slots, + number of4 _. _' _" `' ~# P' ^
  available server queue slots.3 K" _$ g! I5 s  h
2 f9 b3 @& c6 [/ d
  Note that while "fe_conn" may be used, "connslots" comes in especially  V, G0 P$ {8 N/ \
  useful when you have a case of traffic going to one single ip, splitting into) r# q6 W) U( W7 `
  multiple backends (perhaps using acls to do name-based load balancing) and. o2 u8 ?( `: B5 B- z; `
  you want to be able to differentiate between different backends, and their
5 I  E/ K) E( Y! O4 w) ~2 o  available "connslots".  Also, whereas "nbsrv" only measures servers that are$ m$ ?; V/ F8 n# Z, t' C( c
  actually *down*, this acl is more fine-grained and looks into the number of
3 W! w; o1 [9 M! r+ z+ r  available connection slots as well. See also "queue" and "avg_queue".
9 R% H6 n9 t) l/ r- d4 v$ y6 Q/ e$ X, S) O
  OTHER CAVEATS AND NOTES: at this point in time, the code does not take care! n3 i6 }+ W, R/ g. N
  of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,
* d7 B& X7 p2 \( a5 a1 R$ X  then this acl clearly does not make sense, in which case the value returned
- Q- k' h' e, y( s& m) J4 x  will be -1.$ V# Y3 s: W" ^6 @  U2 R6 V. S
& G8 W# Y+ o) K4 x( d. G3 [
dst <ip_address>
/ Y) h( M# W: V7 @( ]  Applies to the local IPv4 address the client connected to. It can be used to+ P1 L  Q( v, g2 V1 e+ o* E
  switch to a different backend for some alternative addresses.; O- p/ y7 d6 _: i) U5 u. T
2 u4 w$ N* `; l4 [) Q& l! k( g2 Y
dst_conn <integer>
( `5 O' a2 H; h3 z- ]! D8 v  Applies to the number of currently established connections on the same socket+ k% ]6 c) J% n
  including the one being evaluated. It can be used to either return a sorry
6 j3 C6 Y6 P, \; }# g  page before hard-blocking, or to use a specific backend to drain new requests
+ r2 G. \% S7 S0 N0 p! F9 d  when the socket is considered saturated. This offers the ability to assign
- T6 p. \2 @, O1 f' }5 Q* p3 \  different limits to different listening ports or addresses. See also the
0 K, b& e: `( [% f) w/ O0 g% k  "fe_conn" and "be_conn" criteria.7 T% z' @9 ]" d% g

. A) q& J8 |# f- v6 _& tdst_port <integer>9 o+ i5 k/ l, J# y
  Applies to the local port the client connected to. It can be used to switch3 i3 Q% J, B! ~) p) M; q
  to a different backend for some alternative ports.
7 ?3 d* V9 V% r8 k
7 `) O' T+ V3 {% r2 T2 Z, a- Jfe_conn <integer>( Y+ r& n+ m; j/ D( O! r1 z( \
fe_conn(frontend) <integer># j( r6 T: Q( a' m
  Applies to the number of currently established connections on the frontend,1 J. M. P9 \- s( n; l  p
  possibly including the connection being evaluated. If no frontend name is5 {& ~/ p+ Q& B* F1 o' Y# D
  specified, the current one is used. But it is also possible to check another4 M6 @/ C! ~2 B6 x) ^
  frontend. It can be used to either return a sorry page before hard-blocking,% B2 X6 ~$ ?) u  c# }" j2 |, w7 \  M) d
  or to use a specific backend to drain new requests when the farm is# x3 ?7 t; t1 H1 n9 @. Y& x/ w
  considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"% H. I: X0 B( y% T/ R9 a
  criteria.
  {6 \8 I8 Q# p+ P5 b. E4 D/ ]0 X4 k1 y5 @2 [, |  }8 v
fe_id <integer>
2 j5 ?+ U* G' x' m  Applies to the frontend's id. Can be used in backends to check from which" ]  |4 l" z3 M& {% s' P
  frontend it was called.
. c9 U7 D, W5 p6 Y! Z' k+ V' X( ], {, f3 I5 h" u
fe_sess_rate <integer>
" `/ t- d6 X  U3 a5 T5 rfe_sess_rate(frontend) <integer>: G5 i! m0 U0 y+ w2 I
  Returns true when the session creation rate on the current or the named
4 y; u! n" K( {% ]. v; @  frontend matches the specified values or ranges, expressed in new sessions9 W0 g3 O& o; R* m
  per second. This is used to limit the connection rate to acceptable ranges in
7 V& J( e$ Q: \9 w  order to prevent abuse of service at the earliest moment. This can be3 x. w  ^; ]4 g3 M
  combined with layer 4 ACLs in order to force the clients to wait a bit for$ K; S9 K5 n% R5 A$ l
  the rate to go down below the limit.
: b" r0 e) a* x9 e8 A; ]
: M  b& |" e; C+ r) J( P+ ^  Example :5 w/ n. y7 R9 I, X: ^
        # This frontend limits incoming mails to 10/s with a max of 100
6 Z; g; C- t* L) \1 D' O2 x( ?0 @        # concurrent connections. We accept any connection below 10/s, and' }* V3 ]+ L; _" m* Q
        # force excess clients to wait for 100 ms. Since clients are limited to0 u/ D. r( v& y+ i7 {" s
        # 100 max, there cannot be more than 10 incoming mails per second.: X  i3 B2 A, \: X8 T& V
        frontend mail
7 @7 t7 @  Z% k# G9 t            bind :25
' V( D- g" }/ B9 c' r            mode tcp
. U* H4 p* B* b) J5 ~; `7 K/ `            maxconn 100
, G4 W) J$ P% F0 H. a            acl too_fast fe_sess_rate ge 10" U+ E3 G0 W8 x% j% d/ Z' {
            tcp-request inspect-delay 100ms
7 a* {: _0 P8 W3 M" b            tcp-request content accept if ! too_fast4 L5 |$ U  j% `+ y$ H1 t
            tcp-request content accept if WAIT_END
, T: X7 J/ b2 o3 W! n: I0 a8 L1 T! u/ I
nbsrv <integer>9 c0 W! z+ r# q: N4 [$ S( P" i- b
nbsrv(backend) <integer>
$ P- v; V0 T( _( ^7 P  Returns true when the number of usable servers of either the current backend
. q" K6 R3 }( @3 G" P  or the named backend matches the values or ranges specified. This is used to
0 G1 Z5 |! b: _% a, R4 s  switch to an alternate backend when the number of servers is too low to" ~" K3 ^: M9 y) s0 @
  to handle some load. It is useful to report a failure when combined with( ]4 k# g4 N; P
  "monitor fail".: C- B% U/ k7 \) l' G. j

% E2 [8 L6 y# M! U3 d0 B+ L; vqueue <integer>% K$ y$ n' h0 l+ K8 o; w
queue(backend) <integer>: s; s& K/ q( b% v* I0 J& f
  Returns the total number of queued connections of the designated backend,
; }; z0 e2 j/ c1 i3 c* O2 Y6 `  including all the connections in server queues. If no backend name is
$ ~4 l/ y. ~/ |- ?1 g  specified, the current one is used, but it is also possible to check another) e- a2 v) x% Y& L( j
  one. This can be used to take actions when queuing goes above a known level,! l8 _5 z, Z& q4 R
  generally indicating a surge of traffic or a massive slowdown on the servers.2 x4 P3 Z. \# Z6 N
  One possible action could be to reject new users but still accept old ones.8 S( e% o  o5 {2 a
  See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.
4 i( z$ J0 X; {, J) q; h/ D7 J% C0 j) h
so_id <integer>
* e! C: ?( s3 J3 O' v  Applies to the socket's id. Useful in frontends with many bind keywords.5 v, u9 G' W# l% @( ^$ [

+ m: C: X* O7 _  isrc <ip_address>+ {! k% u5 T2 ?* r9 g# F: L5 d
  Applies to the client's IPv4 address. It is usually used to limit access to! t8 ]1 x. I1 A
  certain resources such as statistics. Note that it is the TCP-level source9 C$ q' B5 |+ Z3 g2 z
  address which is used, and not the address of a client behind a proxy.2 Z7 h9 r& d' I9 y6 I5 T2 S! {

( X& f  B/ e) p4 c8 W; Tsrc_port <integer>
- B! a6 }) r& o9 d  ]/ r6 Q2 Z  Applies to the client's TCP source port. This has a very limited usage.
$ M8 V% {2 j" I' T6 L4 g# p$ x3 e# c' f, [- Q, L/ K, Q$ {; |5 ~$ K( Z
srv_id <integer>6 D/ E& G! ~% ~* |, n% ^; ?4 ]
  Applies to the server's id. Can be used in frontends or backends.
& Y, z# z4 a* c/ d9 ~, m  T
' B1 d' G( l. G# zsrv_is_up(<server>)8 f1 F% x9 N, w4 [6 m! M1 Z/ v% f+ {
srv_is_up(<backend>/<server>)4 E* W8 E8 H9 w& K/ C
  Returns true when the designated server is UP, and false when it is either
& F/ V2 e* W: J! ^7 g( Z& J3 |) Q  DOWN or in maintenance mode. If <backend> is omitted, then the server is
" m- C6 A, F$ I  y: j  looked up in the current backend. The function takes no arguments since it( R) X; n* Z( s7 c& a2 Q0 U
  is used as a boolean. It is mainly used to take action based on an external2 ^0 o) z7 }/ s7 F6 {7 _7 h" M
  status reported via a health check (eg: a geographical site's availability).. v; c; [7 N1 x" m! ~
  Another possible use which is more of a hack consists in using dummy servers( R* {" x5 G+ Q. D
  as boolean variables that can be enabled or disabled from the CLI, so that
& c9 R5 ]" I0 R2 t# S+ h  B$ ]9 q  rules depending on those ACLs can be tweaked in realtime.
8 q7 V6 f, Y9 s; }
( m: n5 D4 F. i+ F7 f; d4 x* @: |# x) p
7.5.2. Matching contents at Layer 4
: u: j! S6 _: }- ^2 m# U6 f-----------------------------------
6 ~% n, d+ O, T  o$ L1 w' @% w4 X  V/ X- t8 P0 q1 ?6 G
A second set of criteria depends on data found in buffers, but which can change- Q% {& M, y; v3 W
during analysis. This requires that some data has been buffered, for instance
1 h2 h$ z( ], O# L1 Vthrough TCP request content inspection. Please see the "tcp-request" keyword4 X5 E$ r% K- a3 F; s( j
for more detailed information on the subject./ a! f8 r+ m. k  I, \
' w$ J+ V5 B) z0 R: `% L- r
req_len <integer>
) h: _. x. e$ ^/ ]  J4 P' S  Returns true when the length of the data in the request buffer matches the
' b1 ]' [( a, B2 Z7 D$ R9 d' W  specified range. It is important to understand that this test does not$ Q% v4 K2 R. ?0 @! j. E
  return false as long as the buffer is changing. This means that a check with
3 t4 @' b3 k0 i* W4 D) J  equality to zero will almost always immediately match at the beginning of the/ M2 A+ g5 |; {5 v+ x# k
  session, while a test for more data will wait for that data to come in and
, T$ m, A4 L; a/ H  return false only when haproxy is certain that no more data will come in.3 x! O3 c% ^3 O0 G- q3 x
  This test was designed to be used with TCP request content inspection.2 i+ t4 |7 Y  n7 }: {
6 Y0 _3 T; i& s8 V. {/ a* |+ j4 p
req_proto_http  @; i" M- a4 I; f' ]) a7 _- V
  Returns true when data in the request buffer look like HTTP and correctly; A- V% a0 k, R" f, b& x; R& `
  parses as such. It is the same parser as the common HTTP request parser which
0 P& B$ y7 _$ s6 j0 v( |" |  is used so there should be no surprises. This test can be used for instance. o8 E2 a8 V) Z! `" Z2 r6 j. A
  to direct HTTP traffic to a given port and HTTPS traffic to another one: ^% s- B1 I) |! Y8 q  P" Z# D
  using TCP request content inspection rules.6 u- [* `: L- V  [

4 Q0 x; U% e7 o* treq_rdp_cookie       <string>
: h# f, w+ r5 b0 l; treq_rdp_cookie(name) <string>/ w7 k, W, i' d+ q6 c: r  k2 h
  Returns true when data in the request buffer look like the RDP protocol, and# z6 V' D0 M7 h
  a cookie is present and equal to <string>. By default, any cookie name is
0 p: f% b. W1 j5 W0 `7 W  checked, but a specific cookie name can be specified in parenthesis. The1 u# l/ D6 i9 {
  parser only checks for the first cookie, as illustrated in the RDP protocol
: ^. \  L) T4 b9 e' l5 j2 ?( n+ V  specification. The cookie name is case insensitive. This ACL can be useful
+ w8 A# _# e1 o  with the "MSTS" cookie, as it can contain the user name of the client1 A7 g1 O$ B* u1 Z) B& r0 e" ^
  connecting to the server if properly configured on the client. This can be
* f& W" T7 E5 w- x  used to restrict access to certain servers to certain users.
- H7 }8 b; G  J) Z9 `2 K: f6 k: H7 H* R) Q* H
req_rdp_cookie_cnt       <integer>% C) H+ i' E' C+ E
req_rdp_cookie_cnt(name) <integer>& Q2 H+ a6 I% \- H; Q/ |
  Returns true when the data in the request buffer look like the RDP protocol# p9 Q9 W1 I# s
  and the number of RDP cookies matches the specified range (typically zero or# x; U; Z8 I4 \6 A0 c
  one). Optionally a specific cookie name can be checked. This is a simple way
0 X# [. x% g8 i* F  of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH; K9 [; S' x9 _9 Y8 G* \
  cookies.+ H! t' r* s# Z+ `  k( x, C+ s
7 o( o1 m) o* r4 k* q7 `
req_ssl_ver <decimal>  o+ h" Q$ Z( g7 q6 F
  Returns true when data in the request buffer look like SSL, with a protocol
1 @3 d" X/ Q( {1 z: g1 j8 T  version matching the specified range. Both SSLv2 hello messages and SSLv3
- s4 N+ f5 }/ {! y  messages are supported. The test tries to be strict enough to avoid being
; b! z  b" ^) h: E( D& \  easily fooled. In particular, it waits for as many bytes as announced in the
2 P1 y. r( D3 _: r- e1 M$ {  message header if this header looks valid (bound to the buffer size). Note
. o1 [) ~, F8 c# A$ U8 ]4 t  that TLSv1 is announced as SSL version 3.1. This test was designed to be used7 k1 j! L7 X: g# B) o5 ~
  with TCP request content inspection.
3 z* Y3 q( E+ C5 V6 Z' |$ _2 ]  O( E
wait_end
. v; \- V: ~4 e3 I  Waits for the end of the analysis period to return true. This may be used in
8 a" o6 I9 A7 Q& l: v+ B: K  conjunction with content analysis to avoid returning a wrong verdict early.! e' e7 Z: Y( r) a( t
  It may also be used to delay some actions, such as a delayed reject for some# X& q; S! C7 U6 a' M# z
  special addresses. Since it either stops the rules evaluation or immediately+ D$ j9 S: c  o. Z7 u
  returns true, it is recommended to use this acl as the last one in a rule.( e* d8 j7 F$ v3 C) U* G4 L# D
  Please note that the default ACL "WAIT_END" is always usable without prior+ H$ X3 w$ W. Q) H( L& K
  declaration. This test was designed to be used with TCP request content) X% y& r/ @$ v2 F, X
  inspection.
2 v# {) g1 Z# D& t5 s8 D6 |! G( Y3 l6 k' i
  Examples :% g. y0 B8 _2 A! u0 n
     # delay every incoming request by 2 seconds
: L* U! T4 {* ~' {. q6 S: |     tcp-request inspect-delay 2s
/ e( Z) o9 k$ F* T6 J* ]- t" ?     tcp-request content accept if WAIT_END9 t4 g% u9 v- W5 @4 q3 X* o8 E; j
$ i! |: g' B; q; ~1 ^' w
     # don't immediately tell bad guys they are rejected
: y" _* o9 g2 v4 b& p     tcp-request inspect-delay 10s# W0 o& S! U7 B$ r& T
     acl goodguys src 10.0.0.0/24  [+ H, q9 Y, D8 J# o3 H3 F6 L+ V
     acl badguys  src 10.0.1.0/24
3 Y& L7 _- z2 a/ ]% l+ s     tcp-request content accept if goodguys5 a& Q/ D# S( ?. r1 v
     tcp-request content reject if badguys WAIT_END: m' v$ ?- t% V  n, z  d
     tcp-request content reject; _9 v' }- i' E* A: l1 {. W3 W: v

) Q, A, K3 ~7 K( y; U
( z* q+ m0 |3 |4 _/ t7.5.3. Matching at Layer 7! Z2 ~' D8 L1 F* u
--------------------------
/ u( W5 w. f& b$ t; L% F! ?% Y4 l0 o# @* T; A1 }) @2 H
A third set of criteria applies to information which can be found at the+ {- k: B9 O* ]1 A' u& w; ]$ R
application layer (layer 7). Those require that a full HTTP request has been! K% b2 _; z1 b( D; d! z; d& w
read, and are only evaluated then. They may require slightly more CPU resources1 k& R6 Z) w4 O1 C2 B5 W* Q' v
than the layer 4 ones, but not much since the request and response are indexed.5 J9 Q% ^) R* A. z3 s

" |# P& V5 {  n  q( `. z) Ahdr <string>/ h5 Z: d% b" X+ v. j9 g8 w& M
hdr(header) <string>
) j) U& k% p& |* S' ~- s  Note: all the "hdr*" matching criteria either apply to all headers, or to a
* U. U, d% G9 q3 r2 k  particular header whose name is passed between parenthesis and without any" ~' c1 C0 ~1 [# S
  space. The header name is not case-sensitive. The header matching complies
  J  p1 O7 n9 l" E! ?0 {" ?  with RFC2616, and treats as separate headers all values delimited by commas., Z) N' C! _: Q% S+ x8 v# W7 v
  Use the shdr() variant for response headers sent by the server.
' f+ ^2 }, F( X7 o; U3 L- W; e. k% S! k* ]
  The "hdr" criteria returns true if any of the headers matching the criteria
# S& M! i* R6 p3 ~) a# U3 i  match any of the strings. This can be used to check exact for values. For
' h2 V0 k) P6 f6 Q2 F: v# K  instance, checking that "connection: close" is set :  u- s2 s( o* l$ @" C& f
7 h4 W  K: B( _( C5 M, A4 @
     hdr(Connection) -i close2 y" ]& ?/ U/ b- H  r, |
- s; X& y3 |+ ~
hdr_beg <string>
+ U0 ^& m: r* S9 v% Phdr_beg(header) <string>
( R7 m/ k! a- d6 Z4 Q5 x! S9 Z  Returns true when one of the headers begins with one of the strings. See
/ B/ }! r9 J( P( a  "hdr" for more information on header matching. Use the shdr_beg() variant for
7 l$ w# P: D" ]7 |4 ^. b7 b  y+ c  response headers sent by the server.
9 s5 ]1 P/ W( E$ [
* c" A% |* O: G# y5 }/ c, c  k+ ghdr_cnt <integer>3 y; e' ^9 }& [" m
hdr_cnt(header) <integer>' u' F9 z( v& j3 j2 A' l8 i! ]
  Returns true when the number of occurrence of the specified header matches, c, \6 T  o$ X2 N. M, s/ K- q
  the values or ranges specified. It is important to remember that one header
& r- T+ |# C7 j# m7 e. g" V/ ?  line may count as several headers if it has several values. This is used to7 s( }+ d1 S, h# V  {8 B+ H
  detect presence, absence or abuse of a specific header, as well as to block/ R: L2 H) x: q; D$ p, L& _' R5 D
  request smuggling attacks by rejecting requests which contain more than one
5 N" b' m6 I9 l* H7 v* I0 L  of certain headers. See "hdr" for more information on header matching. Use3 D) M, _* O3 I9 O5 o
  the shdr_cnt() variant for response headers sent by the server.
8 C! @2 S+ x% K/ l' s; ]
0 T3 y' o; `/ L% @7 v5 t: khdr_dir <string>: b4 R6 D# n& C& p$ x
hdr_dir(header) <string>* L; s* x4 U) q  `2 w# p$ O
  Returns true when one of the headers contains one of the strings either
3 y1 Q6 S  ]( [' X  isolated or delimited by slashes. This is used to perform filename or. D  R$ F  ]) C. h/ a9 L
  directory name matching, and may be used with Referer. See "hdr" for more/ b" K  ^' G4 U' V
  information on header matching. Use the shdr_dir() variant for response0 |! J7 i( v( {% B  V
  headers sent by the server.
* L; N, a" o5 }4 j0 T6 G: n. J6 A; t  P/ N/ R' Q4 |2 e( e: l0 O
hdr_dom <string>
/ T0 w4 {; M$ |, uhdr_dom(header) <string>8 t$ C$ k, P. M7 A3 |: R' s5 m
  Returns true when one of the headers contains one of the strings either" s8 ~4 }" k+ k/ D5 x8 }
  isolated or delimited by dots. This is used to perform domain name matching,
3 o" \% C  C! t( }6 N. Y0 ~  and may be used with the Host header. See "hdr" for more information on* q% r1 W; N3 r; ]
  header matching. Use the shdr_dom() variant for response headers sent by the
/ }' @0 I9 k& T7 Z0 D+ C$ L2 ~  server.
& z3 X! p3 e) a, N9 ]. f* X& N0 k
hdr_end <string># U& z7 k( B. o
hdr_end(header) <string>
+ X8 T* f9 N4 i& B, u0 p; F5 U& x  Returns true when one of the headers ends with one of the strings. See "hdr"% n, D9 a2 A# z/ g: g
  for more information on header matching. Use the shdr_end() variant for
: `. i; X7 E3 A9 k' A: Q+ w  response headers sent by the server.
. B0 |3 z! Q3 R6 y+ G. N8 l! ^& g" W$ \
hdr_ip <ip_address>
3 Q* N# _, F* ~9 p* {7 w1 Ghdr_ip(header) <ip_address>
3 t6 H/ `* {8 G( Z# R  Returns true when one of the headers' values contains an IP address matching
+ W! ]. I6 L& w  <ip_address>. This is mainly used with headers such as X-Forwarded-For or9 a: o# Z% C7 A
  X-Client-IP. See "hdr" for more information on header matching. Use the
* A% {9 H0 m) O6 M7 J0 f1 s  shdr_ip() variant for response headers sent by the server.
; P3 O6 ]; Y/ i+ S5 J" e( T
8 i0 I4 q  p2 ^hdr_len <integer>
* d0 S& A: W) G9 w& Lhdr_len(<header>) <integer>, D  p3 l" R4 G8 U$ w- w0 z
  Returns true when at least one of the headers has a length which matches the/ w8 F' u9 D" U9 c
  values or ranges specified. This may be used to detect empty or too large
+ \6 v9 z0 E& ]) ?) V5 @  headers. See "hdr" for more information on header matching. Use the, @3 E+ ^/ k/ n
  shdr_len() variant for response headers sent by the server.
! F: f) s, p# f9 H( b5 Q, ~0 C( Q3 W! [6 Q; Q& l
hdr_reg <regex>
5 b7 R' u+ w( |" E+ B% b" `hdr_reg(header) <regex>' k+ ?# @. T. h9 d! M
  Returns true when one of the headers matches of the regular expressions. It: x3 ~; P7 T) b, `2 ?
  can be used at any time, but it is important to remember that regex matching
' U+ q3 i1 r/ ]3 [# e  is slower than other methods. See also other "hdr_" criteria, as well as, }9 g1 [' R  T5 e
  "hdr" for more information on header matching. Use the shdr_reg() variant for
. O0 T  q8 O4 ^; J  response headers sent by the server.
0 K" d* c4 y4 [) ]% s2 K) D* S( @* {' k# L7 n) J& w3 i
hdr_sub <string>
. a5 C8 H# _/ H, v0 ~0 khdr_sub(header) <string>4 a4 U1 ^* W. n+ k7 l4 f" U
  Returns true when one of the headers contains one of the strings. See "hdr"
9 U% F$ H4 x( q$ w$ [. |  for more information on header matching. Use the shdr_sub() variant for
! _, u. [7 d9 ^1 h$ ^- ]! @$ d  response headers sent by the server.
; M% g! L: T+ Z8 U* c! W8 z% _. U) h) {4 `# N( w3 Q) x
hdr_val <integer>% P+ S( z' ?* j
hdr_val(header) <integer>
/ V: {7 L' H6 w# f2 E6 I  Returns true when one of the headers starts with a number which matches the" E3 ~6 a" F% e
  values or ranges specified. This may be used to limit content-length to
$ ^+ i6 e' E) S3 }, M  acceptable values for example. See "hdr" for more information on header3 Z5 |+ W! k9 t$ {, k
  matching. Use the shdr_val() variant for response headers sent by the server.
$ F$ z" J9 l6 ]8 L8 R) i7 r7 r7 [! E" g. w
http_auth(userlist)
9 [# e; M9 f/ e2 Nhttp_auth_group(userlist) <group> [<group>]** q5 _" K+ B9 @! B, z/ ~
  Returns true when authentication data received from the client matches
. y& m8 W" E$ p/ ^* O  username & password stored on the userlist. It is also possible to6 c5 X6 k7 f( ~/ T5 E6 c0 n
  use http_auth_group to check if the user is assigned to at least one
! W. d/ `. E8 {4 U. f  of specified groups.7 S* g- B  q; x  @7 v' X
; ]! B+ B8 F9 z
  Currently only http basic auth is supported.3 W% Y* Y! D3 u! k8 D
! G+ R/ F6 h  u: V
http_first_req" f! S- t6 {. ^; m. H9 S
  Returns true when the request being processed is the first one of the
. T% J) D, ]0 {8 K  connection. This can be used to add or remove headers that may be missing6 Y, c0 c0 n" L1 ]" @4 H$ y; i# j
  from some requests when a request is not the first one, or even to perform  f8 R' y7 @* H& m" [/ P& W* \/ b' H
  some specific ACL checks only on the first request.
3 l6 D2 L- K- j2 T; B3 ^* L4 d9 T/ g0 O. q6 R7 g) Q  c
method <string>  t& D% S1 _. T0 v" F7 e
  Applies to the method in the HTTP request, eg: "GET". Some predefined ACL5 ~0 M' O+ k" M" @% M$ f
  already check for most common methods.
6 k! E/ a, o  a. }
& t$ p$ \! S$ `1 M- I$ a+ apath <string>3 {: ?/ V" T. a9 e  R1 h5 d
  Returns true when the path part of the request, which starts at the first0 x) q  S4 F0 v9 v
  slash and ends before the question mark, equals one of the strings. It may be$ Y4 f3 Q& J  u3 Y
  used to match known files, such as /favicon.ico.& c  M3 W' v0 A& t1 q$ t- I
6 k  R, r+ K' B( ^) \$ c  o  |
path_beg <string>
3 f: e5 E+ R/ S( z4 O' u  Returns true when the path begins with one of the strings. This can be used$ K  y. a1 A" }, ]# I& `. q
  to send certain directory names to alternative backends.. V# i! e# h# n) i/ x

1 p7 S1 c% C. mpath_dir <string>/ ~4 n+ u( j# d  |; u
  Returns true when one of the strings is found isolated or delimited with8 ]% S  Z, @7 j$ u! L$ c
  slashes in the path. This is used to perform filename or directory name; }$ v* X- s) `
  matching without the risk of wrong match due to colliding prefixes. See also
; R4 Y0 T' i% p$ S( J: c' H  "url_dir" and "path_sub".
: l6 j+ u6 v$ V
3 L# S$ c* L9 |* B4 O0 Dpath_dom <string>2 q0 ?( Z! x- W- u$ x
  Returns true when one of the strings is found isolated or delimited with dots
% {  P. x% f7 R& A# w  in the path. This may be used to perform domain name matching in proxy
) S/ M8 ~' K& y  requests. See also "path_sub" and "url_dom".
& v5 M4 L: _* c( a3 Z
" c4 o$ B0 ~5 H2 hpath_end <string>
5 _8 ]6 d9 W# G- n, f$ t  Returns true when the path ends with one of the strings. This may be used to# E. H3 Z- C+ ~& E# h
  control file name extension.' }0 C9 @6 E/ Q
! Y# L! m1 a: d* y7 H/ d* q" T5 r
path_len <integer>
9 ?5 l1 u) K* |5 K2 R+ U  Returns true when the path length matches the values or ranges specified.# b* J; t0 R2 M0 E3 d; {
  This may be used to detect abusive requests for instance.
8 L, M% z7 y0 {! T8 d% h' D# l
0 G9 ^  [" }% ]' t( H* W: L8 Opath_reg <regex>  z- V5 F, {, Q  q# [4 z' z
  Returns true when the path matches one of the regular expressions. It can be/ s+ f& \" ]; x' m1 V
  used any time, but it is important to remember that regex matching is slower
" @7 O- d* ^; [9 D2 Y  than other methods. See also "url_reg" and all "path_" criteria.+ U# N/ O5 H7 E9 m1 i' F( l' c

0 k& e( j  L3 n  t4 Y  e- |1 Rpath_sub <string>; p" A; C8 H- L$ u  j, ^% N
  Returns true when the path contains one of the strings. It can be used to
" {+ V; t& g  T- \% r  detect particular patterns in paths, such as "../" for example. See also
- x( P( C: S/ @* i' z9 U5 q& V+ L* ^  "path_dir".3 L# @" W" z- W

" R: K8 N1 f% B  X. Zreq_ver <string>
5 I7 |/ T1 x# j' w9 s5 W0 N% N  Applies to the version string in the HTTP request, eg: "1.0". Some predefined5 K6 b8 \4 ^- A
  ACL already check for versions 1.0 and 1.1.
, @. y' n7 R# {; y3 w. h% a% t6 T9 Z  R9 G) c4 ~
status <integer>
) I) k, g# U% a2 l1 v* b  Applies to the HTTP status code in the HTTP response, eg: "302". It can be" T* S2 B  Y5 a9 _
  used to act on responses depending on status ranges, for instance, remove
0 Z4 d6 ^4 r/ L' ^- A$ Y% A  any Location header if the response is not a 3xx.# \. ]1 u2 Z- ^5 N/ h$ j2 t
! G. g7 ]4 k9 a2 P: t1 q/ P
url <string>, k% V8 f  \" o7 Y+ ^
  Applies to the whole URL passed in the request. The only real use is to match
9 [9 ]: @/ t( y  "*", for which there already is a predefined ACL.$ j% N5 J9 \: T/ @6 w
) ~( R0 C8 |3 Y
url_beg <string>
! ?: c5 l8 `: R' |" G/ z2 W) t; q  Returns true when the URL begins with one of the strings. This can be used to) ]' S7 l/ O. P8 p. T
  check whether a URL begins with a slash or with a protocol scheme.
* y2 E* u' D* g( k+ m+ w( i
. }3 s& z7 J" b3 c: vurl_dir <string>! X" g! N0 c, Q' c- w4 m
  Returns true when one of the strings is found isolated or delimited with
/ h6 E$ E4 p8 ]9 A1 r  slashes in the URL. This is used to perform filename or directory name) F3 L- I+ B# D. k. s
  matching without the risk of wrong match due to colliding prefixes. See also
5 v! z# \4 h- Q. C0 z, D* U  "path_dir" and "url_sub".9 W9 {5 l! O" C# x6 w
$ `1 o% S- C: m5 j4 x4 S
url_dom <string>
7 c2 v9 J: g- Z3 [1 p1 D  Returns true when one of the strings is found isolated or delimited with dots& e9 r9 w( p2 E$ O
  in the URL. This is used to perform domain name matching without the risk of% e4 L$ K  a" I! R) e
  wrong match due to colliding prefixes. See also "url_sub".
# K5 y5 g2 Y+ |- g' n$ v
: [% l4 c: R% r( |url_end <string>
, i8 q; s2 s3 J8 b  Returns true when the URL ends with one of the strings. It has very limited
: f! Y" T+ t& e- V$ N  use. "path_end" should be used instead for filename matching.6 P) S# ~2 A4 v1 K, x/ y6 Q- O* @
1 k, |# x) K: g4 R% {5 F% Q* S  f
url_ip <ip_address>
0 }; y4 `/ f$ ~6 b/ s% L  Applies to the IP address specified in the absolute URI in an HTTP request.; k. l0 Z7 z" i' @' n9 L) {2 Y
  It can be used to prevent access to certain resources such as local network.
, @  G% a6 f; T* s& _% H  It is useful with option "http_proxy".0 g% i, J6 F# o2 D  y% h! k! E

: J7 \, E, X! K3 g/ n" K& furl_len <integer>
4 {8 h) O/ j$ ^- u8 Z$ [( }8 \  Returns true when the url length matches the values or ranges specified. This
6 O9 J1 h; W+ p% i0 l  may be used to detect abusive requests for instance.
5 D6 k5 Z5 a+ \. R/ `* ~7 Q, ~0 @% j$ Z5 [! Q  e. H, ?% A; ~
url_port <integer>0 [& F* c5 R3 j) r* |% O
  Applies to the port specified in the absolute URI in an HTTP request. It can
( p3 C, [# f% h9 Q. r) A  be used to prevent access to certain resources. It is useful with option3 @# a6 Y9 ^, b4 Y% D& g* v
  "http_proxy". Note that if the port is not specified in the request, port 804 |& H+ e: C5 \& x
  is assumed.
+ f: t8 J; `5 `$ Q/ J7 |$ ?, d! O  \7 b4 f% `5 G8 P
url_reg <regex>; x: A5 i! a+ s5 s0 k) m; B
  Returns true when the URL matches one of the regular expressions. It can be
& q; \9 l0 g+ E' j  used any time, but it is important to remember that regex matching is slower
; u# O+ x* Y- Y8 b& [  than other methods. See also "path_reg" and all "url_" criteria.
1 j2 f" e! y( m: a4 |( M  \# E* [/ a6 o) V  d; h1 Y
url_sub <string>! q% A. ?- ?2 M; N, n6 X7 E. B
  Returns true when the URL contains one of the strings. It can be used to. K) r! }# `0 N, s# I# j- h( P( k
  detect particular patterns in query strings for example. See also "path_sub".6 i0 r( H2 a% t  G( m: f8 A* b, H

/ Q! s' v3 z0 ]& N' O4 Z- g$ }+ {" U0 K- p! X9 {/ K5 ~
7.6. Pre-defined ACLs! G+ A; y7 e* ?$ {
---------------------( |' i: J+ c) F3 x

. M+ T' _! Y! {; S6 f% c& k: @+ y5 i+ }2 dSome predefined ACLs are hard-coded so that they do not have to be declared in
# S5 B, ~' X2 Q+ ]3 {3 ~& r$ Devery frontend which needs them. They all have their names in upper case in8 k! a* C4 N! D' \+ G  @+ {. {" U
order to avoid confusion. Their equivalence is provided below.. d4 G0 V+ o' z2 N; D0 M7 E
  V% w) {3 q( a
ACL name          Equivalent to                Usage
+ g. H$ [: P$ Q; u! T---------------+-----------------------------+---------------------------------  [" k- v* x5 Z8 X) J
FALSE            always_false                  never match
4 O9 d* s9 f% \1 `* v0 P3 V" S, A$ AHTTP             req_proto_http                match if protocol is valid HTTP" U8 W2 j) {* a3 b4 `/ I5 w; C
HTTP_1.0         req_ver 1.0                   match HTTP version 1.0, v' w7 U$ O' y$ ~% L8 t0 U
HTTP_1.1         req_ver 1.1                   match HTTP version 1.1& y6 a: [# a; y: J
HTTP_CONTENT     hdr_val(content-length) gt 0  match an existing content-length
3 r( P# g# q9 pHTTP_URL_ABS     url_reg ^[^/:]*://            match absolute URL with scheme/ L7 b0 q, \$ E& U
HTTP_URL_SLASH   url_beg /                     match URL beginning with "/"6 k8 j8 x5 c7 |
HTTP_URL_STAR    url     *                     match URL equal to "*"
8 Y; J& C5 ^1 P% L" W# PLOCALHOST        src 127.0.0.1/8               match connection from local host; j/ U+ V3 {$ U9 v: S8 M4 d
METH_CONNECT     method  CONNECT               match HTTP CONNECT method& H& U8 D" }  Z% ]
METH_GET         method  GET HEAD              match HTTP GET or HEAD method
$ w  d( A: r6 l) CMETH_HEAD        method  HEAD                  match HTTP HEAD method1 f' f4 X7 ~/ P( c( T& }
METH_OPTIONS     method  OPTIONS               match HTTP OPTIONS method
8 t9 w, ^, L) i! ?9 C& ~METH_POST        method  POST                  match HTTP POST method
# d/ d5 s# l0 L$ u+ x( A! p2 h8 xMETH_TRACE       method  TRACE                 match HTTP TRACE method+ ~% D6 L/ T2 V4 k
RDP_COOKIE       req_rdp_cookie_cnt gt 0       match presence of an RDP cookie* H7 A( A& l- t
REQ_CONTENT      req_len gt 0                  match data in the request buffer$ t5 E/ ]' d* u6 p# F9 X) |+ G; q
TRUE             always_true                   always match
, q/ w/ y6 z8 Q; HWAIT_END         wait_end                      wait for end of content analysis
' o) [6 g! r& a. ~% g& L---------------+-----------------------------+---------------------------------
3 S5 d" ]2 U; y. a  q# ]4 B; l- i& b5 M9 Y
) K. R& T& ^8 L3 h; s, E/ U0 S4 S
7.7. Using ACLs to form conditions6 W" `5 g% w1 B
----------------------------------
2 G# X8 G/ {+ Q( c
& ]: |1 |) N8 O; ], A' ]1 h' r6 ?) ]Some actions are only performed upon a valid condition. A condition is a4 H8 c  o! P- l) X1 U& t3 H3 E) r
combination of ACLs with operators. 3 operators are supported :
( J: n! a& Z8 e% v" Z7 e9 C5 k% X) ?7 `& `2 g- d
  - AND (implicit); J5 Y7 |' |5 e) D5 W. |6 T6 l* P
  - OR  (explicit with the "or" keyword or the "||" operator)# _6 ]! L7 \7 \0 K0 ^2 ?
  - Negation with the exclamation mark ("!")
0 {7 [5 O5 d" g' _% B, U4 g
$ r1 I2 L4 o, I0 |" ^, U: x9 fA condition is formed as a disjunctive form:) u0 e8 F; ^, @8 X) m! I& Z
9 g& C0 e% _; j3 h5 s1 r
   [!]acl1 [!]acl2 ... [!]acln  { or [!]acl1 [!]acl2 ... [!]acln } ...
# E8 g# l: L5 l9 W3 R" D3 V
% ~# z" Q7 J. `Such conditions are generally used after an "if" or "unless" statement,0 ^0 W  U% U5 F) i# I" @: V2 @
indicating when the condition will trigger the action.  k( y* ~5 c( v8 C
( ^, g. j, Q" }; h0 Z
For instance, to block HTTP requests to the "*" URL with methods other than
+ n" P6 ]- U; ^* X2 A"OPTIONS", as well as POST requests without content-length, and GET or HEAD
* Q! q/ k  |' c/ y. P7 drequests with a content-length greater than 0, and finally every request which
; O1 X) n" d5 T8 Vis not either GET/HEAD/POST/OPTIONS !/ Y; Y3 [9 L, _; }5 J5 |4 u% Y

1 n: n$ n, Z: S( Z9 B2 D" S   acl missing_cl hdr_cnt(Content-length) eq 0
( r. B: r& ^0 ^5 e1 y   block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl2 C$ Z5 [6 e% h6 W' Z
   block if METH_GET HTTP_CONTENT
1 J" @- y4 S  h' W- E   block unless METH_GET or METH_POST or METH_OPTIONS
; d! o* W1 v5 C2 i+ a: H) c! g! @. V. K" j
To select a different backend for requests to static contents on the "www" site
" V& y4 }8 t% m8 d. E3 W6 }and to every request on the "img", "video", "download" and "ftp" hosts :8 P2 x  D/ U: P: V" |! x$ X; h. `0 U- S
4 K! _* G3 {3 b* `4 M) N% {+ R
   acl url_static  path_beg         /static /images /img /css
7 G+ q7 D6 h# n1 J: |& i% A2 ~   acl url_static  path_end         .gif .png .jpg .css .js6 ~. j: _' U/ g# {+ m& \
   acl host_www    hdr_beg(host) -i www
% Y9 U2 _! ^5 k. B' p; v6 _6 a   acl host_static hdr_beg(host) -i img. video. download. ftp.
" N& j9 d- `3 r% ?
; l/ h- j( z$ x# u' ^( H   # now use backend "static" for all static-only hosts, and for static urls
: K- A" U5 g, d& `5 J: G   # of host "www". Use backend "www" for the rest.
) \4 a5 ?! s9 ?1 [4 X% ?! c+ X7 X   use_backend static if host_static or host_www url_static
. y$ R2 z6 V3 w2 I; X   use_backend www    if host_www$ I# y+ \: M; Q; H8 w1 e6 J  [

, ?7 D; h+ z0 uIt is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
) g/ r% W3 W  p) ~9 Hexpressions that are built on the fly without needing to be declared. They must
  F5 F+ i) k8 pbe enclosed between braces, with a space before and after each brace (because
# L( q5 H( U9 e4 N0 D9 T/ Gthe braces must be seen as independant words). Example :4 ]/ a5 O$ b& N( r7 g4 x
  ]1 b7 k  i8 v, L( s
   The following rule :% X) b6 l  ^  U3 A  ?4 \* K

" D( X- G0 P( k' |- B7 u       acl missing_cl hdr_cnt(Content-length) eq 0
2 F* p6 `' H. o! |8 D       block if METH_POST missing_cl
& j' L/ k& w2 d, c- d! [4 }
" c; A2 f! T. c4 o4 k   Can also be written that way :
- i0 [6 e+ S" ^( E/ p; Y: F& B
8 e8 T3 L" w* r; Q; q; q* F9 J3 d5 S       block if METH_POST { hdr_cnt(Content-length) eq 0 }$ |1 O6 v( Y1 J$ Y

+ |3 t# L" U+ J7 q( B6 dIt is generally not recommended to use this construct because it's a lot easier
! y4 L5 J, L/ o- a3 |1 @to leave errors in the configuration when written that way. However, for very
8 P+ p, m9 B4 Y; u4 A1 f, Msimple rules matching only one source IP address for instance, it can make more
' L( `1 B& a" o+ q1 @1 hsense to use them than to declare ACLs with random names. Another example of
( B- s/ b9 X/ g( c* \4 c7 k0 y# ogood use is the following :6 a! k6 L& z5 p& E3 ]  W  D
" ]* ]4 F7 D; Z, Q: A
   With named ACLs :: P7 b& g; |& ^9 N8 e9 p6 P& j
( l8 c4 w  B' v2 U- p$ ]
        acl site_dead nbsrv(dynamic) lt 24 o) o, Q; W; K4 i$ ~
        acl site_dead nbsrv(static)  lt 2
2 O6 f/ D$ Z# K* ?+ ^- B        monitor fail  if site_dead
: I0 t8 u5 |, P( t5 w
  v6 F5 N, X- S; {5 A6 i   With anonymous ACLs :: y' r. V- r, A# ^0 Q2 B  q

' ]. _1 x, O+ E+ O: u  ?, p0 ^        monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }8 A, s: }$ r3 W2 a
. K  B% R- B9 A" l
See section 4.2 for detailed help on the "block" and "use_backend" keywords.- F+ ^& y0 F) i  P+ _8 Q7 B- u

# Z3 N5 S, f: Z5 Z' c7 [
9 T( {3 [+ j/ ?+ f3 q7.8. Pattern extraction
8 n9 V* n4 N/ x-----------------------2 X/ ]1 V: ~2 w; e

# V  M* g) q  z% U7 K; dThe stickiness features relies on pattern extraction in the request and
) g, L+ ]* ?+ V! k2 Oresponse. Sometimes the data needs to be converted first before being stored,3 @9 o: X4 x  q% C6 x0 j9 k! _
for instance converted from ASCII to IP or upper case to lower case.
! A6 ?( k" N, I) N! x
6 [9 e4 ?2 W2 N; d( {All these operations of data extraction and conversion are defined as
/ ^$ U0 m5 j+ y. R4 ?* f"pattern extraction rules". A pattern rule always has the same format. It
0 |5 A/ P4 V" g( h/ i, D- Ibegins with a single pattern fetch word, potentially followed by a list of
8 }& t+ l: S' F6 ?, Harguments within parenthesis then an optional list of transformations. As1 [7 u# y" K" @$ e
much as possible, the pattern fetch functions use the same name as their
/ Q1 W" ]" Y0 ~. F' cequivalent used in ACLs.
0 B( z: A8 [* z" Z/ |0 I) N( _6 H5 U7 Q4 v) m( ^% _  T1 ?' [% o
The list of currently supported pattern fetch functions is the following :' W8 T( Q( I" L

0 m2 l- I7 I6 U5 ^! o1 Y  src          This is the source IPv4 address of the client of the session.
0 ^# g7 v: E, d8 K( F               It is of type IP and only works with such tables.* u* U2 D/ b* c3 q' u

4 d/ L8 b! l. a+ x  dst          This is the destination IPv4 address of the session on the) Z5 K! ]& q4 r0 l8 }5 H7 y! g  h
               client side, which is the address the client connected to., @3 o9 M% q& t) ?7 _
               It can be useful when running in transparent mode. It is of. j* i: D3 R( ]) ?2 ]; C/ G
               type IP and only works with such tables.3 Q6 h7 Q/ o  j0 V8 ^. `3 |$ u4 W4 l

$ {% ^6 j. w* R  P/ }5 O  dst_port     This is the destination TCP port of the session on the client, s) _2 X/ j+ ^' t/ c, J
               side, which is the port the client connected to. This might be; a" Q( W7 E$ ^/ U$ }( n; ]) d
               used when running in transparent mode or when assigning dynamic9 A& A- P, X5 `/ P
               ports to some clients for a whole application session. It is of2 `" z/ M- M6 D/ j! l" n; l
               type integer and only works with such tables.9 t4 h# X* H4 v
# d* ?3 k3 M0 W+ v
  hdr(name)    This extracts the last occurrence of header <name> in an HTTP
5 l9 E  \, m/ L: f3 w0 q: _               request and converts it to an IP address. This IP address is$ j+ ]7 N7 E/ g, s7 Y& ^
               then used to match the table. A typical use is with the, M7 }) o3 T; V: M
               x-forwarded-for header.5 V1 U  q, p+ ~% u& x# D

" R$ T3 {4 I5 s2 a" Y: ~6 W4 C) Q7 ]- m5 {2 @( `, K
The currently available list of transformations include :
) a8 P& a' e+ g; x
5 ~2 h. D, _5 i1 l1 N  lower        Convert a string pattern to lower case. This can only be placed7 g" r) n  g  T/ O  v. j
               after a string pattern fetch function or after a conversion+ p7 L3 b  @5 H3 t# V
               function returning a string type. The result is of type string.: `7 z) T, j  A* w2 w

) u: z# A8 a" x; N; h6 u  upper        Convert a string pattern to upper case. This can only be placed
& ]* I# m% p$ O/ B               after a string pattern fetch function or after a conversion
; v  b* B( q8 H, M8 u               function returning a string type. The result is of type string.2 G% `, d# r( R2 I) [" ?

) J1 n& q% ]0 j5 ^( h! t  ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups
% X4 t& q& T3 S2 M6 h; }9 \8 D               and storage. This can be used to make all hosts within a
% U3 c$ A0 Y: l( G! _0 f9 ~               certain mask to share the same table entries and as such use
6 C" u1 P7 [' S  ~" D               the same server. The mask can be passed in dotted form (eg:
, l7 k1 k  e, l0 f  h! M1 M               255.255.255.0) or in CIDR form (eg: 24).
4 `8 y1 x% ]: J8 o$ g4 d' o. s9 p- A/ G& l

2 G0 w0 n* @. R% I6 \8. Logging! D. Z: m: i+ j6 G7 T
----------
5 H, d0 P+ v( Q& b
& _& @# n& D; `. e) X+ O# B: D; pOne of HAProxy's strong points certainly lies is its precise logs. It probably
5 s3 l. k" x7 G7 J$ r) K7 L) jprovides the finest level of information available for such a product, which is
/ `8 b/ {+ k! s" g4 d8 l+ kvery important for troubleshooting complex environments. Standard information
  R' f4 f6 U2 O) `4 F, r2 A! d/ Dprovided in logs include client ports, TCP/HTTP state timers, precise session6 _( l1 r) i$ a( v7 H  x3 c2 i
state at termination and precise termination cause, information about decisions% O3 I! f6 `3 W/ d: [
to direct traffic to a server, and of course the ability to capture arbitrary+ s8 ?& d7 M/ U2 O
headers.
  R. [3 s' c) a' V
9 W$ {' V8 F/ p* QIn order to improve administrators reactivity, it offers a great transparency* m1 q/ R% K! f- @. x3 R* q
about encountered problems, both internal and external, and it is possible to* d' E1 B6 Y- h* l/ P) S
send logs to different sources at the same time with different level filters :
, |7 a1 d6 {; E% c, [, A5 D3 g5 r8 U* v
  - global process-level logs (system errors, start/stop, etc..)6 l, I( W" I" A0 x5 T
  - per-instance system and internal errors (lack of resource, bugs, ...)' r4 E* t# Y# z; I  m
  - per-instance external troubles (servers up/down, max connections)* P# i2 m. {9 U9 H+ N, ^1 v
  - per-instance activity (client connections), either at the establishment or( |0 @* \4 R) U2 e1 s4 K, j6 [
    at the termination.: z6 k4 E7 T4 L: |
8 @- X$ F8 N% k3 c9 b& w! q
The ability to distribute different levels of logs to different log servers
8 \% K* O- q: M/ g# ]* yallow several production teams to interact and to fix their problems as soon, ^4 c5 h, x6 }* p7 E: x
as possible. For example, the system team might monitor system-wide errors,! ~& m) l* N: M5 G% H
while the application team might be monitoring the up/down for their servers in1 p) \& b& i/ _/ w) j/ F
real time, and the security team might analyze the activity logs with one hour
0 J/ E: u5 ?: Z  j: |) Qdelay.- ^# S! S" e3 X3 ^

# `4 t7 ?6 a) Z# v; M* i
. D, h; A1 |5 z% M2 [. w/ s8.1. Log levels
2 h& G8 X/ d& T7 `. U1 b+ S3 }8 Z---------------" x" d+ d! W1 N4 n  x" R8 M7 s. W7 x

! ~2 ~5 G2 I5 G  TTCP and HTTP connections can be logged with information such as the date, time,
! \! o8 U8 q! l* l% S# gsource IP address, destination address, connection duration, response times,
9 h; b$ N' L+ ~# p$ L# d9 SHTTP request, HTTP return code, number of bytes transmitted, conditions
" {$ I3 s1 g$ S+ X$ c( ^1 Z- w' Ein which the session ended, and even exchanged cookies values. For example
- `% G7 [: I) l  |1 Wtrack a particular user's problems. All messages may be sent to up to two
9 }+ b$ ]% v4 u; ]+ J" a: |  rsyslog servers. Check the "log" keyword in section 4.2 for more information
, q0 w# }  h  Q( v( \/ a+ z& W. labout log facilities.
6 ^0 ]  i; [" ~& u0 x
: J: X6 q3 k$ s1 z! n1 P6 ?  n' n" h
8.2. Log formats5 {8 d0 G% Q. `! i  G
----------------9 R8 L% n1 e5 }

0 a7 x3 `2 P* O( g& PHAProxy supports 4 log formats. Several fields are common between these formats
! M) j& y  r! d$ i+ Mand will be detailed in the following sections. A few of them may vary
2 w6 {) i/ W+ n+ dslightly with the configuration, due to indicators specific to certain
# i' g  A$ W$ Q; R/ W  yoptions. The supported formats are as follows :) H  E. n7 t' ^5 T6 h

! A6 x# w: M: a6 @/ D  - the default format, which is very basic and very rarely used. It only2 L. p/ L% T* J+ K9 A3 Q
    provides very basic information about the incoming connection at the moment/ [7 Z, ^% u/ }5 l2 X# r
    it is accepted : source IP:port, destination IP:port, and frontend-name.# x' }; N5 P, W# x  u, x+ `
    This mode will eventually disappear so it will not be described to great
" ?9 M8 r4 W1 h0 `4 P& @9 N- i    extents.
3 G, ?4 x" P+ w4 r# Y/ t2 a2 O
( @; ^; x1 Q  @$ _  - the TCP format, which is more advanced. This format is enabled when "option$ M: J. x' ?' K/ F& `( {
    tcplog" is set on the frontend. HAProxy will then usually wait for the
5 [  a' b. v" g" ^5 Y    connection to terminate before logging. This format provides much richer! Y  Z# Z, X. y' t; K% U
    information, such as timers, connection counts, queue size, etc... This
% a- X& c2 e5 j  l# Q% R3 l! u    format is recommended for pure TCP proxies.% x- N0 @( M: T1 P# X
( m" p/ l  y# ]8 u
  - the HTTP format, which is the most advanced for HTTP proxying. This format
7 s+ K: e- F4 o! C7 Y9 L    is enabled when "option httplog" is set on the frontend. It provides the  r- A* K$ D3 A- L* R! Q
    same information as the TCP format with some HTTP-specific fields such as; }9 v+ s/ R5 G* K' P+ z' G
    the request, the status code, and captures of headers and cookies. This
$ ~0 T  q& y8 }& j  F    format is recommended for HTTP proxies.
+ N4 p* U5 J6 b' ]5 E7 H6 Z, M: B; {( Y4 H& b# ~9 i6 q
  - the CLF HTTP format, which is equivalent to the HTTP format, but with the2 g; F; _" D  ^8 Q4 {$ n2 p) Q
    fields arranged in the same order as the CLF format. In this mode, all
! h. s  t# U- j! n7 R- n8 w$ F    timers, captures, flags, etc... appear one per field after the end of the
6 P7 F& q3 ^% ~: p) U' I& T7 n3 m% ]    common fields, in the same order they appear in the standard HTTP format." h0 \% R0 ?( t7 X; h9 G
- L4 W' Q8 y5 O
Next sections will go deeper into details for each of these formats. Format
2 y+ Y. v. q1 Y2 [/ lspecification will be performed on a "field" basis. Unless stated otherwise, a4 j3 i6 M; b$ h7 Y
field is a portion of text delimited by any number of spaces. Since syslog
" G0 x2 P6 K/ h. @servers are susceptible of inserting fields at the beginning of a line, it is6 V1 B0 H! V9 u. \- A* M
always assumed that the first field is the one containing the process name and
# V: I7 q3 l  Q  U0 |7 d! oidentifier., s5 S. r& J' D) a, U1 F& Y& q& C+ }
2 z# L) e$ i/ `: P$ _2 D" N# Z
Note : Since log lines may be quite long, the log examples in sections below
! V7 d& C% ?2 C2 l$ i7 y       might be broken into multiple lines. The example log lines will be
' v+ W7 R( I7 v0 N/ @5 ?5 D       prefixed with 3 closing angle brackets ('>>>') and each time a log is9 m$ l2 Q6 O' Z& z
       broken into multiple lines, each non-final line will end with a. O/ {3 @6 u; E" l- \
       backslash ('\') and the next line will start indented by two characters.7 d  o& i  A' R+ |; I
; y+ y8 W8 F! s
) C& H  |' o# X3 {' d  [8 y
8.2.1. Default log format
1 L% v/ o) o) j8 E: |) [-------------------------& r4 d+ W# v5 n; w4 M/ U2 E1 O

. f! o4 P5 ~% S$ [  TThis format is used when no specific option is set. The log is emitted as soon9 I4 @: i9 y. c& w7 G5 L" p( c
as the connection is accepted. One should note that this currently is the only+ l5 u5 {/ O$ V1 P: e1 ^
format which logs the request's destination IP and ports." P7 |- p, }4 S  h

& L  T' r) ~+ A/ H1 d4 p  Example :
! y$ F" _9 ]* Y5 g; b        listen www0 _7 Z0 F, d% ^( r! m- H' U
            mode http
8 [# c& Q; O; L/ r/ n! x            log global% [: o/ S' ?2 e' ^2 R
            server srv1 127.0.0.1:8000& O$ [( V) a5 y. y6 ?

) k1 y# `7 I" D% i# ]7 M$ l! A    >>> Feb  6 12:12:09 localhost \
& L7 V: B  i/ z  q0 j          haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \; F, F% }) I' k: C0 N4 K
          (www/HTTP)  |# L- C' v0 [# N  m
. L( v+ ^+ U; `( @
  Field   Format                                Extract from the example above: L: [# g% s5 c0 J% X) p! Y# r7 X+ O
      1   process_name '[' pid ']:'                            haproxy[14385]:
% }* P7 D, \& I( P      2   'Connect from'                                          Connect from
1 t7 m  C- [8 ~2 _      3   source_ip ':' source_port                             10.0.1.2:33312" s* m; L% U! M8 N! A) A1 d* Z
      4   'to'                                                              to
8 ^2 z$ B' _( ^- N( T      5   destination_ip ':' destination_port                   10.0.3.31:8012  j( H% {$ f  S8 v0 \, e
      6   '(' frontend_name '/' mode ')'                            (www/HTTP)7 k8 C2 v- v( Y$ r
+ G; {% ^1 L* F  W& ]$ ^- V) R( V
Detailed fields description :
0 U0 @) h! j9 ~( G  - "source_ip" is the IP address of the client which initiated the connection.
7 S: j" h+ H4 ^- K$ K: j  - "source_port" is the TCP port of the client which initiated the connection.8 o9 b# |5 C2 A# x5 E
  - "destination_ip" is the IP address the client connected to.' ?: `8 O& Q. ^2 U' P, G( |0 Q& P: T
  - "destination_port" is the TCP port the client connected to.
) [' ]+ L( h* W/ `  f  - "frontend_name" is the name of the frontend (or listener) which received
- \+ A& _7 `5 V5 F    and processed the connection.: q) O8 g  z5 f) Q
  - "mode is the mode the frontend is operating (TCP or HTTP).8 s5 \: x# X1 ]; I0 m- W% G: |3 p1 B

/ n  h* C! O, B) jIt is advised not to use this deprecated format for newer installations as it4 W: h$ k: u# E% C* W
will eventually disappear.
, Q- \( _7 e1 e9 K  o- L$ x, O7 T3 i0 m$ m, a- T% E2 E% O
, u% N  m+ e- f0 E4 D# ^! v
8.2.2. TCP log format5 q* r0 e, [$ `) @1 J
---------------------
  _( ?/ z$ d3 {7 S9 n% l* B+ V5 _5 s
The TCP format is used when "option tcplog" is specified in the frontend, and' V* O5 U# ]0 i! G# D+ |2 h# D
is the recommended format for pure TCP proxies. It provides a lot of precious
7 \' l5 b- t% x, qinformation for troubleshooting. Since this format includes timers and byte
3 z3 P& c/ D$ Q* X+ kcounts, the log is normally emitted at the end of the session. It can be# D& l% \: Y& }, s6 U( D
emitted earlier if "option logasap" is specified, which makes sense in most
. B4 D; l" g  ?5 Ienvironments with long sessions such as remote terminals. Sessions which match
0 W" p# @  ~3 Dthe "monitor" rules are never logged. It is also possible not to emit logs for8 J! k( z7 N$ D# U
sessions for which no data were exchanged between the client and the server, by! X4 J4 [, Q1 ~( z+ B
specifying "option dontlognull" in the frontend. Successful connections will
/ Q! h3 E6 M# x  {8 }not be logged if "option dontlog-normal" is specified in the frontend. A few
: f8 {( ]! D/ ?+ W3 p% k9 Bfields may slightly vary depending on some configuration options, those are, Q. K, g% R8 Q6 |4 p$ E& \
marked with a star ('*') after the field name below.. _" V: @$ D! {$ F6 _

; p/ @; V. Z( v0 {. r$ D  Example :6 F/ d. z  R. w( I; C% _  G7 ^; v# c( h
        frontend fnt
( C1 n1 ?! O3 ?( I$ Z+ x. C            mode tcp
/ A3 I; s2 T& ]5 G( _$ f( Y; t            option tcplog
1 H4 l+ A/ {& [3 o8 }5 |* W& o: i* _            log global$ r: W! e' e. Q- u  c5 f
            default_backend bck4 d- M8 B7 J, P( p2 R) I* i& o6 t
3 \2 |3 P+ N9 B# V
        backend bck
* V' X" d2 L2 V2 a2 Z) C            server srv1 127.0.0.1:8000, W" }, N  j( N% A' y0 R" j* Z
4 q* V5 M- s2 Y
    >>> Feb  6 12:12:56 localhost \9 v  H) t5 O( I1 p/ N# Z
          haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \8 n9 _9 t4 M9 _6 R/ q5 o  m0 N2 |
          bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/08 S" c& W# v/ O" B  K( A
! z3 H& T/ s5 @  x0 b$ u0 Y
  Field   Format                                Extract from the example above
( d7 w2 |7 k) ~+ }; \9 V5 U      1   process_name '[' pid ']:'                            haproxy[14387]:
1 l/ Y7 e* e5 d7 V      2   client_ip ':' client_port                             10.0.1.2:33313
* E0 \" ?6 _/ X; u& x  p      3   '[' accept_date ']'                       [06/Feb/2009:12:12:51.443]5 k) \! a) Z  G% U
      4   frontend_name                                                    fnt
' v9 n4 k$ X, V+ h3 j8 S      5   backend_name '/' server_name                                bck/srv1
1 e- y1 s1 y, ?2 J9 o      6   Tw '/' Tc '/' Tt*                                           0/0/5007
9 B2 H* [+ y/ x5 _* c3 u      7   bytes_read*                                                      212) L& k5 s( m# z  g
      8   termination_state                                                 --7 v' h) Z$ f& a. C" d
      9   actconn '/' feconn '/' beconn '/' srv_conn '/' retries*    0/0/0/0/3! ?7 L, [, h% I6 [' S/ A4 B: ]& z2 X
     10   srv_queue '/' backend_queue                                      0/0- @3 z' A6 T; n

5 f$ Q4 S6 r* d4 IDetailed fields description :- j* i7 T8 ?3 M2 \# k
  - "client_ip" is the IP address of the client which initiated the TCP7 d+ Z0 O) H  ?0 n/ F$ x8 R
    connection to haproxy.
6 f. [3 V) Q; j0 o$ b; P
8 u) [. I9 \  a0 o3 W  - "client_port" is the TCP port of the client which initiated the connection.
  }: Z. S& O% ~8 j. h3 {4 _' w+ C" I7 {+ y) c3 g5 N5 J! O
  - "accept_date" is the exact date when the connection was received by haproxy
' r0 b& z+ R: l! Z* j3 U    (which might be very slightly different from the date observed on the" {+ y7 {( {* s+ X1 g
    network if there was some queuing in the system's backlog). This is usually
; ?- {. \9 v3 j# t* R    the same date which may appear in any upstream firewall's log.. X4 y( v. o8 |1 X3 e' o( p
2 A% l. @$ J  r9 C- H
  - "frontend_name" is the name of the frontend (or listener) which received* A, f+ u- u, O' M+ o0 K
    and processed the connection.: F# [3 }4 L8 o' X. B
. f" {4 T4 M* X' l# ]
  - "backend_name" is the name of the backend (or listener) which was selected
% |, y$ Q, r$ h8 D" p7 v    to manage the connection to the server. This will be the same as the
" T! l+ B+ |" \8 B+ s4 M; F" ^7 w. S    frontend if no switching rule has been applied, which is common for TCP
2 i7 q1 I' Q& Y" l    applications.% G/ n: q. v3 N( j) Y0 b

3 F$ r0 ~4 k# U  - "server_name" is the name of the last server to which the connection was
6 G4 E) M6 t  X5 n; C% Z$ Z    sent, which might differ from the first one if there were connection errors
( n) A  E' W3 i( O! A* J2 R" f8 I    and a redispatch occurred. Note that this server belongs to the backend0 R6 @' E5 g$ z8 V
    which processed the request. If the connection was aborted before reaching; a6 w) g- d) x8 o/ I" H
    a server, "<NOSRV>" is indicated instead of a server name.$ j  h5 Z! J& b

6 i7 \; j6 k5 h' f  - "Tw" is the total time in milliseconds spent waiting in the various queues.& `5 ^3 v! ?; X" T! i, S9 }
    It can be "-1" if the connection was aborted before reaching the queue.
5 g  }- `4 C5 m" F    See "Timers" below for more details.; {7 B: O* V1 O' a7 O; F: `# }

; R2 G1 F5 D+ k6 e. {4 g; ]% H9 D8 V  - "Tc" is the total time in milliseconds spent waiting for the connection to4 V  s' ]! n# v
    establish to the final server, including retries. It can be "-1" if the
" n: F% s5 c/ N    connection was aborted before a connection could be established. See; K7 L' j. F% S  F( _# U, H
    "Timers" below for more details.& t. j( W1 W: g* y  z
# ?  y( @! W$ }3 `1 {
  - "Tt" is the total time in milliseconds elapsed between the accept and the
+ B+ r# v% g; @! F4 `3 j- P    last close. It covers all possible processings. There is one exception, if5 \. i3 f7 l* e0 U  K2 z
    "option logasap" was specified, then the time counting stops at the moment
. ^! {/ R4 t$ ^1 v6 h    the log is emitted. In this case, a '+' sign is prepended before the value,
4 T$ W7 ?7 o( L3 c; p: h4 Y    indicating that the final one will be larger. See "Timers" below for more5 A* E; u; W& N  z( ^
    details.7 ?4 [9 i9 d4 ~7 ?2 j& c  C$ U
/ C2 d: m) d9 r8 m
  - "bytes_read" is the total number of bytes transmitted from the server to
5 \3 \  V/ l" O    the client when the log is emitted. If "option logasap" is specified, the
1 n6 q% a& l+ S- }  {7 Z8 C    this value will be prefixed with a '+' sign indicating that the final one5 J& o- L: D) p' \+ \- \
    may be larger. Please note that this value is a 64-bit counter, so log. y( [" T, e, @. P4 \
    analysis tools must be able to handle it without overflowing.7 F; m* r/ s8 V  w5 q3 D6 k: l& G

/ F& b9 e$ \" ^; @1 m  - "termination_state" is the condition the session was in when the session
1 J$ w0 Z/ @; J2 L$ ?    ended. This indicates the session state, which side caused the end of
, o5 |) Z4 V8 T    session to happen, and for what reason (timeout, error, ...). The normal
0 U2 N1 {9 ?7 D% Y- \7 S1 r0 [) c    flags should be "--", indicating the session was closed by either end with
7 r; M4 S2 f% F) `3 l    no data remaining in buffers. See below "Session state at disconnection"" p+ t! `( z6 X4 {8 P" t: h( a2 T7 F
    for more details.
: b- H+ [& d8 H# d3 A. o; N+ O/ i) c1 O2 v) `7 N
  - "actconn" is the total number of concurrent connections on the process when
2 V9 K; m% ~! z, {% a6 S    the session was logged. It it useful to detect when some per-process system( P, Q9 ~' L8 [- Y
    limits have been reached. For instance, if actconn is close to 512 when
# d) q9 v: r) p9 `6 e4 Q    multiple connection errors occur, chances are high that the system limits
6 E0 ~# Z) @# v: n. g    the process to use a maximum of 1024 file descriptors and that all of them
, E4 C; V4 d* m4 X5 e    are used. See section 3 "Global parameters" to find how to tune the system." U7 O+ m# E* [
8 ~/ c9 [9 k+ N2 L) K
  - "feconn" is the total number of concurrent connections on the frontend when$ ]1 t1 V, j, {
    the session was logged. It is useful to estimate the amount of resource
) v7 K% n) }1 g1 e3 ?' B    required to sustain high loads, and to detect when the frontend's "maxconn"& S) x# [0 S& W
    has been reached. Most often when this value increases by huge jumps, it is7 i' K3 N3 k3 G1 O- E# A
    because there is congestion on the backend servers, but sometimes it can be
( @- ]* p' L2 W% B    caused by a denial of service attack.$ [; z9 s6 b% ]3 I

, j$ f8 J- P7 m& M  - "beconn" is the total number of concurrent connections handled by the
! Q7 Y2 \- ?. v5 a# v    backend when the session was logged. It includes the total number of
$ P( @7 S0 e3 E' a7 g9 T3 Z# e4 E    concurrent connections active on servers as well as the number of' U/ Q( A+ e# E2 _
    connections pending in queues. It is useful to estimate the amount of
& H  i# S' p# b, R. D( t3 c# W  b    additional servers needed to support high loads for a given application.
3 r  S- r8 i3 V    Most often when this value increases by huge jumps, it is because there is
6 v# p) U1 e' j    congestion on the backend servers, but sometimes it can be caused by a
" s0 p# A+ }" P7 M  X! p    denial of service attack.
# i/ w9 G; o8 _& X: I! ^* I: ?
8 `7 V  a$ ?7 `5 _0 v  - "srv_conn" is the total number of concurrent connections still active on' R$ Y* x2 k! J; P
    the server when the session was logged. It can never exceed the server's
+ S4 W- K8 h: k" ]    configured "maxconn" parameter. If this value is very often close or equal
# j4 U; @4 _. ?5 \    to the server's "maxconn", it means that traffic regulation is involved a
2 U6 r$ ~) ]7 V    lot, meaning that either the server's maxconn value is too low, or that2 J5 B8 c; [. D
    there aren't enough servers to process the load with an optimal response9 H9 o' i. N! C% {
    time. When only one of the server's "srv_conn" is high, it usually means
" W, G8 O# A# s. g# l# F    that this server has some trouble causing the connections to take longer to8 a& I/ Y$ D4 b1 V& W' h
    be processed than on other servers.
' `1 S* r! S9 A/ U2 j0 H* H1 W
  X5 q4 @% R' q( N- C  E- l# }( k  - "retries" is the number of connection retries experienced by this session
% a2 D+ x7 Q4 [# l( {% {    when trying to connect to the server. It must normally be zero, unless a4 W4 g# J. @6 |# M
    server is being stopped at the same moment the connection was attempted.+ _) }; W* ^4 ?( h) v
    Frequent retries generally indicate either a network problem between) i8 i: H) O/ ?3 D8 J
    haproxy and the server, or a misconfigured system backlog on the server
! y4 B& w3 v: F9 ]& v+ f' B    preventing new connections from being queued. This field may optionally be) ]# V$ K( x! m1 x* g
    prefixed with a '+' sign, indicating that the session has experienced a2 M2 n6 w( L% x: {* H. x7 c- d  D
    redispatch after the maximal retry count has been reached on the initial
2 N2 N# F3 R3 a) V4 ?2 E$ r    server. In this case, the server name appearing in the log is the one the, @7 u$ L+ g& t
    connection was redispatched to, and not the first one, though both may
* x7 S/ j9 N+ A1 U) f' K    sometimes be the same in case of hashing for instance. So as a general rule
6 ^& K% i* Z. K/ U    of thumb, when a '+' is present in front of the retry count, this count
8 z8 l2 _- ]+ s1 L$ j( v" X9 J    should not be attributed to the logged server.
$ f( N& ~+ E4 o. I
/ ?* k- q/ N. T6 ?! R8 P! D& l# }  - "srv_queue" is the total number of requests which were processed before
  ]2 r8 e1 s+ s    this one in the server queue. It is zero when the request has not gone
8 Q2 i3 l. {8 x+ A5 h9 e  R    through the server queue. It makes it possible to estimate the approximate1 p5 P) O- Y% `! Q: Z
    server's response time by dividing the time spent in queue by the number of. B- o; c) v6 ?1 L8 `
    requests in the queue. It is worth noting that if a session experiences a, X2 j3 o7 |5 A3 q1 N
    redispatch and passes through two server queues, their positions will be6 ^% s% a' ?# r3 s: s& t: B
    cumulated. A request should not pass through both the server queue and the
- N# J( P/ x! E) q5 K6 o: D" x    backend queue unless a redispatch occurs.  A* }% r3 ^4 R) Y& h& \

3 ?( y0 Y( h: U: M0 w1 o  - "backend_queue" is the total number of requests which were processed before  F/ k& H- S, u/ W5 o& e9 o1 K2 U3 Q
    this one in the backend's global queue. It is zero when the request has not" z3 @' z' o$ `) o3 C6 z
    gone through the global queue. It makes it possible to estimate the average  T5 Q! k( j3 q" @# a' j
    queue length, which easily translates into a number of missing servers when
0 g: z0 K9 k$ Z4 v( [    divided by a server's "maxconn" parameter. It is worth noting that if a! }& R5 c; n! \
    session experiences a redispatch, it may pass twice in the backend's queue,! f  l2 C8 w1 F; `2 y9 [( i$ W6 m
    and then both positions will be cumulated. A request should not pass
( w0 A$ t8 V! T9 m    through both the server queue and the backend queue unless a redispatch9 i! J+ c3 Z3 B! K. U
    occurs.7 N2 F1 E6 E* N" N/ h9 F" |7 L6 B

% T" n8 A3 V* ?8 O8 ?3 |1 F
) r: j  O3 y" O  i8.2.3. HTTP log format8 Y3 A, m0 `6 R2 f' ^* h; d) H2 b
----------------------+ m7 K8 \# r  n8 F( t1 s0 G

; |1 o5 ]- s# OThe HTTP format is the most complete and the best suited for HTTP proxies. It
! i: r6 O! b8 j9 ~8 q% ais enabled by when "option httplog" is specified in the frontend. It provides
2 ?7 T5 B( e* q; ]the same level of information as the TCP format with additional features which
$ E  K( z* C' ware specific to the HTTP protocol. Just like the TCP format, the log is usually
; y( Z8 M2 w  C4 t" Hemitted at the end of the session, unless "option logasap" is specified, which
. k2 ?) m+ F7 g1 _& r8 ]generally only makes sense for download sites. A session which matches the0 ]" y  @3 Y' l# _' y& l& ~. z; X
"monitor" rules will never logged. It is also possible not to log sessions for" m6 \4 N+ ^" e/ d' f
which no data were sent by the client by specifying "option dontlognull" in the
" x  H$ L; A! |  Gfrontend. Successful connections will not be logged if "option dontlog-normal"6 V: g0 `3 \( j, R5 N
is specified in the frontend.
/ m. Y, {2 H6 z  }4 ~
0 [, U- J) q2 v$ sMost fields are shared with the TCP log, some being different. A few fields may
" x/ r( O' M" w! h! k( F* C8 Cslightly vary depending on some configuration options. Those ones are marked
4 v9 y. M$ _/ O1 vwith a star ('*') after the field name below.* P7 R- n) j. h  r
: M- N* a4 C" M5 h& f9 l  x
  Example :
; _* R  T0 D! B7 j: x        frontend http-in4 X0 D: G7 d/ }$ a/ c& \1 `
            mode http% m. e! A3 W- B  I4 O
            option httplog" S: P' k* x8 G* J* y6 a4 X
            log global; L9 O: q, a- x- ]5 H" X
            default_backend bck
1 k' R6 [/ [, v( @4 q3 i+ m. J' F( R: |
        backend static
0 i1 {2 {8 ?* W            server srv1 127.0.0.1:80007 n* r9 s2 s) [* Y6 ^  P6 o* i

& R1 I/ R9 h2 B; M7 {4 D0 y8 ^    >>> Feb  6 12:14:14 localhost \
4 g! V; A& N& s# e3 t          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \6 _% ?2 |, f: V3 }, s  P  i. ~
          static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \% X& Y/ }" s" \7 ]8 d( c
          {} "GET /index.html HTTP/1.1"6 ]( J9 q8 r5 P" X
0 A( @% R2 ]. S
  Field   Format                                Extract from the example above
/ g/ F2 i- l3 `; K/ p! y      1   process_name '[' pid ']:'                            haproxy[14389]:
1 \3 u8 o, z/ ?7 W      2   client_ip ':' client_port                             10.0.1.2:33317
6 x  |8 V, Q3 ]5 R. T      3   '[' accept_date ']'                       [06/Feb/2009:12:14:14.655]; b1 [% ~/ A2 ]4 [7 ~0 }$ g9 F3 q
      4   frontend_name                                                http-in
) V4 d7 K1 ^  i# j$ \& ^      5   backend_name '/' server_name                             static/srv18 P4 w7 t+ r3 w( A3 v6 T# @
      6   Tq '/' Tw '/' Tc '/' Tr '/' Tt*                       10/0/30/69/1094 Z/ p% |6 X* W; ^( V8 H* A
      7   status_code                                                      2008 S( y6 |! g5 G! _1 ~
      8   bytes_read*                                                     2750
  Y9 k4 y( F$ Z- ?* n0 l      9   captured_request_cookie                                            -$ v0 t- A9 f, {6 K& m
     10   captured_response_cookie                                           -
" j& r3 K( h3 r" D     11   termination_state                                               ----& N* A2 [$ U! S0 W3 A
     12   actconn '/' feconn '/' beconn '/' srv_conn '/' retries*    1/1/1/1/0
3 B/ l) [4 w% b     13   srv_queue '/' backend_queue                                      0/0, q6 P- Y9 `" N
     14   '{' captured_request_headers* '}'                   {haproxy.1wt.eu}8 ?3 L: }0 J* u6 x/ H1 n
     15   '{' captured_response_headers* '}'                                {}
: I* i' l5 U) I5 o6 L: J& M     16   '"' http_request '"'                      "GET /index.html HTTP/1.1"6 X- I1 n  |4 i" @/ k

1 t: t; k0 }* `
! x" b- {) w# sDetailed fields description :
. V& M7 h4 ~# q1 m  - "client_ip" is the IP address of the client which initiated the TCP) s2 V4 ~' R' s% V% @5 _8 P: V
    connection to haproxy.
% I6 n7 L$ S3 ?( G2 s/ p6 ~- F% `! v2 x" l& w' M
  - "client_port" is the TCP port of the client which initiated the connection.9 a: w: S. H, G. V

: P3 Z+ _& W, {  - "accept_date" is the exact date when the TCP connection was received by1 f$ @8 ~# d/ Y) C+ q- H
    haproxy (which might be very slightly different from the date observed on
3 e" {# A2 L, P. ~, _! {$ U    the network if there was some queuing in the system's backlog). This is
( @0 ^- C# m4 V; ]4 m- P    usually the same date which may appear in any upstream firewall's log. This
+ O! I9 ?. v1 e! u# j( W+ E    does not depend on the fact that the client has sent the request or not.1 Y1 |( |! h# w0 w
$ q# e( s- K0 c  X5 {- w4 F
  - "frontend_name" is the name of the frontend (or listener) which received5 a; `, J" I4 W9 |6 y5 G1 y
    and processed the connection.
8 x. |6 c* t/ D4 F0 \
0 c* p$ Y, |8 n+ X  - "backend_name" is the name of the backend (or listener) which was selected
# ]. h3 p( r* [2 Z2 k    to manage the connection to the server. This will be the same as the& d9 B9 D! |- k9 z* T2 @
    frontend if no switching rule has been applied.
+ W, g$ K2 b0 N
( b- H$ ~2 _- F% Y; j2 v  - "server_name" is the name of the last server to which the connection was
- m: m) h: {+ J/ G    sent, which might differ from the first one if there were connection errors: a- P7 G, \0 [$ k: p) w0 `6 n
    and a redispatch occurred. Note that this server belongs to the backend
" Y+ o1 _) C/ w; e) _& k    which processed the request. If the request was aborted before reaching a/ b% O$ D# m. q
    server, "<NOSRV>" is indicated instead of a server name. If the request was0 {' |: C- m0 F0 F
    intercepted by the stats subsystem, "<STATS>" is indicated instead.  \  {2 X# F3 h

  V/ M% F0 r6 F  - "Tq" is the total time in milliseconds spent waiting for the client to send
4 g- o; }- }  f4 Y. d0 W    a full HTTP request, not counting data. It can be "-1" if the connection
+ ~+ r0 E4 Y% [% e! O3 f    was aborted before a complete request could be received. It should always
4 ]+ t7 ?! J& _+ o    be very small because a request generally fits in one single packet. Large
9 F( d0 T( H% M. \! G+ O    times here generally indicate network trouble between the client and
1 r* b7 D' X3 L4 p    haproxy. See "Timers" below for more details.
: o) s4 U1 w8 C% S' V, m# i* N
+ K4 i. ]2 j  I6 m9 N  - "Tw" is the total time in milliseconds spent waiting in the various queues.8 i4 a/ S$ L5 K1 F2 X+ X- X! n* I
    It can be "-1" if the connection was aborted before reaching the queue.
" Z) n! }9 O$ W) x/ R% X6 V! c    See "Timers" below for more details.- d: ~- c7 f" Y0 W
4 A; `$ `  _* G3 O) ]
  - "Tc" is the total time in milliseconds spent waiting for the connection to
7 N, U. _; R" n6 d2 ^    establish to the final server, including retries. It can be "-1" if the- T& ~5 |5 n# M- M" @
    request was aborted before a connection could be established. See "Timers"" H/ h8 Z8 t; y$ P
    below for more details.* v, n9 p2 C9 _( v) r, R
0 A: F9 G& E4 N* w
  - "Tr" is the total time in milliseconds spent waiting for the server to send
3 ~1 t% e$ u7 @- c6 Y    a full HTTP response, not counting data. It can be "-1" if the request was
1 B  r) I  e/ c' l2 m' K' f; F    aborted before a complete response could be received. It generally matches( U2 w/ Q) r# q7 K& G0 A8 F
    the server's processing time for the request, though it may be altered by- i! q0 V( W7 J
    the amount of data sent by the client to the server. Large times here on
; a4 U" C/ S4 w: S    "GET" requests generally indicate an overloaded server. See "Timers" below
& n2 c! N  g4 V    for more details.
' B9 i& z3 m2 v+ e- A. n% j# m* B. M: N) D7 Z
  - "Tt" is the total time in milliseconds elapsed between the accept and the1 [. ^6 D* _0 v5 _6 U" x8 Q: F+ _- {
    last close. It covers all possible processings. There is one exception, if# n% j" M) V0 R6 H* T' ^3 q$ k
    "option logasap" was specified, then the time counting stops at the moment9 k* \/ o& V6 B7 Q
    the log is emitted. In this case, a '+' sign is prepended before the value,% E8 L2 A3 w6 p* P
    indicating that the final one will be larger. See "Timers" below for more- B% P: K! A, i: m8 ]. X
    details.
4 U4 f7 c! z5 b/ J/ t5 L+ |& u
; R. }" K4 Q5 x- M  - "status_code" is the HTTP status code returned to the client. This status9 t: m5 E, P% }2 P
    is generally set by the server, but it might also be set by haproxy when' D) ?* s7 q8 R" [0 Y$ m
    the server cannot be reached or when its response is blocked by haproxy.0 C$ x7 N+ x" M$ ^- u, j3 S* g
- r+ Z. K' l! S5 i5 n; y
  - "bytes_read" is the total number of bytes transmitted to the client when
0 c; w; F, ^' ^: d    the log is emitted. This does include HTTP headers. If "option logasap" is1 y2 M  U# L4 B4 s
    specified, the this value will be prefixed with a '+' sign indicating that% g) v3 M  C" N8 r8 q
    the final one may be larger. Please note that this value is a 64-bit* Z  r' ~4 H4 b
    counter, so log analysis tools must be able to handle it without
! A1 G* u* _. ~8 L: p    overflowing.
; e5 N+ z6 d+ U5 A; Z, `
# k0 D+ z; K. F' l3 E. `* x" Z  - "captured_request_cookie" is an optional "name=value" entry indicating that4 b' `( S$ m5 a$ H8 ^! L
    the client had this cookie in the request. The cookie name and its maximum
( j+ ~2 W- H& X3 ~3 T    length are defined by the "capture cookie" statement in the frontend% X5 t3 e: M& V: u
    configuration. The field is a single dash ('-') when the option is not
8 B. E) [7 L3 I    set. Only one cookie may be captured, it is generally used to track session' P' [6 c8 M+ ~+ Y; o
    ID exchanges between a client and a server to detect session crossing
% I' t$ K, u4 f- B! g    between clients due to application bugs. For more details, please consult6 S9 f9 L+ k2 E5 g% {: d
    the section "Capturing HTTP headers and cookies" below.
  \3 _/ G/ @$ G# x4 [: i: i2 n' d3 Z5 r* [6 S. N. I$ c
  - "captured_response_cookie" is an optional "name=value" entry indicating' y8 q. P  l9 m6 C8 `  R3 _
    that the server has returned a cookie with its response. The cookie name
( E  x# W  x6 a9 T. u5 i+ n    and its maximum length are defined by the "capture cookie" statement in the- M# O# H2 Y( W, L6 t7 k6 f# p/ [2 r
    frontend configuration. The field is a single dash ('-') when the option is
( k+ S: n0 a/ N+ P& p! s7 n$ |    not set. Only one cookie may be captured, it is generally used to track
4 C' p/ M! G; e# |$ K    session ID exchanges between a client and a server to detect session/ w" V( V/ j2 T6 o
    crossing between clients due to application bugs. For more details, please
4 _6 X2 Y2 I7 I. g- @5 Y    consult the section "Capturing HTTP headers and cookies" below.$ v7 y" I' h: M" {! n( B

. d1 _& m( r3 `' |1 L* ?) u  - "termination_state" is the condition the session was in when the session% f4 t" A8 t, t6 t- O$ H1 a
    ended. This indicates the session state, which side caused the end of: V) I3 V. h3 K# x* {; a. b
    session to happen, for what reason (timeout, error, ...), just like in TCP
1 p5 s& X/ C* K/ G2 N3 V    logs, and information about persistence operations on cookies in the last
& o9 x. M3 H% ~: |* W# {- g: O+ _    two characters. The normal flags should begin with "--", indicating the
  g! X; x% L$ u3 X7 c! H    session was closed by either end with no data remaining in buffers. See$ u' [9 B2 k' J" S9 t# w0 u
    below "Session state at disconnection" for more details.8 m  V( z! [9 a. F

, z- s  W# g" K8 L( ]! A0 L  - "actconn" is the total number of concurrent connections on the process when1 Y" m" t6 y' c* E& N
    the session was logged. It it useful to detect when some per-process system* k" p  @( G2 G6 h& v' N& U
    limits have been reached. For instance, if actconn is close to 512 or 1024" a5 \/ j2 L/ L' r
    when multiple connection errors occur, chances are high that the system
0 [2 Q8 N3 ]0 @/ n    limits the process to use a maximum of 1024 file descriptors and that all
$ M( Q1 G$ g8 _! l" a3 R    of them are used. See section 3 "Global parameters" to find how to tune the+ c3 S) `1 s9 [/ H# A
    system.) E+ x5 K3 ~( ^: v* T* ?3 v# S
1 i8 w$ W" \; w2 j) I2 q
  - "feconn" is the total number of concurrent connections on the frontend when1 k' t2 V  V, N( {# Y: C% I0 A2 l
    the session was logged. It is useful to estimate the amount of resource" l, V$ }+ l* W; }
    required to sustain high loads, and to detect when the frontend's "maxconn"( A% _8 t: B- W; n
    has been reached. Most often when this value increases by huge jumps, it is
- M2 u* X5 w* U6 q8 L; D+ }) S    because there is congestion on the backend servers, but sometimes it can be1 ?7 H0 |, C% B4 U$ \2 s
    caused by a denial of service attack.+ p- V* u5 y5 Q; `" p- W1 q

% p/ o# f8 C! R- S% e4 e  - "beconn" is the total number of concurrent connections handled by the
- N3 Q+ k/ f" U1 l8 c9 \* d    backend when the session was logged. It includes the total number of3 L2 F6 M7 ~( `3 w
    concurrent connections active on servers as well as the number of- Z5 L6 l* Z- k8 R4 a7 N0 x* N
    connections pending in queues. It is useful to estimate the amount of4 S# x5 F6 B$ @- l- G
    additional servers needed to support high loads for a given application.
: g2 m; J+ z3 ^7 U3 A$ q1 O$ E- _    Most often when this value increases by huge jumps, it is because there is) k3 ^2 s; C# S5 _
    congestion on the backend servers, but sometimes it can be caused by a
  f" g. v3 v/ |) ]+ l9 f. ~" l    denial of service attack.: k( b* S( m+ v6 f  E) ^  V
. Z% S: i+ X6 z' \9 V: V
  - "srv_conn" is the total number of concurrent connections still active on: c1 y2 {/ N# i
    the server when the session was logged. It can never exceed the server's$ T! d- S- s, \- U5 C# H% K: F, R
    configured "maxconn" parameter. If this value is very often close or equal7 F/ a, v; P) p2 d
    to the server's "maxconn", it means that traffic regulation is involved a6 C! g( E9 M! {! e; m3 N4 k
    lot, meaning that either the server's maxconn value is too low, or that
( e: ^7 }. T) k" h1 ^  C    there aren't enough servers to process the load with an optimal response& @! e  C, Q% v% u
    time. When only one of the server's "srv_conn" is high, it usually means$ H4 n; T4 l& R6 A, Y- j
    that this server has some trouble causing the requests to take longer to be* b% e$ q( V4 x4 B# R; h
    processed than on other servers.
  Z) X7 \6 G( Y2 P' s. a* A
; ^+ c! G! q  C$ j3 [# y  - "retries" is the number of connection retries experienced by this session* P2 r; f  [% q- t% J+ B
    when trying to connect to the server. It must normally be zero, unless a$ ?. J1 Q$ K# o; n* b
    server is being stopped at the same moment the connection was attempted.7 C+ i; I" g" e$ {
    Frequent retries generally indicate either a network problem between; x: D  r/ t- q5 T( @; P/ H/ g
    haproxy and the server, or a misconfigured system backlog on the server
; c2 G. X  v4 |- ~2 D8 {    preventing new connections from being queued. This field may optionally be
. I% c* n' C/ Z    prefixed with a '+' sign, indicating that the session has experienced a
( J5 a7 o! p. i5 N+ \- |! |    redispatch after the maximal retry count has been reached on the initial
3 k. {% C. K" u" p' m/ \# I    server. In this case, the server name appearing in the log is the one the
4 ~$ ~1 n  I9 b) M1 k( l: C    connection was redispatched to, and not the first one, though both may
7 F4 ^% e9 Y' T& N/ ~" s6 j9 V    sometimes be the same in case of hashing for instance. So as a general rule
; m$ f0 K* p9 h# N& }    of thumb, when a '+' is present in front of the retry count, this count' |/ S5 ^4 t. g+ i6 `
    should not be attributed to the logged server.
5 `* L0 w2 }4 O' y& k
" [# l7 o& P/ i$ [0 u7 Q  - "srv_queue" is the total number of requests which were processed before. i; b% H- j1 l8 o* v5 M
    this one in the server queue. It is zero when the request has not gone
& ^' {* y* B+ C. Z6 w" s* s5 I    through the server queue. It makes it possible to estimate the approximate4 \: X) ?2 X- S5 _) Q
    server's response time by dividing the time spent in queue by the number of& E4 m: E, W3 r! r
    requests in the queue. It is worth noting that if a session experiences a
9 P' e) S1 G; }% N; D% Y5 K    redispatch and passes through two server queues, their positions will be. B6 D8 D1 B2 o$ ~4 v
    cumulated. A request should not pass through both the server queue and the
8 X( T5 ]$ s& R3 k' B7 N* [, ]( l0 C    backend queue unless a redispatch occurs.
: G% T$ K2 x, ^& {$ k( `4 u3 T3 K- W6 h3 i( T
  - "backend_queue" is the total number of requests which were processed before
7 S9 P2 `( Z6 a# V    this one in the backend's global queue. It is zero when the request has not
1 k' \4 L4 U3 }6 V; @    gone through the global queue. It makes it possible to estimate the average
2 _" V# b* V. O' R    queue length, which easily translates into a number of missing servers when* _+ D9 p. J0 X+ T0 w
    divided by a server's "maxconn" parameter. It is worth noting that if a0 N$ W' z6 |2 w
    session experiences a redispatch, it may pass twice in the backend's queue,
2 ?9 Q4 Z1 w9 G& b* \2 z- T0 @    and then both positions will be cumulated. A request should not pass4 t0 f7 u; v7 t/ d- ^
    through both the server queue and the backend queue unless a redispatch
: C" S- o7 |& z2 r    occurs.' ?; f- ~9 _3 f
& V1 m8 n6 i1 m0 j8 ?* G- k
  - "captured_request_headers" is a list of headers captured in the request due
0 ~1 }: J& ^( y% {/ O! u0 u2 P    to the presence of the "capture request header" statement in the frontend.
' C1 l; k* A& ?' G    Multiple headers can be captured, they will be delimited by a vertical bar
/ Y% i$ ~0 ^& t2 i    ('|'). When no capture is enabled, the braces do not appear, causing a: C! r1 f. A. k# |6 s" W7 b
    shift of remaining fields. It is important to note that this field may
* U2 y9 f& ]9 _$ O, I    contain spaces, and that using it requires a smarter log parser than when
3 T2 \/ E" e, z/ ~    it's not used. Please consult the section "Capturing HTTP headers and! J) O& j5 I  t' ]* j
    cookies" below for more details.- p# U9 D7 {  t" V5 t, Q4 e/ y. G

8 j7 P/ M  K( a+ ?  i  K/ M  - "captured_response_headers" is a list of headers captured in the response, v+ v  a0 d+ u
    due to the presence of the "capture response header" statement in the
6 I5 s. Q4 q- p    frontend. Multiple headers can be captured, they will be delimited by a; o! |- v6 h" V* M& G& ^+ F" X
    vertical bar ('|'). When no capture is enabled, the braces do not appear,
; \3 @0 k! y+ s9 w: \    causing a shift of remaining fields. It is important to note that this
# H+ B( u2 V+ O7 g. p- s    field may contain spaces, and that using it requires a smarter log parser5 h1 C) s+ y* |- U" ]# O
    than when it's not used. Please consult the section "Capturing HTTP headers
/ a5 f4 ~1 X0 C3 r$ A: D    and cookies" below for more details.
$ ^% ~  N7 V# j2 c: n+ e! s" l
  - "http_request" is the complete HTTP request line, including the method,, \9 ^; K9 @  Z: w0 @5 G9 T
    request and HTTP version string. Non-printable characters are encoded (see* r  `) s# G- I9 \$ r
    below the section "Non-printable characters"). This is always the last
# X7 Y* G7 S7 }% Y    field, and it is always delimited by quotes and is the only one which can6 E3 r! u* N' L1 C4 A, ?9 o
    contain quotes. If new fields are added to the log format, they will be- m3 H! a4 f3 z0 J3 J
    added before this field. This field might be truncated if the request is
: i& B* Q4 c2 I" n/ p" J' X: z    huge and does not fit in the standard syslog buffer (1024 characters). This
! S8 ]: Y5 T7 A6 ?  S    is the reason why this field must always remain the last one.
" B! p0 N* y0 B, |% U! r! z! ^5 D2 p  d, |% V

$ }4 p, I- S5 d0 C# q3 I! b! y5 L6 C8.3. Advanced logging options4 y7 n2 v4 A% L
-----------------------------$ t' O2 J) c7 l; m

& u0 y& ~- E, _% x+ F" |2 KSome advanced logging options are often looked for but are not easy to find out
/ N$ W1 n: C/ C. E$ [1 t2 r3 |just by looking at the various options. Here is an entry point for the few
$ P* B5 k0 Y) T" r" u' Loptions which can enable better logging. Please refer to the keywords reference  w8 T6 L4 l* _: [6 T
for more information about their usage.5 Q. U7 o4 w1 h( P( N: |

5 u; e- h. c' m0 `" ?1 I  O5 P! U
, t0 B2 d! c" d* I1 i5 E8.3.1. Disabling logging of external tests
3 Z4 |  P+ T6 A4 n------------------------------------------5 q" n/ U9 t; j

4 T# K9 N( X2 P- q* T. P/ {1 BIt is quite common to have some monitoring tools perform health checks on# ^1 O4 D( |. {( a0 Z8 _
haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any( X! @0 o/ b5 @( Y; ~; g
commercial load-balancer, and sometimes it will simply be a more complete4 Z  ~. m! K* Y1 T  O- J
monitoring system such as Nagios. When the tests are very frequent, users often# C; a9 L( U5 ~# s
ask how to disable logging for those checks. There are three possibilities :1 P- F9 J' ^) j( D. H) l

4 _+ h( i( R) s0 U. {$ B! {4 y/ f  - if connections come from everywhere and are just TCP probes, it is often
9 G) B6 S+ H+ O+ w- C- F  ]    desired to simply disable logging of connections without data exchange, by
$ Z/ l! J0 h% _2 Z    setting "option dontlognull" in the frontend. It also disables logging of
- P+ x% E7 @- L; T$ A    port scans, which may or may not be desired.
1 h3 M2 E9 [" @7 l3 v7 M! [$ G. G
) |& Q3 `! p* ~1 H; [1 v4 ^  - if the connection come from a known source network, use "monitor-net" to
2 A: B& V5 m! e4 V- ?3 ^( j- i" l! k    declare this network as monitoring only. Any host in this network will then7 a; F, S+ s. m7 |) ?/ D1 I
    only be able to perform health checks, and their requests will not be& r% M' h- J7 T, E
    logged. This is generally appropriate to designate a list of equipments1 J: W& i, Z4 M5 Y6 Z7 k" \' X7 w
    such as other load-balancers.
1 I/ H  x# M, I, S( ~
; J& z7 A  J* G" w' ^  - if the tests are performed on a known URI, use "monitor-uri" to declare
  ]3 v1 S  |) U# H    this URI as dedicated to monitoring. Any host sending this request will
+ a* p8 G" x, m+ H& P/ M: n1 C5 `; q    only get the result of a health-check, and the request will not be logged.
% k0 l9 Z/ D$ C0 w0 s' K  B9 J1 L/ l  s2 C# o' p& s

- @6 `: h3 x" O8.3.2. Logging before waiting for the session to terminate3 H+ W$ K7 c4 B6 h0 e4 `
----------------------------------------------------------1 q; _- J* \; s

; h4 \7 [1 ?# J! W$ u+ yThe problem with logging at end of connection is that you have no clue about- s& L+ A% T* w
what is happening during very long sessions, such as remote terminal sessions7 D8 q( w, |! Z, m$ U
or large file downloads. This problem can be worked around by specifying
6 D* ~; o, K- }"option logasap" in the frontend. Haproxy will then log as soon as possible,
8 b% _+ `  ]6 V: L0 zjust before data transfer begins. This means that in case of TCP, it will still
& N8 U5 B# r1 |" O3 R$ C+ r  `log the connection status to the server, and in case of HTTP, it will log just! O) K" |  `; I1 ^1 B2 l
after processing the server headers. In this case, the number of bytes reported
: |- |7 f3 W1 G( m/ H1 Xis the number of header bytes sent to the client. In order to avoid confusion4 i- q3 k+ T/ F. x
with normal logs, the total time field and the number of bytes are prefixed5 R+ }, ?2 w7 e6 P& D7 |' E& d1 O
with a '+' sign which means that real numbers are certainly larger.
" e! d8 q/ |( d% F! a
/ p) f% c0 L* m1 V# F
1 l2 B  y5 A9 ]- |% K3 ?3 s. ^8.3.3. Raising log level upon errors
; a  ^( ?6 Z1 w------------------------------------! w! r8 d' i  E7 K# \% Q! q

% B: [+ {4 f! ~6 o- c8 G/ {( aSometimes it is more convenient to separate normal traffic from errors logs,. i% j" ]1 W9 ^& ?& N
for instance in order to ease error monitoring from log files. When the option3 f2 u- B2 ]& @* q
"log-separate-errors" is used, connections which experience errors, timeouts,; w8 t* w. N% y% [
retries, redispatches or HTTP status codes 5xx will see their syslog level6 l+ e. Y: b6 W! S' w
raised from "info" to "err". This will help a syslog daemon store the log in  p; Y/ W  l6 {
a separate file. It is very important to keep the errors in the normal traffic$ N( ?1 e9 v4 k4 m0 F! s2 K2 {
file too, so that log ordering is not altered. You should also be careful if
1 e  q$ c* `. Xyou already have configured your syslog daemon to store all logs higher than
- G" B6 ?8 M# y& B* Y% j"notice" in an "admin" file, because the "err" level is higher than "notice".3 ?% O4 ^% v$ C) g
7 l7 K7 x+ d8 f2 Y- y

& J* e- n- n7 I. j3 @- q8.3.4. Disabling logging of successful connections
. \+ h+ C0 b  `2 X--------------------------------------------------& D# E6 ^2 g4 _

7 V; _: m4 z0 E/ `Although this may sound strange at first, some large sites have to deal with
" n; I( s3 s. Pmultiple thousands of logs per second and are experiencing difficulties keeping
: H6 U7 m/ z, A7 `: T/ g! othem intact for a long time or detecting errors within them. If the option
8 [5 E8 E+ V3 b; @! N"dontlog-normal" is set on the frontend, all normal connections will not be
5 |) z+ N% n+ E( b/ ~/ r8 b5 Hlogged. In this regard, a normal connection is defined as one without any
7 P9 R# ]4 x8 x8 V: O1 q5 ierror, timeout, retry nor redispatch. In HTTP, the status code is checked too,
: E7 G3 \' A/ H  j  ^9 N4 Q+ D( ?and a response with a status 5xx is not considered normal and will be logged* B. T: A! \! b5 a+ m
too. Of course, doing is is really discouraged as it will remove most of the0 R2 G& M6 X% X5 q0 z
useful information from the logs. Do this only if you have no other( n0 f5 m; ^: u8 Q/ C6 ~. @
alternative.
4 o7 r$ H# [. j; O7 C7 }% T; O3 l. Z' q, G
9 X/ p% I5 d3 r1 F+ r: N- h* G
8.4. Timing events6 N6 c9 F  `% ^) P3 \
------------------/ t& l7 b9 {4 b- H: b5 t( h- I8 ~7 V

0 F4 I1 A5 M3 RTimers provide a great help in troubleshooting network problems. All values are7 Y; z" Y. q# m4 W+ v. q6 W( P
reported in milliseconds (ms). These timers should be used in conjunction with- ^  B  h+ i: P9 ~: D
the session termination flags. In TCP mode with "option tcplog" set on the
0 M! d" C, _2 J4 v0 L4 H$ ]frontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP0 a/ S8 x: M% T7 v# d
mode, 5 control points are reported under the form "Tq/Tw/Tc/Tr/Tt" :
  h- E- Q3 w3 v4 `
4 o$ [/ B8 B$ t, i7 \  - Tq: total time to get the client request (HTTP mode only). It's the time) A' C" r; q/ @7 ~# X
    elapsed between the moment the client connection was accepted and the  Q) n) E0 v, q' o- G4 m. f1 J" w
    moment the proxy received the last HTTP header. The value "-1" indicates, m% N8 d6 c2 n' S' m! T
    that the end of headers (empty line) has never been seen. This happens when# {  k+ T4 `' b
    the client closes prematurely or times out.; P8 g8 b' ^3 l4 G9 V% [, w& l

% U, a% b. y& [/ [3 Y! G# h+ g  - Tw: total time spent in the queues waiting for a connection slot. It5 P# X8 y2 s4 l. d3 B+ g" p6 |, C
    accounts for backend queue as well as the server queues, and depends on the
' B! A0 r6 M: h: G    queue size, and the time needed for the server to complete previous
" k6 ~( [# [$ D3 m    requests. The value "-1" means that the request was killed before reaching. V5 p2 C9 M: Q9 n
    the queue, which is generally what happens with invalid or denied requests.% M+ z( C3 e: b
. C9 f+ x' B8 F% f/ w  v6 Q4 x, D& ^
  - Tc: total time to establish the TCP connection to the server. It's the time
" K; d3 g, e1 n4 t7 ?    elapsed between the moment the proxy sent the connection request, and the
, M) i! n# h, @* t* \    moment it was acknowledged by the server, or between the TCP SYN packet and
: k* K. A9 g5 z, c3 j7 _" l    the matching SYN/ACK packet in return. The value "-1" means that the9 C* e' n; o# S  \
    connection never established.8 J, r: f( Y5 l) K1 v  d  C
8 a3 T4 j8 V$ O4 |2 [
  - Tr: server response time (HTTP mode only). It's the time elapsed between+ V% W7 c) y7 ^, b0 v
    the moment the TCP connection was established to the server and the moment! B9 w8 M$ t7 j! ]; g! w
    the server sent its complete response headers. It purely shows its request% d  E! x! d6 E& c
    processing time, without the network overhead due to the data transmission.5 e3 `0 G$ {3 A! c+ G2 y) k
    It is worth noting that when the client has data to send to the server, for" l: x% d& V' G/ c5 u
    instance during a POST request, the time already runs, and this can distort1 h: k( R1 R8 `& |+ e
    apparent response time. For this reason, it's generally wise not to trust
. i$ M) X% w& w/ J8 M9 C    too much this field for POST requests initiated from clients behind an
2 ^+ @: \- l/ l5 W- |! g6 E    untrusted network. A value of "-1" here means that the last the response+ e" G0 J3 R+ R* |
    header (empty line) was never seen, most likely because the server timeout: J; K( n$ ^1 K! l) q8 Z# l, u. T
    stroke before the server managed to process the request.
! q3 w$ o3 J4 m/ E
: A7 [+ g" h' L! q  - Tt: total session duration time, between the moment the proxy accepted it
, X1 X$ O5 n, H2 |+ I* Q, e* I    and the moment both ends were closed. The exception is when the "logasap"
6 ]6 V% b; f" j3 W; c9 o5 ?8 E    option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is
5 ~: r. {; m$ x' h- Z, p- }/ J    prefixed with a '+' sign. From this field, we can deduce "Td", the data+ D0 s5 K& Z4 a
    transmission time, by substracting other timers when valid :
  G' Q$ |1 ?. ~/ C$ k( }2 V
) W5 Q2 l! t; i( |5 f% {/ F9 y+ N% r( v        Td = Tt - (Tq + Tw + Tc + Tr)
) N; u4 c4 G7 s* o) f, m, g6 c
    Timers with "-1" values have to be excluded from this equation. In TCP
: u( S+ {0 {1 C. w- T) q3 y1 p    mode, "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be: ~9 F5 M" C' C
    negative.6 d' D  ?$ Y' H! J' |

3 C$ m+ G' H7 i: ZThese timers provide precious indications on trouble causes. Since the TCP+ t2 Q: c# }2 q% T3 ^" T0 C
protocol defines retransmit delays of 3, 6, 12... seconds, we know for sure! A+ r# C7 w5 Y; e. ~) i
that timers close to multiples of 3s are nearly always related to lost packets
; ^0 Z0 C4 H2 w) Cdue to network problems (wires, negotiation, congestion). Moreover, if "Tt" is9 w6 j' P; V6 Y6 ]0 v! V5 _2 P7 N
close to a timeout value specified in the configuration, it often means that a- G+ x' F- I: \  o/ C/ s
session has been aborted on timeout.' q. m- e& b. T) X- J% V
/ F8 ~6 T4 M) m" W' u( z3 D
Most common cases :
! G8 l/ [3 Y& n% p2 b
: `9 s, O) w, L( ~% f: V  - If "Tq" is close to 3000, a packet has probably been lost between the: ^. C! ^, h3 ^/ V4 |2 `4 {9 V
    client and the proxy. This is very rare on local networks but might happen
  G" X) p! u8 J  [5 H    when clients are on far remote networks and send large requests. It may# D( s- O  S8 U9 [9 l
    happen that values larger than usual appear here without any network cause.
  M" g. m, j( s# P; Q" T    Sometimes, during an attack or just after a resource starvation has ended,9 f8 w2 W: Y/ ]% s% Y# [
    haproxy may accept thousands of connections in a few milliseconds. The time% ~% e6 @% ~" G; y$ l; C8 ^
    spent accepting these connections will inevitably slightly delay processing
: p8 N- @" z, K. P% V! v+ j    of other connections, and it can happen that request times in the order of7 Z4 Q6 f( V% |) g
    a few tens of milliseconds are measured after a few thousands of new: t2 p1 J! F$ S; V% X: Q0 v
    connections have been accepted at once. Setting "option http-server-close"& N4 _1 b+ ?: a/ |
    may display larger request times since "Tq" also measures the time spent
1 ?3 V+ n* H5 E& U( X    waiting for additional requests.
2 U* D$ v7 l! d; t: U% b! h: A: [" c5 L% T: U/ g* h/ F( s* |
  - If "Tc" is close to 3000, a packet has probably been lost between the/ i8 K8 \* D7 `" J+ v% c
    server and the proxy during the server connection phase. This value should( W4 H) X- t7 X' Q
    always be very low, such as 1 ms on local networks and less than a few tens
3 x) ]* T$ N% H+ X0 e, C    of ms on remote networks.3 K  D! T" a9 W" t

4 a; Y  b" _) ^4 S5 p9 O* T  - If "Tr" is nearly always lower than 3000 except some rare values which seem
9 U' A+ H, l4 x5 t% c0 v    to be the average majored by 3000, there are probably some packets lost; ^  c$ i" T- [1 f9 v: M9 P! F
    between the proxy and the server.7 H2 L% s8 L. ?
# V& _3 G6 W& B( X0 M& T  d- V
  - If "Tt" is large even for small byte counts, it generally is because+ j/ I0 I' z' ~. V7 A8 F$ S
    neither the client nor the server decides to close the connection, for" ^7 W: d4 V' C$ r
    instance because both have agreed on a keep-alive connection mode. In order
# q$ D: ?- d3 J0 F4 O! J$ M0 Y    to solve this issue, it will be needed to specify "option httpclose" on: E/ f" E) }7 M, l! d0 e" D
    either the frontend or the backend. If the problem persists, it means that9 N7 f5 ^& O1 M; l0 g6 ]
    the server ignores the "close" connection mode and expects the client to
3 ?4 h$ v6 o" o, y: l  g    close. Then it will be required to use "option forceclose". Having the0 p% y3 \/ w: A% [" X9 t
    smallest possible 'Tt' is important when connection regulation is used with) \2 }! S, r  g# o
    the "maxconn" option on the servers, since no new connection will be sent) E: \. B. x4 x' j! b9 u$ R
    to the server until another one is released.! A9 t% S! _7 R3 B4 K5 Z  S3 x

  b! p. A( N0 {Other noticeable HTTP log cases ('xx' means any value to be ignored) :
1 l" }! E  u. [" W- U. A
. e& ^* x. y7 Z6 }! O  Tq/Tw/Tc/Tr/+Tt  The "option logasap" is present on the frontend and the log& N2 {2 }; N& g* N! s# @9 t9 ]
                   was emitted before the data phase. All the timers are valid
  d6 `- s9 a5 _- k2 s                   except "Tt" which is shorter than reality.
6 q  @4 r" `& ~0 v5 O" Z: p) L0 `3 d* S# x; F* M. U
  -1/xx/xx/xx/Tt   The client was not able to send a complete request in time
- p3 ^2 h) D4 I7 B8 f1 s+ s5 H                   or it aborted too early. Check the session termination flags$ \4 z+ ]0 I9 T. M& z$ i/ ~
                   then "timeout http-request" and "timeout client" settings.' n: T% Z; \7 |% X  n, m

2 k: G5 E; h* ?0 W9 j$ q0 A8 v; _  Tq/-1/xx/xx/Tt   It was not possible to process the request, maybe because
+ t2 @0 H$ D% D; _( u* [: k" m1 d                   servers were out of order, because the request was invalid
1 d$ I  O  X- c1 K5 q                   or forbidden by ACL rules. Check the session termination
9 T: e3 B7 e: ?                   flags.. f, H" z2 h3 k6 I, ~/ N6 R
  J- ~1 M9 t( m$ C  \
  Tq/Tw/-1/xx/Tt   The connection could not establish on the server. Either it! I0 e: c8 r3 F" @( c
                   actively refused it or it timed out after Tt-(Tq+Tw) ms.
+ x5 V$ v: e1 F                   Check the session termination flags, then check the
! ]" V& ?) C8 R                   "timeout connect" setting. Note that the tarpit action might" U; Q: }# M$ T: {6 X% R5 {
                   return similar-looking patterns, with "Tw" equal to the time
1 P. ]8 n2 }+ G5 a( ~                   the client connection was maintained open.
' V; A* Q- j3 Q" N5 Z) i* h  f
- @) n* K8 {* ~4 ]  Tq/Tw/Tc/-1/Tt   The server has accepted the connection but did not return
. O* o' P% K; H  {                   a complete response in time, or it closed its connexion% Q2 q9 x3 P+ b0 W2 Q
                   unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session2 m' T! H, v0 H- c1 \0 ~
                   termination flags, then check the "timeout server" setting.3 |0 T0 O4 W) y8 _

  e* E: D+ [/ k0 A* ]" T( B4 `! }4 A
8.5. Session state at disconnection
( w& k- N" T' p- W5 V5 }-----------------------------------/ z; l9 G/ a$ W( k$ q

' p' x2 S, t: f& h# KTCP and HTTP logs provide a session termination indicator in the
, b7 `* _" A" @; k- s' ~; g"termination_state" field, just before the number of active connections. It is: `9 a' o1 ~- |+ d9 G- K& S
2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,9 D% s- a" R/ M, I
each of which has a special meaning :
4 @: V7 L' `  E) h( M$ }3 H% r8 J- ~  d* H
  - On the first character, a code reporting the first event which caused the& |8 y& M9 ~5 Y  r
    session to terminate :: I* L. g2 [+ q, f" M( _
% I  }" Q* l+ R* R/ F9 @3 P' i
        C : the TCP session was unexpectedly aborted by the client.
( K, G* T5 l* a, F( c" d2 n: X6 }+ m. N
        S : the TCP session was unexpectedly aborted by the server, or the: c" ]4 w4 j" x; H6 j, Q
            server explicitly refused it.$ t7 |, ]7 @7 {8 H
; \) `4 \! M5 o% y0 a9 R- B# `
        P : the session was prematurely aborted by the proxy, because of a
3 N& q7 Y. A! }2 M            connection limit enforcement, because a DENY filter was matched,
- o) I; C  _, ?5 t            because of a security check which detected and blocked a dangerous8 t+ {& J" T) D. E
            error in server response which might have caused information leak
* `" f! a1 K, \/ C            (eg: cacheable cookie), or because the response was processed by$ B' j2 }. s: c6 f& c$ C
            the proxy (redirect, stats, etc...).
) X3 W  }# T( V$ Z+ h& k; q7 s. k
+ [; F% }( `# l9 a        R : a resource on the proxy has been exhausted (memory, sockets, source
* p/ ~- g1 ]9 d" ^2 H            ports, ...). Usually, this appears during the connection phase, and
/ p5 ?) J+ R2 u* O3 P6 [( T: e            system logs should contain a copy of the precise error. If this
" l1 k5 f0 t, Z            happens, it must be considered as a very serious anomaly which" o5 S$ k; h9 O
            should be fixed as soon as possible by any means.
5 y+ D$ j9 Y) s  W, ?$ _7 S2 b9 Y
* {# {2 c7 X! N- \3 ?' o. m! g( C        I : an internal error was identified by the proxy during a self-check.
* N7 W- P6 p  G' O/ V. v7 x            This should NEVER happen, and you are encouraged to report any log1 x; H$ A( s: ]9 I( k  H$ S( S
            containing this, because this would almost certainly be a bug. It1 s4 X) {) t7 X" |! G
            would be wise to preventively restart the process after such an
: r6 A1 n! v, W3 R  e            event too, in case it would be caused by memory corruption.' ]- {8 v: e9 Q0 }; H
  n6 f/ C8 r9 D; _* J2 x+ F+ w
        c : the client-side timeout expired while waiting for the client to
! j/ K, w0 S! x) O+ A            send or receive data.
' f3 _6 F! T  n, }, \1 r3 k) o0 h$ U  b" I- D
        s : the server-side timeout expired while waiting for the server to
! }( I# C8 e  |- O2 Z' O            send or receive data.
% A7 Z5 e# |$ w. c# r  w! K
+ }9 @' ^% `; a0 ?6 z1 ~4 T        - : normal session completion, both the client and the server closed6 ]' q  X6 t% M' v" f# j0 E& N6 F! `5 w( K
            with nothing left in the buffers.1 _! Z+ k' A$ H$ ]/ E& u

" F( p" Q+ T& T  - on the second character, the TCP or HTTP session state when it was closed :! T2 ^/ c( L% u2 o0 t/ q9 o; A1 D# i

9 x) v3 d5 ~' d6 Z9 K; P        R : the proxy was waiting for a complete, valid REQUEST from the client) _. k$ M7 c8 s' q/ e  x4 A$ l
            (HTTP mode only). Nothing was sent to any server.$ W7 ]) n/ S! N+ J4 {# |0 `
) Y# S4 V- |0 Q2 O
        Q : the proxy was waiting in the QUEUE for a connection slot. This can
3 X. i( C9 H2 Z( Q% E            only happen when servers have a 'maxconn' parameter set. It can% H5 d: C3 S1 T; l6 E
            also happen in the global queue after a redispatch consecutive to
8 X  V% q% t  I# G8 X" z* b            a failed attempt to connect to a dying server. If no redispatch is
, t& Q1 Q2 D( O1 m8 `            reported, then no connection attempt was made to any server.
: ?$ D( k1 _  Z' {' s4 n; H
. ]6 J" Z  R) w2 k, z/ Z- }, F% f        C : the proxy was waiting for the CONNECTION to establish on the# a" c( @  H  X6 L- n3 M. N' s; `
            server. The server might at most have noticed a connection attempt.
  k& I5 E7 y; n. i
+ O0 P7 T1 U8 i8 L% p        H : the proxy was waiting for complete, valid response HEADERS from the
: X! x* \2 }0 x$ o3 A            server (HTTP only).1 X' _+ X2 |- ~& o9 b; A

. g) o2 b7 a0 B: j        D : the session was in the DATA phase.
2 H+ _+ i9 M4 Z! G8 X5 |6 _" J: o, }9 i1 c3 A, W
        L : the proxy was still transmitting LAST data to the client while the! H6 H: m7 W+ Y' T& x" }5 s4 R
            server had already finished. This one is very rare as it can only
5 S/ T# M2 v0 t& {$ C( |            happen when the client dies while receiving the last packets.
* Q  {" x7 r' f2 ~! y5 P8 C$ ], q; K4 ?$ {
        T : the request was tarpitted. It has been held open with the client( Q; u0 _% \" [; M( e' J4 W
            during the whole "timeout tarpit" duration or until the client
. ~' H: X% W: c; d6 T            closed, both of which will be reported in the "Tw" timer.7 B5 L& b1 b- X* q6 T
6 ?8 ]0 G/ z7 `0 q' X8 A) a5 F* F
        - : normal session completion after end of data transfer.
0 ]" d8 j9 {& a' I& k+ Q2 u) [3 D# P6 g" l' h/ Q% P0 P
  - the third character tells whether the persistence cookie was provided by+ |1 C/ {& g* T' D* k! ]# v
    the client (only in HTTP mode) :6 ~$ m9 r2 x# D

8 X7 A# y4 \6 g2 F* E5 H        N : the client provided NO cookie. This is usually the case for new+ Y7 o0 [  y! r  Z9 b
            visitors, so counting the number of occurrences of this flag in the
1 n: S" m9 @% o) X3 }            logs generally indicate a valid trend for the site frequentation.
0 b& Z- t) p1 q5 w/ g/ W+ }$ T- f
+ G- T) I& u! ~$ z& A& ]        I : the client provided an INVALID cookie matching no known server.* H, V9 Q+ l. t1 i; J- a
            This might be caused by a recent configuration change, mixed
) P* [- D* S4 k. Q( S            cookies between HTTP/HTTPS sites, persistence conditionally5 X6 p3 R8 B4 y. L0 A
            ignored, or an attack.- Q5 R) K' {# ~# d
; m! l, j  ]/ @8 B; T2 K
        D : the client provided a cookie designating a server which was DOWN,
% a$ f, _/ B0 b( \% r% }# L7 Y5 e            so either "option persist" was used and the client was sent to
3 \( B4 R& |! Z9 F! x            this server, or it was not set and the client was redispatched to  G' ^- V6 v" r/ W6 z
            another server.
& X7 U% e; F1 L# ?8 E
) z/ H( p5 g: z3 a- D. x. R, T        V : the client provided a VALID cookie, and was sent to the associated3 k$ q7 v, H/ J! Z
            server.. o/ b* J% x; T5 ?: R* b5 l$ u+ U

, f& e; h) e- [; j6 m% w        E : the client provided a valid cookie, but with a last date which was: U2 A1 r) L4 K7 p' P& H
            older than what is allowed by the "maxidle" cookie parameter, so
( o( D- r' w" H& b            the cookie is consider EXPIRED and is ignored. The request will be; ]; d. @) Y2 E. Y0 c
            redispatched just as if there was no cookie.) {$ k* {) u" W! q; m

5 A, c) L8 b% K        O : the client provided a valid cookie, but with a first date which was
! @" ]- R4 Q0 j- O0 Z  d" ~& W! R: T            older than what is allowed by the "maxlife" cookie parameter, so
7 |2 |& V8 l. i/ A& q! g            the cookie is consider too OLD and is ignored. The request will be5 S  p' w9 g& Y9 D- N6 S
            redispatched just as if there was no cookie.5 a: V$ O6 Z; K, A0 Y

* n" t7 F1 \& N+ O  k5 q        - : does not apply (no cookie set in configuration).4 X# `( @: F5 e

/ s6 S6 q2 M7 @7 a- T, ]1 e1 R  - the last character reports what operations were performed on the persistence7 j+ L% `* e8 j: R" N
    cookie returned by the server (only in HTTP mode) :
( Q  |6 T% g# S  c( I' L' c' ?2 ^( P  i2 R9 o" ?( O% Z2 A
        N : NO cookie was provided by the server, and none was inserted either.
: B: }' g* {0 k  m  S, B$ ^+ J3 m9 p/ F* [" T. h+ B
        I : no cookie was provided by the server, and the proxy INSERTED one.
! d# b: O; t" W, \$ `            Note that in "cookie insert" mode, if the server provides a cookie,9 P$ M3 u6 G) T4 S
            it will still be overwritten and reported as "I" here.
- O  ]* d6 q# q( {3 t! `* i
+ F, Q7 ^3 J9 Q  [( ?        U : the proxy UPDATED the last date in the cookie that was presented by
$ O7 Q! a( j6 R. Y  _* i            the client. This can only happen in insert mode with "maxidle". It
; O) K" ~  M& S            happens everytime there is activity at a different date than the
8 J. v+ |9 d4 w! _1 }/ `8 V            date indicated in the cookie. If any other change happens, such as. o3 `6 o# z! c" @
            a redispatch, then the cookie will be marked as inserted instead.
5 X% r1 w* V% u% r: Q' |- t
8 E3 Y7 X& D+ j- |6 u2 K$ R3 q        P : a cookie was PROVIDED by the server and transmitted as-is.) V' r) h) N7 I& Z" l

5 V* e2 w0 J4 i        R : the cookie provided by the server was REWRITTEN by the proxy, which
8 M4 w2 ]) `2 A5 t; I$ R* P            happens in "cookie rewrite" or "cookie prefix" modes.
  j( i' a. r. g. e
6 `9 G+ Z" M- }        D : the cookie provided by the server was DELETED by the proxy.4 P! n* N- k6 ]
( O( a$ h! K8 ]) h! P
        - : does not apply (no cookie set in configuration).
% M. w% e& i7 O& q: ?( t2 P2 x! q1 Y% W3 \; |' }  L8 ~5 _
The combination of the two first flags gives a lot of information about what
: u' Z! F2 M9 g% ?3 c# Wwas happening when the session terminated, and why it did terminate. It can be& b2 B9 t# o2 L5 S9 E5 A5 k- P
helpful to detect server saturation, network troubles, local system resource
; d4 C- w5 A9 ~& h0 jstarvation, attacks, etc...
0 E) c! {/ s; a4 {7 B7 L! n* p' I6 ]* T; \/ Y% p" J
The most common termination flags combinations are indicated below. They are
9 R2 F2 \# _( T! V" W- n" aalphabetically sorted, with the lowercase set just after the upper case for# y1 ^7 N5 c. G# R* u/ U$ M7 Z
easier finding and understanding.& d0 Z3 g' q" z. q( B5 \4 C

9 Q; N& L/ [3 i1 u5 V  Flags   Reason6 d6 m) T4 c) s% [2 `0 a

' V& F: u1 @3 ?, H% A( r8 L     --   Normal termination." F$ y) z$ v% c6 H* D( ?9 J
$ x4 e7 ]# l7 O" u/ B9 ]
     CC   The client aborted before the connection could be established to the8 m& r! L. J: h' t& g- p
          server. This can happen when haproxy tries to connect to a recently
2 S3 F* K1 L, r7 `          dead (or unchecked) server, and the client aborts while haproxy is
$ J6 x6 [6 k) s: x! |- n7 Y! n          waiting for the server to respond or for "timeout connect" to expire.( h* I- x1 z3 d' b0 L6 x
' C1 a/ m" q& I1 ~& J1 y0 f3 |9 Y
     CD   The client unexpectedly aborted during data transfer. This can be" n/ `" p/ Z0 c
          caused by a browser crash, by an intermediate equipment between the
& t% M& M. k/ T3 v6 w          client and haproxy which decided to actively break the connection,
. n: e5 Y, \  }& F          by network routing issues between the client and haproxy, or by a
$ c0 H. I& }. L" Y4 @          keep-alive session between the server and the client terminated first8 k1 B3 p2 s$ A0 D
          by the client.6 Z) g8 g( I" g- Y2 t) u; h

. X; l- {6 K3 F8 w7 A7 |1 f) u' L     cD   The client did not send nor acknowledge any data for as long as the8 A4 H2 t6 d1 \$ u  Q1 H. V
          "timeout client" delay. This is often caused by network failures on
2 Y% C& A7 F1 }) `' Y, {! Z          the client side, or the client simply leaving the net uncleanly.
$ t% u! z0 w9 D' K, ?( ~# Y" ^7 I1 f* Q9 ~
     CH   The client aborted while waiting for the server to start responding.
7 \1 p6 n1 y' j3 C2 h1 Q          It might be the server taking too long to respond or the client
. o/ j& G% S' u9 D2 L          clicking the 'Stop' button too fast.
) C0 `' ]$ J# z/ d: o
. _7 h5 U0 [' F. ]7 n+ P+ g     cH   The "timeout client" stroke while waiting for client data during a
6 |- N- Z9 _) D+ v          POST request. This is sometimes caused by too large TCP MSS values7 l/ z+ Q3 h2 l) |1 ~# [: l
          for PPPoE networks which cannot transport full-sized packets. It can
1 R  x) |' n0 a2 {! e          also happen when client timeout is smaller than server timeout and/ C7 k# Y* r, I
          the server takes too long to respond.; H: Z1 J/ D, G" }7 O7 U8 O

. T5 F+ P1 f7 P6 L     CQ   The client aborted while its session was queued, waiting for a server
7 u9 C! p+ q1 X6 c8 ~0 n) ?          with enough empty slots to accept it. It might be that either all the/ m4 I' y9 H8 E0 Z+ t. Z  Q
          servers were saturated or that the assigned server was taking too$ t6 A3 }* F0 d& Y- d5 V& n
          long a time to respond.
% T! R/ J* X0 _# {" d
8 B8 u* r9 s, m     CR   The client aborted before sending a full HTTP request. Most likely( G1 z; X+ d% _3 c
          the request was typed by hand using a telnet client, and aborted8 ?2 e4 c+ D1 W8 k
          too early. The HTTP status code is likely a 400 here. Sometimes this
. s9 l) @  n' ]9 E- U          might also be caused by an IDS killing the connection between haproxy
6 T0 z1 k/ V# \; y          and the client.
8 C6 u$ {4 a6 d3 U/ S; @- M* B3 B
  L# \- k2 S0 H  u0 }     cR   The "timeout http-request" stroke before the client sent a full HTTP* K  g8 i/ x" l1 g0 ^
          request. This is sometimes caused by too large TCP MSS values on the
! i0 Z4 z( r9 s  U% m- c. @          client side for PPPoE networks which cannot transport full-sized; p2 ?- ^* \  Q1 W  x; v
          packets, or by clients sending requests by hand and not typing fast- j9 A& g: V6 C! o- ]' {
          enough, or forgetting to enter the empty line at the end of the
2 s8 [1 m0 O. }) K          request. The HTTP status code is likely a 408 here.
& {2 B1 h, |( A9 v/ X; U! |/ v7 F+ P9 N1 M; U0 C0 O+ F6 s# R, z
     CT   The client aborted while its session was tarpitted. It is important to' w" t* q, E7 r' i  P& C
          check if this happens on valid requests, in order to be sure that no
3 A# G7 Z5 n' u7 \& p9 ^- p" W+ ^( @          wrong tarpit rules have been written. If a lot of them happen, it9 O* S8 D$ Q/ A) S- d5 o6 c5 n
          might make sense to lower the "timeout tarpit" value to something
' R2 Y3 f- W3 I# m$ e6 x/ N0 \& T          closer to the average reported "Tw" timer, in order not to consume. I; w; i4 e! x) B
          resources for just a few attackers.
4 H; e5 R" _; @# Q+ S5 F5 l8 ~. ?8 }, m# O- k+ m, A
     SC   The server or an equipment between it and haproxy explicitly refused
0 m- _+ b6 A: @  x) r( c          the TCP connection (the proxy received a TCP RST or an ICMP message. l/ Q: g+ A# y
          in return). Under some circumstances, it can also be the network) Y: ]' q* T% h1 E% q$ s( \) Q& @
          stack telling the proxy that the server is unreachable (eg: no route,
5 `" _( l1 q* H          or no ARP response on local network). When this happens in HTTP mode,5 F2 M5 s* @5 H4 B5 ?7 U, G
          the status code is likely a 502 or 503 here.
, `1 i9 d' [: a3 q* Q( S0 o3 I( L: W
     sC   The "timeout connect" stroke before a connection to the server could3 Z( y$ {' Q; W' h6 P% J2 h% m
          complete. When this happens in HTTP mode, the status code is likely a
; W  v1 T8 W+ w; \8 p! J          503 or 504 here.
6 s; D( A" ]# F9 n7 F! N* V0 l- ^9 V2 S) v/ Q
     SD   The connection to the server died with an error during the data
' s# `) P# |3 q8 s# h          transfer. This usually means that haproxy has received an RST from
% h1 O! D; T3 d          the server or an ICMP message from an intermediate equipment while
# N9 j" ?# h% A          exchanging data with the server. This can be caused by a server crash: T  ~  z. @# s# n, L) x
          or by a network issue on an intermediate equipment., q/ A5 [) i% l; p. Q
& |; h3 s, B$ w
     sD   The server did not send nor acknowledge any data for as long as the. [" V, e9 B1 q, m; _. u' }4 O
          "timeout server" setting during the data phase. This is often caused
( h* a) u& D6 G1 r& I          by too short timeouts on L4 equipments before the server (firewalls,
3 l' ]4 V2 _4 \" V/ c1 i% }          load-balancers, ...), as well as keep-alive sessions maintained
" G7 e3 W% V5 c$ R          between the client and the server expiring first on haproxy.
% O- Q7 S/ v2 S6 Y; o& U# k, p% s8 t4 s' b! {
     SH   The server aborted before sending its full HTTP response headers, or
8 Z9 `' Y0 t; o% a          it crashed while processing the request. Since a server aborting at: o+ z/ h; @3 e# {# U3 `% p
          this moment is very rare, it would be wise to inspect its logs to, j5 l% N) k2 p  l7 `: j/ N
          control whether it crashed and why. The logged request may indicate a
8 v2 Y$ }8 r* {; Q. N4 P3 o  O$ @          small set of faulty requests, demonstrating bugs in the application.
4 t; V  B: x0 e          Sometimes this might also be caused by an IDS killing the connection
/ r5 m; W4 V2 B. T          between haproxy and the server.2 d+ S& k9 q. ]
' Y8 G4 e1 k  j( q+ q0 e3 ?
     sH   The "timeout server" stroke before the server could return its' C  [9 [: D( p; ~; }9 ?
          response headers. This is the most common anomaly, indicating too: W  ~8 n( [5 F- R1 J
          long transactions, probably caused by server or database saturation.7 j( `4 G' f) m: b( _/ a
          The immediate workaround consists in increasing the "timeout server"' z# Q7 k# A8 s3 ^& ^
          setting, but it is important to keep in mind that the user experience
5 x0 j6 q1 [$ J3 L% \/ U          will suffer from these long response times. The only long term* @$ p) B0 ?4 Q9 v6 F, U
          solution is to fix the application.
3 G4 p* l+ p9 `; d! O2 ^5 Q! ?) r
5 m# q- l3 d) q$ }     sQ   The session spent too much time in queue and has been expired. See# a& x1 {9 o5 k0 {2 C* P! a1 w
          the "timeout queue" and "timeout connect" settings to find out how to
6 h9 m3 d$ d- i5 E2 d- M          fix this if it happens too often. If it often happens massively in4 J/ c/ i, i6 A0 C# [
          short periods, it may indicate general problems on the affected+ k2 H3 P0 N/ _6 I) c8 H, i2 ?2 [
          servers due to I/O or database congestion, or saturation caused by/ M: ~- G8 @3 T0 ?( {
          external attacks.
. U$ u* I& k! u% @3 ?' i! L4 g) Y$ V2 z; L! D/ L
     PC   The proxy refused to establish a connection to the server because the8 |1 U0 M7 f0 g7 |
          process' socket limit has been reached while attempting to connect.
$ G- T, T3 g3 E! f5 f' Z" X3 d          The global "maxconn" parameter may be increased in the configuration6 ~% ?3 H) p" h+ n( `# `0 J
          so that it does not happen anymore. This status is very rare and9 T$ C7 D* n& F
          might happen when the global "ulimit-n" parameter is forced by hand.+ C. Y& y' v7 ~

2 A9 e* _$ E6 L$ l2 b! U     PD   The proxy blocked an incorrectly formatted chunked encoded message in- a. ^4 _; i3 X! \& k
          a request or a response, after the server has emitted its headers. In
% l5 p! ]! U+ B9 P          most cases, this will indicate an invalid message from the server to0 f) x" a# g0 j9 I; T
          the client. Haproxy supports chunk sizes of up to 2GB - 1 (2147483647' T7 J) x6 o6 R4 `
          bytes). Any larger size will be considered as an error.1 P! E+ ~' z! p6 k. T- O
8 C) d2 i3 ?+ X
     PH   The proxy blocked the server's response, because it was invalid,
# r( s5 A- ~7 N* D% x) c* p; J          incomplete, dangerous (cache control), or matched a security filter.
7 N! ~. [& v" y) [' w9 O- F! Z          In any case, an HTTP 502 error is sent to the client. One possible
; A) ^! _: d! T5 o2 l7 F1 `          cause for this error is an invalid syntax in an HTTP header name
9 H! e+ F# T: Y% ~; ?$ p          containing unauthorized characters. It is also possible but quite* f. y8 W7 O  C: T5 m
          rare, that the proxy blocked a chunked-encoding request from the4 x; r" I5 n. Q9 ~$ W( a2 c# h
          client due to an invalid syntax, before the server responded. In this
6 s$ c, T1 c8 N$ n          case, an HTTP 400 error is sent to the client and reported in the$ S" [( f7 Q0 H  z1 p! J
          logs.
% Q# B! y3 w; `' q# `0 S& Y1 P$ X6 g
     PR   The proxy blocked the client's HTTP request, either because of an/ m% F6 c/ ~- u# ^
          invalid HTTP syntax, in which case it returned an HTTP 400 error to
4 k9 q6 X- _$ t          the client, or because a deny filter matched, in which case it
) K. g3 g& r/ T( ]: S$ d          returned an HTTP 403 error." I0 G: R4 p7 n  }0 i/ {: w

' ^2 w& E  ~1 B7 c7 W2 Y     PT   The proxy blocked the client's request and has tarpitted its9 [: x8 q, |, [5 E/ P  _
          connection before returning it a 500 server error. Nothing was sent
. U& f' U$ g" G! C( Z: M          to the server. The connection was maintained open for as long as+ R- G9 g( Y9 _  X2 u: {) t: L' v
          reported by the "Tw" timer field." ]$ ]9 w% h* J  W, o2 H/ `, w$ i

% c% I6 ]1 k  i6 z  R% n3 a) G     RC   A local resource has been exhausted (memory, sockets, source ports)
7 s5 s/ q* D+ H" Y. e* S1 H* N          preventing the connection to the server from establishing. The error$ L0 l* U: x# _$ @3 [% h, @
          logs will tell precisely what was missing. This is very rare and can
! X( L; D+ @  q( a0 Q! e8 j2 r  k7 ]          only be solved by proper system tuning.2 Z6 r* N5 ^8 K$ j1 m2 Y

3 i* M; s7 W7 }, yThe combination of the two last flags gives a lot of information about how% ^6 t. e5 f2 T/ C
persistence was handled by the client, the server and by haproxy. This is very3 J  x0 ]0 O1 D: z! I8 d9 Q& I8 |# @
important to troubleshoot disconnections, when users complain they have to( V' ^) e! `$ s0 |5 w+ G6 L
re-authenticate. The commonly encountered flags are :
; p$ r: v# j) I# W* B3 V" N, E% ?) n2 a; K, d
     --   Persistence cookie is not enabled.# [0 G8 r  V8 n; {6 k7 f
0 D- ]  P. c: O: {3 f
     NN   No cookie was provided by the client, none was inserted in the1 [, L- p( |  S0 h3 ]/ X
          response. For instance, this can be in insert mode with "postonly"1 ]3 L. g$ _6 a2 J4 q& w" J' n; l0 t7 }
          set on a GET request.9 S) o6 y; G' T7 J$ _
" C" W/ g- Q8 X9 ]
     II   A cookie designating an invalid server was provided by the client,, [% n! n: [. F* O, o# A
          a valid one was inserted in the response. This typically happens when
  W) r, q( \: E: H0 S, w1 ?  z          a "server" entry is removed from the configuraton, since its cookie; w! s. |) x$ _1 s- U0 V) w
          value can be presented by a client when no other server knows it.7 W4 o/ ]$ n- |: q( ?

; I% r9 u8 s4 M* L" n  s     NI   No cookie was provided by the client, one was inserted in the- W( A* C! W8 {0 X* ^! i
          response. This typically happens for first requests from every user3 Q  r5 S( J+ l1 u! E
          in "insert" mode, which makes it an easy way to count real users.
# P& m5 U* O0 S+ c' F5 U9 n  G# q: N- j. Q) c
     VN   A cookie was provided by the client, none was inserted in the9 [" @* @2 Q4 w5 v% V
          response. This happens for most responses for which the client has
. E/ G2 k2 Z+ i* M% O# r          already got a cookie.7 C5 u5 F: V+ @

' ~$ X' K' F' p6 U4 M  s     VU   A cookie was provided by the client, with a last visit date which is
0 a, p, d+ ~! w3 x, x% m          not completely up-to-date, so an updated cookie was provided in) g9 y# U1 h) e# q  l  x7 a4 u$ s
          response. This can also happen if there was no date at all, or if
$ F& a! m2 Q8 U5 c0 `5 D$ ]          there was a date but the "maxidle" parameter was not set, so that the
6 Z, n" J: K! p4 P          cookie can be switched to unlimited time.
6 e9 e, L3 w+ G, l& j
0 Z7 O$ w+ u- `* W3 o+ X2 i! Y5 b     EI   A cookie was provided by the client, with a last visit date which is) {+ b* @; k* ]5 o5 ]+ n
          too old for the "maxidle" parameter, so the cookie was ignored and a5 }1 ~0 E! j9 `9 T# R; N
          new cookie was inserted in the response.' `9 [; j3 O+ h3 d* C

0 g( |/ s2 P! _* E  U  o& a& r$ |     OI   A cookie was provided by the client, with a first visit date which is4 H/ e2 V0 ?4 Z
          too old for the "maxlife" parameter, so the cookie was ignored and a
# Z8 c7 [% H% v+ A: b( G9 a! j          new cookie was inserted in the response.8 F+ Q- T' k9 `( x0 C# |. f
' t2 a2 A) _- X6 @8 j! y. p
     DI   The server designated by the cookie was down, a new server was6 W. N) Q: F' U+ z: }5 W8 z! S5 ~
          selected and a new cookie was emitted in the response.: Y) Q. ?) w: q. n
' _4 a$ @2 U& L5 n
     VI   The server designated by the cookie was not marked dead but could not
2 x! Q4 {/ o0 ?' @% q0 I# B; W: `/ w          be reached. A redispatch happened and selected another one, which was
; _8 a. Y0 i. ^& a& N% [& e          then advertised in the response.' {7 M0 u+ V9 l' N$ m

' |! ]4 {- m/ R) _# \$ I8 K5 E% E2 {+ U
3 o9 M3 y7 \+ `& \8 m8.6. Non-printable characters
+ b' E0 R& R" N$ S6 q- D  ^! C-----------------------------2 t( {; c# Z7 ~1 e0 ?9 z6 \
' l/ u: m+ p( b: G; [, g* Q4 e
In order not to cause trouble to log analysis tools or terminals during log
' T1 z: y' F7 Lconsulting, non-printable characters are not sent as-is into log files, but are
1 n5 |* g6 r. O6 V4 Q8 Z  F6 Uconverted to the two-digits hexadecimal representation of their ASCII code,
3 S  ^  X5 M8 E) q" Gprefixed by the character '#'. The only characters that can be logged without: T, R" n% S9 J" D1 e, _. B
being escaped are comprised between 32 and 126 (inclusive). Obviously, the8 z5 F9 z: }. p$ K% `( O
escape character '#' itself is also encoded to avoid any ambiguity ("#23"). It# O) c( e" }5 H) h
is the same for the character '"' which becomes "#22", as well as '{', '|' and9 G! o9 W: d9 [, r# u6 j
'}' when logging headers.
6 i8 b( a5 v$ I4 n, i
% P& K+ H3 k- O9 {% S( TNote that the space character (' ') is not encoded in headers, which can cause' A' }5 p0 J& ]5 M2 T2 q
issues for tools relying on space count to locate fields. A typical header
' S) n. s3 I6 tcontaining spaces is "User-Agent".
2 V- Z/ {  i* k& p
8 c) n$ S2 c% X* w! ~4 LLast, it has been observed that some syslog daemons such as syslog-ng escape
+ `6 |9 l2 t$ Q1 s4 d6 x* ?3 [the quote ('"') with a backslash ('\'). The reverse operation can safely be
* X8 X& L3 o, ~performed since no quote may appear anywhere else in the logs.
- g# _) a8 o. l  w1 T7 w! F' m+ R# Q$ i7 N' d6 W: p
8 y% |' \$ g# Q* Y5 H2 n! Q
8.7. Capturing HTTP cookies5 W. K7 a3 g7 z  F+ T
---------------------------; p3 K: O  M" V5 h
6 e' h& n4 L9 Y
Cookie capture simplifies the tracking a complete user session. This can be
. t$ t: V& |5 Qachieved using the "capture cookie" statement in the frontend. Please refer to3 a; g9 O+ s5 ?, c$ Q6 e
section 4.2 for more details. Only one cookie can be captured, and the same
0 A3 {4 g2 P3 }8 v4 \( kcookie will simultaneously be checked in the request ("Cookie:" header) and in
* m5 q! T1 B+ @/ b/ w3 h8 Zthe response ("Set-Cookie:" header). The respective values will be reported in; ]: K4 T9 ?2 k7 V2 ~, J' |
the HTTP logs at the "captured_request_cookie" and "captured_response_cookie"
$ O* ]% N4 m2 L  a, Vlocations (see section 8.2.3 about HTTP log format). When either cookie is
! f5 W9 ^, m* y* p5 Jnot seen, a dash ('-') replaces the value. This way, it's easy to detect when a( P7 F9 U: j( K- N( N
user switches to a new session for example, because the server will reassign it
- {4 H( s! h$ X; Y) Ba new cookie. It is also possible to detect if a server unexpectedly sets a
4 i: {  {4 g7 ]* P+ jwrong cookie to a client, leading to session crossing.
) i1 n/ m9 k$ }! N2 b; j$ e9 \& ^8 p" y4 ]% Z0 E' w. G. a5 h
  Examples :
  E6 o2 B' ~5 {: H0 A$ B( }9 c% k$ c        # capture the first cookie whose name starts with "ASPSESSION"
# L; i( m& P( N. r2 N1 n& ?        capture cookie ASPSESSION len 32& G' J+ l0 r! x, H

: p. ]7 n% g$ t6 g        # capture the first cookie whose name is exactly "vgnvisitor": G0 e+ [5 w8 T9 m2 K: [
        capture cookie vgnvisitor= len 32
% o& h9 N5 D% r& r6 {$ N; _# O; ~2 O/ c+ X0 X4 V) R0 r
1 \, ~3 y; R/ @+ ^# U5 P
8.8. Capturing HTTP headers
* J7 y. p! n) N! {" ^  p# M, n5 o, ]---------------------------8 C5 _+ ]' i9 U! T

/ L& w% y) b# B+ b% M3 mHeader captures are useful to track unique request identifiers set by an upper* O! y: x' Y, ^0 Y6 Q% Q
proxy, virtual host names, user-agents, POST content-length, referrers, etc. In! F$ _8 w  X& B$ c3 Z1 ~
the response, one can search for information about the response length, how the
; ?( z8 m8 b* |5 ?4 {" Qserver asked the cache to behave, or an object location during a redirection.
$ f4 N. N$ j* I/ y% V0 w- q. R; |$ t0 R4 N1 a6 i
Header captures are performed using the "capture request header" and "capture, R5 f/ o8 l9 Z0 l3 ]* M
response header" statements in the frontend. Please consult their definition in
& r% |: Q) U6 M! ~$ @6 Fsection 4.2 for more details.( t7 s6 M0 f9 h  C

" @- D0 ?% }; T; JIt is possible to include both request headers and response headers at the same; |) i  z1 X* N# U
time. Non-existent headers are logged as empty strings, and if one header- _, L, V1 ?( v: K$ L) Q
appears more than once, only its last occurrence will be logged. Request headers
: _" R9 m  d' lare grouped within braces '{' and '}' in the same order as they were declared,8 s# C+ ~/ b6 f( Y1 z/ I1 {
and delimited with a vertical bar '|' without any space. Response headers( d8 O! o3 x5 I
follow the same representation, but are displayed after a space following the
2 c, F) }8 Q$ [" Q4 o  V7 grequest headers block. These blocks are displayed just before the HTTP request1 k! t( \! y+ N2 D5 Y. X
in the logs.
% U- s* m3 j2 _- r$ C+ {  z4 U4 Q% j! B7 h: p! j& j3 S
  Example :
2 R, J) W- z  P: z% f        # This instance chains to the outgoing proxy
' N! J3 I3 P5 A  Z+ e/ s1 X        listen proxy-out
  G. {" c5 k% ]% K! t7 G5 G) x            mode http
+ S9 ^6 i1 ?* N4 H9 n# G            option httplog
- Q1 W3 b/ v; W- W& E4 D            option logasap0 K+ \( @. v  p; g1 R1 r
            log global
! }8 f6 |* r1 m: j            server cache1 192.168.1.1:3128
. |. C4 S. G; _/ q' ^5 y' ?8 n$ u  M. Z) X+ Q+ ^; c
            # log the name of the virtual server4 O7 Z: k6 ]* |3 T) z
            capture request  header Host len 20
! ]- e3 q- Z% q" K  B6 U+ w4 W: j* U& q5 o4 m
            # log the amount of data uploaded during a POST
4 P6 y# w5 `# E) B, }4 w5 @            capture request  header Content-Length len 10
9 P0 x( V* v5 H0 @' d) V9 w/ ^9 z* ~4 ]6 D8 V. m9 ]* G. _
            # log the beginning of the referrer
6 Y1 Q% {8 D' O* ]9 {            capture request  header Referer len 20; o" t- o" t' C5 e. C" A0 I( j

: z( Q3 m, E* Y' V# d            # server name (useful for outgoing proxies only)
& b( p# g5 m* S5 Y1 h& H            capture response header Server len 20
# T) e+ X& ^; Z' I* `+ |
; o$ q! {& P! e! `            # logging the content-length is useful with "option logasap"
' W& q* s) J9 R9 ]& R- l            capture response header Content-Length len 10
5 M' |$ {$ z( f+ P9 ]& ]3 Q6 X* Q! N2 G7 f
            # log the expected cache behaviour on the response/ ~" N" u' z1 y2 ~" Y! \- s
            capture response header Cache-Control len 8
# f! s3 F  r: \% {9 d  j3 k
6 y# o) X0 K2 @# ], e& W            # the Via header will report the next proxy's name: J9 e% z$ y+ |% `
            capture response header Via len 20- m7 N' H( G  ]( l

  Y4 B; \' L6 i, }            # log the URL location during a redirection6 j, V) ]0 A+ O  z' u
            capture response header Location len 20% O$ J$ D* u5 \4 K: t
: p, U: F) b! y" x& k5 Z1 x2 @
    >>> Aug  9 20:26:09 localhost \8 J3 c, }+ x8 D; _2 j' M
          haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \! K6 ?1 M  f4 y. F2 a. e
          proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \# [8 M, U1 n! ~
          {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \
' }. K' f% l# |3 R          "GET http://fr.adserver.yahoo.com/"
) j  ^7 Y) Q  H# L4 S$ g+ ?1 E- U2 P1 t) b9 F# z
    >>> Aug  9 20:30:46 localhost \
* j% J2 a) }" T  A: W5 [          haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \
) [* ^' n7 k' k2 W9 A( _          proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \1 ]1 }. k2 K" D' u5 z. t( ^. Y
          {w.ods.org||} {Formilux/0.1.8|3495|||} \( ?/ T7 O1 t; S0 n( ^. E& z
          "GET http://trafic.1wt.eu/ HTTP/1.1"
* M1 X' Q; _+ i( }, A
. x. C& a, ]- j    >>> Aug  9 20:30:46 localhost \  E6 x7 X4 q( F
          haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \$ \  K- z. v0 }) K; U  h" ]
          proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \
, K& C. y) U, T: N  r' U( f; L          {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \
- }/ e0 n4 m5 q; U0 `+ E" U3 l# k          {Apache|230|||http://www.sytadin.} \
; R/ Z% f- C; |2 t( a          "GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"
) U% i7 t* k( R) Z9 `2 U7 ]4 Z9 U, \8 P4 c* B9 k" B! g" X
- e# ]8 S% h) k" C  N1 Y( T: W. z
8.9. Examples of logs
( Q$ q( c( C* r5 y---------------------6 i7 [4 v8 A+ r& \( J7 v1 a
$ H* b$ W3 V+ F% I
These are real-world examples of logs accompanied with an explanation. Some of
/ s6 z  P1 R5 B" o: _them have been made up by hand. The syslog part has been removed for better: ~+ p# s* Y$ S2 |
reading. Their sole purpose is to explain how to decipher them.5 a: o* d5 x' g
+ Y: Y5 o7 t# L' f: D+ N
    >>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \/ y9 [* \/ ?0 L  J; y9 v  U" b
          px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \
- M; I! z: v2 q/ W          "HEAD / HTTP/1.0"
. Z- e) a4 e5 Q3 O* H' T  s: w
( E8 `0 z) C; |8 f    => long request (6.5s) entered by hand through 'telnet'. The server replied
# h* K! |1 [+ @, u3 a" Y) f       in 147 ms, and the session ended normally ('----')$ b. u; k! _) z
9 }" }" {* s& `6 ~! c# A
    >>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \" u! [* R+ h! }4 q
          px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \# [* x5 T7 e& t! ]: L
          0/9 "HEAD / HTTP/1.0"
; }4 r8 a& i! p' J5 `- a) O. U: w8 i- R: Q3 a3 P6 P% ^
    => Idem, but the request was queued in the global queue behind 9 other  o/ T  o. V6 O( ?6 [+ t; d4 L( d
       requests, and waited there for 1230 ms.  ^& u% C6 F/ n- N. G( h# Y
% O. v& V/ ?4 m- w
    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \
5 v. d7 _& }0 L4 G# F# v; N          px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \7 {" {& L1 U4 h, f$ Q' Y3 o
          "GET /image.iso HTTP/1.0"
' J' k6 T; i6 m5 @0 e/ L1 l0 |! u
    => request for a long data transfer. The "logasap" option was specified, so
: l- h9 j: m6 Y       the log was produced just before transferring data. The server replied in
& ^, n4 G& I: B) {4 q6 c0 j       14 ms, 243 bytes of headers were sent to the client, and total time from* [! R5 K" v' ]& Q
       accept to first data byte is 30 ms.; b" j, [/ z9 B! n
# J6 T6 `) b3 l+ M1 }; K  o
    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
5 z4 g! }9 p2 A* q; t: C! [2 I          px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \2 A7 E9 ~, x! @
          "GET /cgi-bin/bug.cgi? HTTP/1.0"
3 L- }' [; S2 `8 I/ f
8 v6 y; L# g4 ?2 C" b( L    => the proxy blocked a server response either because of an "rspdeny" or' p. I' L* A) }  c! Q; _4 _
       "rspideny" filter, or because the response was improperly formatted and: |4 u# k+ m- G
       not HTTP-compliant, or because it blocked sensitive information which( T( l' B) l' {, ?$ _
       risked being cached. In this case, the response is replaced with a "502( u3 ?& G0 O6 @. e5 Y
       bad gateway". The flags ("PH--") tell us that it was haproxy who decided. R/ J# Q' b' g& `  V2 i
       to return the 502 and not the server.
5 q$ K4 t! ^  ?  s7 c. H" D$ Q: S, F* B' B/ a
    >>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \& y  c/ k9 H9 e% C' [! k( p3 R
          px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""% E; S: \2 \/ j7 }. n$ s/ t
, x+ h4 X8 `5 X% N
    => the client never completed its request and aborted itself ("C---") after% R& A" W' `( f- p
       8.5s, while the proxy was waiting for the request headers ("-R--").5 D  `' L/ P, f" d3 E" ]
       Nothing was sent to any server.
$ p/ r0 w) R# M5 |5 {9 p+ _
3 u! Q8 H2 Z6 |% T    >>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \
2 s; Q4 j1 o. E  g' G5 D1 ^         px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""- l+ k6 d( f$ g( |$ @

7 a/ e: c  s, t0 Y1 l( g; m% p0 P- O    => The client never completed its request, which was aborted by the8 s8 _! D& R5 ~! C9 U3 |
       time-out ("c---") after 50s, while the proxy was waiting for the request' j7 a7 ]- M7 X* }' ^
       headers ("-R--").  Nothing was sent to any server, but the proxy could
' M4 B9 |1 m+ L6 @       send a 408 return code to the client.% _/ e% ]: d/ K9 g+ ~  u9 w# ?

7 |. `5 s$ Q1 X- V    >>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \
1 P4 U/ q0 z7 d& ]: t4 n/ A          px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
$ I( U' I1 b! Q% H/ m# Y! b& g5 C* e& X4 M9 t5 o
    => This log was produced with "option tcplog". The client timed out after* k' ]) S8 y/ y) w! R
       5 seconds ("c----").; ^" r- l. X; C
+ J4 g1 c8 |8 k6 s. @5 h, o
    >>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \) W8 G7 D4 S4 e
          px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \1 v  a" ]8 Y! K( @, U
          0/0 "HEAD / HTTP/1.0"
' V1 j- A7 Z/ g& C5 l2 }
  {- a- ]* Y  w( b- _7 o    => The request took 3s to complete (probably a network problem), and the
' T+ x0 n0 V. m8 b6 N! l       connection to the server failed ('SC--') after 4 attempts of 2 seconds
( Y0 Q7 o, Y, b6 R; }. _! m       (config says 'retries 3'), and no redispatch (otherwise we would have& ~5 D7 s# G. B, K$ v  r' T
       seen "/+3"). Status code 503 was returned to the client. There were 115
5 p+ Z- @4 W& d$ l. u& \* @0 u       connections on this server, 202 connections on this proxy, and 205 on
6 h: r2 U; N% y' {9 `5 B       the global process. It is possible that the server refused the
4 }' i' E3 \" h0 R- M0 c       connection because of too many already established.% Y* O% c& W+ D; C" D
, z7 Y7 F3 S# t8 J6 I. y
2 I$ v) j: C9 n3 j$ ?
9. Statistics and monitoring, b. U- r4 I0 y' A
----------------------------
3 E  o2 c* p$ E0 d0 n
5 M: x8 z# G2 `5 b2 U$ v. HIt is possible to query HAProxy about its status. The most commonly used
0 }( A! h! R; U7 A4 C$ M! Ymechanism is the HTTP statistics page. This page also exposes an alternative* y4 s: T: ~  `: f, p
CSV output format for monitoring tools. The same format is provided on the- T: m' b. D1 ]/ k1 u
Unix socket.
6 e  m) E7 B# L+ s1 e1 t
. C# }5 M, V  W# L2 H* X5 ~6 }$ E: b. }* @
9.1. CSV format  D+ n2 w* q5 \# c3 S" Z
---------------# G5 X& G4 d9 F8 B- i0 s0 j
+ s' j3 |  A0 J6 g0 Q$ W& J
The statistics may be consulted either from the unix socket or from the HTTP3 t% p& Y5 z3 D; s5 @
page. Both means provide a CSV format whose fields follow.
$ v+ @  X( @) b) \
( r% T0 b% f& h: o5 n" ]$ S$ u  0. pxname: proxy name
. t$ [. _+ N# Z$ V4 ]  1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
+ @2 r) l! [( S" N    for server)- i9 K' ]. ^2 B  C0 C% g. d
  2. qcur: current queued requests
8 X2 e: Q2 f1 X  3. qmax: max queued requests
# Y5 w' ]& k+ |& J2 j3 y  4. scur: current sessions
+ q  |  A) H3 N; h% q  5. smax: max sessions! K# ], ~, c- }& T: K
  6. slim: sessions limit+ A4 R! W/ O  w; g% H! q
  7. stot: total sessions
8 k- ~3 N0 P6 X& Z; _  8. bin: bytes in* O# ~1 s* Y& ~7 x" ]1 Z
  9. bout: bytes out' |: P8 _' a, P, F
10. dreq: denied requests
* {) p/ k9 ^: s" E, [$ J 11. dresp: denied responses
' Z" `8 u. {3 \+ U 12. ereq: request errors
. N3 \& |/ E' B' T 13. econ: connection errors  |7 R8 C- n0 k5 s7 h) z: q4 d
14. eresp: response errors (among which srv_abrt)
! x! w. s7 O/ U$ ` 15. wretr: retries (warning)( y! W: |9 P, |. j2 t
16. wredis: redispatches (warning)
% Z- z* {2 z0 ]# v3 L! g6 A% g 17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)- _  ]) Z6 n$ v1 B5 A# A' A
18. weight: server weight (server), total weight (backend)5 k' J8 |' B, }- Y3 a! G
19. act: server is active (server), number of active servers (backend)* Q/ |8 t- p1 s! G4 n7 b; D  d" p
20. bck: server is backup (server), number of backup servers (backend): M3 {! J  S3 f) W$ |
21. chkfail: number of failed checks
* P: e1 J# A& H9 b 22. chkdown: number of UP->DOWN transitions
- V, X4 p% e( D# r* j 23. lastchg: last status change (in seconds)
8 u2 \7 a0 `, ~0 q6 {: E 24. downtime: total downtime (in seconds)
. j. F' P. Y/ t" Z7 ^ 25. qlimit: queue limit
; n! w; v3 [  Y# y9 `8 ^ 26. pid: process id (0 for first instance, 1 for second, ...)' b  ?4 U9 G% e8 {( R0 ]) H
27. iid: unique proxy id9 z* j/ V8 E, ^, H5 J% J
28. sid: service id (unique inside a proxy); t, ?* A! K! Z9 e* M% f
29. throttle: warm up status
! p) t0 G% W9 J" ?3 G# A 30. lbtot: total number of times a server was selected
( }# A: Y2 p: \0 ^3 I$ K& Z) Z/ ] 31. tracked: id of proxy/server if tracking is enabled
9 R" q5 |: b* X1 W; D- ?+ ` 32. type (0=frontend, 1=backend, 2=server, 3=socket)7 c+ Q7 Q; m$ R2 j
33. rate: number of sessions per second over last elapsed second
) e* N: Q6 w5 J  a1 j7 ` 34. rate_lim: limit on new sessions per second
( B1 I6 Q  F4 j8 f7 q# A* k 35. rate_max: max number of new sessions per second# |0 X8 a7 e( \6 R+ `/ g0 e7 c2 z4 p5 E
36. check_status: status of last health check, one of:
" L, m0 q; ?1 t1 K  {2 B( I        UNK     -> unknown
5 X$ w- p! N0 Z& ^3 i7 D4 i+ e        INI     -> initializing
9 f& w0 H) S7 t7 k, b3 \/ z        SOCKERR -> socket error5 x( m6 b& Z" _6 H/ [. Q
        L4OK    -> check passed on layer 4, no upper layers testing enabled6 ?9 c  W6 D3 j, j5 h# }! U1 [
        L4TOUT  -> layer 1-4 timeout& {' Y$ d1 o7 Y8 [* t7 ~! M$ e% L# C
        L4CON   -> layer 1-4 connection problem, for example
2 w5 ~" m7 b7 Z$ m% N% z0 \) \                   "Connection refused" (tcp rst) or "No route to host" (icmp)) f" k" Y; b; F* v1 H+ A
        L6OK    -> check passed on layer 6  U8 E4 Q) h- g1 |' R) c
        L6TOUT  -> layer 6 (SSL) timeout
3 B( Y' ~# T6 B9 ^: i, q+ B' M        L6RSP   -> layer 6 invalid response - protocol error
. m! o7 i9 b: R3 o2 T. _+ B3 H        L7OK    -> check passed on layer 7
4 E9 Q( B, ~! D, ~% ]# e; V        L7OKC   -> check conditionally passed on layer 7, for example 404 with" _% |! I1 M4 l; T- w- \5 e
                   disable-on-404: s  {' S; d3 S$ z
        L7TOUT  -> layer 7 (HTTP/SMTP) timeout% n! A7 b, y; I4 c, e3 O
        L7RSP   -> layer 7 invalid response - protocol error0 x/ r5 i% @6 ?
        L7STS   -> layer 7 response error, for example HTTP 5xx% u/ z4 U  y- r( C: N7 S7 X
37. check_code: layer5-7 code, if available
" z8 V3 ~- Z3 r( Z9 I 38. check_duration: time in ms took to finish last health check
! U/ y( v6 \$ A  X* v 39. hrsp_1xx: http responses with 1xx code
! V9 S$ |+ L# i# o# Z+ S 40. hrsp_2xx: http responses with 2xx code7 n- ?1 ]' H4 f0 ]' T6 F- o
41. hrsp_3xx: http responses with 3xx code
* h  A$ R9 `) u5 K4 V 42. hrsp_4xx: http responses with 4xx code
9 K, m& i& F: _" x 43. hrsp_5xx: http responses with 5xx code; Q" O# K. N9 k9 q: v4 S2 G7 y
44. hrsp_other: http responses with other codes (protocol error)
/ `" L6 r- q/ Z4 R) V 45. hanafail: failed health checks details
7 \7 p! Y  V- ~, j0 d 46. req_rate: HTTP requests per second over last elapsed second
& u; Z' J4 U( {% r, _ 47. req_rate_max: max number of HTTP requests per second observed
4 d8 E, r8 c0 Y# P0 c: O5 t 48. req_tot: total number of HTTP requests received; o" C0 Q; r, R  ^  f, G4 ^
49. cli_abrt: number of data transfers aborted by the client
/ }; N" e7 T- `- o 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
: R5 a* N/ I1 _' T0 T* J, j. I9 k1 {/ Z+ v2 I4 |
6 j3 Q# F5 x- O* H" F6 \! o
9.2. Unix Socket commands
9 N4 E8 j5 g! H1 E7 B-------------------------
2 V  L7 f7 N1 ^2 L3 d
' {! t2 ~- C, H0 h" UThe following commands are supported on the UNIX stats socket ; all of them
0 _5 o5 A& {) w$ C4 y8 w  [must be terminated by a line feed. The socket supports pipelining, so that it
" `1 E2 h& s4 V- I+ C7 Iis possible to chain multiple commands at once provided they are delimited by
+ S! c/ C# r' o& Y- ua semi-colon or a line feed, although the former is more reliable as it has no( t4 R, o2 ^7 t6 K
risk of being truncated over the network. The responses themselves will each be, F  @" g7 _# {7 ?5 w5 \  i
followed by an empty line, so it will be easy for an external script to match a
) I3 z7 _  d+ x6 X% F. U. ^given response with a given request. By default one command line is processed6 }& ^+ k3 H( i( V9 W5 C7 L0 j  m
then the connection closes, but there is an interactive allowing multiple lines- ]8 ?) R" r! \" y
to be issued one at a time.
! J, N1 P3 l/ z6 I: z, X
% L& z& F; N+ YIt is important to understand that when multiple haproxy processes are started
5 o  Y/ U6 i3 @5 q2 q& r0 d2 Uon the same sockets, any process may pick up the request and will output its
# t8 Z! @  [) k4 Q3 zown stats.! d+ Y7 y, J8 u# B

8 t, n; N! V" T6 G5 Y7 H- i- Yclear counters0 R6 P4 E' `' c
  Clear the max values of the statistics counters in each proxy (frontend &
  N7 i- }/ f8 ?1 {6 D* y6 O; T9 x) K  backend) and in each server. The cumulated counters are not affected. This
* V6 Z( g2 @+ N$ C+ i( ^$ [# Z# t  can be used to get clean counters after an incident, without having to
! v5 e- X: n2 v2 `% e7 w$ H* o% F  restart nor to clear traffic counters. This command is restricted and can% f2 y0 A& W& ?+ D' p; T; H1 M% S
  only be issued on sockets configured for levels "operator" or "admin".
8 N: w6 t- R4 X' V* A% P1 t) Y2 U! Q! Y4 y5 _2 }  P" M- b6 B
clear counters all
7 |8 E: j/ |3 V! R) Q8 m  Clear all statistics counters in each proxy (frontend & backend) and in each$ n1 v; g, x! C
  server. This has the same effect as restarting. This command is restricted7 @. {# D( z& J4 k# Z# c4 G
  and can only be issued on sockets configured for level "admin".
9 E- S* I$ _7 r+ r8 u1 a
# W9 q8 ?7 w. p+ vdisable server <backend>/<server>
( c* M' k7 z6 E9 N3 W  Mark the server DOWN for maintenance. In this mode, no more checks will be8 Z  L3 E3 g  d% Q  M* L
  performed on the server until it leaves maintenance.8 g8 l, B, g$ x: n" v
  If the server is tracked by other servers, those servers will be set to DOWN
; ^' N7 G6 G/ I  during the maintenance.
$ x+ e1 B+ t$ z2 E+ @
- i% n. f  L, ^! `2 M! `  In the statistics page, a server DOWN for maintenance will appear with a8 U3 a5 ^2 i) P2 g9 H" [
  "MAINT" status, its tracking servers with the "MAINT(via)" one.9 I! U. B# \) D2 E" B, o; O
. W0 k/ G% b7 W$ x/ a
  Both the backend and the server may be specified either by their name or by
; g' y7 U  E: y  their numeric ID, prefixed with a sharp ('#').
0 z& J+ C/ U3 r- ?1 }, C5 G7 |( ^3 J
  This command is restricted and can only be issued on sockets configured for
' n2 z. B" x# }, z8 \2 |( a  level "admin".
4 [$ `- c& }  Q5 g: u" Y
7 x" R7 k( z/ q+ [. B7 v* I) kenable server <backend>/<server>
6 a  y( H. D9 b2 G3 R/ s' e; N- t  If the server was previously marked as DOWN for maintenance, this marks the
. e" A3 t! Y' f. o$ i& \( C  server UP and checks are re-enabled.5 X" d0 U6 G& K2 }: m& T

8 F% K5 i5 Z' N( E- @  Both the backend and the server may be specified either by their name or by
& g# O5 n$ y- H0 t" {- {' R  their numeric ID, prefixed with a sharp ('#').
4 j9 V6 [* r2 y/ G5 l$ Q
8 X) W( I3 ]' t* I3 F% G/ r# }  This command is restricted and can only be issued on sockets configured for
- b  x; g+ s$ ~" g  S  level "admin".; |: {4 H7 }8 F1 C  [1 m0 E

9 l* b. O7 ^2 Y) O$ S- E5 q$ Sget weight <backend>/<server>
4 u3 _$ E& n) f1 {, Z  Report the current weight and the initial weight of server <server> in
. M  M: m0 G1 h) @. {- `& ]% {* `( o  backend <backend> or an error if either doesn't exist. The initial weight is* H- a& N" T1 L0 {+ w
  the one that appears in the configuration file. Both are normally equal) L3 b( N/ Q  B, T2 X7 K2 B
  unless the current weight has been changed. Both the backend and the server
: n# m, K1 v! r: s  may be specified either by their name or by their numeric ID, prefixed with a+ h/ z; k/ M# [$ |# v5 X# W/ r% N% v
  sharp ('#').7 y3 x* n- I9 g, }& _- \
8 C0 I6 e  n) x9 v
help) \/ ?: k- s$ A6 D. H+ p$ `, E
  Print the list of known keywords and their basic usage. The same help screen1 f9 Q5 ]; B" H7 w
  is also displayed for unknown commands.
. m+ p2 t6 h! c
- e; j5 O0 o& _! Y3 F, A$ W& Q, Y4 Uprompt
0 b  z; q- R) {% M  Toggle the prompt at the beginning of the line and enter or leave interactive. O( c1 m$ \- V' s) O
  mode. In interactive mode, the connection is not closed after a command
6 b# l' K2 \3 c) F( H  completes. Instead, the prompt will appear again, indicating the user that5 @* Y. t# E" V6 F
  the interpreter is waiting for a new command. The prompt consists in a right4 d; t1 x! i+ x: V+ p0 i! ?
  angle bracket followed by a space "> ". This mode is particularly convenient
: X6 ~# {' j5 E0 V7 Z+ ?  when one wants to periodically check information such as stats or errors.  Q& b6 P3 m% N
  It is also a good idea to enter interactive mode before issuing a "help"
1 {+ t5 X3 Q" ^+ P( E7 [$ D# U  command./ k( s7 N( M$ G: p# y
5 u* }) L! {  J1 n& {* S( _
quit: y$ P" I. I1 @1 m
  Close the connection when in interactive mode.
* E! C1 e* K$ W( L" }3 ~, p% O+ W' {( C; Y& R
set timeout cli <delay>
: D  H3 d6 |9 Q+ }. i# J+ B6 O# P  j  Change the CLI interface timeout for current connection. This can be useful9 _- p. X* {+ [/ n
  during long debugging sessions where the user needs to constantly inspect
9 \! n" P4 e2 Z9 [8 X1 _  some indicators without being disconnected. The delay is passed in seconds.7 P% f  B. {% |) ]5 ~

4 M4 }! w1 t' _8 A, t9 `# Wset weight <backend>/<server> <weight>[%]* Z& u, S0 [, k& b
  Change a server's weight to the value passed in argument. If the value ends
* U+ C- X* B* [* ~. i+ j  with the '%' sign, then the new weight will be relative to the initially
0 q" O2 Q4 n# G4 E  L  configured weight. Relative weights are only permitted between 0 and 100%," h8 [- X9 b6 A, M
  and absolute weights are permitted between 0 and 256. Servers which are part
& B9 I. r$ Y) k: M- w4 V  of a farm running a static load-balancing algorithm have stricter limitations! @* D+ T; l: H( e; E" P! }" ^
  because the weight cannot change once set. Thus for these servers, the only
/ |3 N/ B6 E0 |+ [  accepted values are 0 and 100% (or 0 and the initial weight). Changes take
8 N/ `3 A8 W. g( ]" ^& t/ B* X  effect immediately, though certain LB algorithms require a certain amount of8 u3 ]& J+ {: s5 V  d! |
  requests to consider changes. A typical usage of this command is to disable
0 C: P' _" R! D1 T  a server during an update by setting its weight to zero, then to enable it  K9 ~+ d7 D( p$ t6 h
  again after the update by setting it back to 100%. This command is restricted
1 \. v  l3 w2 `( ~  and can only be issued on sockets configured for level "admin". Both the
0 G! p" ~, S8 X, O  backend and the server may be specified either by their name or by their
$ e; k3 L4 L- n! t' e# G) N3 J' q  numeric ID, prefixed with a sharp ('#').: i/ a' [# t+ t; H$ N  T8 i) S

$ X& b; `+ H2 f9 W% x) E7 `) dshow errors [<iid>]
& [. r4 b3 l' S- T1 e  Dump last known request and response errors collected by frontends and# U* O4 i. C7 w' v' j  L4 B1 z
  backends. If <iid> is specified, the limit the dump to errors concerning
4 E  x/ ]2 i; S* Y, H0 O  either frontend or backend whose ID is <iid>. This command is restricted
. C+ q1 B. V7 ]  r4 ~; R  and can only be issued on sockets configured for levels "operator" or5 I* T6 c0 P& r/ ?5 g
  "admin".4 |6 @3 B. J6 N& c) t& `
, o' r5 A$ m  y5 f7 b: p5 P
  The errors which may be collected are the last request and response errors( q8 n9 h  b' D" q; Q4 H
  caused by protocol violations, often due to invalid characters in header' [' l# F) [+ |7 s+ a" M/ C
  names. The report precisely indicates what exact character violated the
0 ]) L7 I0 l* z( y3 I* T' {) o  protocol. Other important information such as the exact date the error was
2 J% \* D& m& L0 V8 @* M, ]  detected, frontend and backend names, the server name (when known), the9 l1 Y' {6 a! e" m
  internal session ID and the source address which has initiated the session( ?8 H% ]% `) ^2 w2 K5 a
  are reported too.
4 ~2 n1 U& q* r' U
" c8 |' q$ o  d% c3 Z  M5 Y) u" @1 c  All characters are returned, and non-printable characters are encoded. The
. R1 K+ L7 Y  r0 R+ F% B  most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one
: ?3 P2 r9 c8 W! [  p  letter following a backslash. The backslash itself is encoded as '\\' to2 E% y" M7 l  [, T2 i8 G
  avoid confusion. Other non-printable characters are encoded '\xNN' where6 ]0 }' t, s0 q
  NN is the two-digits hexadecimal representation of the character's ASCII  A3 H, p$ A: l  h/ v
  code.5 F' a; J/ I9 E& N
7 W* g8 ]. ]' E
  Lines are prefixed with the position of their first character, starting at 0
5 h/ @/ l! v" j& w/ g  for the beginning of the buffer. At most one input line is printed per line,
8 }, t. g$ L3 g$ U3 s7 [  and large lines will be broken into multiple consecutive output lines so that% M9 R8 W9 K3 P7 A
  the output never goes beyond 79 characters wide. It is easy to detect if a/ Z$ L' Z1 b9 g8 K) r0 P: w
  line was broken, because it will not end with '\n' and the next line's offset
; i6 |! [" J# _" j4 O7 ]* K$ ~  will be followed by a '+' sign, indicating it is a continuation of previous
' N& x; v: v% E2 {, ^3 ~! I* Y  line.8 n$ L/ `6 V: o3 \" r

" Z% n# l. o* Y4 d  Example :) s( U- _& D5 f6 P( \
    >>> $ echo "show errors" | socat stdio /tmp/sock1
) {9 h+ Z) Z5 X2 C        [04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response
$ P& n! T* M' d4 \, z8 M& b          src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)
6 x% y& h* Q) a4 w7 G          response length 213 bytes, error at position 23:
4 r2 r- P' {: a: d& w; b& d+ ~( d2 |9 V7 @) Q" h0 n6 y0 f
          00000  HTTP/1.0 200 OK\r\n
, J8 w, @( f- F  v          00017  header/bizarre:blah\r\n( K" A! c. |  l) H1 V( r, c, C
          00038  Location: blah\r\n9 d& P5 T4 o0 q6 T
          00054  Long-line: this is a very long line which should b" x0 E* C4 `: [+ U
          00104+ e broken into multiple lines on the output buffer,. x' n: q# Z- b- t% [
          00154+  otherwise it would be too large to print in a ter( E8 Q0 R( R3 g
          00204+ minal\r\n
# a1 w# C: a$ y          00211  \r\n6 ]  Q% T# Z1 X8 z7 y

- e1 f) X$ N9 w4 _, i: G3 Q/ Y    In the example above, we see that the backend "http-in" which has internal
; `/ z8 T! D" q3 @& s. `9 \9 s    ID 2 has blocked an invalid response from its server s2 which has internal
& @, ^% }9 x9 P& |7 }2 v    ID 1. The request was on session 54 initiated by source 127.0.0.1 and1 s5 C( U6 b/ x
    received by frontend fe-eth0 whose ID is 1. The total response length was
9 J% ^4 x8 Q0 I7 w7 [) g- N    213 bytes when the error was detected, and the error was at byte 23. This
" `, A0 K2 o& @) Z    is the slash ('/') in header name "header/bizarre", which is not a valid
' k9 i" f& `/ ^5 C% u    HTTP character for a header name.
  b+ W6 s& B3 S9 \) M
- P1 v- m3 H7 ?4 h% i9 b  Hshow info' G% _  g) ^4 @2 s9 X: F
  Dump info about haproxy status on current process.
0 w& P% S1 B4 Y' ?9 _
; o6 K$ V9 R* Ishow sess4 B. c, n# H1 n- O4 d+ a7 ]1 g
  Dump all known sessions. Avoid doing this on slow connections as this can
* I1 _# {( A* |' B% [7 r2 b  be huge. This command is restricted and can only be issued on sockets
5 d0 ~' }) d- Q7 s  configured for levels "operator" or "admin".
/ ]# S+ ~2 L4 S  ^6 c7 D  k5 A' s5 Y& F1 c- R  `
show sess <id>
4 M% P% v% t! F  w: c0 a  Display a lot of internal information about the specified session identifier.
7 D. o* @3 f# u& i$ q1 [  This identifier is the first field at the beginning of the lines in the dumps& B: n" b) y2 c! A
  of "show sess" (it corresponds to the session pointer). Those information are
& G% v  ]2 S5 z+ a2 {5 m" a0 |- I) z  useless to most users but may be used by haproxy developers to troubleshoot a" Y/ s% B+ g4 Y8 f- b5 _
  complex bug. The output format is intentionally not documented so that it can
+ S" q( P0 S* |0 f! c2 y  freely evolve depending on demands.
1 N+ G/ o9 ^- f- j8 C
, ~( E$ M1 j% W- bshow stat [<iid> <type> <sid>]
2 I$ J' ~/ P, J5 }  Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
. O& @4 ]3 S1 H  possible to dump only selected items :7 {( h* T5 p. J8 Y/ o( j- C6 O% v
    - <iid> is a proxy ID, -1 to dump everything
" R- x6 e; Z; H' {  H! p    - <type> selects the type of dumpable objects : 1 for frontends, 2 for# c* j, O/ D; k' a9 o+ f
       backends, 4 for servers, -1 for everything. These values can be ORed,
7 \) V( Z" X% d* |( c       for example:' b4 `- m$ r! h% m- l
          1 + 2     = 3   -> frontend + backend.
: x" |  v2 N- q' Y0 _          1 + 2 + 4 = 7   -> frontend + backend + server.
/ B& t6 U3 R) V    - <sid> is a server ID, -1 to dump everything from the selected proxy.
$ J6 F. T7 S0 g6 P: j* K, X3 c' G5 a
  Example :6 @$ T9 d; o( n6 A
    >>> $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock1( i4 c3 K: X8 h% Z9 g4 F0 v
        Name: HAProxy! |) q0 `& X# C# y( y$ i- G4 A
        Version: 1.4-dev2-495 W% F7 }7 J$ {  J
        Release_date: 2009/09/23$ `+ n* Z/ V2 F# B* c
        Nbproc: 1; V- v! g5 ]* l9 f
        Process_num: 1
: H! ^7 e% M) r! f" C( E/ a        (...)
) _" _; t# L7 |( c' e, K, h( Q+ N) ^& |: |+ B; U5 Y
        # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,  (...)
: _) [5 x9 {, C- `6 o3 J4 b        stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
# F5 y3 c4 `9 V7 a/ H        stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...)
2 B- U7 P7 \; J) `! S/ b' E        (...)+ J$ K, D6 ~3 {( i; T' r5 W
        www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)& K2 q4 R) S. {( x# M

( M" d4 r( \8 V3 K# q5 F4 r        $$ d, T! F( r8 F  J  p# f/ l, ?
8 Y6 C& C- Y' C% [% e
    Here, two commands have been issued at once. That way it's easy to find
# d, y4 o% g: j- F    which process the stats apply to in multi-process mode. Notice the empty2 U6 X' ]3 P7 y) O& e+ G# \: c
    line after the information output which marks the end of the first block.( m5 b6 M- {9 M9 ?) G
    A similar empty line appears at the end of the second block (stats) so that
; ]7 C  B/ `) m/ ^+ r    the reader knows the output has not been truncated.
- C+ C) f1 U, L. }! ~/ o) R1 \; \9 c9 G

+ x1 z- Y* @- C/*
$ ^: x- u/ w" ^$ B$ F6 M4 B! r& l  O, V * Local variables:$ ~- c5 }" E  Q  P: x' A( k! Z
*  fill-column: 79. f) t7 |2 t. h4 M9 y3 s
* End:
6 U! _6 e6 ?6 _2 d- G& K& E' j' O */5 p2 l( c* ]6 \* P, B

1 J9 R) `" L! A: O. t0 x
* ~6 D3 A) ?# `: z6 u
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 01:43 , Processed in 0.058138 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表