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

configuration

[复制链接]

40

主题

29

回帖

471

积分

新手上路

积分
471
发表于 2016-8-17 21:51:30 | 显示全部楼层 |阅读模式
                         ----------------------
- D  `! X. V% l* F1 Y5 _                                 HAProxy
$ r/ ?& v9 p0 M2 S* Q! H$ D                          Configuration Manual
! g! N4 J' O4 }! Q' u) U. @                         ----------------------
$ i9 U( q0 g7 E+ f+ l) k' D; {; e2 c# o                             version 1.4.273 O6 |' Q' h" M( ^
                             willy tarreau
" u$ z6 C! i+ m+ u6 V: X                               2016/03/13
- ?9 {& R0 N4 x5 e2 \
& m. P) m7 c& b$ v4 L/ X' S1 e
4 E- a' V* I8 M* }( y/ d/ L  G2 RThis document covers the configuration language as implemented in the version+ ]; P1 r' }, M+ b0 k2 w% ^
specified above. It does not provide any hint, example or advice. For such
+ F3 T, ^3 q7 l% r8 kdocumentation, please refer to the Reference Manual or the Architecture Manual.+ O2 E! ?2 Z9 M, l" q, [9 i) a. [  ]( Q
The summary below is meant to help you search sections by name and navigate3 e# M1 U/ Y" m* ~4 R5 v% p
through the document., |2 c0 {( O$ E1 l
/ o; M8 B: @) x# O# r/ P
Note to documentation contributors :% t4 x; P! c1 F9 E
    This document is formated with 80 columns per line, with even number of
5 j0 N5 M# F' b1 a' S    spaces for indentation and without tabs. Please follow these rules strictly& @1 }5 }  G  |8 j, x3 a( Q0 d  v/ ?3 o
    so that it remains easily printable everywhere. If a line needs to be
+ S2 \! B0 ^  C; Q: o    printed verbatim and does not fit, please end each line with a backslash
/ U" i% j! P1 l" _( X) p    ('\') and continue on next line. If you add sections, please update the, ^& I2 c2 j8 {
    summary below for easier searching.
% b8 j8 B  w1 |4 k
  l- Q- e- S& W0 `. G7 @" @
: h' F) I" r# W5 @1 \# LSummary
0 ?0 V) G4 {- |' N. B! E, c-------. q' t" q2 o) Z4 |+ D
- K! K* S- _, A. y. @' C
1.    Quick reminder about HTTP" ^) W# A2 e+ T4 t
1.1.      The HTTP transaction model5 X2 [* [1 k! t4 a9 t* w  n
1.2.      HTTP request
- H6 V# A: ]; o2 W9 u1.2.1.        The Request line
. |) c' L0 ~( D) Y1.2.2.        The request headers
- u) f, g7 A& I' a1.3.      HTTP response# {# g' f4 q9 d  }
1.3.1.        The Response line
4 ?; Y- u0 {) W$ Q) C* v0 f* H1 E1.3.2.        The response headers
- [/ O7 [6 R) O' R- e- |" U
3 \( L8 W% G. H3 O: P. X2.    Configuring HAProxy
0 y9 p; y1 v% b2.1.      Configuration file format1 ?+ z% m% j# s5 e5 {
2.2.      Time format
5 c( o0 j: f, B7 k9 e/ ?2.3.      Examples
5 D; v7 A+ p6 E' o
" ?) k' v' W# m: l" w) f3.    Global parameters! ~8 C" W; r9 Z
3.1.      Process management and security
- z, Z5 v) w) T3.2.      Performance tuning1 M, G% H7 N! _! i
3.3.      Debugging8 M  n4 h$ G" s
3.4.      Userlists
! L; I- I. E2 ]; f' ]+ o( {$ n" F$ q" ?2 R% B8 u4 I
4.    Proxies) |! r. r' H3 Q4 C7 S9 u" V  p
4.1.      Proxy keywords matrix
) l1 U) m4 V+ s) |/ ~4.2.      Alphabetically sorted keywords reference4 H9 [0 H' b) B2 ^9 G$ d( z

) D- P; d: P3 s- t$ l3 S7 L5.    Server and default-server options- y; \" E- j+ }% c) G, G

9 z2 n% e  l: }/ D  B. V% p1 }2 n6.    HTTP header manipulation
8 \/ q% Z& H9 q, F* Q; y. F5 `- S( C. I+ S5 t
7.    Using ACLs and pattern extraction( n- x1 ?& _4 ?
7.1.      Matching integers
. s* ~- w9 G2 n1 X- R" i7 p7.2.      Matching strings
: k$ g8 Y' K3 e) i" b1 l7.3.      Matching regular expressions (regexes)" w  e, P0 ?2 v6 q
7.4.      Matching IPv4 addresses2 N! `  S4 O! Y- _7 s6 |3 \
7.5.      Available matching criteria3 F. A/ x" Y. V1 c( ?
7.5.1.        Matching at Layer 4 and below0 F3 d) x: R" Z0 U+ ~6 I9 z2 Z$ ~
7.5.2.        Matching contents at Layer 4* w; X  Q4 C. K3 {
7.5.3.        Matching at Layer 7
2 g, D% }: _' i$ z1 _+ m7.6.      Pre-defined ACLs: Q- E9 V6 c3 W; i
7.7.      Using ACLs to form conditions
" z' F5 j. \' x! ~9 {1 \( a; H6 g7.8.      Pattern extraction0 W/ t- _! F  E! P7 @* `2 M
- p% _4 t8 m5 T7 ~' B& v1 z
8.    Logging. m. D1 f/ ~% O
8.1.      Log levels
% ~/ ]5 @, y8 F" t8.2.      Log formats, F& E# x/ j6 E2 x: X2 `& r8 ^; m
8.2.1.        Default log format
4 w2 R& M- l- p7 ]. d# N" ]8.2.2.        TCP log format
( [1 C: l- L6 W/ _# J0 m8.2.3.        HTTP log format
9 Q3 O9 R* h- q* h, Y. K9 X$ A2 u8.3.      Advanced logging options8 a  |6 E0 X! a1 I; _( [
8.3.1.        Disabling logging of external tests
7 {3 ]2 T$ l4 l+ q! J5 ~8.3.2.        Logging before waiting for the session to terminate
! J3 i0 {' f) n* G8 Z8.3.3.        Raising log level upon errors
. r  z- w$ t8 o5 c0 p8.3.4.        Disabling logging of successful connections9 s" m2 n  c" M; ^5 m" o+ H
8.4.      Timing events# F2 X, |3 o7 n" K9 w9 m
8.5.      Session state at disconnection$ O) ^' t! ?/ l+ J/ }9 [' N# C! n
8.6.      Non-printable characters6 o: j$ X% O6 T9 {
8.7.      Capturing HTTP cookies
, u1 V5 n& ?- n3 z/ b  d8.8.      Capturing HTTP headers2 r1 C& y! T0 Y3 q* o! N
8.9.      Examples of logs
) D4 T$ d; C4 ^6 u
. d- T) q% j/ m9.    Statistics and monitoring
0 J! F( [* I5 m* ]. x5 _4 H9.1.      CSV format
. I/ f5 p' d  }$ C4 B( P( v; o9.2.      Unix Socket commands
; S; l4 E+ v) J7 x; L! H" M1 G; L$ z& U) a

' @6 ^9 b0 Z, u* E/ V. E9 Z1. Quick reminder about HTTP* S+ c0 S+ V5 ?, o! y
----------------------------1 k+ A: @- N6 @! m! F) L5 G

) F# r# L# o$ C7 H4 q0 |When haproxy is running in HTTP mode, both the request and the response are
$ k! d* L2 C( e+ vfully analyzed and indexed, thus it becomes possible to build matching criteria! S) K' M1 B; Q" ]6 s
on almost anything found in the contents." D. F3 r" Q0 u
0 Z' i% r/ m* L8 M. V6 ~  x
However, it is important to understand how HTTP requests and responses are+ [2 _0 y$ s& ?
formed, and how HAProxy decomposes them. It will then become easier to write
& R4 S4 F2 z1 Ncorrect rules and to debug existing configurations.1 c  `! h# i! g4 E9 \' s# B8 B; f
: }% \7 A1 J8 E9 T& v4 Y
5 V+ Y6 S. V) a% l: a
1.1. The HTTP transaction model+ {2 a, D- I: Y
-------------------------------
. |* }. t1 ~: Z- o5 |$ g0 a
) D, ]! N8 i5 sThe HTTP protocol is transaction-driven. This means that each request will lead) k+ n, _7 \' U7 D' s; @6 i
to one and only one response. Traditionally, a TCP connection is established
8 x- V3 a* p6 L8 h/ [from the client to the server, a request is sent by the client on the; y7 N$ g1 `- H, ^) E: I2 N9 F
connection, the server responds and the connection is closed. A new request
( w! W# K1 D5 {( ~$ t  w5 q) Kwill involve a new connection :
$ n' y) f8 c! U8 r8 [) D+ U' D: @2 X/ X0 t- F3 A& [
  [CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ...
. k! i+ U9 v' k& ?
) J. Z# g9 Z% W' ^/ A- i& o7 AIn this mode, called the "HTTP close" mode, there are as many connection
7 Y, B/ a" {! r  u4 Festablishments as there are HTTP transactions. Since the connection is closed
2 D% P( i/ n/ s% g2 s! g1 H* g# u! Wby the server after the response, the client does not need to know the content* N# h5 w+ S# f# ]2 I* m. t/ ^
length.; h, ?% g2 X; g' E- D3 ?. m
1 Y0 w0 H' K0 m% m( z- }+ l
Due to the transactional nature of the protocol, it was possible to improve it
* J- e- l' ?7 i( ?6 u& U) j% Yto avoid closing a connection between two subsequent transactions. In this mode
  i* f  R6 h; A' H9 ihowever, it is mandatory that the server indicates the content length for each+ p& O  y. r' A
response so that the client does not wait indefinitely. For this, a special
5 n. W  ]: k$ Sheader is used: "Content-length". This mode is called the "keep-alive" mode :/ O8 K2 s8 u( T; X( I3 C7 E

  h* d5 ?6 G; i6 N7 c' J/ b- {* n  [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ...  z# g* t/ v5 Y  @! B" |' k

' S" ~# U+ w4 {) R: V8 iIts advantages are a reduced latency between transactions, and less processing
4 I7 A) [2 J0 S% }+ Vpower required on the server side. It is generally better than the close mode,, r* k' E% x  I, A# s
but not always because the clients often limit their concurrent connections to
3 V5 R) V, |' J7 V4 d3 C, ta smaller value.
. u& i" T& S8 ~
4 Y. f7 O$ V6 Z" S9 YA last improvement in the communications is the pipelining mode. It still uses
- D8 h( r; ~" i# t# n* x( ]keep-alive, but the client does not wait for the first response to send the
/ |1 g# [9 k9 y3 dsecond request. This is useful for fetching large number of images composing a% u6 ?( v. I  M1 c7 S, U$ T% _/ T
page :, T* a( E+ s$ p

# U: f/ f) O1 u5 v1 ]( \  [CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ...9 O; n; c4 j7 [1 m2 v9 W. v# A
. e7 ?1 N/ d+ N
This can obviously have a tremendous benefit on performance because the network
1 {* E: ~* X/ R! t, ylatency is eliminated between subsequent requests. Many HTTP agents do not# |5 k$ C( l+ I
correctly support pipelining since there is no way to associate a response with7 R5 T$ B- ~+ Z  X
the corresponding request in HTTP. For this reason, it is mandatory for the
4 Q8 z( Q; M" _+ x! pserver to reply in the exact same order as the requests were received.
& G/ b9 p% e" z& R# |; a" d$ p, f1 N+ @' h
By default HAProxy operates in a tunnel-like mode with regards to persistent: Z! M" z, I( G) g+ M
connections: for each connection it processes the first request and forwards6 q) R8 {/ @9 q
everything else (including additional requests) to selected server. Once
( f* u% A) y2 Z' I0 M4 Hestablished, the connection is persisted both on the client and server
$ L  B! A, z; ]$ N+ x6 X( csides. Use "option http-server-close" to preserve client persistent connections4 b$ [# Q8 b7 Z, @+ k7 E) s; s
while handling every incoming request individually, dispatching them one after
3 ]0 N' w" H; ~another to servers, in HTTP close mode. Use "option httpclose" to switch both3 \8 G( o) H$ g7 S; B( ^& ~
sides to HTTP close mode. "option forceclose" and "option
& e9 @- g7 c+ chttp-pretend-keepalive" help working around servers misbehaving in HTTP close8 o1 S8 s# [, `7 X3 U! Q
mode.
" z9 Q6 O+ E1 v# [2 f9 M3 u9 ^4 I$ ?8 u# A( ^

& s# T6 z  S# I# C! v8 K1.2. HTTP request8 U6 [# R3 u% f* y/ K3 k2 a
-----------------
/ j+ u, Q9 N' `9 H$ _# v- ~8 M8 f, i1 ~0 d) }
First, let's consider this HTTP request :
  z: B8 ~2 O: r; Z: @+ ~& _+ E! }4 _$ b- ^: s' b
  Line     Contents. l' c" f$ f& ?6 U* g3 ^  T
  number
( M7 x9 e& ]1 S6 i$ v. Y6 |" b     1     GET /serv/login.php?lang=en&profile=2 HTTP/1.11 U! A' G1 }# {( `
     2     Host: www.mydomain.com
: W; X/ w: x9 k8 f( f     3     User-agent: my small browser3 Q7 W8 y# j& O: l
     4     Accept: image/jpeg, image/gif. v# M  \5 Y, ]4 b4 N4 b! T7 h
     5     Accept: image/png6 M( U. B/ u1 h. |% v2 z4 i* R2 q1 Q

% v* H; o; _$ U" a  O# G6 I) d) C* K  @" n
1.2.1. The Request line
  W5 P  r* s+ l8 V" i6 \-----------------------
' J6 T# M' `6 {% K% D# M5 k5 s1 o5 I6 q2 d
Line 1 is the "request line". It is always composed of 3 fields :9 }& f( N3 A( p/ e2 O9 U- [
, O* |( r4 V. N6 `; U/ _" p
  - a METHOD      : GET
7 k& s" j, y6 R# b) N  - a URI         : /serv/login.php?lang=en&profile=2  R  O+ G% b: H$ E" r/ d
  - a version tag : HTTP/1.1
. t8 D: ^% q" Z
* S2 u* i+ S; ~% ^2 d( yAll of them are delimited by what the standard calls LWS (linear white spaces),7 ?) H3 f2 ?, S& ]7 }4 J
which are commonly spaces, but can also be tabs or line feeds/carriage returns/ e% h. V! R+ i( t2 e7 Z. o3 O2 N
followed by spaces/tabs. The method itself cannot contain any colon (':') and
9 p* k, _% N1 I) w* d- Qis limited to alphabetic letters. All those various combinations make it) ^" t& k" r8 }2 i# r
desirable that HAProxy performs the splitting itself rather than leaving it to
# V) g! r& n/ A& f$ ?: A% Wthe user to write a complex or inaccurate regular expression.+ Z/ b/ P" ?/ V% t

, P1 Z9 e$ ]2 HThe URI itself can have several forms :
2 `  V$ T4 A5 P+ M3 k% v6 r
( \( z: ^0 }* D% `  - A "relative URI" :0 i) U' H1 e! o1 W/ R! Z

3 C2 Q5 {* b% W1 X3 l      /serv/login.php?lang=en&profile=21 e; k- y0 L* @' o# w, E( r' C
0 ]" u+ t% ~' a, o% G1 U1 w
    It is a complete URL without the host part. This is generally what is
. p  ~4 U' ]! G! L    received by servers, reverse proxies and transparent proxies.
& M) `0 y1 G- H' Q1 ]% w) \
' W4 m: B( L1 e/ C3 [6 n! e! Y  - An "absolute URI", also called a "URL" :9 H, v: _) W' X/ p
# V* G% [. L0 o  A4 Y! g: W
      http://192.168.0.12:8080/serv/login.php?lang=en&profile=2
* ~' q0 W3 `5 y0 d# t) T3 h+ Z) B+ o3 [/ G
    It is composed of a "scheme" (the protocol name followed by '://'), a host! m0 C9 t* X# Q0 f
    name or address, optionally a colon (':') followed by a port number, then
9 |. ~  w- D# |& a' j    a relative URI beginning at the first slash ('/') after the address part.4 Q# `( i4 v4 B! u* O) E
    This is generally what proxies receive, but a server supporting HTTP/1.11 b# f9 U; ~2 ~; U3 A" Q
    must accept this form too.
' n  F+ l, @7 q. s& D: N& @( [
8 |# g7 m4 d, l, U7 k1 p  - a star ('*') : this form is only accepted in association with the OPTIONS
, N: K4 V7 L$ R6 A9 w! t- H6 x    method and is not relayable. It is used to inquiry a next hop's% R, z! @7 `2 t' {2 D
    capabilities.
8 y4 ?" b: G- S, Z0 E  K( X# U3 n) @
4 E1 i6 N: \) D# A& |% e9 h. Q/ {  - an address:port combination : 192.168.0.12:80! a  f  y  l8 J$ J4 ?
    This is used with the CONNECT method, which is used to establish TCP
  n* ]+ k8 @/ {9 D6 \, l! {    tunnels through HTTP proxies, generally for HTTPS, but sometimes for, j5 J! x/ r/ b, H" G; S% M
    other protocols too.
! n1 p" O4 w$ q. C. L/ ^" J. t* c2 d+ ?7 O8 t+ h* N4 G* }8 _
In a relative URI, two sub-parts are identified. The part before the question
0 x& X/ U5 F) `9 }: nmark is called the "path". It is typically the relative path to static objects
  J7 r# A1 T9 }& zon the server. The part after the question mark is called the "query string".# v/ f' O( e# _2 |; ~1 }  a1 D: ]
It is mostly used with GET requests sent to dynamic scripts and is very. O; c! `# h, @' a$ G
specific to the language, framework or application in use.9 t, d& U( \& X

$ A0 e! V. m/ z
. Q, t  H7 R2 {; x  h4 I1.2.2. The request headers
! G& n/ O& L: R- Q+ z3 b& h--------------------------
: ~; [6 Z0 V8 ?5 m: J' G8 w2 R1 H% c4 a* ]
The headers start at the second line. They are composed of a name at the% O. Y- _9 r* W
beginning of the line, immediately followed by a colon (':'). Traditionally,
4 c( k6 R/ z! r# C# A/ yan LWS is added after the colon but that's not required. Then come the values.
) r2 E# ~) {$ h! mMultiple identical headers may be folded into one single line, delimiting the
- b7 C& i' n3 G$ `# h0 i; Hvalues with commas, provided that their order is respected. This is commonly
# L& X7 L7 _2 ^" |+ `encountered in the "Cookie:" field. A header may span over multiple lines if
: X- W3 _) {' \2 |& |4 n; \2 jthe subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 5
9 l% W8 I0 q- E9 p* \0 M/ u" qdefine a total of 3 values for the "Accept:" header.8 X8 x4 {8 ~( M2 C# j
' V: _8 U3 k! ]2 F& \
Contrary to a common mis-conception, header names are not case-sensitive, and  _; c* j! w8 e* \. O7 T# r
their values are not either if they refer to other header names (such as the
4 D  B6 t% p" L  t9 k  h5 }. |"Connection:" header).+ S* B! l. W; l, k% S* ]
/ D5 e9 x8 ?# p7 v
The end of the headers is indicated by the first empty line. People often say
, R% b6 I5 D, m+ w7 G6 qthat it's a double line feed, which is not exact, even if a double line feed
9 s0 n& E. a& q; t( F0 j$ O. a1 dis one valid form of empty line.: Y8 p. ]# t$ [# G

; \3 `5 k9 p) \Fortunately, HAProxy takes care of all these complex combinations when indexing. B$ P2 {. `4 O! y; g& Q7 [
headers, checking values and counting them, so there is no reason to worry6 G1 Y* u0 G9 G6 ~, [2 p; z
about the way they could be written, but it is important not to accuse an, h# s/ S1 T) {3 G& {* [# Z8 F" k
application of being buggy if it does unusual, valid things.7 N5 z: r- e+ R! S
; g  j, n8 B; m* I7 A. _
Important note:9 V# }; x( e/ h; M; @( ?
   As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks# d0 \4 j& K' @: Q, c7 T# v
   in the middle of headers by LWS in order to join multi-line headers. This: h9 X6 y. m7 q( S& c
   is necessary for proper analysis and helps less capable HTTP parsers to work/ \  M. w; H- g# r7 }
   correctly and not to be fooled by such complex constructs.4 u+ r! I! s4 s3 T, P+ o
4 Q+ b3 p. B: z3 j4 V: i

8 t8 h$ Q2 t! d1.3. HTTP response* ~4 u3 n  m1 [( ]* F; ?! ^( Y
------------------' [0 F$ M. ]- E$ _- B
( d/ A6 a' p; p2 e4 [5 K) k) F
An HTTP response looks very much like an HTTP request. Both are called HTTP
+ ?0 R0 R' I- Omessages. Let's consider this HTTP response :$ a* o+ F9 c% H2 r' X
4 ~8 F* q. F1 f
  Line     Contents
$ |3 Q: e1 g- `' x9 @- H' D8 v4 X  number' I! D9 [% _( W
     1     HTTP/1.1 200 OK" S% I* X/ Q8 n: @+ w% [* s
     2     Content-length: 350! S0 r+ L- w9 N5 t7 Z8 L
     3     Content-Type: text/html
+ Y, b2 n& @* q" Q
- A! m5 s5 N! x" t2 DAs a special case, HTTP supports so called "Informational responses" as status/ S: w" b$ `: b; b& T/ u! v
codes 1xx. These messages are special in that they don't convey any part of the
1 [8 {: B# ?4 D3 y* }9 r" ?' d7 Sresponse, they're just used as sort of a signaling message to ask a client to( |1 j  C: w) x# Y
continue to post its request for instance. In the case of a status 100 response- S/ L6 ^( h; P# o& @+ z
the requested information will be carried by the next non-100 response message4 [, e9 n: c3 }# ?8 r8 _% y
following the informational one. This implies that multiple responses may be; T- p5 ?* i  F
sent to a single request, and that this only works when keep-alive is enabled
, r" c8 T8 s' C4 f7 J(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to
6 d/ u2 i) O  S1 L: ~$ e3 w  t9 wcorrectly forward and skip them, and only process the next non-100 response. As
$ g) b0 w! P. w/ t) T# zsuch, these messages are neither logged nor transformed, unless explicitly& R! }' `7 Q4 w( B
state otherwise. Status 101 messages indicate that the protocol is changing
* r5 p( F( ~  A" T! Pover the same connection and that haproxy must switch to tunnel mode, just as1 z) z5 W! [' P  @" w
if a CONNECT had occurred. Then the Upgrade header would contain additional' H8 p& v4 m9 h# V( J/ t
information about the type of protocol the connection is switching to.
' z/ C: U% W7 m' n  o8 c# {7 q; ?; K* c
! N' n9 q2 k4 U: F
1.3.1. The Response line. Q" Q* }4 Z% ?- C8 `
------------------------
$ t0 [9 [1 Z% @: v, O( _
6 G0 R0 i" A) `" zLine 1 is the "response line". It is always composed of 3 fields :( g6 G2 `$ L9 s" j) x5 j) V) u
/ w& `: p) r3 \, j7 \" i
  - a version tag : HTTP/1.1
$ M% d+ k& u: b9 R2 D- @3 f6 C! @' [  - a status code : 200
, ~/ [5 f% l! _9 r  - a reason      : OK# r- Y9 Y" b8 w) N

  M, b9 o: G  K9 n7 Z5 c! yThe status code is always 3-digit. The first digit indicates a general status :9 R8 _: O+ b8 p% |1 Q) }7 F
- 1xx = informational message to be skipped (eg: 100, 101)) Y- D$ G  [8 n
- 2xx = OK, content is following   (eg: 200, 206)
! S% N9 Z" p$ E! L0 y" O - 3xx = OK, no content following   (eg: 302, 304)% e6 p' i: i- h: M/ X
- 4xx = error caused by the client (eg: 401, 403, 404)
1 b. T3 l. G* M* D1 J - 5xx = error caused by the server (eg: 500, 502, 503)/ `0 |$ M# u7 B; b6 t+ M/ D

. w& h3 y3 A9 [8 H0 p. zPlease refer to RFC2616 for the detailed meaning of all such codes. The  H! T7 p- ~' b& U0 a
"reason" field is just a hint, but is not parsed by clients. Anything can be
3 M3 j1 L; ^1 Y# G1 B- x: R. Dfound there, but it's a common practice to respect the well-established5 K" N9 ]! }8 ^
messages. It can be composed of one or multiple words, such as "OK", "Found",) E+ [8 ~( ]: |# h% Z% b
or "Authentication Required".' V% m# ~0 \5 [6 F/ v
$ K" {: B3 @( [$ X9 Q5 T. q
Haproxy may emit the following status codes by itself :8 D7 g) L: O( y3 Y

. z" I+ H) y5 q! H  ~2 O  Code  When / reason
, c' U# `8 N* m# Z7 B( P3 m   200  access to stats page, and when replying to monitoring requests$ t* i/ E! ]+ e& a- v" r, @  q! H
   301  when performing a redirection, depending on the configured code
  B6 Q% A# a* K& j" I( c, A   302  when performing a redirection, depending on the configured code
, x; A* o  d9 ?   303  when performing a redirection, depending on the configured code
1 V4 z/ Z! ?- z3 j8 T3 w   307  when performing a redirection, depending on the configured code6 j% W5 u. u# ?$ v* I& k
   308  when performing a redirection, depending on the configured code
% p' c0 M% L5 N3 `! Y% I  z   400  for an invalid or too large request
9 M: D' g* y* R, J   401  when an authentication is required to perform the action (when
( V! A! q% H$ M' Z3 H; e4 ?        accessing the stats page)1 d8 S/ I3 {- n3 a! I
   403  when a request is forbidden by a "block" ACL or "reqdeny" filter% t6 V- W& c0 }2 X
   408  when the request timeout strikes before the request is complete
4 k+ c' Z4 G' c# o: j   500  when haproxy encounters an unrecoverable internal error, such as a
1 h5 e6 v+ N+ m        memory allocation failure, which should never happen
3 Z& D& M0 t! h/ o- D   502  when the server returns an empty, invalid or incomplete response, or. n) {9 X% Q, r  K0 s6 q
        when an "rspdeny" filter blocks the response.+ a1 b2 g, g) H
   503  when no server was available to handle the request, or in response to. W( k+ Z: a7 f7 ]; v2 w) `# N
        monitoring requests which match the "monitor fail" condition
. ]( ]/ _5 }  l# _( k7 M   504  when the response timeout strikes before the server responds9 f, C: i2 y# [( W- _

9 L: y  |, c; l9 V7 j9 HThe error 4xx and 5xx codes above may be customized (see "errorloc" in section* L4 i2 v, j4 o+ D% N5 K9 R
4.2).8 X5 ^* H# ?: X9 ~. F+ T
6 F& i. A; A6 y% V- g; h' B

# K. Z( C0 v& Q9 a1.3.2. The response headers) |) P5 {5 z  c
---------------------------
# O1 m" O  o$ }0 T: h
$ ^5 l  J. B. b4 v. `6 i0 N0 MResponse headers work exactly like request headers, and as such, HAProxy uses
) m/ S' k6 w8 E% r+ Sthe same parsing function for both. Please refer to paragraph 1.2.2 for more
0 t4 E4 b" g) n  V9 D6 d7 qdetails.
8 f8 a! C6 w1 a: M0 r6 B. H  K
" s+ ]& F4 V; w5 p" r' Z3 [+ l7 _1 ^$ X7 v9 R4 @; _8 a3 l
2. Configuring HAProxy0 S( d3 t" s( i8 e8 E
----------------------7 i' f8 e, D: P
6 j! \2 }# K0 i* P! w
2.1. Configuration file format
' G" j, K9 j3 v% i6 d& k------------------------------3 G2 u3 d$ k/ f8 o2 Q, u
; S6 [1 p$ I* f
HAProxy's configuration process involves 3 major sources of parameters :
4 y7 P$ {( {, |$ c9 I- p, b8 K9 B3 w% Y. Y3 c: U% D* H* s
  - the arguments from the command-line, which always take precedence2 i5 Y, s9 ^9 h: c' a
  - the "global" section, which sets process-wide parameters
6 b! |  U" V9 H$ ?" `5 n0 Y  - the proxies sections which can take form of "defaults", "listen",, x" M% {6 L& j' _7 t$ ?' N
    "frontend" and "backend".. k; T. }& z4 v9 k- M$ k
  ^7 e* b# m5 `& j' L
The configuration file syntax consists in lines beginning with a keyword/ s  O% R. @6 u. ~1 l  I- j. N
referenced in this manual, optionally followed by one or several parameters  }  i  {9 K9 C& b
delimited by spaces. If spaces have to be entered in strings, then they must be% ~: u6 |- T* j6 e) m
preceded by a backslash ('\') to be escaped. Backslashes also have to be$ ?% M; h$ R8 O6 R+ M5 N2 b
escaped by doubling them.
7 u  @# U  o9 C, Y2 c9 o, d) S' Z2 f
2 K+ J9 \, f3 `
2.2. Time format! A5 `% H/ o" d# J) V
----------------2 U' B' J4 K9 r$ v1 U( `2 `

. A2 {9 n  }: B& cSome parameters involve values representing time, such as timeouts. These
1 }0 n! ]. |/ g& gvalues are generally expressed in milliseconds (unless explicitly stated, W0 \6 U7 H/ }: k4 k2 R! }4 v
otherwise) but may be expressed in any other unit by suffixing the unit to the) R' G% J( F6 y/ X, L& C6 `! B
numeric value. It is important to consider this because it will not be repeated- y- T  x; @7 U2 D
for every keyword. Supported units are :
! G# w& Q3 Y  ~5 j, l4 S
! g' B5 U0 Z6 ?* Q2 D% a  - us : microseconds. 1 microsecond = 1/1000000 second7 V4 k0 V7 [- z# N* W) ]
  - ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.2 |+ G/ j4 W- S  f1 N' ^5 t, D4 G* [9 ?, T
  - s  : seconds. 1s = 1000ms
! a4 Y- B& p9 r( V  - m  : minutes. 1m = 60s = 60000ms; ?2 n8 p. o' s7 b
  - h  : hours.   1h = 60m = 3600s = 3600000ms
; f7 o% E. a0 U  - d  : days.    1d = 24h = 1440m = 86400s = 86400000ms
" Z( b/ M$ u, `6 K/ q& v4 R/ N) t6 W' `. K: M  T

8 M- Z8 b2 [8 x# N( L, I2.3. Examples
+ Z* U* Y$ O+ t/ j4 z-------------, F6 q3 A9 N5 p

9 E# q! a* N  M- g  c    # Simple configuration for an HTTP proxy listening on port 80 on all
% m0 _$ G, F0 D% _7 G4 f    # interfaces and forwarding requests to a single backend "servers" with a! A, t5 }3 Z7 g1 B- _5 ]% x: b
    # single server "server1" listening on 127.0.0.1:8000
0 ~$ ~5 t6 l' r8 p$ x: e, [1 P    global
- w6 A" s9 ?8 E2 N# F+ B        daemon
% V$ j6 m; g0 Z% h& F        maxconn 256
" q  F# ^9 @  L3 t/ t- y" H" Z" t* [' f
    defaults2 k& x7 {. G' ?3 [- \
        mode http
% H8 U- x( T- z) n5 e+ J3 {; x9 O. p3 b        timeout connect 5000ms
0 U1 k* Y. l4 W& m) x& D; l        timeout client 50000ms
+ x+ H- |. S. K        timeout server 50000ms# d# C' y8 r, j! C& P

7 E( y" [6 L; _% y4 b" v    frontend http-in
9 V+ T" S  g3 P; ]        bind *:80
1 r3 \0 d8 ~6 K9 {8 D5 D        default_backend servers
3 s* [9 P6 l* S5 C; L) |
" x; m2 Q( |) [5 d- m8 w    backend servers
+ \! ^. f% e/ q! H9 [  v% ?        server server1 127.0.0.1:8000 maxconn 32
5 X. d4 A6 I; x" M. \7 Q9 j
3 F9 [) O, }% @, Q% @+ M, B! U+ I
' W8 R, U' Q% v3 Q" O    # The same configuration defined with a single listen block. Shorter but
, k, j. r+ L, @/ F' I: [    # less expressive, especially in HTTP mode.
8 Y4 L4 K/ ~! p) \: N    global
" o$ z! v; e2 U" n        daemon7 D( ?/ O# }: L" p- S
        maxconn 2563 M, a0 Z7 b& K/ X

7 D) L$ \8 w6 N    defaults
* k" h) g" n) W) r        mode http
: Q0 \* u6 R0 T: d" [        timeout connect 5000ms) z+ I5 V# O  G& v
        timeout client 50000ms$ ~1 s8 @7 {. n) c1 ^* g
        timeout server 50000ms
# w/ [0 t' k/ ^2 q' ~5 N' ^' Z& }* F2 P
    listen http-in  v5 V/ ^) l& t/ V
        bind *:80
0 N/ ^7 R: P& I        server server1 127.0.0.1:8000 maxconn 32
* V  I$ Q: Y* m4 x/ ]& ~- |) s
) d$ Y$ K1 i+ g* y
+ I  A& B3 W" b9 |Assuming haproxy is in $PATH, test these configurations in a shell with:
1 I2 y0 k: Z8 {; P7 }' a9 c
( X3 F4 h" e. S. [    $ sudo haproxy -f configuration.conf -c& w  q- O( k' s2 w& r! A1 i

7 ?/ |, d* u+ C" Q3 t* Y# e$ ~
3. Global parameters
. Q6 w6 c: D, g8 I9 E, @- E--------------------
+ ~  ~+ F" y3 J7 d% u% C7 y8 S6 @3 A* q. \, R- i4 ]) r% I- @) D
Parameters in the "global" section are process-wide and often OS-specific. They/ G( [+ C* D- o$ l2 F
are generally set once for all and do not need being changed once correct. Some
  ]4 Q/ |/ b  u4 Bof them have command-line equivalents.
& [8 I5 A( Z+ @6 X+ R0 L9 j1 r" d$ h- y. W! x- j' X5 U& L/ i
The following keywords are supported in the "global" section :
+ g# F+ Q2 }  Z3 e2 G! k& Y: c. @' r' y
* Process management and security
  J( Y, e+ X2 s7 q, c   - chroot, o5 {  h, m. b: T! t
   - daemon* B0 p, P9 V2 K/ J( U9 q! n
   - gid; @- Y" r$ u1 a7 v3 X$ [
   - group: D" U& f+ b9 {
   - log
* v( z' D' o; f, L0 w   - log-send-hostname# F2 B& H2 m- i8 P3 ~0 P' R$ ]& _
   - nbproc
3 J6 |. ?) e6 X5 ~" @' }   - pidfile6 R4 w5 a  q* ?# f/ l$ F% v3 x
   - uid
6 D4 J  ^) n& ?5 D2 c7 k: \5 O   - ulimit-n
, n: V6 C& }- s9 p8 B   - user) S; ~( ~- e# z5 L9 e- |
   - stats
, {" m' B' x0 G+ B1 Q" m   - node
$ d  e2 f& `! E  i) |   - description
) z: D2 }& E6 J$ G2 ^' v* I* P. o
. ^- j) R3 h# P& e * Performance tuning
: L: W) E3 v. D$ \4 [6 U   - maxconn6 S5 w1 m5 J, t" e: H7 w( o
   - maxpipes
  v" I# \1 J0 x9 L; K$ l   - noepoll- |5 v9 x9 ?0 B/ w" |' k. D
   - nokqueue
  W+ a# e+ m) O# E4 N: p% Z   - nopoll; q1 [4 N2 h& X* I  j
   - nosepoll
3 u0 Y9 F; O; R# d: P4 L4 s   - nosplice
7 @' j# R/ l, k3 r, X1 W   - spread-checks$ l! I0 r& @, J5 j
   - tune.bufsize
- ]" q/ ]5 [. ^: D, r9 J" m$ j0 Z& I   - tune.chksize* w( U, s! a6 V: Z
   - tune.maxaccept6 T' p; Z4 C( }" e* ~( q6 |( i
   - tune.maxpollevents
( @1 N8 f) U( v7 j/ j- I& Z8 @   - tune.maxrewrite
, R4 z( O* E/ i4 ^   - tune.rcvbuf.client
+ w8 l6 J, f& L/ V. B3 y4 @3 L   - tune.rcvbuf.server9 w! ^* r! _5 d6 U. f
   - tune.sndbuf.client- Q: o7 [; v  ]* c: Q
   - tune.sndbuf.server
8 q: e  [8 `4 y( t+ n0 K! z9 [& V! `* ~* _
* Debugging6 w- J( ?- a3 M+ E
   - debug
8 o% h6 d- @& ?: h4 f   - quiet1 q) n8 G7 i# C

  e( S" q( x+ D' c' N" G7 I; }* L6 [8 y4 Q
3.1. Process management and security
- o) u/ a7 x$ t5 S  U* k3 G------------------------------------+ r3 l" A' H/ |- S- K' S0 t
( J. I0 ^8 [* O  b, L
chroot <jail dir># Q) m/ ]- Y' O6 y
  Changes current directory to <jail dir> and performs a chroot() there before
/ ~! d$ M/ }" d2 n, N7 m3 U  dropping privileges. This increases the security level in case an unknown
- p3 {$ ^" ?9 R3 P, R* s  vulnerability would be exploited, since it would make it very hard for the
' |# M4 j7 w0 r  attacker to exploit the system. This only works when the process is started/ e4 d: ^" N: c9 U
  with superuser privileges. It is important to ensure that <jail_dir> is both
( s! J7 D5 `2 y# `  D) E  empty and unwritable to anyone.
6 n% g- a% [" |2 |2 i6 l) G  D6 A5 s9 }7 ], m& j
daemon
" J; k8 x5 b9 V6 K) x  Makes the process fork into background. This is the recommended mode of
$ [! x  z7 J- A* U) y) }7 [  operation. It is equivalent to the command line "-D" argument. It can be) J! D! G. z. O. ?
  disabled by the command line "-db" argument.
1 _1 E& r( B( B( u! J5 E8 N3 r' L% _$ n1 U2 m& ?
gid <number>0 R' `: l! e9 j% T4 C
  Changes the process' group ID to <number>. It is recommended that the group) O( C, W' e. p0 _+ p
  ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must: U& w5 j9 a- I) B8 y3 M& o
  be started with a user belonging to this group, or with superuser privileges.
! h  {5 A% ~* m- b0 s  Note that if haproxy is started from a user having supplementary groups, it
; F5 H: H' o( l. G% p3 `- q0 [  will only be able to drop these groups if started with superuser privileges.
/ {: u# b  E6 Q8 H# @1 \$ u  See also "group" and "uid".
2 K' U/ J. @" Y! b& Z6 f
$ K1 `5 j3 j* h7 ~! w' Y2 Fgroup <group name>6 G/ t4 a: l: n* R3 l) U& p7 K* _
  Similar to "gid" but uses the GID of group name <group name> from /etc/group.
: C5 l- ~4 ]! s  See also "gid" and "user"." ~5 d% o: {& l& f& g' d- m, a

3 O9 |8 ]2 R- D; g6 I4 g2 Slog <address> <facility> [max level [min level]]5 q* d5 h8 ]/ V; ]' e! v& O$ s  B7 [
  Adds a global syslog server. Up to two global servers can be defined. They
. W7 B$ @9 |5 Z5 d5 K+ }& c, h  will receive logs for startups and exits, as well as all logs from proxies) v+ h7 x  L1 l
  configured with "log global".
) B' E" ^) r, C! Q: S+ K: I. Z# O$ C: p: g+ `
  <address> can be one of:
" `' _% L! d9 R) O; k8 V8 A+ c/ F- `, V0 @4 H  Q# a+ w
        - An IPv4 address optionally followed by a colon and a UDP port. If
, T. N# D& k" P          no port is specified, 514 is used by default (the standard syslog0 d( t' e+ e* J  \5 e* \  F
          port).
% o5 I; m( F" e; @& m, Y9 ^
" M) U+ ^/ n% F9 P/ u: V' O        - A filesystem path to a UNIX domain socket, keeping in mind6 K0 L1 d" _; s9 w: u
          considerations for chroot (be sure the path is accessible inside
; p2 K( A' r* x  E          the chroot) and uid/gid (be sure the path is appropriately
6 E/ g- ], g" F8 d0 b) P0 |          writeable).7 a  ]+ }4 w0 w  w: K
8 u/ t5 y; C. W! V
  <facility> must be one of the 24 standard syslog facilities :) u$ r7 r% q) {

: l" D4 }: y* {# C; Z' k: }4 |+ R          kern   user   mail   daemon auth   syslog lpr    news
5 S! S& R5 ^0 {9 R. f$ }3 W. U          uucp   cron   auth2  ftp    ntp    audit  alert  cron2
! R% X3 X1 {6 w          local0 local1 local2 local3 local4 local5 local6 local7
. s& F4 y3 c6 w; U+ _) o
: Y5 @2 |3 l+ U: M- g/ `! z  An optional level can be specified to filter outgoing messages. By default,4 N' A7 \: r# w- M
  all messages are sent. If a maximum level is specified, only messages with a
) F0 V6 N" a% B+ u6 W" E  severity at least as important as this level will be sent. An optional minimum
! w- M  m4 W& M  H9 c7 D  level can be specified. If it is set, logs emitted with a more severe level1 e6 D  p/ F- u/ q7 k( {6 Q. z5 T
  than this one will be capped to this level. This is used to avoid sending
$ f# z$ N" f* ?  "emerg" messages on all terminals on some default syslog configurations.
' A* L, Y0 ?4 H) c: P/ ]: _  Eight levels are known :
- a2 m: s) o  b8 m: E* a6 z2 X! W8 q, Z8 y+ r9 p' R% x
          emerg  alert  crit   err    warning notice info  debug1 w; u7 G- U8 T) m
1 }3 I5 B2 y% y) w
log-send-hostname [<string>]/ n& }: [* w9 S, O- F
  Sets the hostname field in the syslog header. If optional "string" parameter6 \- q  x7 U/ n) r9 P
  is set the header is set to the string contents, otherwise uses the hostname, e: w" ]3 f9 y
  of the system. Generally used if one is not relaying logs through an' p( D( F$ ]' h" K! T  J
  intermediate syslog server or for simply customizing the hostname printed in
4 G, F+ Z( v  N. S; E6 {" }2 a  the logs.
$ E: j7 b, Z9 g
7 [) m9 q6 y6 n8 }4 |4 V$ Jlog-tag <string>, ?; F8 W7 x. e4 q
  Sets the tag field in the syslog header to this string. It defaults to the
% u) P8 c0 O8 a+ E& q7 L$ H  program name as launched from the command line, which usually is "haproxy".
  X6 T, y" D/ \  Sometimes it can be useful to differentiate between multiple processes0 j; f$ P( Q" h( a+ f2 ~3 Y) k0 ]; y' N
  running on the same host.
% r2 ]( C* a& B" }4 B1 l' J1 `1 L+ R4 `0 Q2 z
nbproc <number>6 W/ q+ o/ P2 U
  Creates <number> processes when going daemon. This requires the "daemon"
  {0 N# X! q! ^  mode. By default, only one process is created, which is the recommended mode
. f3 |. R: x5 ?( B7 t5 F  of operation. For systems limited to small sets of file descriptors per
& a0 U0 T# r) W. B' }% c  process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES
6 `4 T  ~8 }/ ]# k- \  IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".% ~1 }4 @  I+ l6 k8 ~6 s5 ?" ~
$ [- ~$ y7 g/ S" H& t. N8 q
pidfile <pidfile>
- k$ W/ G, S( P7 r$ S; R, v7 H  Writes pids of all daemons into file <pidfile>. This option is equivalent to
6 F" x* ~: H$ t# ^+ ]8 R- ]+ O/ h  the "-p" command line argument. The file must be accessible to the user. k  Z/ G6 C; w. p! J6 [
  starting the process. See also "daemon".
; ?, u7 ]- _$ c8 j  X8 t; S6 f0 E& y: l- b
stats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]/ D- ^+ B2 y, X( z% s3 W" g
             [level <level>]
/ o% E3 S7 n* O6 u
, u* C# ^% ?) `4 c2 R: s$ o  Creates a UNIX socket in stream mode at location <path>. Any previously$ l% M' D  H' a$ ^
  existing socket will be backed up then replaced. Connections to this socket
: {5 T- f$ y& u( |  L  will return various statistics outputs and even allow some commands to be
) ~0 V) K6 {9 |: s9 I  issued. Please consult section 9.2 "Unix Socket commands" for more details.' O- S7 D7 `' p" J" K5 a& P8 k
! ?$ B7 D/ b2 _
  An optional "level" parameter can be specified to restrict the nature of
7 A# O1 c8 e5 R) |, k1 s1 f- u  the commands that can be issued on the socket :6 K: B" \1 e# o+ ^, G
    - "user" is the least privileged level ; only non-sensitive stats can be1 e& u/ D3 ?, o; g8 {; O
      read, and no change is allowed. It would make sense on systems where it
9 D+ j+ U0 [, v( W' |! y      is not easy to restrict access to the socket.
  J7 o( B% A7 f+ E/ T5 Q0 `0 ?! [8 C
    - "operator" is the default level and fits most common uses. All data can
& g" Z! U0 Y6 }) |; Z1 B      be read, and only non-sensitive changes are permitted (eg: clear max
( d' Z! {3 o# {; J  @5 K      counters).# a0 A: A# M5 Y0 A& o9 h* y

: F# q$ A3 R; Q1 n. z; k- ~    - "admin" should be used with care, as everything is permitted (eg: clear
: ^+ F/ d& @# k0 ^& h- Y      all counters).4 q+ @( {5 u" i9 K' a3 T

" |) s0 S/ y* p" I, G  On platforms which support it, it is possible to restrict access to this/ g' J, t" p% N+ W  w- i! N
  socket by specifying numerical IDs after "uid" and "gid", or valid user and
. q6 m7 [* ~! D2 Y5 o) I4 x  group names after the "user" and "group" keywords. It is also possible to
0 m6 o/ M$ ]' f6 k* j  restrict permissions on the socket by passing an octal value after the "mode"- J; c, G4 x- }$ }5 {" X
  keyword (same syntax as chmod). Depending on the platform, the permissions on
! K" ^. U- c' b  the socket will be inherited from the directory which hosts it, or from the* }3 z$ U+ R' Y9 M: V
  user the process is started with.
; P& z+ }" o8 t
9 n7 l' E; N" U# h9 B3 hstats timeout <timeout, in milliseconds>/ w- |# }, {8 P9 s0 O/ j
  The default timeout on the stats socket is set to 10 seconds. It is possible
3 z+ x6 a; ]# Z4 p$ k7 X/ i8 _' a  to change this value with "stats timeout". The value must be passed in6 s5 ?% w$ H8 j) ]
  milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }.7 N1 o# w& t  w& @$ S

3 X& b/ d! u. x  O* F8 j9 _) C4 Jstats maxconn <connections>
, b7 q! }9 B) g" p  By default, the stats socket is limited to 10 concurrent connections. It is
, V7 o8 f0 g, j7 e- a  possible to change this value with "stats maxconn".
+ k7 T# c% e3 q, j4 _0 f* j8 V9 L6 x8 q. U+ w% [
uid <number>
1 p( V2 H  ], N! O7 t" v" d  Changes the process' user ID to <number>. It is recommended that the user ID
1 U# ]' X( l0 H" C# ^- e# Z5 V  is dedicated to HAProxy or to a small set of similar daemons. HAProxy must7 c. D8 e9 l2 l! W# c& W+ y
  be started with superuser privileges in order to be able to switch to another
% T. Z3 P" a4 N  one. See also "gid" and "user".8 M7 _* O% g3 _8 [/ t. v

3 I& p" U8 a$ l( _3 Q4 F; \6 y2 i* E+ culimit-n <number>3 r1 }3 k( D: x- j* M
  Sets the maximum number of per-process file-descriptors to <number>. By
4 m3 ]1 H5 h/ \  E8 Z7 z- g  default, it is automatically computed, so it is recommended not to use this% k$ P6 W' v: _2 Y
  option.
8 j3 j. H3 {: Z2 C4 |# y1 m" N8 X, @; U( r1 m  G8 I
user <user name>
( S& j6 V0 C% G; b! }6 C3 S  Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.
: p. I" x  ~# T7 w2 O; E  w5 Y  See also "uid" and "group".
% ]8 g  f9 Z9 q7 ]7 t. Q
- A- s$ W' j3 e  N$ \% H3 @$ Wnode <name>8 j8 Y; d" H. @. I) u
  Only letters, digits, hyphen and underscore are allowed, like in DNS names.
1 _3 U( l! p7 g$ i' ?* E1 g1 }& X. U% s! |' I. m0 C
  This statement is useful in HA configurations where two or more processes or2 z# Y; Y/ O0 `9 ^0 E
  servers share the same IP address. By setting a different node-name on all
1 d3 u7 `- B$ Z& V; s  nodes, it becomes easy to immediately spot what server is handling the
. Q% l8 i/ s: M: T+ m  traffic.. q5 b9 L5 C4 W2 b9 \

  I# H8 ^# d0 n) Ydescription <text>
$ M- v4 K0 T8 r' H3 c  Add a text that describes the instance.0 m$ m! d( ?; s+ U; U
: k8 w# A. ?2 [3 }$ a, C
  Please note that it is required to escape certain characters (# for example)
/ e( ^9 w7 r& p; c  and this text is inserted into a html page so you should avoid using
0 H) \% K. D$ B! W8 d6 E8 e  "<" and ">" characters.7 Y4 c, x8 ~1 ?8 \
* J9 M9 d2 t1 @) f8 M' H/ r: m

- k5 K7 d( R5 V0 \+ o3.2. Performance tuning
2 ^* p" c  w) g+ K, Z' m-----------------------
$ R4 k$ E! F3 r1 H- N+ A4 k  ^1 P8 n" k7 L  Q8 E
maxconn <number>
2 o9 N' r4 p2 x" N$ }1 R5 @! d/ i  Sets the maximum per-process number of concurrent connections to <number>. It2 S$ d  q" H7 T* P4 E: n3 N# n8 t
  is equivalent to the command-line argument "-n". Proxies will stop accepting
/ p, h0 f8 A" k. A# U  connections when this limit is reached. The "ulimit-n" parameter is
& \% Z# v" j# E: z9 t. x  automatically adjusted according to this value. See also "ulimit-n".
3 f4 e; t9 c$ z, v6 a( x9 ~+ v' K) \" o8 Y1 J4 p( u
maxpipes <number>! c  @8 `+ V# Q) K  b8 x/ S
  Sets the maximum per-process number of pipes to <number>. Currently, pipes! }+ ~, y8 x4 W" F9 E2 i
  are only used by kernel-based tcp splicing. Since a pipe contains two file
; }# m; x6 I+ ^4 k/ [% ^1 M. A  descriptors, the "ulimit-n" value will be increased accordingly. The default6 A6 G. }) m6 t. d- ]$ A+ l# m
  value is maxconn/4, which seems to be more than enough for most heavy usages.
, A1 k1 v# I1 a8 n" B5 V$ \/ y  The splice code dynamically allocates and releases pipes, and can fall back
  F6 d0 W+ E% p' `  to standard copy, so setting this value too low may only impact performance.( J7 C2 X3 a* b# M& r

% S3 R0 v. `2 [9 {5 \noepoll
& b8 ]$ e& G4 M2 \  Disables the use of the "epoll" event polling system on Linux. It is4 P9 y9 E- d: k# T# v/ Y/ ~/ x
  equivalent to the command-line argument "-de". The next polling system+ W+ H) T% y+ J# B# \
  used will generally be "poll". See also "nosepoll", and "nopoll"." j/ q' W! h; _+ g2 [3 B8 n3 z' H
. Q7 i  k  E; d8 F# D
nokqueue
* U6 c* Q! Z/ i1 m5 O+ }  Disables the use of the "kqueue" event polling system on BSD. It is& U! {- @" E3 y* E, S" a
  equivalent to the command-line argument "-dk". The next polling system$ r& t3 U0 \/ [, J) _& F& H! H
  used will generally be "poll". See also "nopoll".9 y% e, X5 l: z" o
' D; _& e1 x1 x$ p$ o% t
nopoll- w+ R0 s  D+ t
  Disables the use of the "poll" event polling system. It is equivalent to the; z( _& K9 o* {8 D" W+ ?: c
  command-line argument "-dp". The next polling system used will be "select".
9 E% u* k& R: J9 w& {  It should never be needed to disable "poll" since it's available on all
1 O" I$ A- X' O' i- O, Q/ G$ }8 T( y  platforms supported by HAProxy. See also "nosepoll", and "nopoll" and
! i- [. u9 N, R4 `  "nokqueue".  I) k2 j, l7 e/ U/ J. P% B& ?6 a
' b: Y, H3 K6 r' q1 Q8 c; f
nosepoll. \5 T: D, _/ _9 [% M, O0 X
  Disables the use of the "speculative epoll" event polling system on Linux. It& t; e+ K+ W4 E1 @
  is equivalent to the command-line argument "-ds". The next polling system! @' q& S' h/ h! H  L. y2 p2 F
  used will generally be "epoll". See also "noepoll", and "nopoll".3 S- T- [, d, [: ]

3 o( J) Q3 F4 inosplice3 C/ t! L0 n9 v
  Disables the use of kernel tcp splicing between sockets on Linux. It is
. Q) l0 D% b* R; L  equivalent to the command line argument "-dS".  Data will then be copied
( i" O8 @7 B7 w! d7 z2 b* f4 D  using conventional and more portable recv/send calls. Kernel tcp splicing is
& v8 J1 N6 H* p1 p. Q  limited to some very recent instances of kernel 2.6. Most versions between0 s* p" X' {, D  g" f
  2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not! ]; v, i( M+ Q) v3 p
  be used. This option makes it easier to globally disable kernel splicing in
5 u! C: p* K0 Z# g& t  case of doubt. See also "option splice-auto", "option splice-request" and
! y/ Q( o) v, z: }9 e  "option splice-response".
" b5 k+ p& w0 o% y8 {# F: [& L' i, k8 T+ t* ^  o9 ^' H" [
spread-checks <0..50, in percent>! P4 n2 F5 D4 E" W( R
  Sometimes it is desirable to avoid sending health checks to servers at exact5 w: j; F  E) C# b2 f
  intervals, for instance when many logical servers are located on the same
* o) Z6 M2 [# Z0 s7 T- I3 [  physical server. With the help of this parameter, it becomes possible to add
6 @7 G/ s" q3 S  some randomness in the check interval between 0 and +/- 50%. A value between4 D" A$ m% ]& t* B
  2 and 5 seems to show good results. The default value remains at 0.
* u4 I' a6 r4 X' M1 w; R
6 w$ f, U3 K# @) }8 M1 u$ vtune.bufsize <number># w1 I9 I( Q7 J# x" G9 U0 `% ~
  Sets the buffer size to this size (in bytes). Lower values allow more
% b3 p  j$ B3 P- S$ p- L+ o% M& M  sessions to coexist in the same amount of RAM, and higher values allow some
4 y  q8 W) C5 e: O+ m  applications with very large cookies to work. The default value is 16384 and
7 v$ h0 l2 n' z0 u  can be changed at build time. It is strongly recommended not to change this2 E  ^0 S& ?2 F; H9 M7 h
  from the default value, as very low values will break some services such as
; @  h$ [' Q6 M  statistics, and values larger than default size will increase memory usage,
  a7 A; K- G$ M# `$ g3 H  possibly causing the system to run out of memory. At least the global maxconn
7 e9 ~! e8 l8 Q- a  parameter should be decreased by the same factor as this one is increased.
  j" F! Q) {4 Y/ R, ?8 ?$ p/ n( P+ B
+ {0 B, {' v6 T. Qtune.chksize <number>; h" B( |5 a2 G( H, V
  Sets the check buffer size to this size (in bytes). Higher values may help8 Z7 w0 g+ j2 w- j
  find string or regex patterns in very large pages, though doing so may imply* m$ J8 `0 L  H% E) L3 q
  more memory and CPU usage. The default value is 16384 and can be changed at
2 v! `( K: U( q* Z9 t  build time. It is not recommended to change this value, but to use better: _1 K$ O& ^/ j! e
  checks whenever possible.! P3 o. o8 i" {
/ U% s0 E" w" P$ ?
tune.maxaccept <number>/ {" y5 k; G! l4 P
  Sets the maximum number of consecutive accepts that a process may perform on
+ ~. B% Y  \, o* v3 k  a single wake up. High values give higher priority to high connection rates,# r1 J. d- p6 K5 u2 ?
  while lower values give higher priority to already established connections.
+ L. E1 r) ~" s  This value is limited to 100 by default in single process mode. However, in+ e' u/ B5 Z! P
  multi-process mode (nbproc > 1), it defaults to 8 so that when one process
! M4 v( y* E+ j  wakes up, it does not take all incoming connections for itself and leaves a9 |! }  H  }$ X: L# b3 R1 t
  part of them to other processes. Setting this value to -1 completely disables- ~  N% H. r) m3 B7 c
  the limitation. It should normally not be needed to tweak this value.
9 x9 ]( x% O  o3 @( o9 I; m7 p; i( N; ]  r; O3 N
tune.maxpollevents <number>
+ O4 B, Z  v; q- J  Sets the maximum amount of events that can be processed at once in a call to
' @3 n) P* z5 F4 g( Q  the polling system. The default value is adapted to the operating system. It
6 t, G% p! G7 v  ?. C  has been noticed that reducing it below 200 tends to slightly decrease9 n; _5 P" D  ^# |* Z% D
  latency at the expense of network bandwidth, and increasing it above 200
) l( d  K& ]- }* S9 y: }# X  tends to trade latency for slightly increased bandwidth.( A6 x6 D. J3 d; ?& L$ j

, R$ R% D, `8 M9 {$ D" X9 i# T" xtune.maxrewrite <number>0 ~% m: e4 [2 }0 J: M
  Sets the reserved buffer space to this size in bytes. The reserved space is$ q$ ~2 {% v+ O: Q6 L
  used for header rewriting or appending. The first reads on sockets will never
9 s" i8 B; u/ I% [" u4 |  fill more than bufsize-maxrewrite. Historically it has defaulted to half of& s9 x7 A  M0 v4 s
  bufsize, though that does not make much sense since there are rarely large
7 a! I. M3 N. _) O/ \/ q# q  numbers of headers to add. Setting it too high prevents processing of large' S$ i) F" _% k
  requests or responses. Setting it too low prevents addition of new headers# [4 b7 S% w$ f) A. m. \/ u
  to already large requests or to POST requests. It is generally wise to set it
) h: M' v$ b! e8 I; c0 K' |  b$ \# B  to about 1024. It is automatically readjusted to half of bufsize if it is* @5 \9 P/ R+ G3 {6 @  t
  larger than that. This means you don't have to worry about it when changing4 T& @& T" Q6 v5 F3 z, O; l
  bufsize.' n3 R8 H( U7 h( r0 K

7 L% q" Z* @0 O4 Etune.rcvbuf.client <number>
$ s* x9 n! i4 n$ }7 Gtune.rcvbuf.server <number>
) B9 [' K* D6 D  Forces the kernel socket receive buffer size on the client or the server side  {4 O5 ~: m/ `% h  d
  to the specified value in bytes. This value applies to all TCP/HTTP frontends
' w' i( N' U- i! f/ q0 k2 ^; q% N  and backends. It should normally never be set, and the default size (0) lets0 X+ E* ^$ a; M& a% a$ ]) C
  the kernel autotune this value depending on the amount of available memory.
3 Z! S" t0 Z4 b5 _6 x8 O0 @  However it can sometimes help to set it to very low values (eg: 4096) in
9 @, A8 L8 W, D; {4 a5 y4 A  order to save kernel memory by preventing it from buffering too large amounts
* T* {9 ]. E; u" E: N( v  of received data. Lower values will significantly increase CPU usage though.  ?2 b/ \/ [( X
. C2 ~# Y: y, d- }6 M! O
tune.sndbuf.client <number>
; y% Y# h7 t% g1 b7 A/ y  [tune.sndbuf.server <number>
& H* ]  y  R7 ~" _; d# o  Forces the kernel socket send buffer size on the client or the server side to
4 D2 u7 |, c5 ?- N4 w  the specified value in bytes. This value applies to all TCP/HTTP frontends
+ S" W2 ^/ w) [  and backends. It should normally never be set, and the default size (0) lets
, K% a/ z: l, {/ ^4 v" u1 G7 K  the kernel autotune this value depending on the amount of available memory.% r; `  Y1 V7 ?- R& s( g
  However it can sometimes help to set it to very low values (eg: 4096) in
, K5 a, \8 ~5 M0 h: L! n. u' O  order to save kernel memory by preventing it from buffering too large amounts
; E" W- `! B1 q8 Z  of received data. Lower values will significantly increase CPU usage though.
) V8 }7 t, g, |9 S/ r6 r% x, ~2 z  Another use case is to prevent write timeouts with extremely slow clients due- `8 {7 L! v* J# P) g/ W
  to the kernel waiting for a large part of the buffer to be read before, t4 W" ~, K4 M4 [
  notifying haproxy again.7 t" ^; v; w+ Z# y4 N
8 u* D$ I* E  H  P0 r( c* ~

0 ?' w) w. k7 y. t' t3.3. Debugging
& o9 S$ U) v3 r3 |* f$ R--------------& u$ }3 V' C( N- s& _! Q
1 @+ j4 ^- O8 v! W. u
debug
) _+ a3 Q  i% P, {2 j6 ]) E# m  Enables debug mode which dumps to stdout all exchanges, and disables forking
5 h0 O, k2 s# N9 v4 x! d0 w  into background. It is the equivalent of the command-line argument "-d". It. R& h* i& O7 `% y' D
  should never be used in a production configuration since it may prevent full9 s& b1 }' H0 K$ E
  system startup.
1 G9 `6 V! p  E4 k- n; d7 t# ^- r. t  A: U3 i6 a) h
quiet* ~# G: j: {( x# U% P7 V5 z
  Do not display any message during startup. It is equivalent to the command-
& D% ?) s( @/ I* [  line argument "-q".4 |1 G4 {1 a# i: f0 ^
5 g* w: f8 l  J" \3 _4 O
3.4. Userlists! I$ M9 l2 b4 l; w+ ?4 P1 Q  f
--------------3 @0 v! J, @/ _! l% P! }# g" C
It is possible to control access to frontend/backend/listen sections or to1 ?& I7 C8 |1 g. d
http stats by allowing only authenticated and authorized users. To do this,+ l/ ?  e/ m5 P/ l2 w( k+ |0 f
it is required to create at least one userlist and to define users.
8 b( m: j0 }# ]6 C* M  @) E- m
$ p0 A0 F, \! `3 Z" c! H3 R0 N' H# A: Suserlist <listname>
: S' L5 s4 ~: u" i' F( L" |5 U  Creates new userlist with name <listname>. Many independent userlists can be
$ \5 M/ I; a0 b- a+ m( j  used to store authentication & authorization data for independent customers.' J6 x3 S( K, \7 D! t
/ _2 |# D' h* `) e/ z
group <groupname> [users <user>,<user>,(...)]
% {- F% a& s. t: {, r4 s7 r2 W5 a$ `) q8 }  Adds group <groupname> to the current userlist. It is also possible to8 x4 g. L  F* K
  attach users to this group by using a comma separated list of names
* U+ Z1 w7 F. u  proceeded by "users" keyword.
8 z9 d9 t8 h, }  u$ a- q4 x  ?0 i1 d+ l% a! I9 o( J
user <username> [password|insecure-password <password>]
, u; @3 X, j, c0 X8 U1 O" S                [groups <group>,<group>,(...)]
4 ?  o2 t% ?9 d/ e6 J6 z- |  Adds user <username> to the current userlist. Both secure (encrypted) and" H. O7 e/ n7 k3 Z" \
  insecure (unencrypted) passwords can be used. Encrypted passwords are5 r# ~( n0 A, g
  evaluated using the crypt(3) function so depending of the system's  |$ m3 [1 l' h& I6 q
  capabilities, different algorithms are supported. For example modern Glibc7 U/ L% i# T- C/ [- g
  based Linux system supports MD5, SHA-256, SHA-512 and of course classic,5 G7 D$ ^" R  c
  DES-based method of crypting passwords.4 F4 I5 L) f, s5 p0 Y
0 N- t; v: b+ T! g

* Y# Y6 s- P3 X9 p  Example:
! R; ?$ }4 ?' T  q1 h4 Q        userlist L1' _0 a- W6 @6 W! G2 N
          group G1 users tiger,scott, @6 U" M% l$ V" ?) V7 x4 J3 m. A/ H
          group G2 users xdb,scott; {  h; W7 q4 O; f& a% ~

& g0 P4 t  S" L; I& a& u: S4 s          user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91) }4 Z9 E* O9 Q/ n8 z
          user scott insecure-password elgato
# n9 T4 d7 _) k0 p$ |8 f9 S4 ~          user xdb insecure-password hello  F" t. z' Q  c, T3 b# t
! i2 r& K0 j& p
        userlist L2
2 L- T7 |* v. L( e7 G6 a          group G1" \7 z9 Z5 D1 p  G
          group G2$ J7 R8 [, x/ b
, B4 S/ {- W: a. m$ q1 \
          user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
9 s! m+ i3 H( x( ?" k* C" Z          user scott insecure-password elgato groups G1,G2- Q% C  g; Y7 e8 f) M5 b9 p
          user xdb insecure-password hello groups G2/ x3 }$ v! O  f$ [# ?6 t
" g0 {/ w8 |" r( n9 G0 ]- a
  Please note that both lists are functionally identical.
7 V3 Z' ?# A4 W
9 k# [" Q6 \( g2 m3 m5 V4. Proxies
) n$ ]* M* l3 P2 g6 P----------
. f6 X/ a0 q1 J6 x6 `3 Z9 w
4 ^; B3 U$ B1 e/ A' X# m' v3 jProxy configuration can be located in a set of sections :
: O8 e" s. [3 {) x. u4 P: s - defaults <name>
/ U. e# m$ |& E1 V0 g# E - frontend <name>
+ W0 E4 G9 }# H - backend  <name>" T9 F! O. W1 H+ w9 x5 @
- listen   <name>1 e  V+ \# z- E
1 ]- h1 r; q4 W# N
A "defaults" section sets default parameters for all other sections following. c" |' }! ^0 B  H- w7 d
its declaration. Those default parameters are reset by the next "defaults"+ o: D% o# k% d" m
section. See below for the list of parameters which can be set in a "defaults"
8 y. g7 ^- w$ C5 ?# g- H2 R- ~section. The name is optional but its use is encouraged for better readability." z" ^4 W: I; I* ^# t" b4 k/ T

$ x  v" ~+ K. ^: O& E9 [A "frontend" section describes a set of listening sockets accepting client# A$ V6 P; \; x* A$ Q9 t" z7 I
connections.& w7 G2 b' {6 J- j! b* g- G- a2 ^
8 x) W  U" S1 a1 [0 X" U' Y( L
A "backend" section describes a set of servers to which the proxy will connect
! g5 h6 w. i7 c7 B0 lto forward incoming connections.
" A. P, x3 b& @5 b
4 H, s- S, k: ]A "listen" section defines a complete proxy with its frontend and backend
! D0 }5 c5 s4 c+ F% x; Z# Rparts combined in one section. It is generally useful for TCP-only traffic.0 q$ u, R* M0 s4 a% P* d' @
2 z, w7 y& r0 Z) W
All proxy names must be formed from upper and lower case letters, digits,/ {' s* h9 l; m: c7 l1 K/ {
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are8 s4 L; D4 @: |% l
case-sensitive, which means that "www" and "WWW" are two different proxies./ }# F2 c3 i, i5 L- {
8 q/ z( l5 \% N" {8 n
Historically, all proxy names could overlap, it just caused troubles in the2 g& b# t9 I; T6 u
logs. Since the introduction of content switching, it is mandatory that two
+ s' v  {; k3 S5 Qproxies with overlapping capabilities (frontend/backend) have different names.
% I' f4 ]/ e( j5 E( F0 y' _% VHowever, it is still permitted that a frontend and a backend share the same% f( O5 j  o- Q2 ~
name, as this configuration seems to be commonly encountered.& X* r4 c: i' g# j& V

! }% C2 G: O# o$ s4 A# QRight now, two major proxy modes are supported : "tcp", also known as layer 4,
6 d! N9 o! A" F% Nand "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards; Z4 _* X+ \* a7 m, r! j8 Q: n. j
bidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the: z3 F, V7 k5 s. ?. z9 a
protocol, and can interact with it by allowing, blocking, switching, adding,
& }& X$ E+ C7 Z. H3 g& Qmodifying, or removing arbitrary contents in requests or responses, based on
3 g& p) _2 ~8 O3 Tarbitrary criteria.
3 E  A+ E' X4 D9 e+ k8 [  K  B
$ x$ |+ c- O0 n, }7 L& Q0 ]) t' r# h$ t0 z; n1 P  x
4.1. Proxy keywords matrix
9 m8 ^) N- l$ X- K9 f  g" G1 u--------------------------9 T% H0 X  i- \6 Z
$ F" P. m( y! _5 r* w
The following list of keywords is supported. Most of them may only be used in a
( D' e- E6 @; i1 \0 ?( P. climited set of section types. Some of them are marked as "deprecated" because
2 U& y9 y% b$ o8 g( Uthey are inherited from an old syntax which may be confusing or functionally8 K3 M0 k9 `- _, r8 `2 R5 b  L
limited, and there are new recommended keywords to replace them. Keywords/ X" }8 }3 s; y* f" d  q7 K
marked with "(*)" can be optionally inverted using the "no" prefix, eg. "no/ e+ i! [% s9 g* s2 E
option contstats". This makes sense when the option has been enabled by default# B1 i) H3 m5 B( w: A4 z/ q4 K* I
and must be disabled for a specific instance. Such options may also be prefixed
* D2 H7 V2 p5 s. ~9 swith "default" in order to restore default settings regardless of what has been
: k, V9 ]; Q  S( {specified in a previous "defaults" section.) d% N3 g6 ^7 x, ^
4 S* h) B( A6 _1 {  l* L
! y$ `4 K# b9 Y( U7 U
keyword                              defaults   frontend   listen    backend
& n* U$ h' L: o/ ~  C, ]------------------------------------+----------+----------+---------+---------
( n4 C5 m" a1 M- _" F# n! d; Lacl                                       -          X         X         X
  D! l$ Z/ |! D$ b4 F2 dappsession                                -          -         X         X
. ?# ^$ O6 W) r) f, Q- E1 J! Ebacklog                                   X          X         X         -
; K9 r1 G0 T5 a8 p7 W1 }! hbalance                                   X          -         X         X/ l' t# b; s! v
bind                                      -          X         X         -& t5 y7 L5 x% @1 P9 q! p, q
bind-process                              X          X         X         X! }/ O9 C- d; u* [$ l: n& c. Q
block                                     -          X         X         X
; J0 U; O* F1 O4 acapture cookie                            -          X         X         -% t5 i9 |  V, T* U0 [
capture request header                    -          X         X         -
* i" |+ |  p/ ~0 I' h& p& Pcapture response header                   -          X         X         -2 v0 J# g. S7 _4 }" G" Y
clitimeout                  (deprecated)  X          X         X         -( c8 q0 ~: ?% X
contimeout                  (deprecated)  X          -         X         X
' d6 y: z7 a- L( N0 I; K' bcookie                                    X          -         X         X; C$ y1 z' V0 F" L) |
default-server                            X          -         X         X
% n* M: u1 J! I3 o2 Ndefault_backend                           X          X         X         -
: l( D2 U: c; t0 Y) U1 sdescription                               -          X         X         X
4 Q. g: _; L. W4 r& ndisabled                                  X          X         X         X
0 \% m1 i/ V1 F8 l3 H9 {2 tdispatch                                  -          -         X         X  W) B# k! M4 y" i& e
enabled                                   X          X         X         X
+ _& o( I  u$ P, c! ~errorfile                                 X          X         X         X8 q, I& K9 e/ h2 G, M, g) g
errorloc                                  X          X         X         X
" \. G# F" f: Uerrorloc302                               X          X         X         X
/ P( k( l3 u+ ~/ j! R; k; ^1 T-- keyword -------------------------- defaults - frontend - listen -- backend -6 h+ `3 g$ i  b$ U4 g
errorloc303                               X          X         X         X
0 b5 I' e/ K; p$ Q6 @force-persist                             -          X         X         X
0 @  E3 R8 _" G% @" r0 nfullconn                                  X          -         X         X
3 Y$ f% H+ q5 y# h' @grace                                     X          X         X         X
# x6 |. S. C: ~4 F- b; {3 X. h% mhash-type                                 X          -         X         X
  V" t7 c! {/ f0 R0 ~; Bhttp-check disable-on-404                 X          -         X         X
5 Z, i* `+ J5 w! yhttp-check expect                         -          -         X         X
1 f- c1 F& a& W$ v0 Yhttp-check send-state                     X          -         X         X4 {& g! b7 v, X* ]5 W" J- j8 y
http-request                              -          X         X         X
: ~$ v0 F% |. t$ Oid                                        -          X         X         X
  M: h' f  j0 A$ p* G: m7 Jignore-persist                            -          X         X         X# u5 R! @: e5 W" M
log                                       X          X         X         X
# }2 K: i7 r( b4 H! A" V/ l: Pmaxconn                                   X          X         X         -8 ~: m  \) t# T, M) o
mode                                      X          X         X         X
5 x. F5 H2 w+ v& B) e) ]monitor fail                              -          X         X         -
/ Y: z! A# g! E5 @7 z& r6 n7 Smonitor-net                               X          X         X         -
, {6 Z7 E* o1 y2 ?" m/ D/ B/ Amonitor-uri                               X          X         X         -, b) k: y" K2 ~6 z, b& O
option abortonclose                  (*)  X          -         X         X
, s3 M+ o4 Q% C! A8 g( u# Koption accept-invalid-http-request   (*)  X          X         X         -
9 D" \" U& H% S0 Goption accept-invalid-http-response  (*)  X          -         X         X( P; K- M: a$ I+ B/ _
option allbackups                    (*)  X          -         X         X
$ t. Z$ D: W/ P% [9 b/ Foption checkcache                    (*)  X          -         X         X4 E) c  d. j; A  D
option clitcpka                      (*)  X          X         X         -
! U& ]) g0 d& N4 Noption contstats                     (*)  X          X         X         -
) ~2 ~9 m  R7 @/ G# eoption dontlog-normal                (*)  X          X         X         -
1 g9 b4 M) G& l; c" H& K8 Y1 t: Z! ?option dontlognull                   (*)  X          X         X         -) d* v0 m. j% r6 F2 ?1 @" i- x
option forceclose                    (*)  X          X         X         X
0 B' |! }/ T  Z8 Z: M7 E) x3 y3 v-- keyword -------------------------- defaults - frontend - listen -- backend -
. L1 f% v% ?  {& E5 Foption forwardfor                         X          X         X         X
" o) b- P; v& i; t6 B  d4 Woption http-no-delay                 (*)  X          X         X         X
! b( Y) e- P5 X& |6 ^5 \& Boption http-pretend-keepalive        (*)  X          X         X         X
& s, {9 H/ g  R% x! ooption http-server-close             (*)  X          X         X         X9 y- @: r" l. e$ a7 y; ^1 o6 `$ l4 z
option http-use-proxy-header         (*)  X          X         X         -' H( M  O! v  X) p9 R( y7 W+ N
option httpchk                            X          -         X         X/ l/ d1 }) G+ w7 F0 S
option httpclose                     (*)  X          X         X         X7 f8 }% s2 a8 H
option httplog                            X          X         X         X
3 f& [9 e) e& Toption http_proxy                    (*)  X          X         X         X
# F$ u0 }: w4 `option independant-streams           (*)  X          X         X         X
) E! f$ r) \) z9 g. xoption ldap-check                         X          -         X         X$ Y8 }/ d& J& A: g9 U
option log-health-checks             (*)  X          -         X         X$ G4 X) h, H1 s
option log-separate-errors           (*)  X          X         X         -
8 H6 ?& O9 U, f& h& o6 koption logasap                       (*)  X          X         X         -
$ ?2 Y( G! q) o5 D& c! E' Moption mysql-check                        X          -         X         X  b$ |7 H0 }) [* F  X& T
option nolinger                      (*)  X          X         X         X
0 T$ R$ x' L) Z: \8 Z6 ^" Goption originalto                         X          X         X         X$ b) H; i& [0 ~5 n* F
option persist                       (*)  X          -         X         X: d5 ?* A4 o- \+ `
option redispatch                    (*)  X          -         X         X/ Z( i( Z% F' k( ?- w
option smtpchk                            X          -         X         X
6 \# l6 ~  o: ]option socket-stats                  (*)  X          X         X         -
& n6 ^2 u+ F0 X% j3 V2 H4 noption splice-auto                   (*)  X          X         X         X, V, d8 \, Z' T* `
option splice-request                (*)  X          X         X         X
. U! y* c5 ?4 J6 R; G7 F& voption splice-response               (*)  X          X         X         X
# c3 s, n" |6 x+ \# c8 n! ^# yoption srvtcpka                      (*)  X          -         X         X/ K* I1 z. o& T& d" z3 w# v/ S
option ssl-hello-chk                      X          -         X         X
7 J; Z6 p2 W! C! n-- keyword -------------------------- defaults - frontend - listen -- backend -
& W9 X) r1 h- r0 s: N. q* zoption tcp-smart-accept              (*)  X          X         X         -2 S% f2 c' j1 h' q, ~
option tcp-smart-connect             (*)  X          -         X         X0 x5 M* T* w8 H( k: {
option tcpka                              X          X         X         X! j' H: n1 h+ i/ l/ @2 f8 b* Z
option tcplog                             X          X         X         X
, L, [+ p& ^7 Q* K9 A" Koption transparent                   (*)  X          -         X         X
/ {3 A  P7 E  T, spersist rdp-cookie                        X          -         X         X" G# h% `5 z7 u$ B" y, J. w; G
rate-limit sessions                       X          X         X         -' _: [6 q: N* H
redirect                                  -          X         X         X* W: h  W# C1 b# ?! q& _2 I0 m
redisp                      (deprecated)  X          -         X         X+ I( v: p& J5 U' i  O3 a
redispatch                  (deprecated)  X          -         X         X
9 I' F. r/ y0 a1 F/ ?7 w. Nreqadd                                    -          X         X         X" [2 I+ X- Z* d
reqallow                                  -          X         X         X
5 ]2 ^) b# W' K8 e& wreqdel                                    -          X         X         X) ^) i. j7 d/ u
reqdeny                                   -          X         X         X, {- X' K( m& {8 V, e
reqiallow                                 -          X         X         X) s) y# Z$ c9 `/ w& k  ~, v
reqidel                                   -          X         X         X# [: ?$ |+ ]( N1 U
reqideny                                  -          X         X         X3 I, f9 y/ J/ D' f9 r5 c0 t
reqipass                                  -          X         X         X$ ~  b7 f  B' V& E4 W) n- \2 n8 X
reqirep                                   -          X         X         X
. k0 m: `- e8 _& }9 f# areqisetbe                                 -          X         X         X
5 Y% v1 M- k4 C. Q1 l3 d; e0 Qreqitarpit                                -          X         X         X
2 T2 x$ B* |) D* r6 Z8 Areqpass                                   -          X         X         X
: \/ R8 e$ Y* U5 L/ y' ireqrep                                    -          X         X         X
" m3 ?8 s+ C: k. w. R; h/ }-- keyword -------------------------- defaults - frontend - listen -- backend -$ Y6 m! C8 q4 Q- j8 T7 ?
reqsetbe                                  -          X         X         X
, g! g) T% [$ W8 V" n& C" @3 rreqtarpit                                 -          X         X         X' I% K7 s& f1 }7 ^% }* J( }; S
retries                                   X          -         X         X8 W! H3 L* s/ D% X1 N
rspadd                                    -          X         X         X& h/ k% t4 E$ r7 K% e
rspdel                                    -          X         X         X
; |3 d" r: h$ ^5 ^rspdeny                                   -          X         X         X4 g# L$ H* G, {; D/ p) K+ I
rspidel                                   -          X         X         X5 {8 ^: y$ V$ q5 b2 U/ U/ N. o! q
rspideny                                  -          X         X         X5 i' b! G/ w0 n. I4 l2 x
rspirep                                   -          X         X         X4 T0 X& f' r, C# `0 s' x. E& f! P( B
rsprep                                    -          X         X         X
; L- e5 n* u! o) j) Dserver                                    -          -         X         X
, D9 ^) A" Z4 @$ y1 w% osource                                    X          -         X         X& w* u: K' H3 h* Y; }( _% o0 X$ p
srvtimeout                  (deprecated)  X          -         X         X
& ]! m7 A  Y5 L4 I: Pstats admin                               -          -         X         X
: M1 B/ Y& ?" m$ n2 q4 ?7 [7 bstats auth                                X          -         X         X  W9 J! V  o* s: R- w
stats enable                              X          -         X         X6 b% e& f' E9 Y: ?  [  s# Y4 P
stats hide-version                        X          -         X         X
* s8 b2 R/ o# [$ Dstats http-request                        -          -         X         X
2 X- Q8 @% U6 Dstats realm                               X          -         X         X
/ N/ P# r3 |2 f( }7 tstats refresh                             X          -         X         X
) t8 Q9 S. n& K' K5 Jstats scope                               X          -         X         X
3 H6 M! \" u% L7 C7 d6 o- |stats show-desc                           X          -         X         X
$ D# M3 M9 P0 X4 Rstats show-legends                        X          -         X         X
. ?- D9 Y' H+ [stats show-node                           X          -         X         X
* f! ]8 b/ N! Vstats uri                                 X          -         X         X
  P/ a' M  J( Y7 K-- keyword -------------------------- defaults - frontend - listen -- backend -
& v, a8 T& \( A7 Jstick match                               -          -         X         X: F6 R! i! o4 y$ d
stick on                                  -          -         X         X
0 c! R4 U& Q7 [; F2 jstick store-request                       -          -         X         X
0 g4 p5 Z9 g8 x# D9 istick-table                               -          -         X         X
! L: e% F/ {5 \& etcp-request content accept                -          X         X         -5 k: [1 m% |) P1 o
tcp-request content reject                -          X         X         -9 K% Z" i% R2 ?
tcp-request inspect-delay                 -          X         X         -
% O! b* O7 K( etimeout check                             X          -         X         X
6 R1 P6 B8 }9 t# v2 _/ S' ?' ntimeout client                            X          X         X         -% A) o" ]5 N7 l0 B; }$ Q$ K. O
timeout clitimeout          (deprecated)  X          X         X         -
+ t3 C' n3 f8 z  @timeout connect                           X          -         X         X, o: h& P2 R& I$ {3 q3 H  ^
timeout contimeout          (deprecated)  X          -         X         X6 z' `4 y7 A3 `; W1 e
timeout http-keep-alive                   X          X         X         X
5 ?2 l# p/ q3 Z3 wtimeout http-request                      X          X         X         X
7 h' |7 u" N) H% f1 g0 d4 Utimeout queue                             X          -         X         X7 W9 ?# @. o. ~% W0 t+ a
timeout server                            X          -         X         X
: t6 r! d. W2 S6 Y0 e. q0 Gtimeout srvtimeout          (deprecated)  X          -         X         X
% {: g0 J- V  G: otimeout tarpit                            X          X         X         X
; x% @7 u4 n! U8 Ktransparent                 (deprecated)  X          -         X         X
& H/ {' C/ ~1 _+ @: quse_backend                               -          X         X         -3 @+ W# Z1 i5 f+ m8 |- f2 {
------------------------------------+----------+----------+---------+---------
4 ?$ y( G& T8 ?6 s# F keyword                              defaults   frontend   listen    backend- H2 X7 z" @4 H( ^6 Y
) g  E; J9 L- c% a
0 G; t$ w% v3 M: t; G% K% S
4.2. Alphabetically sorted keywords reference' m% f8 q4 [0 q4 o
---------------------------------------------* s* p! K8 [3 @0 x2 L& A7 _( ?4 f
+ z3 w, G7 c' b' a# I
This section provides a description of each keyword and its usage.5 D9 a8 Q" t4 ?6 U+ D$ S2 T

. e8 W3 u6 w3 K! g# \
; x" s$ k. u7 y. W; ~0 ^acl <aclname> <criterion> [flags] [operator] <value> ...- Y# b. }6 o$ w4 H2 d5 H
  Declare or complete an access list.
, {+ Z, D$ [' v% U" m$ M" J8 b/ |  May be used in sections :   defaults | frontend | listen | backend( q( |5 f2 ~# G) }8 E' ~% n' d+ B
                                 no    |    yes   |   yes  |   yes* R+ `6 l2 W4 c9 `% O3 J
  Example:5 V/ u7 l% q# @' E1 p; z6 [
        acl invalid_src  src          0.0.0.0/7 224.0.0.0/38 Z8 @, W5 n3 h* C7 M! }
        acl invalid_src  src_port     0:1023# k! S1 K1 Z2 Q" b
        acl local_dst    hdr(host) -i localhost
! U1 k5 a1 j! t1 H6 p
( C( ]/ t, K( e* c2 t  See section 7 about ACL usage.+ F, I0 r3 t$ a, X) x$ `

2 _$ Y3 @" Y4 L& h6 S& o' C- d
5 H/ j) L8 V- @) k6 P: E$ tappsession <cookie> len <length> timeout <holdtime>
- {3 ^* H6 H  S: D2 f           [request-learn] [prefix] [mode <path-parameters|query-string>]
& _" ^6 V' s4 G2 @6 z. Y  Define session stickiness on an existing application cookie.8 C5 c, S: _" z7 q
  May be used in sections :   defaults | frontend | listen | backend
3 d, E- G2 k8 }/ ?; a                                 no    |    no    |   yes  |   yes& t/ J( E$ P! g6 ^/ |: w
  Arguments :
; \6 }; S2 }% b) e2 i% C    <cookie>   this is the name of the cookie used by the application and which
* }% A, b: o& C. E4 i               HAProxy will have to learn for each new session.
0 V' T* W) a/ _0 R' \
9 w$ ]- \* d+ `6 x: U6 _  ^" C    <length>   this is the max number of characters that will be memorized and
- E6 j% H  }7 J/ o5 y9 @2 R- x               checked in each cookie value.) ^( s8 [5 ~, @

) }" d: F) O2 g* @+ m    <holdtime> this is the time after which the cookie will be removed from
! y' P0 W3 d0 l/ G' B6 _7 ^               memory if unused. If no unit is specified, this time is in( c+ X# M) h* a' ?' @1 a  Q
               milliseconds.
" ]. s, @& j+ O) }
3 i/ }" P3 K+ i3 N    request-learn6 I$ i0 O/ y  y7 [0 m2 |6 |& e
               If this option is specified, then haproxy will be able to learn" k. x1 O3 ~( H& H: Q# [6 Q
               the cookie found in the request in case the server does not
( b" ~% I. V6 l1 B- p1 C# v               specify any in response. This is typically what happens with
& C6 d6 w! F2 u! ]3 y" m, i               PHPSESSID cookies, or when haproxy's session expires before
0 c1 P8 b4 k8 P/ `' U8 c2 |4 ~               the application's session and the correct server is selected.; L0 N$ h! E9 r6 [
               It is recommended to specify this option to improve reliability.
& }% E. Q7 T7 l6 n7 u4 a, T; }3 o9 p  Y
    prefix     When this option is specified, haproxy will match on the cookie
5 m, E# t$ \2 @- R3 P               prefix (or URL parameter prefix). The appsession value is the& [- x, s! V/ @
               data following this prefix.) R1 p9 X1 w: G7 v5 x1 \
  |) e, V" n8 p
               Example :
6 `: j% M. }9 x% q               appsession ASPSESSIONID len 64 timeout 3h prefix- ]8 e& p# q0 U8 }

% |6 o2 u8 g4 m5 ]               This will match the cookie ASPSESSIONIDXXXX=XXXXX,1 ?, R; f' \5 b4 e  i4 e
               the appsession value will be XXXX=XXXXX.
& f* U- }9 H" P7 d3 @- T; K: u
, v$ ~. _) ^) F# n( T: ~    mode       This option allows to change the URL parser mode./ _8 a# N* Z& V5 G* Q3 Q, P9 W
               2 modes are currently supported :
& c, U8 e  S0 u3 U9 V               - path-parameters :
) u) N; y) [% q7 m/ x                 The parser looks for the appsession in the path parameters
1 l) @. b9 d" ^* ]3 _                 part (each parameter is separated by a semi-colon), which is5 H( S  l. T. n3 e! l
                 convenient for JSESSIONID for example.' D( j4 I- H2 p5 r4 i5 X- o8 {
                 This is the default mode if the option is not set.( C! Z( U2 e  V6 |- @; N: |
               - query-string :# V/ e2 w; K  L' K9 {
                 In this mode, the parser will look for the appsession in the
  w, P& y4 ?$ D4 b' T3 u6 R                 query string., M- ^+ R1 `; {/ R8 J6 A5 H. M9 Q
9 r1 \3 W4 f; q2 ]% l% }
  When an application cookie is defined in a backend, HAProxy will check when, p8 M* H4 k$ G
  the server sets such a cookie, and will store its value in a table, and) d& X: M2 b- y/ B% i% \. u
  associate it with the server's identifier. Up to <length> characters from2 r4 c- F' g" k3 v
  the value will be retained. On each connection, haproxy will look for this
& O* n6 ]) ]. t0 j" }0 E6 w! X1 L+ y  cookie both in the "Cookie:" headers, and as a URL parameter (depending on' F  I  @  Z5 p0 o' Z$ R
  the mode used). If a known value is found, the client will be directed to the" H  k: y4 Z9 c( v2 u7 H
  server associated with this value. Otherwise, the load balancing algorithm is
/ D5 L: h- v3 F& R8 [  applied. Cookies are automatically removed from memory when they have been; b% }- P- c9 N+ E: g9 c' v5 E3 Z
  unused for a duration longer than <holdtime>.& w7 u  F) P$ q! S9 K- N
" B( `7 L2 V7 {. S5 U& p5 a% h" q
  The definition of an application cookie is limited to one per backend.
+ ~. M1 x8 z& \$ b7 W, I. {. m) P5 N! D2 ~
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
1 V$ i+ q% r) @  `: b         unless you know what you do : memory is not shared between the5 ^0 l# m; w& L/ P+ [
         processes, which can result in random behaviours.3 S/ Z6 w  z8 w0 P. A2 b
: L5 C2 w5 {4 H& Z6 X
  Example :1 S* V3 }9 N6 Q$ w& A2 L
        appsession JSESSIONID len 52 timeout 3h
0 g9 V/ i/ l4 b% A/ _2 H6 W: n  |' B
( Y6 R: ~7 Q1 ^- x& b8 `) n  See also : "cookie", "capture cookie", "balance", "stick", "stick-table",7 t' _! ?& m' t0 a+ {
             "ignore-persist", "nbproc" and "bind-process"." J! ^( ?* @  N7 C+ z3 M* E  P

- f+ h8 n5 t7 e) Y4 J' H5 S
$ U7 u% ?. f$ W0 F, a* d6 nbacklog <conns>
2 o4 X$ K1 o' E2 ?. S9 b  Give hints to the system about the approximate listen backlog desired size* v9 w- Z2 Y- t6 D2 E# ~& i
  May be used in sections :   defaults | frontend | listen | backend
$ I% |6 f" h* }+ {2 M- k& I: @                                 yes   |    yes   |   yes  |   no
) p1 B3 h( k0 L& d  Arguments :4 `* A. e+ |) Q2 _6 S$ K4 F8 U. p
    <conns>   is the number of pending connections. Depending on the operating
1 l5 h% m9 r  x! z* k              system, it may represent the number of already acknowledged# W' h+ `' A/ p6 q2 W
              connections, of non-acknowledged ones, or both.  ~. r( p. ^6 Y6 M* J
8 I3 m: t) V* }2 x
  In order to protect against SYN flood attacks, one solution is to increase
; N! W8 C% p' N. I9 Z  the system's SYN backlog size. Depending on the system, sometimes it is just
! x7 x  m9 c, Y  tunable via a system parameter, sometimes it is not adjustable at all, and
" Z4 Y) n8 i' ]7 `/ _" m  sometimes the system relies on hints given by the application at the time of
. @/ {# X  [4 v% b  the listen() syscall. By default, HAProxy passes the frontend's maxconn value- e, w9 R: I9 m* H- T
  to the listen() syscall. On systems which can make use of this value, it can4 B* r6 k  I  P
  sometimes be useful to be able to specify a different value, hence this) }* D5 I7 R# ^) ?% v  W
  backlog parameter.
7 @) O( Y* F5 o/ ]7 v* A; ]6 k; c/ f9 X* v7 r* }
  On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is
- o" G, V, b$ T1 V  used as a hint and the system accepts up to the smallest greater power of
2 f) R  J5 N3 i9 o2 k# V- f  two, and never more than some limits (usually 32768).
' b* j5 g! T" Q: {& e8 l& n9 F) f9 O  X- x5 Z$ c6 t
  See also : "maxconn" and the target operating system's tuning guide.
' C0 [; b9 @* B6 t# m4 ^
' O3 g/ J- t5 B' f$ |9 ^& {& c5 {
# W: D/ m- L, L8 p9 b" j' }( lbalance <algorithm> [ <arguments> ]
4 f+ b$ d9 ^. Ibalance url_param <param> [check_post [<max_wait>]]  i" o% V$ ?& }* E. W0 X9 W
  Define the load balancing algorithm to be used in a backend.
' V" F% e$ e% o( J9 L* T/ H  May be used in sections :   defaults | frontend | listen | backend
: U5 P2 u3 U' C+ T                                 yes   |    no    |   yes  |   yes5 b2 ?! V5 B4 U9 {
  Arguments :9 P' c) F( L0 r. k
    <algorithm> is the algorithm used to select a server when doing load( I& E% V7 \/ ~% G
                balancing. This only applies when no persistence information
) x- E8 T  e7 r7 @' @5 Z                is available, or when a connection is redispatched to another
- Z7 ~/ s9 n% j# I6 G( T& }                server. <algorithm> may be one of the following :/ h  T& ]+ V& m0 Y
( F4 Q- m6 u( L% F% Z# ~, x, o" ?
      roundrobin  Each server is used in turns, according to their weights., K- W4 ^8 m6 J. ?0 W5 Q
                  This is the smoothest and fairest algorithm when the server's
9 D7 L# R) ]* K' e                  processing time remains equally distributed. This algorithm& I" c+ R+ i$ x) S, d
                  is dynamic, which means that server weights may be adjusted
  V7 m1 L( l) I* U+ m                  on the fly for slow starts for instance. It is limited by& X% P# x6 S* e4 u8 J8 }
                  design to 4095 active servers per backend. Note that in some/ N2 @; u( k; o* h
                  large farms, when a server becomes up after having been down. P0 n' J$ I0 C+ m" D2 t/ W) n& j
                  for a very short time, it may sometimes take a few hundreds
6 H+ }  V$ V; m. N# N                  requests for it to be re-integrated into the farm and start
, V$ c# A# Q, P) r  R/ D                  receiving traffic. This is normal, though very rare. It is. Q1 _- h; Z  E1 I5 n
                  indicated here in case you would have the chance to observe  B  E! ?# y# I" C* p' ]* g1 d
                  it, so that you don't worry.
% F+ H6 Q7 g1 T: h0 o! R
. Y, Q3 \$ Z  N+ c8 x5 A7 c      static-rr   Each server is used in turns, according to their weights.
! L" k, P" K2 V- n7 x                  This algorithm is as similar to roundrobin except that it is1 P7 J* E. ~0 n% T  \
                  static, which means that changing a server's weight on the
4 V+ |% o! `' X4 Z& n' o" l  n2 D                  fly will have no effect. On the other hand, it has no design( e8 }! \9 A8 w7 {$ U+ n
                  limitation on the number of servers, and when a server goes9 S* l& d! l4 M  E( k8 d4 k. C' x
                  up, it is always immediately reintroduced into the farm, once
- G9 |- q  |" y                  the full map is recomputed. It also uses slightly less CPU to
5 @4 F1 U: p4 J* l; M9 y9 f4 C                  run (around -1%).
- @4 P  l0 x; w$ R! m( v) Y. i6 n4 z% A2 u, S9 S$ L4 f
      leastconn   The server with the lowest number of connections receives the5 Y/ W5 u# W1 a, S
                  connection. Round-robin is performed within groups of servers
0 C0 X) b6 _, g- K8 D  `                  of the same load to ensure that all servers will be used. Use
- T3 J, k. y* g! j. n" t                  of this algorithm is recommended where very long sessions are3 h+ ?: w8 U$ O  B! k2 ]  q  T
                  expected, such as LDAP, SQL, TSE, etc... but is not very well
( D8 E( ~( z- T3 o, Z2 D  K                  suited for protocols using short sessions such as HTTP. This
0 d3 \7 n+ d# E% j                  algorithm is dynamic, which means that server weights may be
! r% S; ^: G' ]& p$ N                  adjusted on the fly for slow starts for instance.# U6 \7 @+ z8 q; z. Z) l: D2 }# |/ S

  v# H4 i* f5 W2 r      source      The source IP address is hashed and divided by the total3 \$ J# F9 k1 Y8 s% E; W4 u# p7 l
                  weight of the running servers to designate which server will
9 }& |; d5 A( l; R                  receive the request. This ensures that the same client IP: G4 F0 j. B) d. }0 ^& i; Z
                  address will always reach the same server as long as no, S# i) g1 O$ G5 l; f) \6 q, j
                  server goes down or up. If the hash result changes due to the+ m' e# f! s! _, r7 |- _& ^: [" j: Z* |. a
                  number of running servers changing, many clients will be$ t8 Y( l$ \: a7 t- t. d
                  directed to a different server. This algorithm is generally
' w( M4 Q( d6 q! q; t5 X                  used in TCP mode where no cookie may be inserted. It may also
  P0 ~4 B5 q& I0 k# v                  be used on the Internet to provide a best-effort stickiness* k. Y+ x- i, [8 ?- [
                  to clients which refuse session cookies. This algorithm is# }( B- @, G- {4 q7 O, P% x
                  static by default, which means that changing a server's6 y- [/ s' `  g0 U' X; N8 X( G- v
                  weight on the fly will have no effect, but this can be
# i  s: j% G( @/ N7 y' b$ p1 ^                  changed using "hash-type".% V" E# I. k# I; O. P

" X7 B4 w0 d* E& M5 P, A6 T3 h1 B- g      uri         This algorithm hashes either the left part of the URI (before# i, ~* ?1 U  ]. Z3 W! e( a4 ?
                  the question mark) or the whole URI (if the "whole" parameter
# t- {2 c) t, E% Z' F2 _  X8 ^$ H                  is present) and divides the hash value by the total weight of
; j! V) I7 F* a9 |                  the running servers. The result designates which server will
$ w/ S' }# P* A- L* w                  receive the request. This ensures that the same URI will
5 Q: N% `4 B! \* q! M( s6 ]4 ^5 b                  always be directed to the same server as long as no server# w6 _1 y( e0 N; @( J! g9 o
                  goes up or down. This is used with proxy caches and1 V9 X  ^  H" {3 g' |# G
                  anti-virus proxies in order to maximize the cache hit rate.( F) Y5 R# l, K
                  Note that this algorithm may only be used in an HTTP backend.1 Q, B5 f6 z$ X7 l) ~% e# C8 v
                  This algorithm is static by default, which means that" H' b; \( p: |. Y4 @: v( Y9 n
                  changing a server's weight on the fly will have no effect,
, r, s2 [8 \7 I6 d2 x: `) u4 ^" e1 g                  but this can be changed using "hash-type".
4 @8 c2 X' ?/ h" r
9 K5 C2 x# C8 ~8 E. q                  This algorithm supports two optional parameters "len" and
# b! t' z# j5 E/ O* L. D                  "depth", both followed by a positive integer number. These! J! G( B6 m, T! K
                  options may be helpful when it is needed to balance servers8 @7 L4 r' `- D* g, K& A
                  based on the beginning of the URI only. The "len" parameter2 x: f0 d+ |2 |3 F
                  indicates that the algorithm should only consider that many; z9 X, V. l, K1 }3 q% K
                  characters at the beginning of the URI to compute the hash.* M2 k1 [+ r# G& Y2 k; H# a
                  Note that having "len" set to 1 rarely makes sense since most/ V- j! e! J6 K( Y( s  V
                  URIs start with a leading "/".* l$ X- c9 a" w0 K  T2 O
4 L' A+ Y! p) b6 T9 v
                  The "depth" parameter indicates the maximum directory depth/ E7 z4 g1 y6 q2 U0 B7 @
                  to be used to compute the hash. One level is counted for each9 m. h- l( E: {! Q0 s
                  slash in the request. If both parameters are specified, the  t# x7 m2 F8 p% [7 P$ r0 N
                  evaluation stops when either is reached.
( s- S2 L7 Z0 b4 K. _+ t- x8 k9 M( |% Z: W& \- [/ d7 S
      url_param   The URL parameter specified in argument will be looked up in  j! Q  [( w- k+ t) V2 y. B9 U" ^8 ~
                  the query string of each HTTP GET request.
- j3 x( |7 I. z+ y7 m
" g7 H9 F$ j: O: K+ b- n                  If the modifier "check_post" is used, then an HTTP POST
+ S4 D3 B6 h8 ?  c/ p                  request entity will be searched for the parameter argument,
8 m. ]) _3 Q. [5 c                  when it is not found in a query string after a question mark& M, g9 |* C2 g7 U' I8 S1 ]2 _: Y7 d
                  ('?') in the URL. Optionally, specify a number of octets to
3 m  b+ n5 q9 y! r- c2 i% e1 E                  wait for before attempting to search the message body. If the
2 b- s: j# ]8 \+ u$ o6 S* I) n. p4 L* @& M                  entity can not be searched, then round robin is used for each
& ?" t& {- I$ s0 {+ f: j1 }$ H                  request. For instance, if your clients always send the LB' b7 U: ]3 ~: T
                  parameter in the first 128 bytes, then specify that. The
. k. K, D1 G" R                  default is 48. The entity data will not be scanned until the
3 v; M5 K* i: V" A/ m+ v# h* w. @                  required number of octets have arrived at the gateway, this
$ C2 k2 d9 J+ F, L6 ^) I/ T                  is the minimum of: (default/max_wait, Content-Length or first# n9 q" V" H# B" j2 ]/ W
                  chunk length). If Content-Length is missing or zero, it does1 ^5 h# }$ M' {; C$ ?( z; I
                  not need to wait for more data than the client promised to
1 P0 u2 V* l+ D' T5 W                  send. When Content-Length is present and larger than  e! ~, J4 N9 r6 @) s3 H4 C
                  <max_wait>, then waiting is limited to <max_wait> and it is  P$ N- @* D/ G3 Q- D4 [6 b
                  assumed that this will be enough data to search for the0 a; ^2 z4 x( C9 y, G7 @
                  presence of the parameter. In the unlikely event that( l- P8 d1 t8 z! |' g
                  Transfer-Encoding: chunked is used, only the first chunk is
4 ^# }! h, A9 V0 M* w. v; }                  scanned. Parameter values separated by a chunk boundary, may
; S, F5 t$ L" f4 `6 [7 I                  be randomly balanced if at all.! D: e5 z6 {& \0 n6 D. `

9 G7 {9 X! O+ P                  If the parameter is found followed by an equal sign ('=') and' V% M% t! l( I0 S3 x, D4 _8 {# m' B
                  a value, then the value is hashed and divided by the total
' g2 x7 P2 Y2 H: T; x5 n                  weight of the running servers. The result designates which( T- |8 g/ v! ]' B
                  server will receive the request.
' o" C. N; w4 h+ P7 f
1 b6 F$ Q$ h) ~. B6 s                  This is used to track user identifiers in requests and ensure0 k. u) K% U! S) _0 C
                  that a same user ID will always be sent to the same server as9 S* a, R  M6 X  W, ^2 j' L) z
                  long as no server goes up or down. If no value is found or if
: J2 I6 k3 L8 ^' B# Z                  the parameter is not found, then a round robin algorithm is/ b! K- d" R3 ?; }
                  applied. Note that this algorithm may only be used in an HTTP! a& r: B1 f5 p: ~
                  backend. This algorithm is static by default, which means
& K7 S- G  k/ v% ^0 ?% }                  that changing a server's weight on the fly will have no
% c: b: r6 z  c4 S                  effect, but this can be changed using "hash-type".
1 I# c$ a7 R+ n! w3 N
9 p* {/ z+ U; i- K. a1 Q- r( v      hdr(<name>) The HTTP header <name> will be looked up in each HTTP request.& u) l" v3 W' [! k
                  Just as with the equivalent ACL 'hdr()' function, the header" r2 }8 F* j4 v/ s1 O
                  name in parenthesis is not case sensitive. If the header is
3 T- A& F& i* E8 ?/ s; Y1 j6 Y                  absent or if it does not contain any value, the roundrobin
* B  T& u, D7 v" G$ r9 y) n                  algorithm is applied instead.
/ k: T9 Z. n9 g+ s; i3 f0 K8 G7 h( A+ }  ]9 \) {6 [
                  An optional 'use_domain_only' parameter is available, for/ s, {$ J, `. L8 v* r9 r! c
                  reducing the hash algorithm to the main domain part with some
( D. z  v' j/ H5 H7 ?                  specific headers such as 'Host'. For instance, in the Host
" c" H; X1 [, W' M% A                  value "haproxy.1wt.eu", only "1wt" will be considered.
" ?; D4 ]: R3 o% J: G
% ~8 i# P' X  W7 S7 k                  This algorithm is static by default, which means that* L& ~8 [% P0 ]7 Y
                  changing a server's weight on the fly will have no effect,. [# P$ [8 x" X% f+ o$ m
                  but this can be changed using "hash-type".
- P* ^( {9 g' C, D" Q* f6 r' D  r
      rdp-cookie+ P3 O; K  l4 E& n& f
      rdp-cookie(name)! o2 i+ N  H2 E6 p. p& Q$ \
                  The RDP cookie <name> (or "mstshash" if omitted) will be
6 j4 @0 m, ~9 h9 [( U8 n. [                  looked up and hashed for each incoming TCP request. Just as# n& e# {' d" g- R9 G6 L
                  with the equivalent ACL 'req_rdp_cookie()' function, the name
2 R2 Z. H9 E' \                  is not case-sensitive. This mechanism is useful as a degraded+ L# }2 U1 D% J
                  persistence mode, as it makes it possible to always send the
" B- f8 O. X$ n! n, |8 |                  same user (or the same session ID) to the same server. If the
- ~, Q4 e( s4 [8 o- x                  cookie is not found, the normal roundrobin algorithm is: A% P1 O& c7 e
                  used instead.
+ v5 B( V4 p, o7 v
6 P; s4 f9 {7 x/ {" u. d3 g/ t                  Note that for this to work, the frontend must ensure that an0 A; O- M& U% B& B5 p
                  RDP cookie is already present in the request buffer. For this
' h8 k/ u# Z& D! F0 Z$ R- q                  you must use 'tcp-request content accept' rule combined with; k# k# |# M1 Y+ O- a2 ?
                  a 'req_rdp_cookie_cnt' ACL.
1 M  K0 v$ y6 J! c# y0 K7 H4 Z& O8 {" x& u- m# L
                  This algorithm is static by default, which means that. M& j, d% A- E
                  changing a server's weight on the fly will have no effect,
; X% a( [) E1 D1 G$ V                  but this can be changed using "hash-type".
0 x) ]) d; W+ r
. S7 Z: }9 G7 V8 ^    <arguments> is an optional list of arguments which may be needed by some; c5 ], D7 d8 F; s1 r0 ]' X
                algorithms. Right now, only "url_param" and "uri" support an
$ Z  B5 w  T& t' P8 D, N0 c$ D                optional argument.
/ N6 s; _0 h( I* @- \% B2 N  \& h. X; P( h% z
                balance uri [len <len>] [depth <depth>]! v# S: W8 i- B$ k
                balance url_param <param> [check_post [<max_wait>]]
3 o: G% b: ?- A+ }9 a2 a
( c: P( k# @0 F4 p" Q: y; N  The load balancing algorithm of a backend is set to roundrobin when no other+ P9 m; b; |4 n+ U$ ^$ D
  algorithm, mode nor option have been set. The algorithm may only be set once
; H$ U. u. C; h) `% V- s2 |  for each backend.  Z% a+ f  _, m' M' e

' T) D' }+ |* [0 |  Examples :$ C; i- L  Z1 T9 _% Q& a
        balance roundrobin
( z. \) `' C% L        balance url_param userid4 [4 i, i! g( |. K
        balance url_param session_id check_post 640 g) n; k1 R2 p" y- L* p' q
        balance hdr(User-Agent)8 h1 V( H4 @5 Q' F4 v  J
        balance hdr(host)6 n& x8 A7 P& ~4 x! b4 h
        balance hdr(Host) use_domain_only
. v1 E8 y" G0 V" r1 J" F. w) }, k$ V: I/ a; q" E+ S
  Note: the following caveats and limitations on using the "check_post"" @5 S+ {9 Q: Y6 ^$ K8 F0 E( ]
  extension with "url_param" must be considered :
+ ^% J! j" ?( T! [! t
! ]7 P% Z8 y6 |4 T9 B( P" y    - all POST requests are eligible for consideration, because there is no way
4 m, A; x. n  P3 U6 [; c  Z      to determine if the parameters will be found in the body or entity which
9 N& z1 I: S4 h$ N: y/ V% o      may contain binary data. Therefore another method may be required to
2 R" T8 v$ `/ e2 F+ D5 r      restrict consideration of POST requests that have no URL parameters in2 W. {/ c, P. A9 k
      the body. (see acl reqideny http_end)7 U; R! f  P& T4 a2 R# o2 ?
, `3 e) F- @$ t$ a5 `+ o! H- _
    - using a <max_wait> value larger than the request buffer size does not8 N+ ]( p' y# L" o6 o: [. j1 a$ }" \; b
      make sense and is useless. The buffer size is set at build time, and
& b! X1 L' _/ [" q" S$ x      defaults to 16 kB.
3 e4 W% u8 }3 e. H3 y* k* }
$ U' v3 x9 r8 {# c    - Content-Encoding is not supported, the parameter search will probably
! ^# X5 E/ r) J6 l) b& s      fail; and load balancing will fall back to Round Robin.2 P) t# N0 \  \

) m+ z8 u$ V# w. x/ `    - Expect: 100-continue is not supported, load balancing will fall back to$ R, V* m# ~1 U5 J" [, C
      Round Robin.) h& m8 w" o2 d+ i* u! e% @- U: L
' L" F" t8 F9 P
    - Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk.. w, |- p1 V& ]: ~& {
      If the entire parameter value is not present in the first chunk, the
6 {1 r' ~* ?3 _9 ]. h      selection of server is undefined (actually, defined by how little) a) ~2 h* X+ |
      actually appeared in the first chunk).* y/ T2 o6 u) t6 V8 @. F, R

' u' a; E6 q3 p    - This feature does not support generation of a 100, 411 or 501 response.9 f& \- B# i3 a# }) C# N
4 \7 E4 z# s: A* V" g
    - In some cases, requesting "check_post" MAY attempt to scan the entire5 ^! u) Z; C- b" u3 u, c
      contents of a message body. Scanning normally terminates when linear5 F( J3 ^  U9 j5 F& O" M
      white space or control characters are found, indicating the end of what
( Y' _6 Q- D% U. [4 s0 b/ s      might be a URL parameter list. This is probably not a concern with SGML2 f4 y. `1 g+ F$ V, n
      type message bodies." a7 D3 {5 F  i% ^0 B
* l3 S5 j* S- N; t3 R
  See also : "dispatch", "cookie", "appsession", "transparent", "hash-type" and
$ c9 M; z3 X* O$ E+ x             "http_proxy".; Q, C& U& d1 f
- G0 \3 Q1 k0 i/ q

9 l% G/ _) L5 k* n0 }+ v! pbind [<address>]:<port_range> [, ...]
7 l1 P4 A. V/ k8 i* h* s/ `bind [<address>]:<port_range> [, ...] interface <interface>0 n. S$ F3 g  v0 T0 ]
bind [<address>]:<port_range> [, ...] mss <maxseg>+ _! V( m$ U7 \/ {5 n) L$ t
bind [<address>]:<port_range> [, ...] transparent+ w5 i; s# T, C: j* `! D  o: y
bind [<address>]:<port_range> [, ...] id <id>4 ~  P: q4 e$ w2 G1 Z' }1 ^) e
bind [<address>]:<port_range> [, ...] name <name>; `% B3 |4 I( b  g* I5 A
bind [<address>]:<port_range> [, ...] defer-accept/ l" T+ `+ Q% W. m
  Define one or several listening addresses and/or ports in a frontend.
$ s7 z- d- G/ ]/ S  e  ~5 y  May be used in sections :   defaults | frontend | listen | backend- m" ]8 F. Y* D: b
                                  no   |    yes   |   yes  |   no. r/ A# O  B7 r8 I9 M7 x  X
  Arguments :1 z2 w6 `6 X& {3 d
    <address>     is optional and can be a host name, an IPv4 address, an IPv6
" F: H8 A" `' _* y+ j                  address, or '*'. It designates the address the frontend will, _- A3 R6 q/ Z9 O: ?
                  listen on. If unset, all IPv4 addresses of the system will be
6 X/ t0 q8 _( s6 [                  listened on. The same will apply for '*' or the system's
9 J' I8 D3 T1 |2 Q7 |  }9 Y                  special address "0.0.0.0".6 C" R& c( x- `) D9 B

' d! V- P. W/ G4 a  A) b3 u  [    <port_range>  is either a unique TCP port, or a port range for which the
0 H% P; e  R3 y* }  H                  proxy will accept connections for the IP address specified/ B) X& }+ ~5 a4 C
                  above. The port is mandatory. Note that in the case of an
. @5 W5 t8 m- t1 C" {7 {, D                  IPv6 address, the port is always the number after the last
# o5 L& b; @8 E  G% S                  colon (':'). A range can either be :
# Y- i8 p$ N( X( s9 E, l                   - a numerical port (ex: '80'). _8 j+ @) d3 v! l
                   - a dash-delimited ports range explicitly stating the lower. v% A4 K' F' _
                     and upper bounds (ex: '2000-2100') which are included in8 ^+ H/ Z5 T% f  |3 P. t
                     the range.
: u1 }' s- p, K' {. i5 S" U2 Y; I9 B2 V: {: v
                  Particular care must be taken against port ranges, because
5 S) F5 p: B- P  \+ B6 _                  every <address:port> couple consumes one socket (= a file& H4 ~5 ]3 q$ Z: d2 K4 t' g
                  descriptor), so it's easy to consume lots of descriptors$ e9 z; v7 s0 E' E" P5 d6 x* g1 L
                  with a simple range, and to run out of sockets. Also, each5 g6 z5 r$ M& ~- _5 T) D
                  <address:port> couple must be used only once among all6 a* x" j# M% ?3 g& m: T! [5 L) u
                  instances running on a same system. Please note that binding
/ z' W" {& n0 Z, W4 ~0 H" D                  to ports lower than 1024 generally require particular9 F$ |6 C/ p3 _0 X
                  privileges to start the program, which are independant of7 q8 ~2 L" \" B! T7 s& N) q
                  the 'uid' parameter.
7 C- \9 f7 Z: i, a$ h' c6 g% @$ ~2 H
    <interface>   is an optional physical interface name. This is currently
5 I1 c- g2 |4 M' J  T                  only supported on Linux. The interface must be a physical+ t8 n: H. x, }
                  interface, not an aliased interface. When specified, all
' u" \) R+ E1 e( W/ ~( t8 e                  addresses on the same line will only be accepted if the9 U$ r% }4 f$ ^: J1 U3 ]7 f
                  incoming packet physically come through the designated
$ r# B" w% l) z4 W8 H% U                  interface. It is also possible to bind multiple frontends to# G9 C+ m& V$ F0 Z: Q" U" t+ \
                  the same address if they are bound to different interfaces.
# J8 P0 M! q8 D6 m) K  U, w+ {                  Note that binding to a physical interface requires root
0 |) j0 l; O3 d  `& G                  privileges.
" O, {1 U' D/ g! n4 O" g! F9 B' ~# ?' l( P8 t. ?
    <maxseg>      is an optional TCP Maximum Segment Size (MSS) value to be' q* I2 s* w' x* c9 [3 Z) e. \2 u
                  advertised on incoming connections. This can be used to force* b% k9 N# L! Y1 P) d: ?0 Y
                  a lower MSS for certain specific ports, for instance for2 C9 F" a# U" f) ^6 F6 o& a4 C
                  connections passing through a VPN. Note that this relies on a$ U, a7 H9 B9 _" R! Q5 m; @
                  kernel feature which is theorically supported under Linux but7 O, b0 r3 n$ l
                  was buggy in all versions prior to 2.6.28. It may or may not/ s8 q! C' c* K  O+ m/ F
                  work on other operating systems. The commonly advertised
7 l, p6 k8 R$ E2 Q! q: a+ E                  value on Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP).! j, g5 ]3 q4 x# `: T, N+ O3 p' q

3 C9 J, W- J5 w3 y/ u7 f    <id>          is a persistent value for socket ID. Must be positive and
( A+ |5 y: E* J) Z" O5 E                  unique in the proxy. An unused value will automatically be; I3 j+ |; ?9 P" B( R' q0 X
                  assigned if unset. Can only be used when defining only a0 y4 p& ~- [) N$ t* C
                  single socket.
/ c9 p% V, q3 Z  {# l0 L; N# }( {, p; M6 q' @
    <name>        is an optional name provided for stats
6 o# d6 N& ~& M4 u1 G8 i& i! Q* ^' p# o: g
    transparent   is an optional keyword which is supported only on certain" `0 n6 l& Q! j0 I  @
                  Linux kernels. It indicates that the addresses will be bound* g# J. e, [% S3 I; v/ G
                  even if they do not belong to the local machine. Any packet8 {$ Y2 ^* H" v
                  targeting any of these addresses will be caught just as if3 E. `$ F$ v; h  z" J3 t
                  the address was locally configured. This normally requires5 J& c# S; \7 g: r: D& b7 v
                  that IP forwarding is enabled. Caution! do not use this with+ F. C( T6 @/ A, K# i
                  the default address '*', as it would redirect any traffic for. v; @  X5 L- H
                  the specified port. This keyword is available only when( Q" u! h) i/ F9 o
                  HAProxy is built with USE_LINUX_TPROXY=1.
+ ?- t' v5 x9 Y& x' @& s5 K: n  \( I# O
    defer-accept  is an optional keyword which is supported only on certain
: \3 v" V5 U/ G7 G1 {                  Linux kernels. It states that a connection will only be5 V& s# J. A" b- t3 @
                  accepted once some data arrive on it, or at worst after the
9 \9 I  ~$ `4 z' m3 F# a                  first retransmit. This should be used only on protocols for
, {+ k1 r0 R0 |" y2 N% h+ k                  which the client talks first (eg: HTTP). It can slightly
9 K: {9 S/ w4 V6 I- c                  improve performance by ensuring that most of the request is
; m$ j" O% A) @& a1 P& ?. d                  already available when the connection is accepted. On the
/ y+ Q7 }4 r+ l. i8 z9 b                  other hand, it will not be able to detect connections which, M" b2 V/ [$ G! ]( b& T. {  V
                  don't talk. It is important to note that this option is
4 s/ F( j6 y' B4 d; b                  broken in all kernels up to 2.6.31, as the connection is
8 P  Q1 ]3 [) e  p+ c5 e                  never accepted until the client talks. This can cause issues0 S5 O  U/ p4 }" u, W* W
                  with front firewalls which would see an established$ m% B; W( ?# W# c
                  connection while the proxy will only see it in SYN_RECV.
* @9 _5 w* V+ s8 C# B- `6 o. z4 T$ M' x; ]
  It is possible to specify a list of address:port combinations delimited by
; m0 s, a; m$ B6 z  t; k5 ?+ p' {5 b  c  commas. The frontend will then listen on all of these addresses. There is no# x- e: M+ f3 p' m
  fixed limit to the number of addresses and ports which can be listened on in+ u9 \3 S+ Q* Q1 y5 D2 x
  a frontend, as well as there is no limit to the number of "bind" statements( s3 d/ a; ^+ y
  in a frontend.5 N  ]4 e4 D* v1 h4 q
9 w" q. _3 w/ J2 @" Y7 }* e( K" [
  Example :
; k- d3 r6 Q) C* H/ `5 z        listen http_proxy3 C& h/ Z! x0 W2 O! P7 k
            bind :80,:443+ f* L8 B% S3 _' f+ p8 |( [5 o/ [
            bind 10.0.0.1:10080,10.0.0.1:10443
- P' q: i2 K7 }) X+ T' Z; b3 J1 I9 A. O8 G0 w
  See also : "source".
4 T1 i# Q( B2 T9 `# i+ y, [5 n  V2 Y; z, R+ `
8 C* h5 I1 I& A% S
bind-process [ all | odd | even | <number 1-32> ] ...8 J* T, m/ ~! q1 s
  Limit visibility of an instance to a certain set of processes numbers.; x! H% u9 n( v. W0 k
  May be used in sections :   defaults | frontend | listen | backend
7 P4 Y8 u, h- c6 l. H1 X: f                                 yes   |    yes   |   yes  |   yes
, g4 a2 p8 f- q' l  Arguments :
7 C/ B( w* i4 O4 O0 ]1 k* Q    all           All process will see this instance. This is the default. It+ W9 p- r/ s! w! h" a( N. O: q
                  may be used to override a default value.
# E' c, H- e$ o" T; r2 p4 H! Y
6 v) d( g" }9 Q# c6 J# @    odd           This instance will be enabled on processes 1,3,5,...31. This/ X1 A( @$ s5 ~' E- T4 D
                  option may be combined with other numbers.
% a* |$ `  i+ ?  A; W& Y8 d& S' R+ l
    even          This instance will be enabled on processes 2,4,6,...32. This
8 ?7 U6 x. C* b2 r* [, m                  option may be combined with other numbers. Do not use it
* z" ~2 Q5 Z" z1 a* O) _/ J+ C1 C                  with less than 2 processes otherwise some instances might be, z6 T* G# m8 d, h4 \! _; C
                  missing from all processes.
( ^1 v: @, b. @1 z% i: l8 D4 \  I4 N) o2 N8 m* N8 q
    number        The instance will be enabled on this process number, between- N6 N# X5 N2 ]0 b, u$ }5 g
                  1 and 32. You must be careful not to reference a process
2 ~& m0 U# i9 o. ~: x0 M                  number greater than the configured global.nbproc, otherwise
% ^3 J4 L+ C+ N! `- T8 S                  some instances might be missing from all processes.' ?$ Y& c: \* b% Z7 E4 ^/ M
/ |4 x0 M1 n- [' t' j
  This keyword limits binding of certain instances to certain processes. This
$ w4 r$ }+ I( p9 X" P  is useful in order not to have too many processes listening to the same1 h3 a8 p) x2 ?+ x
  ports. For instance, on a dual-core machine, it might make sense to set4 P4 h) ^- j" k  m+ Y- U
  'nbproc 2' in the global section, then distributes the listeners among 'odd': q/ Z$ e" e) \: w! [2 B
  and 'even' instances.
) P9 m8 {( r: @/ z7 g  Y6 {/ M8 a/ O; _( A2 o; h
  At the moment, it is not possible to reference more than 32 processes using
; X$ ]8 Y- R7 b& l5 }  this keyword, but this should be more than enough for most setups. Please
, [% y/ \* |" P  note that 'all' really means all processes and is not limited to the first, v" W6 }/ g9 i$ m$ X3 S
  32.
1 F4 B( w. g  k$ O0 V' T# f% ~3 c1 T/ H( k7 `1 G# U. h! T
  If some backends are referenced by frontends bound to other processes, the
' G+ M' ]" y2 l- }6 ?  backend automatically inherits the frontend's processes.
2 b, l/ q0 L) a6 q7 V  F
: f/ ~  g# Q5 E- B  Example :
  |! T6 F! A6 p2 H) A& ?        listen app_ip1
0 I. C9 f/ {% s6 Q6 A& P& S! b2 j            bind 10.0.0.1:80
  e* m% l3 n% |; Q! F9 D! c9 \+ Q. o, E            bind-process odd
- o: T; F4 m& B( ]" W- Z
% G& G5 W! ^% M# j9 v8 d        listen app_ip2
& z; y4 N4 l8 c/ h& M: M            bind 10.0.0.2:80: V* J# D  A3 g! \
            bind-process even
& s" S9 T$ U* I3 b8 O4 F; `. w# @/ K- K( L4 q6 B( n0 k8 g
        listen management
' X! {  O" m' R% Z, y            bind 10.0.0.3:800 d" o8 y+ p8 X* K6 |
            bind-process 1 2 3 4
2 b2 L0 k+ F5 [/ {3 q9 ^, }: Z  k9 {) `5 Y7 F
  See also : "nbproc" in global section.
7 z# O' ^% g$ [6 d3 j' g9 U, L
  r' \$ e& D! f% L% W. }
2 c; A* K/ t  N& ^& z9 a3 Oblock { if | unless } <condition>
' _; ~8 @5 S( \" O9 `  Block a layer 7 request if/unless a condition is matched' ]+ F% R+ G& z) d. E
  May be used in sections :   defaults | frontend | listen | backend
$ \5 y/ D% ^. t, A, M" \                                 no    |    yes   |   yes  |   yes9 h' n8 `9 X/ }2 a" o3 `
; m; r- }0 T3 r# m0 ?+ N
  The HTTP request will be blocked very early in the layer 7 processing
8 u1 i- i( `) D# f! C" l% q7 D! j  if/unless <condition> is matched. A 403 error will be returned if the request4 z8 X, [# G+ B  J( E1 h1 t* Q+ }: p: [( b
  is blocked. The condition has to reference ACLs (see section 7). This is
9 |. X/ D% Z2 I! k7 E* Y. K4 D  typically used to deny access to certain sensitive resources if some
& ~" D. x% o& L- U: f/ W  conditions are met or not met. There is no fixed limit to the number of
2 l* G2 r* M% E% f  "block" statements per instance.
# C+ j% Y0 x& k' Q& Z
) z, {$ X0 v# a9 j8 L/ t% r- o  Example:
4 L* k7 y5 T. q4 M/ n8 `        acl invalid_src  src          0.0.0.0/7 224.0.0.0/3
% T# c- m% b: [4 @- Q        acl invalid_src  src_port     0:1023
" I, W. S; s; X0 S9 V. v1 @        acl local_dst    hdr(host) -i localhost6 `' R0 H1 z) E9 a$ ?0 t
        block if invalid_src || local_dst
3 J- \0 A" w" q2 {6 n8 G' e: S) c3 O
  See section 7 about ACL usage.
* q* S" L; U: Y: [( h  T8 c, t
9 T6 F1 w2 f4 }$ r. K6 ?% O
4 h) x1 Z4 v3 @- Z6 qcapture cookie <name> len <length>
" ~% V, d1 p( q7 \# H  Capture and log a cookie in the request and in the response.5 ]# c- q4 X$ {, w8 R
  May be used in sections :   defaults | frontend | listen | backend
2 B1 K5 B: ]8 r' b, H                                  no   |    yes   |   yes  |   no: K: H4 s- \3 _3 I( s* n* @
  Arguments :8 E( v5 X0 f; c7 I" `0 u% A" c" ]! T
    <name>    is the beginning of the name of the cookie to capture. In order- c: {( p  R( F9 p/ o8 U' x5 ^
              to match the exact name, simply suffix the name with an equal
. @' ~3 E. U( v4 W9 H6 L, A              sign ('='). The full name will appear in the logs, which is9 z+ U7 `4 [, j
              useful with application servers which adjust both the cookie name2 C; n& _$ }/ ~& Q! Q3 u3 R7 T1 Z
              and value (eg: ASPSESSIONXXXXX).1 Q: |# R8 ?3 s8 r) o5 m! D4 I2 }* Z
  a  M: X4 }( U
    <length>  is the maximum number of characters to report in the logs, which+ d8 r0 S% M: A- z2 Q! G1 B3 h% e
              include the cookie name, the equal sign and the value, all in the
% \9 j* U# e3 Y; }1 g8 q8 Q              standard "name=value" form. The string will be truncated on the" t5 e7 r' O. [/ y' U% K+ @. a1 u  ]
              right if it exceeds <length>.
$ L5 K8 ?5 _# c& b8 _
$ X2 B( K$ O9 l% g" _' i  Only the first cookie is captured. Both the "cookie" request headers and the. F" S- S# l8 N8 a/ ?- H/ W9 Z
  "set-cookie" response headers are monitored. This is particularly useful to
/ O* e* v: O) r4 F6 u$ f  check for application bugs causing session crossing or stealing between9 [/ d4 a7 W5 P6 ]- t
  users, because generally the user's cookies can only change on a login page.
) h# h5 e( B# ]: \& y6 |6 X+ z$ r3 |% T
  When the cookie was not presented by the client, the associated log column
7 O8 E5 {  c6 s9 f, n# Q  will report "-". When a request does not cause a cookie to be assigned by the# V% q5 i, ~- W
  server, a "-" is reported in the response column.3 p# z/ t) J+ Y8 V0 [0 b6 a

  d8 L& \7 S2 ], C" J( H  The capture is performed in the frontend only because it is necessary that
, z$ s# Z' W% M) B; `9 ?  the log format does not change for a given frontend depending on the9 i5 m- O' q8 t4 ~& ~" ^
  backends. This may change in the future. Note that there can be only one
7 v  w% D& Q% i! l8 {) H: N: `& A  "capture cookie" statement in a frontend. The maximum capture length is" @! p( u2 |, k$ p5 k0 Z
  configured in the sources by default to 64 characters. It is not possible to& n5 j; g# j2 S6 l! q+ e
  specify a capture in a "defaults" section.  k' b4 v. N" \" n% |
0 v. M% ]! ?7 h; }1 w, Y* p6 ^
  Example:
. t9 n4 e  [# j9 u  Y4 f0 I        capture cookie ASPSESSION len 32
. d, g/ l1 Q7 l0 _  Y: @+ H' t+ r
- u- Z0 L3 p4 M( A8 \  See also : "capture request header", "capture response header" as well as
  ?$ ^! q; c. Y4 Q! S2 D            section 8 about logging.
3 C, k* z% `& U7 l& m, p7 r" n  M5 c; Z. l+ ~+ h

5 o3 g$ x4 [: }  |5 P/ Mcapture request header <name> len <length>
0 w, B' c# }8 L/ c& L; O( z  Capture and log the first occurrence of the specified request header.
# W% c$ @0 T7 y  May be used in sections :   defaults | frontend | listen | backend
" Q4 P: K& q& D5 ?                                  no   |    yes   |   yes  |   no
6 J8 x0 a, \! c: v  Arguments :
1 m# p5 l4 i0 H! r& C& R    <name>    is the name of the header to capture. The header names are not
* z0 m: E, C( `- |6 e              case-sensitive, but it is a common practice to write them as they" J3 K3 L" E) \
              appear in the requests, with the first letter of each word in3 t6 m) A% O1 N/ c; ?2 _
              upper case. The header name will not appear in the logs, only the& e( Y4 i6 c% S8 a* l" a& \7 [
              value is reported, but the position in the logs is respected.
- M. p; u$ Z$ N# _+ f" P
- c  f1 E3 u2 {  C# z    <length>  is the maximum number of characters to extract from the value and% Z& }: Q4 |5 y8 }1 g0 @
              report in the logs. The string will be truncated on the right if$ S; }7 Y  b) y
              it exceeds <length>.
9 e; w. h" g7 _  K
! L/ Y6 j1 g9 r5 a. S  Only the first value of the last occurrence of the header is captured. The6 s. ?+ k, Q% D
  value will be added to the logs between braces ('{}'). If multiple headers
# c6 P) t& Q- m2 y- w) I# I  are captured, they will be delimited by a vertical bar ('|') and will appear
, p& |/ r8 b& z5 q3 U  in the same order they were declared in the configuration. Non-existent
7 V# b) X' }+ w% j; `) _- {; r" H  headers will be logged just as an empty string. Common uses for request
! m6 M5 ?5 @+ M: p. R" e  header captures include the "Host" field in virtual hosting environments, the
5 A, D/ _- l; J" k1 e  "Content-length" when uploads are supported, "User-agent" to quickly% L# w7 Y( U5 U1 G5 Q
  differentiate between real users and robots, and "X-Forwarded-For" in proxied* h' k5 d( m( X' |$ X& `
  environments to find where the request came from.0 w0 E' P6 B6 a+ Q% l" P7 d
- w2 i& v: D  x0 o+ t
  Note that when capturing headers such as "User-agent", some spaces may be
; R/ z  s0 V9 O  n, @( I; _1 l  K9 U  logged, making the log analysis more difficult. Thus be careful about what
7 [, G$ K; h, s* r: \( [3 T  you log if you know your log parser is not smart enough to rely on the
. Z" G# ^7 A' |' `- J9 g  braces.+ ]9 Y1 y4 I' r3 q: M
  T* w2 }3 O, h2 _" S2 x4 g& I; [# X
  There is no limit to the number of captured request headers, but each capture
" H4 g# n% l. C8 ~; A% {& _  is limited to 64 characters. In order to keep log format consistent for a
  D0 c( v5 |: j. E3 Y  V% y  same frontend, header captures can only be declared in a frontend. It is not+ y7 X. \8 a. J+ [6 `# F
  possible to specify a capture in a "defaults" section.
3 r9 n' }+ `4 I6 [3 {4 S1 q
* {4 v: ~5 S+ O6 J2 X0 u0 Y0 t  Example:7 w, y) v! E6 N: V7 Q8 l+ [
        capture request header Host len 15+ E6 Z3 M* ^$ x, U  S: s1 O
        capture request header X-Forwarded-For len 15* ]% N0 E1 P" {/ [* T4 V; d
        capture request header Referer len 15
' u9 F6 D9 J+ T  Y( y' [. S5 f/ b$ U1 x) d  z
  See also : "capture cookie", "capture response header" as well as section 88 B! f0 F2 l& l6 E& e# n  `
             about logging.
& B* w- G) v7 v) W* w. v% X4 X: [) H% J+ f3 v
9 u+ t0 V9 a: m1 ~0 ^  L! F
capture response header <name> len <length>3 w: G6 u2 E/ D0 ~# q
  Capture and log the first occurrence of the specified response header.
4 f+ D9 `) E! q# r  p( h  May be used in sections :   defaults | frontend | listen | backend2 F& G# T- h* ^3 k$ f/ ^: {% H. i
                                  no   |    yes   |   yes  |   no
* P9 J+ a" s9 U9 U  Arguments :
$ Q2 C* |0 o9 C$ \7 ?4 h    <name>    is the name of the header to capture. The header names are not( Z7 L, F2 P" y1 N" o
              case-sensitive, but it is a common practice to write them as they$ d0 k0 F! u# B% }3 X3 R% z6 Z
              appear in the response, with the first letter of each word in
5 I/ M1 M' t) w; X5 a1 `+ O( x6 X# L              upper case. The header name will not appear in the logs, only the2 c4 v: b- g3 g" S+ G& @8 S3 G
              value is reported, but the position in the logs is respected.7 W/ b. J# A/ L. x, p+ ?

+ P. \- u( }; J0 H9 y    <length>  is the maximum number of characters to extract from the value and
, |$ u( O6 I- M              report in the logs. The string will be truncated on the right if# h& J, P. u5 ]' R3 z2 c
              it exceeds <length>.
' C- D: {/ N, L$ l* Q( `0 M
0 u0 ~3 W* s8 S( r  Only the first value of the last occurrence of the header is captured. The! C2 Y3 F- c& w' h. r# F
  result will be added to the logs between braces ('{}') after the captured
$ C9 g+ h# l! U  request headers. If multiple headers are captured, they will be delimited by4 J3 D# g9 B, X2 ?) n" C
  a vertical bar ('|') and will appear in the same order they were declared in
  z' \  j3 C) l  the configuration. Non-existent headers will be logged just as an empty
3 M1 k* E2 n) j2 o  string. Common uses for response header captures include the "Content-length"
% W, U7 `) j3 G1 q* E  header which indicates how many bytes are expected to be returned, the
: A* W  j2 E6 t. J/ f3 H, Q4 E  "Location" header to track redirections.. ]) d4 r" U! ?6 f

4 q* e& E; ]/ @$ o( s; A  There is no limit to the number of captured response headers, but each/ w- i: A; t9 `2 J+ g
  capture is limited to 64 characters. In order to keep log format consistent
8 C  ?* U9 h* r8 T( k6 u3 a! y& W  for a same frontend, header captures can only be declared in a frontend. It* Y3 x& v! \7 G0 o  U  j$ z3 l
  is not possible to specify a capture in a "defaults" section.- r* g+ |3 H7 t" g

+ J9 U# P/ i1 M9 D! w1 s! n  Example:
. m& r% Z# A, V# y" d; f        capture response header Content-length len 9
3 F% ^& w1 J1 ~3 t9 ~" y% }; i, c  ~        capture response header Location len 15+ K) [% a7 a# |4 S8 Q4 m2 ^' s; x/ ]6 k  M

% L& V2 }# i0 Y+ }$ \  See also : "capture cookie", "capture request header" as well as section 8/ a& O1 l% z* h
             about logging.
+ F' g6 H% j- |. C  m6 g8 b7 J, s
1 `8 V2 R) I! f
clitimeout <timeout> (deprecated)0 y# `- m. v9 X3 L0 I2 }
  Set the maximum inactivity time on the client side.3 _( n) D4 @9 E. I: W
  May be used in sections :   defaults | frontend | listen | backend. q4 ?. C7 ^9 w. X& m- F. z$ W
                                 yes   |    yes   |   yes  |   no
, Y4 P7 I3 e# g$ W# V  Arguments :/ f( g+ F: Y6 l' T, q. {) K9 G) T
    <timeout> is the timeout value is specified in milliseconds by default, but' \/ {$ \3 m5 s. _
              can be in any other unit if the number is suffixed by the unit,* U! m: F4 N4 w" L
              as explained at the top of this document.- |! U( z8 e; [3 c, R% B) `

$ ~5 \' W) k" f( J4 E* B  The inactivity timeout applies when the client is expected to acknowledge or
9 A) ?% _7 K3 l' n: K  send data. In HTTP mode, this timeout is particularly important to consider& v% z4 d. u" R% i2 K: q
  during the first phase, when the client sends the request, and during the
& N. a5 H* T7 R8 E  response while it is reading data sent by the server. The value is specified$ J- C' C: I; V# N" _# G9 V! }
  in milliseconds by default, but can be in any other unit if the number is
, l( {  L. w  s* A, r" T  suffixed by the unit, as specified at the top of this document. In TCP mode3 O: J( D# P2 j6 x% |" K
  (and to a lesser extent, in HTTP mode), it is highly recommended that the
( m4 F* G$ N! i  client timeout remains equal to the server timeout in order to avoid complex2 h, s7 g5 M; c0 ?* G, a9 L$ H6 j
  situations to debug. It is a good practice to cover one or several TCP packet
2 C5 d6 ~" v5 w8 p) k& C  losses by specifying timeouts that are slightly above multiples of 3 seconds# t! o8 Q3 N5 v- a
  (eg: 4 or 5 seconds).% W+ N# _7 {, L' r5 r8 @$ P
, N# K( D! d9 j0 K/ R5 W
  This parameter is specific to frontends, but can be specified once for all in
1 u* j$ F  n. N) w5 F  "defaults" sections. This is in fact one of the easiest solutions not to' p" u7 w* R  m/ c/ O  D" E7 F! F3 @8 E
  forget about it. An unspecified timeout results in an infinite timeout, which
; X& d# j9 h# {8 b: h9 Y! Q) h3 \  is not recommended. Such a usage is accepted and works but reports a warning/ Y7 V, C# n0 w3 W5 N  v" |  h% G9 {
  during startup because it may results in accumulation of expired sessions in3 p9 N" Z. j' c: Z7 `
  the system if the system's timeouts are not configured either.; d% t# h4 g- O- |9 D7 v: V( h
% m# @) q5 W) ?4 @+ C
  This parameter is provided for compatibility but is currently deprecated.
7 u1 Y+ }$ {$ G' Q( o2 j2 {! {  Please use "timeout client" instead.5 y% n9 _& X- S1 m

2 }2 S7 w' U! q. ~1 i  See also : "timeout client", "timeout http-request", "timeout server", and
4 N! b$ S- b- ~. P5 G# U             "srvtimeout".% N3 ~5 {$ o4 F8 Z2 \

& J! w9 z  n" \) N
6 M3 r- [. p  J( s/ ucontimeout <timeout> (deprecated)5 M( ]1 ~7 A- [+ l  L" w; O
  Set the maximum time to wait for a connection attempt to a server to succeed.8 T) Z3 ~+ `' g8 ]* F9 y8 j9 M1 s3 L
  May be used in sections :   defaults | frontend | listen | backend" ~0 R3 k6 Y! E9 I/ ~) D8 B
                                 yes   |    no    |   yes  |   yes
% R1 l/ V4 E9 z  Arguments :' c' g7 d, M1 k% g1 D5 F
    <timeout> is the timeout value is specified in milliseconds by default, but* I) h/ k4 e+ l# \0 g" Y  k7 i+ X+ z
              can be in any other unit if the number is suffixed by the unit,- T7 l9 B4 H6 w1 f, ?
              as explained at the top of this document.( z% z7 r$ N% y, x4 Q& d1 Z

4 s. |) _  u6 R8 r  If the server is located on the same LAN as haproxy, the connection should be6 s: G( u/ ]$ {! p. X5 G' M' p2 ~
  immediate (less than a few milliseconds). Anyway, it is a good practice to
# _/ l4 v  x  a2 I/ y  cover one or several TCP packet losses by specifying timeouts that are
3 w/ x" [3 {% }  slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the/ i( Q0 N) A  [* B0 N( `2 l; B
  connect timeout also presets the queue timeout to the same value if this one
! u" \5 \* L- V/ ~+ Y  has not been specified. Historically, the contimeout was also used to set the' }* ]& J2 e+ n( Q# s
  tarpit timeout in a listen section, which is not possible in a pure frontend.' u' |/ r2 x- T: j) N& L; f$ V
0 H% a% Y6 q% q* h' d7 C" Z+ R
  This parameter is specific to backends, but can be specified once for all in4 b+ ]! ]. {. N; _  l' T9 s& [9 i
  "defaults" sections. This is in fact one of the easiest solutions not to
+ q2 F" T3 |2 `: X, |) |5 p  forget about it. An unspecified timeout results in an infinite timeout, which
' @- _: Y- X1 |1 y5 I  is not recommended. Such a usage is accepted and works but reports a warning3 m+ f- d  i; Y0 u) h7 ]
  during startup because it may results in accumulation of failed sessions in
4 q2 M) V. J4 @! q3 ~$ Z/ {$ s  the system if the system's timeouts are not configured either.$ |) h, N# p  x1 x/ o

9 q) @! i' n6 N, d  This parameter is provided for backwards compatibility but is currently; F9 k3 Q% ?  I. w: y& U
  deprecated. Please use "timeout connect", "timeout queue" or "timeout tarpit"
( \. K1 M6 x5 r1 ^  instead./ k* C. S- G) u. R( |) W! [
1 B; u* }! {4 G) p6 m; J0 }  ?4 D; z
  See also : "timeout connect", "timeout queue", "timeout tarpit",
8 m5 d0 M; l* |) o1 P9 O             "timeout server", "contimeout"., Q! f/ J% U: \/ R

$ d& D5 T7 x4 m7 v! Y4 N3 M! p; g9 z& X; F, v; O- ^6 {0 k
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
3 [) C( y" A1 N1 s8 Y5 u              [ postonly ] [ preserve ] [ httponly ] [ secure ]$ ^# F) E8 `+ e/ O4 L) s9 |4 p2 y
              [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
% [# \6 |. l. Q( t  Enable cookie-based persistence in a backend.
5 O2 G: R/ x7 Y. _+ y! G  May be used in sections :   defaults | frontend | listen | backend
$ B$ m: K! o) `1 n                                 yes   |    no    |   yes  |   yes# G8 _/ O* G+ I( N
  Arguments :8 k, k) Z) o" m. W
    <name>    is the name of the cookie which will be monitored, modified or
; E. p5 K; y- `( Z( Z              inserted in order to bring persistence. This cookie is sent to
: q2 I" [0 n* w              the client via a "Set-Cookie" header in the response, and is- i/ q' {% t# m& p" U% b
              brought back by the client in a "Cookie" header in all requests.7 o1 O9 E% @! _7 X" u2 `' Z" I( A
              Special care should be taken to choose a name which does not' E8 E8 G5 c/ Q/ d" s
              conflict with any likely application cookie. Also, if the same
' ~$ v3 t$ N" Y6 Q; a1 @              backends are subject to be used by the same clients (eg:4 H7 p8 w: t1 f
              HTTP/HTTPS), care should be taken to use different cookie names+ @6 {* N% E" m( c3 S" K
              between all backends if persistence between them is not desired.) F2 I( l8 X% a/ O$ S2 x, w: m
/ y8 T8 f! l) A
    rewrite   This keyword indicates that the cookie will be provided by the* R# F/ f: h$ J# X5 e3 [8 z
              server and that haproxy will have to modify its value to set the# ?1 k, \. O0 t% K' {* w
              server's identifier in it. This mode is handy when the management4 P. p5 k( U, w: ^" f  o, W
              of complex combinations of "Set-cookie" and "Cache-control"* ?# v- z% n- p! s6 j; a
              headers is left to the application. The application can then, w0 v) m7 K# a% A- |- B- ~
              decide whether or not it is appropriate to emit a persistence
" l6 y) K* a8 g  a              cookie. Since all responses should be monitored, this mode only2 Y9 w+ d8 e. Q: u( u; B
              works in HTTP close mode. Unless the application behaviour is) i: u8 h; {3 q+ j6 g- ]1 B: W* J* d
              very complex and/or broken, it is advised not to start with this- p' n& J8 K( }2 O% S0 C+ A
              mode for new deployments. This keyword is incompatible with
6 d/ O, ]( O, h- y8 ^" Y              "insert" and "prefix".
$ G# M, r5 b  x. N  J3 f* M; w
* M% o; c6 j+ u+ S    insert    This keyword indicates that the persistence cookie will have to
; H. J& f* n% i! R              be inserted by haproxy in server responses if the client did not
7 {: u$ D" c' x9 |0 N9 s  `; A
! z9 g5 f7 v; K& Q$ [6 M, ]$ ]              already have a cookie that would have permitted it to access this- H2 B) M- {  }% l" E* t4 y
              server. When used without the "preserve" option, if the server
/ e. t- ~2 v# I; W; b" X" v              emits a cookie with the same name, it will be remove before
4 Z6 v/ x: @8 |1 T0 T              processing.  For this reason, this mode can be used to upgrade
  i" d. J! k' t( B' H0 ^              existing configurations running in the "rewrite" mode. The cookie
; F1 I; ^; X* R# ^              will only be a session cookie and will not be stored on the
6 D, s0 z9 o, a5 L* y5 t1 `4 f* p. P              client's disk. By default, unless the "indirect" option is added,
* B, P8 s0 T" _( R6 c/ h2 B+ r9 P# S              the server will see the cookies emitted by the client. Due to. O0 ~4 A4 N/ U5 V# |
              caching effects, it is generally wise to add the "nocache" or( i8 ^2 h( k8 U% p7 F5 t+ o( c, S% z
              "postonly" keywords (see below). The "insert" keyword is not
; ], L+ k7 Q/ Z" W6 l! S2 t6 ~              compatible with "rewrite" and "prefix".. w1 w. f8 F( x7 \/ l$ L* x! T4 J( ?
. X7 f+ `6 }% S7 N# H( d/ w
    prefix    This keyword indicates that instead of relying on a dedicated" a* z$ O( a4 B+ y' ?" t
              cookie for the persistence, an existing one will be completed.: s! \1 v. u- _7 M( ?4 U  w9 W0 p
              This may be needed in some specific environments where the client1 \0 q5 y* K+ y9 i) D" T) ^
              does not support more than one single cookie and the application
6 C$ R" f& z1 y              already needs it. In this case, whenever the server sets a cookie
" ^) @& T3 A* u- ^- M1 g0 |              named <name>, it will be prefixed with the server's identifier$ F& c. o1 e  Y/ k. S0 ~& Z
              and a delimiter. The prefix will be removed from all client
7 A! L' r; B2 o+ `) q9 H0 V; E6 Y& d              requests so that the server still finds the cookie it emitted.% H* z& Q8 R1 V
              Since all requests and responses are subject to being modified,- E% U5 p, U2 f0 X3 f  e
              this mode requires the HTTP close mode. The "prefix" keyword is
% c; ]. m# _6 E- k, z              not compatible with "rewrite" and "insert".. W* g1 z, W. g2 b3 b
/ G% t3 q1 H9 K, k; {3 ]. g6 e9 a. l
    indirect  When this option is specified, no cookie will be emitted to a
% J9 K+ A, h( ?% ?              client which already has a valid one for the server which has5 n; G- ^3 G2 @
              processed the request. If the server sets such a cookie itself,6 v9 S2 `8 R  D6 C+ U* g$ P' B
              it will be removed, unless the "preserve" option is also set. In
1 k: d! p5 R0 s# m, e              "insert" mode, this will additionally remove cookies from the
+ R4 ~0 d' t9 [$ l              requests transmitted to the server, making the persistence
. ~2 r7 n+ w9 b# J& U              mechanism totally transparent from an application point of view.
  `0 H( F: _' M5 w+ N  L; f, u3 I/ V, b5 h/ E
    nocache   This option is recommended in conjunction with the insert mode$ P: c/ X! Z! @
              when there is a cache between the client and HAProxy, as it
) }; z/ Y! d3 L5 b" D) d% m              ensures that a cacheable response will be tagged non-cacheable if
3 v' Y/ @, a& u              a cookie needs to be inserted. This is important because if all3 W! m5 G/ e0 c- G- f. k, I
              persistence cookies are added on a cacheable home page for, x' k. r$ }1 g
              instance, then all customers will then fetch the page from an
/ U8 J" D' y3 `              outer cache and will all share the same persistence cookie,# v4 N5 L! n7 i" e  V& n0 n& v) G. q5 w
              leading to one server receiving much more traffic than others.
4 k' L' p3 O; s& E; T. O9 y              See also the "insert" and "postonly" options.
' N: j- V& E2 T7 p  Q2 g7 T) T8 {. x5 v0 N) Q9 Y
    postonly  This option ensures that cookie insertion will only be performed, p8 ~  f3 O3 j. q3 I
              on responses to POST requests. It is an alternative to the
4 F+ U& L8 z( B" |              "nocache" option, because POST responses are not cacheable, so$ E; r) D  g, |- Q
              this ensures that the persistence cookie will never get cached.
* N$ b6 i5 x' `0 ^              Since most sites do not need any sort of persistence before the
% t  Z8 D1 f! Z7 _5 N0 ^: H9 H7 ~              first POST which generally is a login request, this is a very
9 |* Y" S" i! O: I% w              efficient method to optimize caching without risking to find a6 Z; k9 ]" y4 R
              persistence cookie in the cache.
7 L8 L0 `$ L2 t              See also the "insert" and "nocache" options.
( j$ X1 p) W1 a3 O& b' N* K- S6 {( |  x/ O2 ~& @
    preserve  This option may only be used with "insert" and/or "indirect". It+ x" |4 E: |; Q/ a% e4 d
              allows the server to emit the persistence cookie itself. In this  D  T( f7 X% u2 X
              case, if a cookie is found in the response, haproxy will leave it
: O0 p: D7 @/ G5 _$ l              untouched. This is useful in order to end persistence after a. }% C2 m# M2 W% M6 _8 w  P
              logout request for instance. For this, the server just has to, A4 M( f& y* W6 r5 d8 _* o# \7 f
              emit a cookie with an invalid value (eg: empty) or with a date in
) f  d3 Y/ Q" |  {- R6 J              the past. By combining this mechanism with the "disable-on-404"" C: i3 Y& P; ~6 W) Q3 Z
              check option, it is possible to perform a completely graceful) j6 `4 @) Z8 W# P
              shutdown because users will definitely leave the server after3 {' p4 t+ S1 f8 `
              they logout.
/ a( p( U6 Q9 g8 G; C) l
) U$ ~$ ]" f' K& A! b    httponly  This option tells haproxy to add an "HttpOnly" cookie attribute
" @. U* H; j- a: k              when a cookie is inserted. This attribute is used so that a$ D. H# U* Y  S
              user agent doesn't share the cookie with non-HTTP components.
1 o4 v1 Z) h$ b              Please check RFC6265 for more information on this attribute.
) K  Y* c8 a) P0 T% f( b$ V& S7 i* Y. J- {( T7 y( I  c! O$ _
    secure    This option tells haproxy to add a "Secure" cookie attribute when$ `  I2 _2 j2 @6 T+ X; Z
              a cookie is inserted. This attribute is used so that a user agent
$ c8 Q% c5 Q4 ~# Y6 b              never emits this cookie over non-secure channels, which means
: z9 u1 I4 |1 f2 D4 M. s              that a cookie learned with this flag will be presented only over! y! `5 {& p! c# L0 O
              SSL/TLS connections. Please check RFC6265 for more information on
- W  |7 E: i8 X" U, Z              this attribute.% e' N; `! O* e- W5 ]2 T9 l
) k' `- e4 {5 k8 C3 _; A1 {
    domain    This option allows to specify the domain at which a cookie is
8 X$ Y1 p3 m! d6 ~0 b/ {) @  f$ c              inserted. It requires exactly one parameter: a valid domain
0 e/ \- y7 v2 E1 V              name. If the domain begins with a dot, the browser is allowed to
$ p' G! `3 l9 [, x/ p+ [              use it for any host ending with that name. It is also possible to7 R; B( I* I$ V
              specify several domain names by invoking this option multiple$ i4 f7 \# M$ R0 n* B# P. }
              times. Some browsers might have small limits on the number of
5 r" ?: x; Q+ _- x              domains, so be careful when doing that. For the record, sending
/ F; c# `& P+ \! @! v  T              10 domains to MSIE 6 or Firefox 2 works as expected.6 m  Y+ S& i' `+ s/ |: N0 b! e

- G$ {2 y- O6 M1 f' e    maxidle   This option allows inserted cookies to be ignored after some idle9 y/ h7 m5 W. i
              time. It only works with insert-mode cookies. When a cookie is# W- i" h4 N# F* t% S* B9 H
              sent to the client, the date this cookie was emitted is sent too.% S- i9 W+ Z6 L( s1 ^. [, c
              Upon further presentations of this cookie, if the date is older3 V8 M: w1 O2 {3 Q. m1 Y
              than the delay indicated by the parameter (in seconds), it will
4 w, K: d2 R) `% M              be ignored. Otherwise, it will be refreshed if needed when the5 G$ l# F! S8 b
              response is sent to the client. This is particularly useful to; z7 C6 X& Z: o  }; L* c
              prevent users who never close their browsers from remaining for
9 r3 m# p. f% ]  H. g% Z              too long on the same server (eg: after a farm size change). When4 n8 P) m$ u! N" f% M( L
              this option is set and a cookie has no date, it is always
) m# f' B  f5 O1 w3 a1 U              accepted, but gets refreshed in the response. This maintains the! `" A9 a6 c% h. P
              ability for admins to access their sites. Cookies that have a( S& a% d3 v, E8 X. Y: ?$ \; n( J
              date in the future further than 24 hours are ignored. Doing so
( j. g: `- V* d6 ^              lets admins fix timezone issues without risking kicking users off
# E* ?" m+ e) \- L& U0 s              the site.
/ k2 x* S' }1 d$ M; d& U, N2 a0 F' K  r$ A: R
    maxlife   This option allows inserted cookies to be ignored after some life4 ^- \8 e$ l/ U! H" f" U
              time, whether they're in use or not. It only works with insert
. a' i3 N. a) R) T1 O  y0 n              mode cookies. When a cookie is first sent to the client, the date
& p' ~9 d# c) s8 u/ g% N              this cookie was emitted is sent too. Upon further presentations
" X. @) ^; f0 x, ^7 m* B              of this cookie, if the date is older than the delay indicated by
' _; A( [8 A1 U. t% z              the parameter (in seconds), it will be ignored. If the cookie in
  U" E/ r1 l% |& {( ?              the request has no date, it is accepted and a date will be set.! U) I# D- L" G( @2 M1 D$ K( H
              Cookies that have a date in the future further than 24 hours are8 i2 z- |+ W  R& v2 Q
              ignored. Doing so lets admins fix timezone issues without risking& c9 n$ i! \# D
              kicking users off the site. Contrary to maxidle, this value is' q5 |- `! F5 k( G' p# I2 k
              not refreshed, only the first visit date counts. Both maxidle and  C7 d: }6 y, A+ ~
              maxlife may be used at the time. This is particularly useful to
0 v* B1 C( b& L( Z5 v5 A, U2 S4 m              prevent users who never close their browsers from remaining for' D% A$ }$ U' P, {
              too long on the same server (eg: after a farm size change). This
+ {; ^" s1 f3 k3 v5 X              is stronger than the maxidle method in that it forces a/ }8 d3 f/ U: b& i" Y6 G: p  x% I
              redispatch after some absolute delay.
& Y) A4 I' Y1 ?  m8 e
# z1 \8 h3 G8 F2 z  i8 D9 Y5 p& q  There can be only one persistence cookie per HTTP backend, and it can be
: L  R" K8 t  ~+ b  declared in a defaults section. The value of the cookie will be the value
. R* T0 I, X" X9 l  indicated after the "cookie" keyword in a "server" statement. If no cookie/ G4 c3 V/ h: [) ?& [# A+ U6 e
  is declared for a given server, the cookie is not set.
0 \4 _" k+ O# W/ |' R* d; v4 @2 ^* l5 q& B; j
  Examples :
* M3 a9 q, E9 T        cookie JSESSIONID prefix6 C( w0 Z& B+ K  Z6 H: e
        cookie SRV insert indirect nocache
% y( V+ e) l! y7 ?        cookie SRV insert postonly indirect7 b* I, G2 ]& h* r4 ?
        cookie SRV insert indirect nocache maxidle 30m maxlife 8h1 X) k8 a! S0 z1 V4 k" A. i

& w! P, }8 I( F  See also : "appsession", "balance source", "capture cookie", "server"2 R- G  W! G) b* ~6 X( ~/ j
             and "ignore-persist".
/ l' C3 ^0 d4 z. m6 K$ w
( a0 H& `$ c. T
4 Z$ w" Y3 p8 n# Tdefault-server [param*]9 m" X6 R3 C9 T3 ~$ z" ~
  Change default options for a server in a backend
. ^5 c  p# M* B1 _6 q! y! C  May be used in sections :   defaults | frontend | listen | backend" R& v8 B/ s! R$ a4 e+ O# O
                                 yes   |    no    |   yes  |   yes( H# w& ^" P! @9 R& P- g, c% l
  Arguments:
: F( f0 Y7 c2 v0 o+ b    <param*>  is a list of parameters for this server. The "default-server"4 N+ I! X8 V7 z. _
              keyword accepts an important number of options and has a complete* t( d* W' ]- Z3 S8 N% r
              section dedicated to it. Please refer to section 5 for more
  z- B- I; j+ Y- y0 ?              details.
8 W; ]- H! v, Q3 K7 u9 l& M0 H- z& u+ B2 {- C
  Example :
2 Y  y- u$ o1 S( N        default-server inter 1000 weight 13
2 W( [5 h7 C) c- C0 s. f$ i% G
" V, Q" A& B0 b6 v* Q  See also: "server" and section 5 about server options3 E% K: d- t6 k: i
+ y% {! @/ D( p) o1 ]# {
6 x* n* P1 l; N  n1 a- A# \
default_backend <backend>
% Z4 d% I" {9 H0 _4 ^7 b  Specify the backend to use when no "use_backend" rule has been matched.5 ^1 _2 K$ p7 d5 X6 U
  May be used in sections :   defaults | frontend | listen | backend0 q+ K: B/ b. M( p! w
                                 yes   |    yes   |   yes  |   no
  u- O' r0 H& f. |  Arguments :
" E2 I  w& Z5 x& z. ]& C+ c    <backend> is the name of the backend to use.
) t/ E) d( S5 G1 F# ?8 r# ?% i. W" ~
  When doing content-switching between frontend and backends using the, k& G4 Z* x2 A" G6 H0 \
  "use_backend" keyword, it is often useful to indicate which backend will be7 J# Z8 b8 Q1 Y# o- J
  used when no rule has matched. It generally is the dynamic backend which
' o$ B" u) |( o7 x0 r! }  will catch all undetermined requests.
& Y! g' `5 s; F$ u4 ]2 {- M1 i/ E8 n6 C& X! S
  Example :) z) C$ `- ]% z( K6 e

7 D; |3 K1 P. q& W5 m+ _; ^: G) o        use_backend     dynamic  if  url_dyn
0 c. L1 `0 |3 i* E5 Y        use_backend     static   if  url_css url_img extension_img
# b" E, ]! y; b        default_backend dynamic* e4 @$ V" E% ?# {# A

$ I  ?! C- T" m: t" p  See also : "use_backend", "reqsetbe", "reqisetbe"
/ `& e) e' ]- G( L& V2 q/ o; K3 {6 K, m. E6 h6 d. t' g4 B
+ _' v! o) L) i
disabled
' f7 @8 e1 z$ z  Disable a proxy, frontend or backend.6 D* _% T7 [* e3 g" p! y$ i
  May be used in sections :   defaults | frontend | listen | backend' ?% u; M- t9 H& n" Y) D
                                 yes   |    yes   |   yes  |   yes/ M: f3 b3 x" X# K% ]; Y+ s+ P
  Arguments :- ^& r& y* E9 w1 k. O

( [: @$ a* t8 t8 x  The "disabled" keyword is used to disable an instance, mainly in order to1 q& F, W2 p' F
  liberate a listening port or to temporarily disable a service. The instance6 T; j% J) h. N. \
  will still be created and its configuration will be checked, but it will be
2 O6 J5 Z2 J/ k  created in the "stopped" state and will appear as such in the statistics. It: l6 a" t6 l( H  v4 w. X
  will not receive any traffic nor will it send any health-checks or logs. It- H. y6 ~. v( R# `: ^  O: m* ~
  is possible to disable many instances at once by adding the "disabled"! p# g# c6 E  [7 S8 E
  keyword in a "defaults" section.
* I+ P% ~2 S0 {( K+ O$ [4 q5 u5 k1 u: `$ E7 n) t. R! H
  See also : "enabled"6 g8 {  ~( Q) `; h5 P
; q, o" c8 V, U: Z  t2 v

1 @: k$ `# ^- f: M' Z9 T/ `5 j" h6 H4 vdispatch <address>:<port>1 a( L0 X* U' b" K& S, k1 f% p
  Set a default server address
5 E) r, S! D. C" |  May be used in sections :   defaults | frontend | listen | backend
: U4 l  j- e  v- d& c2 t                                 no    |    no    |   yes  |   yes
. F. `- H1 e, ^7 i  Arguments : none5 |& }, K( Y( x5 \5 @" D, ]
7 Y7 v* l6 V! W) P( \9 K9 ?5 w
    <address> is the IPv4 address of the default server. Alternatively, a2 _) I0 ?$ p+ w
              resolvable hostname is supported, but this name will be resolved
3 z' V8 ?- Y1 m! q              during start-up.
( C& M. m3 S0 y$ d- P  P  p" v/ e6 t* |
    <ports>   is a mandatory port specification. All connections will be sent" m9 q' E7 ?/ B9 l- i" ^
              to this port, and it is not permitted to use port offsets as is  {; O+ H! g2 ?8 _+ I- ?& r
              possible with normal servers.
1 I3 ^! r9 [  `
7 T7 s, [4 Z& n7 a+ f  The "dispatch" keyword designates a default server for use when no other
& A/ K5 L( v6 D5 F1 H: e  server can take the connection. In the past it was used to forward non0 }( B" a$ U6 p/ K- p& ?
  persistent connections to an auxiliary load balancer. Due to its simple
3 c% e! e" U" ]  syntax, it has also been used for simple TCP relays. It is recommended not to1 O& j8 W; w9 Q6 i/ }* {
  use it for more clarity, and to use the "server" directive instead.8 C  U% {6 I# E/ G

; `5 r- @- z7 v+ s  j% P/ Y  See also : "server"
8 [' d& ~& W* t9 H1 B
! U, z6 a2 R/ f2 M. F% J
+ m$ y* i- J1 {2 @9 j/ N( lenabled* V5 o1 {( P6 S- k( s6 {! q
  Enable a proxy, frontend or backend.( t/ W; D. l6 }$ [
  May be used in sections :   defaults | frontend | listen | backend
7 C) l0 x) v: V4 f# U* D8 v; I                                 yes   |    yes   |   yes  |   yes
2 m% S' p; p4 t9 ]3 k4 m  Arguments : none
( d, Z* m) [; U. w  x  x* x  J4 ^1 u4 Q: z
  The "enabled" keyword is used to explicitly enable an instance, when the5 G; I% X9 Z% M* k) ~
  defaults has been set to "disabled". This is very rarely used.
$ @, }, G8 x' E( e
7 f% y, W  C9 }. ^' ]( e" |+ B' f& u* k4 I  See also : "disabled"8 b0 x9 e- y! |, b

* [9 l9 g% E3 j( f+ Y( d, p% i7 [) N5 H7 ?" |
errorfile <code> <file>: y8 Y- ?3 j( X$ M
  Return a file contents instead of errors generated by HAProxy  m. T, A! F; O$ N5 ?
  May be used in sections :   defaults | frontend | listen | backend1 t) I6 j& ]" D# R, N
                                 yes   |    yes   |   yes  |   yes- X/ u7 x  x" ]& G# h2 T: q
  Arguments :0 q1 F: y  @* r; U
    <code>    is the HTTP status code. Currently, HAProxy is capable of- N0 ?2 h2 ~3 D+ W8 A& u7 B5 Q
              generating codes 200, 400, 403, 408, 500, 502, 503, and 504.4 N" X4 B& ]& M2 k6 D* k+ P3 ?

5 T% i# s' v  [- P. _2 f+ s: [( n    <file>    designates a file containing the full HTTP response. It is
7 P1 o( ~& X! o; g% q; E              recommended to follow the common practice of appending ".http" to
( \# q" B, `+ h* {" b& |9 P9 r              the filename so that people do not confuse the response with HTML$ r5 c- J: ?$ l
              error pages, and to use absolute paths, since files are read
  ]! \9 l. I* O# G8 o1 d              before any chroot is performed.
" E! h$ N# U4 H" @8 F+ U  j6 h/ u, i7 m; D7 O7 J' x
  It is important to understand that this keyword is not meant to rewrite9 ~* {1 V, K4 B0 P/ B7 {
  errors returned by the server, but errors detected and returned by HAProxy.
; @: t- ]6 ?5 C/ v: }5 V  This is why the list of supported errors is limited to a small set.
+ K  h5 a: Q* Y' }+ s/ G9 {9 d+ M# l, N' d) b/ }. [
  Code 200 is emitted in response to requests matching a "monitor-uri" rule.! z" D/ I7 H& [$ ~. {$ J

. [. S5 V! b3 F5 ]* K& d  The files are returned verbatim on the TCP socket. This allows any trick such# Y/ y4 f7 A8 I% S* H7 m
  as redirections to another URL or site, as well as tricks to clean cookies,
$ {2 ?" I9 t7 X0 @  force enable or disable caching, etc... The package provides default error
+ i( P$ t  o5 t6 X  files returning the same contents as default errors.3 \4 M  d" l( W7 Q
$ e! O9 ?6 H: v7 U" }( f5 I
  The files should not exceed the configured buffer size (BUFSIZE), which
* q0 `9 y9 H* e/ ]+ b# i9 O  generally is 8 or 16 kB, otherwise they will be truncated. It is also wise
7 N5 [; S" C9 E5 h  not to put any reference to local contents (eg: images) in order to avoid; F; L5 g2 p8 \% N! n8 f& ]
  loops between the client and HAProxy when all servers are down, causing an) Z3 Q, \8 ^: q3 u
  error to be returned instead of an image. For better HTTP compliance, it is4 T2 Q! A$ S* ^3 I1 K
  recommended that all header lines end with CR-LF and not LF alone.2 b6 z, b1 }( \5 a0 T4 Q& C- K
( ^* f* A1 G5 N+ X4 ]" M) B
  The files are read at the same time as the configuration and kept in memory.: C* a/ {$ v& T! n
  For this reason, the errors continue to be returned even when the process is
: D. D+ I. ~, K* Y  chrooted, and no file change is considered while the process is running. A
2 b  y, a. p! A2 ~3 \  simple method for developing those files consists in associating them to the. d5 h& D# n  L. b
  403 status code and interrogating a blocked URL." ~! Y3 }- i; ^4 o+ f

' z; |7 x' w3 L8 c  See also : "errorloc", "errorloc302", "errorloc303"5 ~& Z+ c& Y% g
& j4 i* H& t9 z0 I, ?: B$ o
  Example :( ^+ k( C+ z# |  t8 [# N/ l7 H$ T
        errorfile 400 /etc/haproxy/errorfiles/400badreq.http# l: b2 _" n$ ^+ {& i" j
        errorfile 403 /etc/haproxy/errorfiles/403forbid.http1 u, D4 P2 r' M* Z2 E. T7 C
        errorfile 503 /etc/haproxy/errorfiles/503sorry.http8 [3 \6 P# N3 a

1 V8 w2 i4 p  Y2 I3 r. w; _
% j; U2 ?% l' ?# d$ U- R7 Oerrorloc <code> <url>
* C/ G" w8 J3 C$ ~* V1 Berrorloc302 <code> <url>
  Y7 ^) X9 G9 j6 P* U) }5 ^: B  Return an HTTP redirection to a URL instead of errors generated by HAProxy* p5 N. I4 L" L7 I$ q2 Q
  May be used in sections :   defaults | frontend | listen | backend
2 O% C% \1 j' Y% ]                                 yes   |    yes   |   yes  |   yes
5 R  t4 c* C" \: T9 D! Y  Arguments :# ?7 y4 b1 f$ \9 u8 t
    <code>    is the HTTP status code. Currently, HAProxy is capable of0 s1 C& w- V9 @  ^7 w7 D
              generating codes 200, 400, 403, 408, 500, 502, 503, and 504." }+ W! D' b; |

! Y% [- Q% E8 A! C    <url>     it is the exact contents of the "Location" header. It may contain
% D# q+ q9 M0 q- p4 f7 ~% G+ d              either a relative URI to an error page hosted on the same site,* |7 ]: V- Q2 r9 [
              or an absolute URI designating an error page on another site.! T5 S" Y! z8 m6 ?
              Special care should be given to relative URIs to avoid redirect" u4 F) |) ~$ T( L* ~  M& m/ ]. Q/ o
              loops if the URI itself may generate the same error (eg: 500).
. r2 ~5 X" @- b: I, [) ]4 H- d. f" m. }. \6 I4 D, w
  It is important to understand that this keyword is not meant to rewrite
) G$ J- A% X2 K. W) e5 P; m$ c6 R0 H% h  errors returned by the server, but errors detected and returned by HAProxy.+ C4 T* l' G) R$ U
  This is why the list of supported errors is limited to a small set.
* G& u6 }$ U& X' B2 C9 P5 o9 s' W+ b1 e1 L9 i& Q/ v8 ~
  Code 200 is emitted in response to requests matching a "monitor-uri" rule.6 ]: t+ u; }1 K/ q8 V8 j* T7 x

# I8 z9 v+ o9 E# D% k1 Q5 R  Note that both keyword return the HTTP 302 status code, which tells the
& M* J. y) f6 l6 c  client to fetch the designated URL using the same HTTP method. This can be7 h5 J* K  k, N
  quite problematic in case of non-GET methods such as POST, because the URL; G+ [  |; C0 W  Y# Z8 D
  sent to the client might not be allowed for something other than GET. To# @+ W9 p8 @* r4 u) _& g8 r
  workaround this problem, please use "errorloc303" which send the HTTP 303
. s& Q3 y4 z/ O( F6 a1 R& I' G! b  status code, indicating to the client that the URL must be fetched with a GET
0 ~% J* i8 E3 B7 I  request.
6 o+ {+ `: z, E* d: I' ~
6 [6 U8 e; U) {; W1 k9 Z: n7 x  See also : "errorfile", "errorloc303"4 D) {. D5 ]' m/ `1 Z7 @- s8 z% B/ z
$ r+ p+ z1 C- y, p: V3 e* Q' x& s
. u/ ~* o" \8 l8 q- c" Z
errorloc303 <code> <url>
% A; g0 E- T+ I0 ], {7 F  Return an HTTP redirection to a URL instead of errors generated by HAProxy
2 p7 p- Z3 I4 `- U  May be used in sections :   defaults | frontend | listen | backend
2 _9 V# l( \: A" B7 D                                 yes   |    yes   |   yes  |   yes8 C; N  E6 A. {: N6 d
  Arguments :
# @' o* S7 @8 B0 o$ H% Q    <code>    is the HTTP status code. Currently, HAProxy is capable of' P, {/ f3 a, f& U) O' G
              generating codes 400, 403, 408, 500, 502, 503, and 504.
" q( ]- u) X4 k5 o/ Y1 m# q
! m7 Q$ {  }# S) x1 \1 N8 m    <url>     it is the exact contents of the "Location" header. It may contain
8 A+ g# v2 {2 c              either a relative URI to an error page hosted on the same site,7 _+ y( O! R; T
              or an absolute URI designating an error page on another site.
4 t/ X  Y$ q5 V0 o/ |; s! f              Special care should be given to relative URIs to avoid redirect
0 l3 B8 L: P. D  F9 V              loops if the URI itself may generate the same error (eg: 500).
! W9 T0 q5 p7 i  h: H
. A. l" j( U% ]; A5 {0 h& N  It is important to understand that this keyword is not meant to rewrite7 z0 k/ _  F% X: M; f' X8 G
  errors returned by the server, but errors detected and returned by HAProxy.: `# e) U; X  y/ c8 {  P
  This is why the list of supported errors is limited to a small set.
1 u* }* F0 x, ?1 \2 {0 P6 M, }6 F" v+ W& j
  Code 200 is emitted in response to requests matching a "monitor-uri" rule.: D: A7 K) W/ a( y& \( L! a$ r7 ]

2 U* Z* f) G5 G" J  Note that both keyword return the HTTP 303 status code, which tells the/ K* f, t* H% {4 z7 }! A( I
  client to fetch the designated URL using the same HTTP GET method. This/ t. r9 U/ x# K- |/ X$ M0 t
  solves the usual problems associated with "errorloc" and the 302 code. It is
0 o& h7 P8 |/ c$ r/ F* a  possible that some very old browsers designed before HTTP/1.1 do not support& G8 g$ c3 j* ?% w. O& d( @8 ^
  it, but no such problem has been reported till now.$ K8 g0 z# p" C1 k' w% d
5 L, m1 b2 G8 j0 F0 c" f
  See also : "errorfile", "errorloc", "errorloc302"
% _1 t* {7 o1 x- Q
9 N3 E/ V* Q" A
/ r1 M- T9 L! x1 i. q( {" zforce-persist { if | unless } <condition>
: H, i& m7 }$ t9 s* e7 U  Declare a condition to force persistence on down servers3 I' i1 w: ~. E. p" e0 w+ K
  May be used in sections:    defaults | frontend | listen | backend0 {: g. d+ D: Q, M: V- [- M
                                  no   |    yes   |   yes  |   yes' p/ p) M" {& F! \+ P/ U) }

1 h& e' L: Q8 G7 Z' u  By default, requests are not dispatched to down servers. It is possible to
% P* u( a5 |" ]: b. x- Z  force this using "option persist", but it is unconditional and redispatches
; x) }4 O, j3 N& c/ P  to a valid server if "option redispatch" is set. That leaves with very little* ^! t$ m7 w5 B
  possibilities to force some requests to reach a server which is artificially8 {9 S7 M$ l" ^* c& d$ V. A
  marked down for maintenance operations.
: f1 h% U/ I; S! \! J2 Y7 g% {  a
  The "force-persist" statement allows one to declare various ACL-based& U( O& ?" s- `% h3 R2 O/ l
  conditions which, when met, will cause a request to ignore the down status of+ F. b) i$ p1 r9 Z* J* @
  a server and still try to connect to it. That makes it possible to start a
; B# T2 e) g; `9 h  server, still replying an error to the health checks, and run a specially
) b: x. E3 G7 @/ X0 C( [  configured browser to test the service. Among the handy methods, one could
  K' G' h( P6 ^& P# |5 E  use a specific source IP address, or a specific cookie. The cookie also has4 y! r! F. B: `$ u( T. L% [" r
  the advantage that it can easily be added/removed on the browser from a test- N. Z( V  k; P7 {' C: g- j$ g
  page. Once the service is validated, it is then possible to open the service
% A1 M& F' I1 x( G  u  to the world by returning a valid response to health checks.
2 W9 B/ p" F* D2 M
" E3 X) J- Y% Z  The forced persistence is enabled when an "if" condition is met, or unless an
4 S% H; @/ _. h$ [  z  "unless" condition is met. The final redispatch is always disabled when this
2 y) L4 N9 I8 ~1 s! M* V# r4 @8 P3 ?  is used.5 |( e& X) s5 j
$ o; P5 }& t, J  J- J
  See also : "option redispatch", "ignore-persist", "persist",; ?1 @$ \6 ]* A2 f( I- _
             and section 7 about ACL usage.$ F2 F1 [  G7 {+ N0 t& k

5 U( h6 `7 Q  V8 T
2 u0 [9 M7 U3 a5 {8 xfullconn <conns>0 ~8 e, }6 B0 p7 G# y$ t# D5 K3 X
  Specify at what backend load the servers will reach their maxconn
. H. ]" \: N( b5 G  May be used in sections :   defaults | frontend | listen | backend0 Q$ ~( m4 s: ^6 m+ q, V0 A5 {
                                 yes   |    no    |   yes  |   yes
: V/ W# u6 q* j% X% n  Arguments :! S2 B: O8 j/ f* P+ K$ t+ L, w! h
    <conns>   is the number of connections on the backend which will make the
' r. o5 t% I- D" s7 F  A9 @+ U              servers use the maximal number of connections.
( A( G+ S! V# h; `9 R
0 d7 {. S* ?- ^# q  When a server has a "maxconn" parameter specified, it means that its number
* U) }. v" j9 F% e  of concurrent connections will never go higher. Additionally, if it has a
+ h- B0 V* `$ t& ~' b' m2 H  "minconn" parameter, it indicates a dynamic limit following the backend's! F$ ]6 e5 \3 [: K6 Z( t
  load. The server will then always accept at least <minconn> connections,
/ l* _3 Z: C0 X7 h  never more than <maxconn>, and the limit will be on the ramp between both
  e' I' ?5 ?6 G  values when the backend has less than <conns> concurrent connections. This: [0 W1 j: W! F( H
  makes it possible to limit the load on the servers during normal loads, but
" ^" `" J' M# u2 L. \- \' T  push it further for important loads without overloading the servers during# B* f0 K% N4 r; @1 \/ ^
  exceptional loads.
( L8 O; d3 d, A0 X2 z" i- W9 V' d: d- V( D! G3 b$ t
  Example :* r. M  d3 S- q
     # The servers will accept between 100 and 1000 concurrent connections each3 |+ j% P0 n* a% X3 y4 C! T
     # and the maximum of 1000 will be reached when the backend reaches 10000' }/ G' `  u% P( {+ {1 V" O5 _* y$ D
     # connections.
/ w# H) V: u! q+ y     backend dynamic
" X3 {& k6 J. E5 u/ u0 K6 l        fullconn   10000. [9 ]- \. [7 Z7 K
        server     srv1   dyn1:80 minconn 100 maxconn 10005 P3 y; K/ c+ M- ~3 m
        server     srv2   dyn2:80 minconn 100 maxconn 10005 o5 b/ ?3 ?+ [  C0 p
6 c8 I- r) c8 a! H
  See also : "maxconn", "server"
3 t( @# U  K4 `' S
( w. w5 ^: V& V
6 P  [1 D$ R3 n6 m  n+ kgrace <time>
8 t8 i, x' ^. V0 m3 l4 ?  Maintain a proxy operational for some time after a soft stop
8 t/ n0 z5 }0 o0 \9 Q  May be used in sections :   defaults | frontend | listen | backend
6 a9 l3 P5 w+ Q3 a! s. s' q4 h                                 yes   |    yes   |   yes  |   yes0 j9 Q: I5 J! i4 U6 o
  Arguments :( E9 x9 A. H& d$ x' X, ^
    <time>    is the time (by default in milliseconds) for which the instance4 h: h9 P. L8 c( @/ T
              will remain operational with the frontend sockets still listening
! h$ t* R, N- Y0 X! g              when a soft-stop is received via the SIGUSR1 signal.
4 A- w6 q% c9 G9 w+ i' V* `, P2 k2 f( W& r/ W
  This may be used to ensure that the services disappear in a certain order.6 a4 i+ L* U: Y# q4 _2 B
  This was designed so that frontends which are dedicated to monitoring by an4 ^7 ^- w* r9 L& _- Z& G" J+ T( Z
  external equipment fail immediately while other ones remain up for the time
: B( x1 s' Q, q5 S. t  needed by the equipment to detect the failure./ a$ Z) X9 U5 W4 ~$ b! n

/ |6 |  {6 M/ c2 ~& L% c. ~5 G+ V1 U  Note that currently, there is very little benefit in using this parameter,
7 o% p6 P1 t+ ^  and it may in fact complicate the soft-reconfiguration process more than
/ s* x2 w$ s% ^2 ~  simplify it.
7 [& P- ^9 {" h2 D& j$ U. P  _4 ?6 W4 w6 I/ |, i

0 O, |' J; X' g7 n) vhash-type <method>* G# z3 b" |4 X1 j$ f2 d4 I7 @, t6 r
  Specify a method to use for mapping hashes to servers5 }  y/ W& a1 |  X2 \) }4 I+ n
  May be used in sections :   defaults | frontend | listen | backend
' n: U% I% a5 A                                 yes   |    no    |   yes  |   yes$ d2 Q3 L& e/ C. R! {  R' s. b
  Arguments :
6 e4 W( l$ @& p2 {    map-based   the hash table is a static array containing all alive servers.  D* H" g- D( i. I4 l! z' Y
                The hashes will be very smooth, will consider weights, but will
$ T- p, h6 l+ V3 {                be static in that weight changes while a server is up will be
9 \3 y1 H6 {$ R9 y/ ^  n+ J0 s                ignored. This means that there will be no slow start. Also,' w% o& @0 j5 a' T. ^6 A
                since a server is selected by its position in the array, most# b; S$ b, [+ s3 m# H  B% b
                mappings are changed when the server count changes. This means. `7 Z8 H5 I* @, D& o: B' ?
                that when a server goes up or down, or when a server is added
/ u  K) n7 X2 j, E  b9 n                to a farm, most connections will be redistributed to different9 Q5 ^' |2 K3 R: c) @
                servers. This can be inconvenient with caches for instance., u1 {# i; ~# q4 H/ N
2 f( L: z" {8 M" D
    consistent  the hash table is a tree filled with many occurrences of each
( v8 _, Z3 X. N* G! I                server. The hash key is looked up in the tree and the closest2 s' f2 p% _; v8 k& m4 ]
                server is chosen. This hash is dynamic, it supports changing1 ^6 S. D, Y3 C
                weights while the servers are up, so it is compatible with the" \, z& \8 }1 a
                slow start feature. It has the advantage that when a server
6 T6 s% A4 ^: g! M- X$ K7 t                goes up or down, only its associations are moved. When a server
7 C. S" p6 \, B                is added to the farm, only a few part of the mappings are( T9 `( R$ Y+ P6 I: G1 k% o' z
                redistributed, making it an ideal algorithm for caches.- c- f% A3 D/ S) u
                However, due to its principle, the algorithm will never be very3 h, z0 R5 U5 L9 p. ~
                smooth and it may sometimes be necessary to adjust a server's
) y4 W* `  i! B9 w0 }, {% C' `                weight or its ID to get a more balanced distribution. In order
1 \0 a/ \0 S; n1 Q0 B7 J4 k1 O                to get the same distribution on multiple load balancers, it is* s3 r9 y! m" a& O
                important that all servers have the same IDs.4 w. t5 J% W2 ]. u; `6 R
/ T; {! T! O- V/ D: x* T
  The default hash type is "map-based" and is recommended for most usages.4 g. n; e6 o- c% T- O

0 Z, A  m& {% W, q8 k  p  See also : "balance", "server"
4 S9 K7 I! |& _: x% y1 C+ T
( \3 c, l% I, h. a
) _; Q* z. h! h0 v) ]http-check disable-on-404; h% U6 z3 G0 ~& Q0 Q
  Enable a maintenance mode upon HTTP/404 response to health-checks$ |5 B. L& y( H6 ]
  May be used in sections :   defaults | frontend | listen | backend9 ]4 A! v1 I% ~' f
                                 yes   |    no    |   yes  |   yes7 f1 J) _5 I" }. G9 _: m
  Arguments : none
6 g& @) R- p% B+ a" P
# Z4 ~1 V) a+ B8 c  When this option is set, a server which returns an HTTP code 404 will be8 L+ p% A2 F6 x+ Q
  excluded from further load-balancing, but will still receive persistent7 ^! M  W7 S6 _/ E' D$ t% R  B
  connections. This provides a very convenient method for Web administrators
4 B+ S& R; N! Y8 m4 X, t" k  to perform a graceful shutdown of their servers. It is also important to note( A( W& F: m( i2 G7 [: n
  that a server which is detected as failed while it was in this mode will not
( I: r% V+ Z3 @7 G5 r6 e  generate an alert, just a notice. If the server responds 2xx or 3xx again, it
: @. r% j# _+ L# y  will immediately be reinserted into the farm. The status on the stats page7 i5 y! C. g0 Q. s+ \# K9 @
  reports "NOLB" for a server in this mode. It is important to note that this! r( g$ B$ p/ Y, A9 c8 N
  option only works in conjunction with the "httpchk" option. If this option' x2 J7 }5 d" B: C1 d, K
  is used with "http-check expect", then it has precedence over it so that 4040 U8 Y' Z6 ]+ n4 o; c4 T; F$ _
  responses will still be considered as soft-stop.
; I# }5 I9 f, F8 z1 A0 X/ W; T3 L7 b/ k' n3 I
  See also : "option httpchk", "http-check expect"
' H7 E2 S5 _" T3 f/ ]. T/ E
/ b" y$ P# u8 W, z1 \+ r  @' F" h3 ~# Q6 I' p
http-check expect [!] <match> <pattern>
) \. p: S: W5 d8 y5 r4 K  Make HTTP health checks consider reponse contents or specific status codes7 n: x/ \) P1 n0 C6 C/ E7 b
  May be used in sections :   defaults | frontend | listen | backend
7 J) }+ s( Z( R  M                                 yes   |    no    |   yes  |   yes; Z8 E  p% W2 f; r
  Arguments :
5 h3 Z1 n# \' c" a* ?    <match>   is a keyword indicating how to look for a specific pattern in the" [, t- a* N6 `; B+ _
              response. The keyword may be one of "status", "rstatus",
; w- ~# w( @/ k: d7 ^              "string", or "rstring". The keyword may be preceeded by an
: x. `* t2 S1 |: n4 e% s& w4 V2 t0 a              exclamation mark ("!") to negate the match. Spaces are allowed
$ n% }7 a  d( U/ s1 |              between the exclamation mark and the keyword. See below for more" [4 L" @, M5 X7 f/ f* p* ?) v
              details on the supported keywords.* S) w7 r9 A+ P4 _' ]
9 W0 d% O6 {# Y  k7 R
    <pattern> is the pattern to look for. It may be a string or a regular
9 i4 ?' V6 I5 n  j3 p              expression. If the pattern contains spaces, they must be escaped/ ^9 @' y4 n  |/ t4 i; t% g" w0 W
              with the usual backslash ('\').7 Q( m! b0 u" H; A2 u9 O7 J0 _

9 \/ E+ B2 U& |0 k% x  E* B( o. f  By default, "option httpchk" considers that response statuses 2xx and 3xx
8 Y( Y; }* w0 M, j3 [- {  are valid, and that others are invalid. When "http-check expect" is used,
( }6 e) m% D- L; r0 m; k  it defines what is considered valid or invalid. Only one "http-check"+ J5 n9 W9 a3 E% o* w" T
  statement is supported in a backend. If a server fails to respond or times( G! j7 B2 _+ i# Q2 F& u- {% _4 {, ?
  out, the check obviously fails. The available matches are :
! @' Z/ k, \: a9 v. t- w2 p( \  h9 ~+ O  l# {! u
    status <string> : test the exact string match for the HTTP status code.% J/ C- \. l$ G6 c7 a
                      A health check respose will be considered valid if the4 t& f" v9 U; y7 p6 w7 X
                      response's status code is exactly this string. If the
# x; X+ U  t5 g                      "status" keyword is prefixed with "!", then the response
2 N# m* b: m5 W0 ~) L                      will be considered invalid if the status code matches.+ z$ S! F0 N& l- W

$ g( E4 h- k* ]( q: o0 n    rstatus <regex> : test a regular expression for the HTTP status code./ r- t2 y& v3 r& a0 c" A
                      A health check respose will be considered valid if the
9 F; v! y% y% B' b! \                      response's status code matches the expression. If the
8 f. M# }7 f% ]! x                      "rstatus" keyword is prefixed with "!", then the response
/ {" n$ p1 A* {& b+ z& n                      will be considered invalid if the status code matches.
* m- b8 k; R5 S' G/ E                      This is mostly used to check for multiple codes.
0 d& e' M3 {3 f$ N: B: ^
3 p; L7 I) S0 `: ^1 k- D* I    string <string> : test the exact string match in the HTTP response body.
3 R& V' _" l0 W8 P! S                      A health check respose will be considered valid if the5 X( l9 Z7 v) Z8 a" [' Q
                      response's body contains this exact string. If the
# B- L5 w* t6 U- H0 U                      "string" keyword is prefixed with "!", then the response
) o$ n) C0 R. U& v% t3 V# R                      will be considered invalid if the body contains this
5 B( b7 {& V" K                      string. This can be used to look for a mandatory word at' s9 _, `: n3 B) x2 h' l  a* o, w
                      the end of a dynamic page, or to detect a failure when a
7 i# X. h4 o" B  [) X( f                      specific error appears on the check page (eg: a stack
: Z4 W9 O( R9 V0 a: W                      trace).7 T) S! v! m7 t7 k% g: z

! v- M9 A; W. j+ p, b    rstring <regex> : test a regular expression on the HTTP response body.
5 Q+ n1 A5 V1 ~) Q9 P  i0 ~                      A health check respose will be considered valid if the
- b3 G, p, Y% ^1 c/ H                      response's body matches this expression. If the "rstring"+ }) `7 E' V% k0 v
                      keyword is prefixed with "!", then the response will be
5 i6 s# o/ W$ o; q2 L                      considered invalid if the body matches the expression.
3 ^1 B( j  A' m+ B  C% @4 k7 U                      This can be used to look for a mandatory word at the end
/ j: G& V4 y# r) P; X" Q: {% p* V                      of a dynamic page, or to detect a failure when a specific
+ F0 G$ [" x$ t3 W5 K                      error appears on the check page (eg: a stack trace).( T, M3 u! C6 [* r

" V/ q/ G& N1 B3 p! B  It is important to note that the responses will be limited to a certain size) g) [. D- j- P9 X
  defined by the global "tune.chksize" option, which defaults to 16384 bytes.
( w: z+ u2 v: `. Q' L  Thus, too large responses may not contain the mandatory pattern when using
- ~* d% h2 Q; \, Y4 n0 Y' v  "string" or "rstring". If a large response is absolutely required, it is7 D* [7 m" ?9 \0 P
  possible to change the default max size by setting the global variable.
8 ~3 B- J. N+ e8 ?$ Z4 M  However, it is worth keeping in mind that parsing very large responses can0 |0 y, A3 S- e8 |7 c) Q2 h
  waste some CPU cycles, especially when regular expressions are used, and that0 s. x) I3 ~  ?
  it is always better to focus the checks on smaller resources.; P$ q' ~1 n# R

5 M* h  t& U, \6 Y* A  Also "http-check expect" doesn't support HTTP keep-alive. Keep in mind that it* A" T4 i, k1 S: l+ ^0 m' ?( S
  will automatically append a "Connection: close" header, meaning that this, r2 z/ `  J- p1 ^% ^, d, ^
  header should not be present in the request provided by "option httpchk"., W6 q! e' x+ ^5 A

8 U9 t9 Y* S4 M% Z: ?" m  Last, if "http-check expect" is combined with "http-check disable-on-404",
( ~% ?) d* @, L( h( E  then this last one has precedence when the server responds with 404.! b# l6 H+ {! q1 q

  L+ ?' z8 x" t% }  Examples :
0 [( w7 c- M9 C8 M0 x         # only accept status 200 as valid8 T8 B& x/ D% r/ k
         http-check expect status 2005 X5 s! u( z+ C3 z, J$ z+ l

. ~$ p- n2 l3 Z$ A7 D" `         # consider SQL errors as errors
* L8 m( `( W+ g5 a5 L         http-check expect ! string SQL\ Error6 Y* d: [" F& k6 z7 W
& M, H; _; s# Y: m
         # consider status 5xx only as errors: ?: R$ x( h5 ~+ n, j
         http-check expect ! rstatus ^5
4 X0 |$ a* B; \+ T: `
1 Q# k7 K! s4 ], t% E# d         # check that we have a correct hexadecimal tag before /html$ [6 v- `9 G7 o: z
         http-check expect rstring <!--tag:[0-9a-f]*</html>
; A7 g! O4 D% |/ w: u$ W+ y7 L5 b
  See also : "option httpchk", "http-check disable-on-404"
- ~: _* o* J1 {2 v! B. P, d
: w0 |" \4 Q% q. E' |3 j) x  T; b5 N5 w) F, x! l+ Q, B
http-check send-state& x- Y3 K) O" O) E+ X
  Enable emission of a state header with HTTP health checks0 ]1 W5 K5 w# f% ]! V. r
  May be used in sections :   defaults | frontend | listen | backend6 ?2 m" T6 D9 E' ~7 {' p
                                 yes   |    no    |   yes  |   yes7 C! J: S# J# k9 [
  Arguments : none
  ]1 u5 c$ v5 w. z; N' b/ t7 ?! O1 M, s' i* P, `
  When this option is set, haproxy will systematically send a special header7 l8 I9 D, h: I( e1 I
  "X-Haproxy-Server-State" with a list of parameters indicating to each server$ _! h% S7 M& H
  how they are seen by haproxy. This can be used for instance when a server is5 m) \: K! l0 D# Y; u
  manipulated without access to haproxy and the operator needs to know whether5 K. P; h" u7 g' O/ |$ ?* L
  haproxy still sees it up or not, or if the server is the last one in a farm.
1 D  ~' ^4 U. {% s9 }; C- J: q
. c+ Y0 N4 [' z9 @  The header is composed of fields delimited by semi-colons, the first of which
3 N. R4 k" g6 U5 k2 `( g1 Q  F  is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid1 @1 u7 V  |4 [6 H5 I1 J5 D
  checks on the total number before transition, just as appears in the stats
! W' o# `) @% c8 i- Z% s  interface. Next headers are in the form "<variable>=<value>", indicating in& n1 \2 n+ A$ y  ^  v6 B
  no specific order some values available in the stats interface :
+ C8 m6 E1 F  G! i' B    - a variable "name", containing the name of the backend followed by a slash: f7 I2 x5 z- E" ]4 s' M+ [
      ("/") then the name of the server. This can be used when a server is8 b0 R  N3 g$ x$ C# s8 k
      checked in multiple backends.9 L) X, h) ?( o. z& @- [" e9 P
, m4 }% ?8 j) a7 A0 t- B, b' n3 u
    - a variable "node" containing the name of the haproxy node, as set in the
, r/ h" k8 J# ~5 p# Z. E. {7 o      global "node" variable, otherwise the system's hostname if unspecified.
, k. F) D# T" \7 i3 y, a/ H/ H0 |1 T5 B4 R' t7 A
    - a variable "weight" indicating the weight of the server, a slash ("/"); k+ J! x! A( J: o+ t
      and the total weight of the farm (just counting usable servers). This
2 j3 }1 |* J* \  {% Q) C: N* {: g      helps to know if other servers are available to handle the load when this( A% C* }0 J2 i; b) ]0 X
      one fails.  I; |9 {8 Z* B- W3 I! G8 `* |& a
% T; }# ]/ s0 E5 F
    - a variable "scur" indicating the current number of concurrent connections
; }4 J& z1 s% F5 C6 j& ~3 _      on the server, followed by a slash ("/") then the total number of
. h4 h4 }" |4 K8 I: C      connections on all servers of the same backend., Z5 z1 x, g) ?0 J) Q* Q
7 s) D8 t+ }$ b% k) Y+ `! V; J+ o
    - a variable "qcur" indicating the current number of requests in the) {9 t9 F  `) D4 }
      server's queue." l! v& J" R; {: q
! _7 s' C4 Q6 M2 n: ^1 ?+ s
  Example of a header received by the application server :
/ e- K# A- }. v; b' o/ O    >>>  X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \
. e+ Y, F1 c3 ^/ O           scur=13/22; qcur=07 Q' o" Y: d2 L0 y! V
9 v, N" b4 m/ O) c5 K, Z
  See also : "option httpchk", "http-check disable-on-404"
" o: _/ L) Z& Z; j
, y9 e2 V" j3 @8 A0 l# j3 P" p% phttp-request { allow | deny | auth [realm <realm>] }
0 L1 t' @. t0 f) T* N) O             [ { if | unless } <condition> ]8 c- s- D" Y; j) q4 W
  Access control for Layer 7 requests
+ }! |. d0 z- I6 V1 e8 |! b( q% a' k1 Y! R" k
  May be used in sections:   defaults | frontend | listen | backend
3 f9 b3 @. v4 D                                no    |    yes   |   yes  |   yes
+ v1 _. t. N- F' S4 Z/ c4 m) _: A$ y) ?2 A% W2 D
  These set of options allow to fine control access to a2 K/ d/ g6 |1 H" [0 G* E/ y! x
  frontend/listen/backend. Each option may be followed by if/unless and acl.2 C  D7 I1 G. Z  m
  First option with matched condition (or option without condition) is final., f5 n1 t3 }, c( a! D/ B6 D
  For "deny" a 403 error will be returned, for "allow" normal processing is3 @( y% y: c; ^3 |1 `9 N8 a
  performed, for "auth" a 401/407 error code is returned so the client# h# u6 Z) c- e7 t0 K8 e
  should be asked to enter a username and password.; U1 U5 ^" ]0 |  b( I

. x3 u0 y+ d+ ?7 N4 d7 n6 g  There is no fixed limit to the number of http-request statements per
% [/ u' x$ R) Q2 J  instance.0 }' }" V6 H7 B; i/ g  g& F& o4 S
! I- x' S" \$ f; E7 @; d
  Example:
, U. `* Q9 D! ~% t3 u1 O        acl nagios src 192.168.129.3
% l2 Y) F3 B  d" r% N        acl local_net src 192.168.0.0/16
' g% I/ t  W, [- n/ L& ^; ?        acl auth_ok http_auth(L1)
+ Y# c/ A. V+ S1 f- K" f* K
# ]! u5 H, m  }6 g        http-request allow if nagios# _1 Y. U7 R5 k" B
        http-request allow if local_net auth_ok6 `! G* a+ {4 S
        http-request auth realm Gimme if local_net auth_ok
- E. l, O: `5 C6 b4 m        http-request deny
2 I+ C, ~+ P9 q# m- s, Y8 t5 O
. M6 V* d' Z7 b  Example:
+ A! S" ]. e$ l# o& f; o        acl auth_ok http_auth_group(L1) G1. }: Q( z5 v2 I5 C8 K( p
* R' B  g" L3 q, c# U0 B- S# Q
        http-request auth unless auth_ok
9 I+ _# y' z" e% ~$ l; J
4 Q7 j: g8 V& Y- o3 _  See also : "stats http-request", section 3.4 about userlists and section 7
% S4 M4 W* E+ g: f* ?             about ACL usage.
2 Q$ A0 W  w# N9 f! P+ r, s2 y5 o: Q% A3 c( f6 a
http-send-name-header [<header>]1 c  d3 q( ]5 v9 t" E& n
  Add the server name to a request. Use the header string given by <header>* {! ~. u  M1 Y8 C, G8 V! }% O$ U  L) m
6 Z( i. W: X5 N4 O8 w  K% j
  May be used in sections:   defaults | frontend | listen | backend6 w9 i, k  I" }( x$ m; b
                               yes    |    no    |   yes  |   yes, x1 W  |- ^' }3 j- N+ I: f
* b7 _. k5 `  i: s2 \8 ?7 y
  Arguments :
& A7 B1 i# V" W3 E6 J
8 a# }4 h7 _1 B4 u6 N1 k    <header>  The header string to use to send the server name
+ t8 L2 K; F9 E6 s" m9 O
" b) j0 h/ f  T$ J) t& h  The "http-send-name-header" statement causes the name of the target
# i0 K9 g& W; u2 ^& R  server to be added to the headers of an HTTP request.  The name! N5 Y" Q/ }4 H- U+ \5 Q4 U, B9 ^; M
  is added with the header string proved.' \* c) Y: A) `2 C  c

  \% h' w$ l$ _5 F, R2 Q  See also : "server"" t% l# |, t- ]7 c
1 Z4 X2 I. J2 ^, U; {# \
id <value>
8 i/ o" Y8 z) D- B0 X  Set a persistent ID to a proxy.' i5 N2 C! r1 i+ @. ~
  May be used in sections :   defaults | frontend | listen | backend
; r3 |4 V# e! o0 r' ^/ l9 g                                  no   |    yes   |   yes  |   yes
( w7 X2 U, _9 o0 d0 g9 }  Arguments : none$ ?" a) q# W& |+ U! R3 d" c+ V+ X) k
' W6 S1 S# F. w. D9 `
  Set a persistent ID for the proxy. This ID must be unique and positive.
0 ?# `% ?+ F5 T& B# F  An unused ID will automatically be assigned if unset. The first assigned7 Z$ z( j7 v. r( x: m6 k
  value will be 1. This ID is currently only returned in statistics.% B; x4 ~" G& `

/ r3 r4 N2 X; M4 f8 E7 n, |
! L. [5 f+ u( I# ^. F( X* rignore-persist { if | unless } <condition>
0 y2 x- |  i& }7 I4 D  Declare a condition to ignore persistence, t0 q" l1 x; t" J: J& @
  May be used in sections:    defaults | frontend | listen | backend
6 v  B; _. p# x- F2 z6 `4 O                                  no   |    yes   |   yes  |   yes
: @' X1 z4 ^1 s! Z  \' U+ d7 v; a, d% r5 w, X" i& r4 j
  By default, when cookie persistence is enabled, every requests containing- h9 A+ F& p) B% ]$ Y/ W
  the cookie are unconditionally persistent (assuming the target server is up
* y$ h0 K8 H+ v$ o' X6 F) {& Y  j  and running).
/ O$ X; e( n8 o" Y* N9 c2 f) E4 V! l6 ?) R8 H1 S  y
  The "ignore-persist" statement allows one to declare various ACL-based
/ n# q/ b$ E9 e0 P0 Q! }8 _9 J  conditions which, when met, will cause a request to ignore persistence.0 ~+ ^6 d& S& Y3 [. Z( Z
  This is sometimes useful to load balance requests for static files, which0 g5 ~/ j9 U+ w
  oftenly don't require persistence. This can also be used to fully disable3 Z% h- m/ R9 Q4 _  N% o
  persistence for a specific User-Agent (for example, some web crawler bots).; Y  o( _9 u0 ~  F! x
1 z# G7 Y. U, ]# M9 I' y/ L) h4 v1 p
  Combined with "appsession", it can also help reduce HAProxy memory usage, as  m/ L; E$ C1 z- L% V! G; W/ R
  the appsession table won't grow if persistence is ignored.
" ]& K1 i$ L: D5 x. D( p( W6 O& t( D6 \( [
  The persistence is ignored when an "if" condition is met, or unless an
9 g+ E. X9 E5 L! X+ J$ [  "unless" condition is met.
  P3 a* l) R/ k9 _9 q# ~4 |( P4 F: b6 t
  See also : "force-persist", "cookie", and section 7 about ACL usage.
* L: g) Q  J/ B1 y) a! o: D
, x! _+ C, D* B6 z! S+ n2 c; z1 L" Y+ ]" X8 Q
log global
( X" P( U+ d- w7 N# B( q( A& nlog <address> <facility> [<level> [<minlevel>]]! M, v. l7 O8 Z$ c, u+ \2 ~: n
  Enable per-instance logging of events and traffic.9 C+ V" {8 r# m1 ~; ]
  May be used in sections :   defaults | frontend | listen | backend/ O% |1 ~6 K7 @& Y/ o* U
                                 yes   |    yes   |   yes  |   yes
% F9 @* ?+ ^) m  Arguments :
' L% w) O* l3 T" f$ o' M    global     should be used when the instance's logging parameters are the
% e6 J4 h& l- N6 \               same as the global ones. This is the most common usage. "global"
& ^8 [1 [5 ]8 K5 F               replaces <address>, <facility> and <level> with those of the log
) w, @6 x$ V. D3 Y& J( U/ D! X               entries found in the "global" section. Only one "log global"& k% K9 d9 x& F. J9 m
               statement may be used per instance, and this form takes no other; w7 p3 Y3 i9 c$ q' h1 X; l& F
               parameter.
* n: @. ~* o$ Q7 E7 l8 A8 G$ c1 R4 d: E* T, [
    <address>  indicates where to send the logs. It takes the same format as
$ M8 ~9 T) I" U& }8 [1 n               for the "global" section's logs, and can be one of :
0 U+ E: g/ \- a! L4 j
0 k$ r! ?! ]. H               - An IPv4 address optionally followed by a colon (':') and a UDP7 ^% I! f( o1 J! Y# p2 [& P
                 port. If no port is specified, 514 is used by default (the
9 i$ g+ |  z4 x' R  K3 I                 standard syslog port).- T" l# y; z6 A. x4 i& U  r: K
2 z& l% b5 O' E8 ]5 f
               - A filesystem path to a UNIX domain socket, keeping in mind3 Q" _, {  R/ X) c: x
                 considerations for chroot (be sure the path is accessible. o' A+ Z$ y9 r3 {7 i/ |3 S
                 inside the chroot) and uid/gid (be sure the path is+ W2 b" n  a* w0 v
                 appropriately writeable).
8 Q" I/ @) b$ W+ n7 I
  J- Z8 d% [) u1 p    <facility> must be one of the 24 standard syslog facilities :
( H3 W$ l9 N% B
$ d/ S, u% D9 }/ K. H                 kern   user   mail   daemon auth   syslog lpr    news2 X$ b; i3 v' Y
                 uucp   cron   auth2  ftp    ntp    audit  alert  cron2  ?5 d: \# O( Z1 b
                 local0 local1 local2 local3 local4 local5 local6 local7
' e& g, p7 ^, {% N8 l) V
% A" C8 J' \9 b  b5 k  F# m    <level>    is optional and can be specified to filter outgoing messages. By
- F) Z* r$ N+ N! `9 w- V3 b7 B* K9 `               default, all messages are sent. If a level is specified, only( D7 f6 I( q4 {2 o+ ]4 h* d1 V8 G
               messages with a severity at least as important as this level
' n  x: M% D6 q; }, |               will be sent. An optional minimum level can be specified. If it+ `( j& D- D: d, M( Y
               is set, logs emitted with a more severe level than this one will
0 k3 M: T  {( ~# u( G9 Z               be capped to this level. This is used to avoid sending "emerg", p4 E/ L& ]7 a$ T
               messages on all terminals on some default syslog configurations.
, ~) C1 S% y9 U' b; j2 o1 J               Eight levels are known :
1 G* V. a! Q; X1 d: N
' }% O/ p, `. Y# q6 @0 T- K% ^' z                 emerg  alert  crit   err    warning notice info  debug+ B* J# k1 n0 c; l, l- j" B

) t( Y- l, ^7 v2 J  Note that up to two "log" entries may be specified per instance. However, if
& y! r! x" k5 D  "log global" is used and if the "global" section already contains 2 log
8 a! g! j+ a! @4 F, ^1 Y  entries, then additional log entries will be ignored.
7 L' _( U- v/ K! S* X9 K
. J. W& c9 o) m! y. W' |8 @  Also, it is important to keep in mind that it is the frontend which decides' Y. [# D  f) z2 _) j# t6 F# s/ C. _
  what to log from a connection, and that in case of content switching, the log
' Q$ U& {4 D/ F8 |  entries from the backend will be ignored. Connections are logged at level% c. l7 k! m, I9 @
  "info".# w+ v4 u% Y: b! A+ m, N9 B

, B, n3 J$ W5 m( `! y  However, backend log declaration define how and where servers status changes
2 ^9 p: q6 w: o. `% z2 J  will be logged. Level "notice" will be used to indicate a server going up,
3 C1 B$ f8 w/ `, W3 \( r- R# p  "warning" will be used for termination signals and definitive service
7 S! G0 J3 m6 M9 \3 E  termination, and "alert" will be used for when a server goes down.! I2 @+ w3 M7 y  L9 ^
' E; z9 Y7 E1 C  ?2 X
  Note : According to RFC3164, messages are truncated to 1024 bytes before0 a8 P5 B# {/ U/ {! F* s; h
         being emitted.4 i2 v1 p0 s- E  T$ S6 m' ^
/ r% t$ J& ~0 K+ O+ Y. E
  Example :
/ L& U2 H0 a8 e7 ~  q    log global# n! N. e1 k: ~5 y
    log 127.0.0.1:514 local0 notice         # only send important events
4 j4 U* f/ P4 }3 q' A- ~    log 127.0.0.1:514 local0 notice notice  # same but limit output level0 i+ C) p6 }6 S
4 h2 \9 B0 w* l' D
3 n' _9 u' F5 c7 P3 K- G0 z' H
maxconn <conns>1 H$ X! k" R& K1 s2 s& E
  Fix the maximum number of concurrent connections on a frontend
5 r( Z5 i) t2 c" m9 Q3 W5 C) o  May be used in sections :   defaults | frontend | listen | backend$ \$ S4 ~1 C4 t  h5 X- M% L* n' m0 v
                                 yes   |    yes   |   yes  |   no) c+ N5 {' I2 B2 \9 C
  Arguments :& s/ k6 w: S6 G9 y) k7 ^. b! n0 q
    <conns>   is the maximum number of concurrent connections the frontend will
0 m, {( b/ o- u& k4 n- R              accept to serve. Excess connections will be queued by the system) F1 c' z) s0 F+ R# h! c, K" y
              in the socket's listen queue and will be served once a connection
* O- e+ h9 }  Z9 X              closes.
' O6 P& S2 a! H" {, I5 N7 S& X) |2 V1 t9 G( G) ^
  If the system supports it, it can be useful on big sites to raise this limit/ B/ @! ~4 [' K7 E
  very high so that haproxy manages connection queues, instead of leaving the/ r4 W8 u% Z! s7 H
  clients with unanswered connection attempts. This value should not exceed the, ?8 o6 P2 e" r6 p4 w! f
  global maxconn. Also, keep in mind that a connection contains two buffers
) K7 e; x# p  e+ ?. l5 {  of 8kB each, as well as some other data resulting in about 17 kB of RAM being0 i: L5 L$ b) I6 |$ O: W
  consumed per established connection. That means that a medium system equipped6 q# u% f" T& e9 a- _0 K, @  _; t: B
  with 1GB of RAM can withstand around 40000-50000 concurrent connections if. t' ^  ]; V* |# v6 \7 n2 y; g  q
  properly tuned.
9 a9 e3 a- ?6 T& d; s! X3 U1 _* C2 ]8 _7 ^# Q4 R. S' ~! x! u
  Also, when <conns> is set to large values, it is possible that the servers" \, `: l% i5 G/ [( z/ i; v% ?$ z
  are not sized to accept such loads, and for this reason it is generally wise
! _8 [+ Y% L/ N/ x4 K  to assign them some reasonable connection limits.
5 X' X& n  Z7 V3 u: E7 B' e* D9 L0 J/ p4 S9 m0 N4 v. Z2 L
  By default, this value is set to 2000.
6 E% S' E- b1 `, W" }8 c
& W: ~9 q" P+ e$ t. {2 x. f/ J  See also : "server", global section's "maxconn", "fullconn"
* U( R  y( T- j5 J, v
8 [7 q9 G' M! Q# T8 _" e+ v9 A& k; ^8 z& f7 {
mode { tcp|http|health }9 l5 {. _- G( ?8 C
  Set the running mode or protocol of the instance
' \  s) i) `! o( U/ ^  e  May be used in sections :   defaults | frontend | listen | backend
2 T( Z0 D; C% |                                 yes   |    yes   |   yes  |   yes
0 W$ t7 B) O# x& p* \% a  Arguments :
4 B( J( l' Y5 u9 {% }    tcp       The instance will work in pure TCP mode. A full-duplex connection$ [5 a# Z" p3 A, I) n: R9 Q
              will be established between clients and servers, and no layer 7
# x6 e% k+ E% G4 ~6 s2 I) r; ?              examination will be performed. This is the default mode. It( l/ b1 u4 N1 K/ J6 ^% B
              should be used for SSL, SSH, SMTP, ...
7 @& Q$ |) s  _  `2 A3 }& s1 P( d
    http      The instance will work in HTTP mode. The client request will be4 r5 q  t: Y# P
              analyzed in depth before connecting to any server. Any request
& l& K/ K# q2 p- y              which is not RFC-compliant will be rejected. Layer 7 filtering,& f- ?& V' [9 T8 H
              processing and switching will be possible. This is the mode which
' C6 s- g. M/ X2 O3 k6 s7 ]- W3 W              brings HAProxy most of its value.# F/ f1 F% W" s* B1 ]) M# f! u

! M5 ?- z2 b0 k* z- G$ d    health    The instance will work in "health" mode. It will just reply "OK"7 t. u# P# {& E) u$ Y! n0 @4 m/ W
              to incoming connections and close the connection. Nothing will be
) K3 t* C) a* T/ [  S2 `' D) d( E              logged. This mode is used to reply to external components health1 {* {7 q* d3 r7 X
              checks. This mode is deprecated and should not be used anymore as
; A- `4 D$ w% _2 R1 ~/ X              it is possible to do the same and even better by combining TCP or( a3 _$ Q" k" X. f: v
              HTTP modes with the "monitor" keyword.
1 w% r# z+ j) g' Q- S0 w( L0 W, l' R" U. b- P6 x4 o* Y; V- G! {
  When doing content switching, it is mandatory that the frontend and the3 z. a7 C& Q* O/ u) k$ k  u
  backend are in the same mode (generally HTTP), otherwise the configuration# q* k( H" c: E& I# K
  will be refused.% l% J9 p! _7 f3 u! f! d1 {
. R! _  O  y& {" O" v
  Example :
% {, u  {8 Z6 a0 E     defaults http_instances2 o& ]; X; B! h9 N* W5 A( L
         mode http
3 i& `( b0 k" D$ J: w7 L. }& T( @5 D
, M% N# H# P" x% y  See also : "monitor", "monitor-net": C5 ?% u& a- `3 b1 r

/ P/ k/ B# U! C7 b. Z- [  Y+ I0 t/ s4 k4 d
monitor fail { if | unless } <condition>: W* E+ b0 ]- o1 l3 u; ?
  Add a condition to report a failure to a monitor HTTP request.
: ]2 {, d: v6 A" M1 p# q  May be used in sections :   defaults | frontend | listen | backend
# z! \4 E( e& D8 J5 }/ G- g: _                                 no    |    yes   |   yes  |   no
0 ?6 ~, Z" ^. p) r+ B  Arguments :9 I) n5 K8 M! l; F3 G- x  |
    if <cond>     the monitor request will fail if the condition is satisfied,
7 @9 i0 p% v, D0 ^9 y                  and will succeed otherwise. The condition should describe a& d% C: X$ |# w% g
                  combined test which must induce a failure if all conditions
! J3 Z* T7 l" Q: T                  are met, for instance a low number of servers both in a
+ N8 J3 b- F9 H! j' t1 K                  backend and its backup." d* Q# A) u! N0 I( L
' e3 s- S6 s" A2 y3 X* W+ B
    unless <cond> the monitor request will succeed only if the condition is6 \/ n: ?6 e/ ^$ {2 q; a: c% K" |
                  satisfied, and will fail otherwise. Such a condition may be# D1 T- B! q( u! n# `6 a
                  based on a test on the presence of a minimum number of active+ ]2 C7 x/ r4 K$ I/ n+ X- Y8 t
                  servers in a list of backends.$ R- G* y5 Y0 B% S

! }# Z( W7 `6 e* R1 i5 A7 z  This statement adds a condition which can force the response to a monitor
' H! j: ~' M, i5 p3 h# B. N- V# Y  request to report a failure. By default, when an external component queries, \1 u# P; G) G
  the URI dedicated to monitoring, a 200 response is returned. When one of the
2 S/ ?. ^4 m! D% g$ q  conditions above is met, haproxy will return 503 instead of 200. This is' w+ Q9 g, f& E
  very useful to report a site failure to an external component which may base
. S, |8 z9 f7 C. P! d- O# K* B" t/ I  routing advertisements between multiple sites on the availability reported by- S! b) Q) ~7 y) }
  haproxy. In this case, one would rely on an ACL involving the "nbsrv") J! J, Q# O) t1 k! d- l' W+ u6 G
  criterion. Note that "monitor fail" only works in HTTP mode. Both status
( \( e& I* n, i. k' J8 U  messages may be tweaked using "errorfile" or "errorloc" if needed., t5 _+ g4 \4 k. \& ~) K

1 Z9 o1 {/ d0 I6 e- y  Example:
6 e+ B8 l$ C; t: N- U6 b     frontend www
. A) N, H. P1 I% ^  l6 {2 B        mode http
7 M; H4 {( a- d0 S% v+ B        acl site_dead nbsrv(dynamic) lt 2! Y6 r, Y* {# h& d, K+ p
        acl site_dead nbsrv(static)  lt 29 y2 k8 a: l* q$ E, G! _6 [5 W
        monitor-uri   /site_alive
! M% g: v& A+ Q        monitor fail  if site_dead
% r+ U2 u1 z: a1 X! ^9 \" h( p# [& ?- W% e
  See also : "monitor-net", "monitor-uri", "errorfile", "errorloc"- m6 Q/ ]7 Q) s/ b8 R) c
$ O. V$ Y* L9 R6 T

0 H7 B7 r; F: Ymonitor-net <source>5 ]% U6 g+ w. t; R: w
  Declare a source network which is limited to monitor requests4 b4 U1 S' J. k4 k& v+ q
  May be used in sections :   defaults | frontend | listen | backend' D1 Q4 b7 R8 _1 A
                                 yes   |    yes   |   yes  |   no
1 h: B5 V  T; X" W  Arguments :
$ |& l" F0 b  p% u$ h8 h0 @) v% h    <source>  is the source IPv4 address or network which will only be able to, G# z$ r+ G: y% V! O; o& P4 q; E
              get monitor responses to any request. It can be either an IPv4# B7 A$ J3 M/ v/ e% H9 D
              address, a host name, or an address followed by a slash ('/')
/ r' r5 p- E2 p! Y& A              followed by a mask.( M( Q. V* _7 i( c8 `. m; s
! \# |5 ^2 K; G. e" N
  In TCP mode, any connection coming from a source matching <source> will cause
) T7 I- L1 `$ E/ I& C+ L. x  the connection to be immediately closed without any log. This allows another7 n4 ?5 `+ U3 x! C3 N" s( A
  equipment to probe the port and verify that it is still listening, without/ r' E" @, a/ @
  forwarding the connection to a remote server.
, T# p1 n9 s( j
- K  Q4 ]' X' o  In HTTP mode, a connection coming from a source matching <source> will be
8 ~  B, V' h; y( m1 y/ @, K0 s  accepted, the following response will be sent without waiting for a request,
7 D+ D, L0 ^* ?2 z* K  then the connection will be closed : "HTTP/1.0 200 OK". This is normally/ v" i8 e; q/ u  ^" S3 o* s
  enough for any front-end HTTP probe to detect that the service is UP and% c. O- U6 A0 U7 A/ J& \  S1 t
  running without forwarding the request to a backend server.( E+ s/ l4 F5 V/ }7 y

% C! E. p% i5 `: \7 Z  M  Monitor requests are processed very early. It is not possible to block nor
1 [, M  g2 P- ?0 K& P, ?- K9 D1 K  divert them using ACLs. They cannot be logged either, and it is the intended
8 D6 j: Q; I, ]' H, S3 U4 J  purpose. They are only used to report HAProxy's health to an upper component,
9 }' y% r1 N3 b  nothing more. Right now, it is not possible to set failure conditions on* u. U3 z% r/ `4 v- a
  requests caught by "monitor-net".
# d% G- n8 n, f; F: V' ^4 {
8 J! \/ H8 v5 h; s2 K+ ~  Last, please note that only one "monitor-net" statement can be specified in, _4 [8 o$ [" v
  a frontend. If more than one is found, only the last one will be considered.  ]: Z) {9 }( V/ k4 v
$ ^9 T, t% p# }! q7 g
  Example :
% v; E. {# _; n- y% I: N" s4 j    # addresses .252 and .253 are just probing us.
4 Q: w; R$ @1 @' e# [& Y    frontend www
$ n! L, y7 s3 Y, o+ Y' V$ z5 t        monitor-net 192.168.0.252/31
  N6 |6 y' c2 X/ \% b9 Z
  T/ S6 c$ t) @, t) }; a  M6 T- u  See also : "monitor fail", "monitor-uri"; a& l$ _# W' F0 |( j
" Y0 l" g. B8 }' ~! H" F
3 |* Z$ q% `' e& M! f3 s8 z
monitor-uri <uri>5 u! z, Q1 Z, E, ^
  Intercept a URI used by external components' monitor requests
4 O9 m+ M8 S8 w$ p  May be used in sections :   defaults | frontend | listen | backend
# X' S8 ^0 _  B                                 yes   |    yes   |   yes  |   no
$ R7 E2 V4 r( w9 d  Arguments :
  k6 a* d8 B' v* M    <uri>     is the exact URI which we want to intercept to return HAProxy's
. {3 a4 F) a  z; q1 l. b0 X              health status instead of forwarding the request.: x2 m: D, H. k7 T

5 P8 u' W: k# O6 j  When an HTTP request referencing <uri> will be received on a frontend,5 ~4 j$ n1 c( S3 r$ B
  HAProxy will not forward it nor log it, but instead will return either5 S+ ^7 h: S+ N7 T' X& H8 X
  "HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure! r7 T8 f6 M7 [/ j/ H* M# [
  conditions defined with "monitor fail". This is normally enough for any$ L- a* K* R) ]2 ^& o: z# J
  front-end HTTP probe to detect that the service is UP and running without3 L9 o$ b: G! \9 c' D
  forwarding the request to a backend server. Note that the HTTP method, the" \+ S$ ]1 J# T/ r; K# F) ~
  version and all headers are ignored, but the request must at least be valid; O: Z& x, M; ~1 Z, K
  at the HTTP level. This keyword may only be used with an HTTP-mode frontend./ {) d" F5 s: H. R# R
( \5 X  G: E* ~' k6 [$ j
  Monitor requests are processed very early. It is not possible to block nor' w# H) ?6 Z: w; o% p) Z1 h6 E9 K8 S
  divert them using ACLs. They cannot be logged either, and it is the intended
# A% p0 A8 Q: f$ P7 I# f3 j  purpose. They are only used to report HAProxy's health to an upper component,4 V: X; [5 c5 L5 q/ a4 v
  nothing more. However, it is possible to add any number of conditions using
/ Z5 a7 C4 ]0 ?, P  "monitor fail" and ACLs so that the result can be adjusted to whatever check
3 f$ B; a9 v6 K) q$ ]3 j2 u  can be imagined (most often the number of available servers in a backend).: c) g7 e3 m8 v; L

! r) w& h" t$ Y1 t$ `  Example :
0 ]$ d6 O  T- b# k! ~, W    # Use /haproxy_test to report haproxy's status
$ ?6 L! l* Q! J; V    frontend www
' ~- i: \: o; m3 a0 T        mode http
' L5 b1 C4 w. v' M: \- L7 w        monitor-uri /haproxy_test
; @! }9 n+ U% ^3 d/ Z1 ^5 H. J) T& v/ X8 Z0 p
  See also : "monitor fail", "monitor-net"
5 {. b; q3 U  q+ ]6 P3 D3 G" [5 b: `: d  |: a
0 G# k7 G% O. s- ~
option abortonclose
% r' q  X. a& N# }- o( t9 m- yno option abortonclose
# O  s. u5 i: n* p, s/ D' J  Enable or disable early dropping of aborted requests pending in queues.9 e8 c) n. m8 g. L: g8 U
  May be used in sections :   defaults | frontend | listen | backend
% _" c+ S. N9 Y3 Z' k5 t3 F                                 yes   |     no   |   yes  |   yes
. P% }( y% U. H- T  Arguments : none
) t3 W. m3 X' x+ L7 D0 r' ^4 G+ K( Y+ I$ |
  In presence of very high loads, the servers will take some time to respond.
( r8 M% c8 Y& |4 Z" C9 p, d  The per-instance connection queue will inflate, and the response time will# a3 B8 a  a" P8 Z9 n8 [5 ?+ K
  increase respective to the size of the queue times the average per-session
/ X, S' ]( q6 ?! W; b+ t  response time. When clients will wait for more than a few seconds, they will  d3 I" B& {) L2 Z; q5 ~" ~0 b9 N9 i
  often hit the "STOP" button on their browser, leaving a useless request in
& }7 L/ `5 {+ R0 Q% z4 @& Y1 N  the queue, and slowing down other users, and the servers as well, because the
3 h1 c/ l" j* V( R: c7 N  \! }9 `  request will eventually be served, then aborted at the first error, I$ i& }/ I! @" Z( a
  encountered while delivering the response.! {6 }8 p# }9 L8 l  Y
; C6 l7 s1 s0 ~+ \( S$ T( O# l) X) s
  As there is no way to distinguish between a full STOP and a simple output
% z: R  |3 ~9 H3 m7 c1 u  close on the client side, HTTP agents should be conservative and consider
8 Z7 A! [5 e" S. H; Q* n; h  that the client might only have closed its output channel while waiting for
0 Y# ~; `+ f& X8 ~- C0 _4 ^  the response. However, this introduces risks of congestion when lots of users( V$ z( t; {: h0 W0 I- H
  do the same, and is completely useless nowadays because probably no client at
. R3 v+ u0 Z6 W% E7 ?' Z6 t  all will close the session while waiting for the response. Some HTTP agents
7 A. G7 M- ^; v+ N7 `! p! ?- Z  support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most- D$ {9 j1 F9 S
  hardware-based load balancers). So the probability for a closed input channel
* H' n, T, d9 j+ f0 E  to represent a user hitting the "STOP" button is close to 100%, and the risk
7 N4 K; p  L. Z* {  of being the single component to break rare but valid traffic is extremely& I+ Z7 T! O9 @
  low, which adds to the temptation to be able to abort a session early while- d8 k# A9 ?6 G4 ?6 N
  still not served and not pollute the servers.
8 p2 o: p* d( q5 m0 Z( W& n0 ^' R3 j# H7 W: p/ G4 J9 l( P& g
  In HAProxy, the user can choose the desired behaviour using the option7 G+ O, ?. l9 N- O
  "abortonclose". By default (without the option) the behaviour is HTTP
' d% }" ~" o9 X  compliant and aborted requests will be served. But when the option is- b1 O2 ~" `) X) U" t: o
  specified, a session with an incoming channel closed will be aborted while
4 Z: ^/ y( M! ^/ c0 j% m  it is still possible, either pending in the queue for a connection slot, or
, |. _) \9 i$ A7 j  during the connection establishment if the server has not yet acknowledged
/ x- {0 ^9 L. }+ x  the connection request. This considerably reduces the queue size and the load" l5 f, G. }3 s* a3 ?7 _
  on saturated servers when users are tempted to click on STOP, which in turn, C8 N3 i8 F3 f- ]
  reduces the response time for other users.& X' g2 r+ F5 J$ g% \1 M

4 e* M. v" r. G' b  If this option has been enabled in a "defaults" section, it can be disabled( h3 o4 `! d0 i9 ]
  in a specific instance by prepending the "no" keyword before it.2 H  Q' U" C$ N- Q* O3 }

! W% v- s( j! h* ]  J7 @6 c  See also : "timeout queue" and server's "maxconn" and "maxqueue" parameters( ^$ }. N; C: ^! h7 H" O

+ O$ N. i2 C$ L$ f2 z6 s: B4 Z: i, K, Q
option accept-invalid-http-request
1 e% e0 [( w. f( |, ~* v* Uno option accept-invalid-http-request- X6 o. ?8 i2 U! F" h  {
  Enable or disable relaxing of HTTP request parsing9 |. @/ i( U" c7 f8 `! S. F
  May be used in sections :   defaults | frontend | listen | backend; K' B  J0 H. a  J5 I
                                 yes   |    yes   |   yes  |   no
# z1 \/ z) e, P" L/ z8 |3 z  Arguments : none7 m) r, q% e; Q2 B

, F6 Z9 z+ D+ b" Q. t; {: k. n  By default, HAProxy complies with RFC7230 in terms of message parsing. This
# N! `6 P/ ~+ ^' M  means that invalid characters in header names are not permitted and cause an, |! @9 Y9 W3 h
  error to be returned to the client. This is the desired behaviour as such
( u! h/ ]+ B% g  forbidden characters are essentially used to build attacks exploiting server$ I: ^/ e/ ]7 _; r7 I7 F$ f
  weaknesses, and bypass security filtering. Sometimes, a buggy browser or
, ?: m& H2 Z& Y. a' [  server will emit invalid header names for whatever reason (configuration,
# N- h/ e! |+ {1 q  implementation) and the issue will not be immediately fixed. In such a case,
( `* X4 ^6 _8 g7 z/ O/ ^" P  it is possible to relax HAProxy's header name parser to accept any character
- ]- \" w0 ~, \* C% d; |  even if that does not make sense, by specifying this option. This option also  H0 e. J5 s+ g: H5 B
  relaxes the test on the HTTP version format, it allows multiple digits for1 q% C; r9 a4 x/ _
  both the major and the minor version.
5 M* u0 n) X& O5 `+ W& L# k7 x
2 |% S$ W0 C. w  This option should never be enabled by default as it hides application bugs! t  i( G( Y  p+ o! M+ y
  and open security breaches. It should only be deployed after a problem has9 Y0 X/ a* H" p! d$ A* S) L+ r
  been confirmed." ^3 {+ C4 L9 I0 L2 o
5 W5 `* O8 B: F  q
  When this option is enabled, erroneous header names will still be accepted in/ b+ }' [" o: t2 ?
  requests, but the complete request will be captured in order to permit later  l! k. J2 f3 \8 s
  analysis using the "show errors" request on the UNIX stats socket. Doing this
5 E, i! U" j- ^: b, ?  also helps confirming that the issue has been solved.1 }& i2 C2 Y3 T9 t* t  F9 Y

# x, w, L  B: V* E2 U  If this option has been enabled in a "defaults" section, it can be disabled0 E' u' S  t  M7 L9 \- |
  in a specific instance by prepending the "no" keyword before it.
1 T( J- F; H9 [& i
6 J7 t+ z) \# `2 w, w5 G8 l- V  See also : "option accept-invalid-http-response" and "show errors" on the
9 k7 _$ ~% q* j: u" a8 ^5 ~             stats socket.: y7 q3 D! S9 Y( `( |( l
/ w# v+ [  [# E: y7 Z
& s5 w0 @) y2 b; G' `; J& ^* C. I
option accept-invalid-http-response
9 f% ^* ?$ p' G- Z, xno option accept-invalid-http-response
1 T5 a6 @5 [- y$ B$ c  Enable or disable relaxing of HTTP response parsing
, T. a" S2 Q: z/ s  May be used in sections :   defaults | frontend | listen | backend
7 i: u+ g. K9 M                                 yes   |     no   |   yes  |   yes
7 o7 x0 P- X7 V/ P4 z/ J0 {  Arguments : none
; \0 e/ X6 I7 ~3 ^! I2 q
* V8 C* f  Q/ R  By default, HAProxy complies with RFC7230 in terms of message parsing. This
% u" N- O* R/ U/ d( L  means that invalid characters in header names are not permitted and cause an
# N+ U; ^( E6 m  error to be returned to the client. This is the desired behaviour as such+ u, a$ ^$ K! q* Q! p( m
  forbidden characters are essentially used to build attacks exploiting server2 T9 m  i+ q' t9 X) \8 g# I
  weaknesses, and bypass security filtering. Sometimes, a buggy browser or
' \3 Q7 l6 J. t6 A6 P1 P  server will emit invalid header names for whatever reason (configuration,& S3 z7 D% o" R  W- g
  implementation) and the issue will not be immediately fixed. In such a case,: O# L8 G4 O7 y
  it is possible to relax HAProxy's header name parser to accept any character
* n9 `' t' {. ?1 T) {# p  I: g  even if that does not make sense, by specifying this option. This option also& J1 U0 I! a1 _, @3 R
  relaxes the test on the HTTP version format, it allows multiple digits for
8 b$ I; Y4 G5 h, y  both the major and the minor version.
1 F# J! h8 M, ^& }+ Y! h3 L+ Q# g' [# {" x
  This option should never be enabled by default as it hides application bugs; h& t/ s! r6 H6 I/ m8 k% N
  and open security breaches. It should only be deployed after a problem has
, G0 c, F+ g" B1 F# A  X5 r5 _5 L  C  been confirmed.! d) I' v( j! n6 T+ Y( p0 n8 s

3 \# t* ~; _9 W$ X3 V4 m9 h- W5 l  When this option is enabled, erroneous header names will still be accepted in; q6 I0 R: \. j( ~$ U; @& F
  responses, but the complete response will be captured in order to permit
; F- s8 P: K6 z- H9 u% z$ {  later analysis using the "show errors" request on the UNIX stats socket.% w& J+ ^0 q0 k) h
  Doing this also helps confirming that the issue has been solved.
6 v5 O  e/ Y5 L9 Q$ r* s7 `: i- e& I7 _2 J1 o
  If this option has been enabled in a "defaults" section, it can be disabled
* \! w/ z( x$ g6 b& H  in a specific instance by prepending the "no" keyword before it.
5 U. g, u8 q( {7 {) I) k
0 o% `0 n, |$ d) g- I: E" b. R; W- K  See also : "option accept-invalid-http-request" and "show errors" on the6 e* p( Y) Q8 k- `
             stats socket.+ [8 L+ r+ m( V% ~; W9 {
4 ^$ S' I  Q) l7 n# Y
- ]9 G6 j" Y- O. g- Y$ {1 x$ a
option allbackups4 N5 v3 }0 z% Z1 X* L" ]- i/ e
no option allbackups0 I9 ~1 k6 m, v5 O0 s" w
  Use either all backup servers at a time or only the first one
7 |: w$ k* g7 W- I1 v! _* l  May be used in sections :   defaults | frontend | listen | backend' i  W6 y* J3 k- B8 X- r
                                 yes   |     no   |   yes  |   yes
, U( e) x- T( t  O, j! _5 d  Arguments : none
' W3 K+ C- p  Q  v8 z2 N" h$ F6 W0 Q  Z
  By default, the first operational backup server gets all traffic when normal" d9 h+ z2 Q- {4 z- {* I1 U" e1 |
  servers are all down. Sometimes, it may be preferred to use multiple backups- |. ~) _0 Z5 I: s% }
  at once, because one will not be enough. When "option allbackups" is enabled,2 Y/ _/ e- Q' P* K7 Y- n/ o
  the load balancing will be performed among all backup servers when all normal
2 T% u. ]+ T3 u: z4 m. z  ones are unavailable. The same load balancing algorithm will be used and the; m% C2 J6 Q9 B! I4 b
  servers' weights will be respected. Thus, there will not be any priority5 {( E/ I: j2 P6 I
  order between the backup servers anymore.% Y  X( f& B! W9 s$ N( b
! _5 D0 k' Y( ]
  This option is mostly used with static server farms dedicated to return a  `+ H8 }7 g$ c+ l
  "sorry" page when an application is completely offline.
" }" r* v! B! r/ w! Y3 m# T# M$ d* l( j' k+ t2 o5 r
  If this option has been enabled in a "defaults" section, it can be disabled# ~! n; a1 f! n3 w' q
  in a specific instance by prepending the "no" keyword before it.
5 z7 x- {% {! l, m: O- S# \6 b1 F  N1 ^/ \! H- K- P9 f0 ]9 Y& w) x; s
" V$ X: r- M$ m" @+ x! m
option checkcache
! S% j9 |6 E8 I0 rno option checkcache# k! S0 U; L9 ~' ^+ `  ~5 \
  Analyze all server responses and block requests with cacheable cookies
! W0 U+ T6 j8 ^  B1 h  May be used in sections :   defaults | frontend | listen | backend2 s! P. j+ g( |" D1 B6 H
                                 yes   |     no   |   yes  |   yes- b3 G2 Z: m. }# r# F1 b! s
  Arguments : none6 ?' F- ]; I5 D2 g

- m- ^: ~) m' v1 f( \$ }  Some high-level frameworks set application cookies everywhere and do not
# e/ G; b: B& c5 ^( q8 u3 T  always let enough control to the developer to manage how the responses should, I+ K: s# b' I/ n7 T
  be cached. When a session cookie is returned on a cacheable object, there is a" M  h% k' r0 t0 X' V% ^; C
  high risk of session crossing or stealing between users traversing the same2 n5 R1 C0 N% l5 g
  caches. In some situations, it is better to block the response than to let6 i9 x) D5 M' |% D$ L0 c
  some sensitive session information go in the wild.4 N  l7 Q* L) i/ n  B6 B9 b+ F
# p9 a2 q8 P; u5 h5 a  W
  The option "checkcache" enables deep inspection of all server responses for9 y# I' e% C# U* d! _+ m0 Z" c+ Y
  strict compliance with HTTP specification in terms of cacheability. It, D/ e6 P% ?% z, u: M# R
  carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server
  P5 s* e4 Z( N1 n  response to check if there's a risk of caching a cookie on a client-side
  _7 M1 p6 K' _8 q, T  proxy. When this option is enabled, the only responses which can be delivered
. z& v! y0 `# D, |6 a  to the client are :
0 U$ U) c- y9 B- s1 S# a    - all those without "Set-Cookie" header ;
" f6 `% a( G1 w; q3 O    - all those with a return code other than 200, 203, 206, 300, 301, 410,# B% ]8 B, q7 }- P% f" N) b7 u
      provided that the server has not set a "Cache-control: public" header ;8 ]2 N" \; s  s2 ?  _: _3 j
    - all those that come from a POST request, provided that the server has not
5 h" \0 \1 u& @) T: f1 x, c) [. X      set a 'Cache-Control: public' header ;% T4 C  B  j2 Y' B
    - those with a 'Pragma: no-cache' header/ w0 d# y- r( c, r! D
    - those with a 'Cache-control: private' header9 y) M, o$ e/ y1 q( L
    - those with a 'Cache-control: no-store' header
6 Y, t3 e! R8 x. E- B- }    - those with a 'Cache-control: max-age=0' header
# Q& l: }) ~' s9 }- o    - those with a 'Cache-control: s-maxage=0' header
6 c+ W' x. E9 E6 t    - those with a 'Cache-control: no-cache' header
, a( u2 Z* y: Z4 R& _    - those with a 'Cache-control: no-cache="set-cookie"' header
* v: f/ A" O& v" [    - those with a 'Cache-control: no-cache="set-cookie,' header: y, F+ {$ U' l) h  Q6 L. n# F
      (allowing other fields after set-cookie)
0 D0 L& f( e/ L" v) z
; Y9 P  B8 C7 C& {4 W* |  If a response doesn't respect these requirements, then it will be blocked
. t2 f7 Y, z, `5 Z- X  just as if it was from an "rspdeny" filter, with an "HTTP 502 bad gateway".
( k5 y% d3 e& @1 E' q5 Q' L  The session state shows "PH--" meaning that the proxy blocked the response# S9 H8 t: c2 g* ^& d
  during headers processing. Additionally, an alert will be sent in the logs so
8 _2 }- `8 J0 O) Z6 |- G" g  that admins are informed that there's something to be fixed.
5 z3 u% H, h% X% m1 Z% t. B( r$ G5 J& C9 _& U$ [
  Due to the high impact on the application, the application should be tested
0 m7 ]6 c+ n2 Q$ u8 n# A* g  in depth with the option enabled before going to production. It is also a$ T' e" r9 {! A8 Z! k" P% Z
  good practice to always activate it during tests, even if it is not used in
' I3 v. ^, B6 R9 e# r7 `  production, as it will report potentially dangerous application behaviours.% D0 C" d- I/ j

1 S+ ?4 ?" I( V  If this option has been enabled in a "defaults" section, it can be disabled* I, G& R+ T! }" }( K4 I1 o
  in a specific instance by prepending the "no" keyword before it.* N5 l8 e, n) K0 S% K. g0 A

/ }+ X! r1 U& _/ z9 K
& S" m6 D9 u+ [8 i6 ]option clitcpka
/ {3 a- I. F8 K: ?; K  N( D6 wno option clitcpka
+ x6 k6 P( F0 O9 h( K! i( C! a: I  Enable or disable the sending of TCP keepalive packets on the client side! f: r$ ~* f; C, n/ |! P
  May be used in sections :   defaults | frontend | listen | backend
+ I' W: A) T( V                                 yes   |    yes   |   yes  |   no
6 o( G% q8 E' n# M% L! T  Arguments : none+ Q9 v% e, ^- D4 j

9 m, s& B" Z! \1 p7 k  When there is a firewall or any session-aware component between a client and+ E8 p6 W1 Z% w7 F9 o$ R  z
  a server, and when the protocol involves very long sessions with long idle
/ i' A9 e8 Z. f0 v: u, I8 W" K  periods (eg: remote desktops), there is a risk that one of the intermediate
. c3 t% U; y) Q: D  components decides to expire a session which has remained idle for too long.+ ^$ }  Y5 q/ I4 p6 I

; A* c$ K7 J. S5 g0 m  Enabling socket-level TCP keep-alives makes the system regularly send packets
0 w$ e$ w2 ?8 L7 n' y, X; Z  to the other end of the connection, leaving it active. The delay between& B* x3 k3 Y/ A
  keep-alive probes is controlled by the system only and depends both on the2 P) g# n$ P" w* b, z) c1 v% ]
  operating system and its tuning parameters.1 Q! \" P5 @4 {; b4 t' H# T

- B, |1 U- x9 q! c, c" m& @1 l; i  It is important to understand that keep-alive packets are neither emitted nor
9 y7 y4 k/ {9 Z/ |, ^6 o0 v( B1 m& B  received at the application level. It is only the network stacks which sees
* Q5 T5 N" w% C" C" h& W3 }! g; j  them. For this reason, even if one side of the proxy already uses keep-alives; {; u' k5 Z9 t7 I/ m4 s: c3 \
  to maintain its connection alive, those keep-alive packets will not be- c/ U" I1 v( Y7 X
  forwarded to the other side of the proxy.
/ T% i* [# m2 G% }7 K; t: h+ t+ J; t
  Please note that this has nothing to do with HTTP keep-alive.) u- T" K* b8 H% L+ [* S
0 ^' t% A/ }- ?- H: X
  Using option "clitcpka" enables the emission of TCP keep-alive probes on the
) A7 T( t4 Q; c5 a0 I! v! g( N  client side of a connection, which should help when session expirations are
1 A$ s& g$ T0 o- G9 B  D4 }& r  noticed between HAProxy and a client.. y( j  o" n  T( [3 T2 R$ I" w
. H) i1 u- }( e- r( {
  If this option has been enabled in a "defaults" section, it can be disabled' D& v) P8 L$ G+ z  W- j
  in a specific instance by prepending the "no" keyword before it.1 I% n( b, J& g2 p; U5 @" T6 M+ |% {

3 K% b2 f. a) b1 q" F/ s: _# _+ e2 v  See also : "option srvtcpka", "option tcpka"  I& l/ s! L' m+ K) U
) }& H; I+ l$ q7 ~/ L

  m0 X/ E5 k* z1 U8 Soption contstats0 c% G* b% `3 L7 K1 r6 j! X& \9 C
  Enable continuous traffic statistics updates! L' {" n* Z8 P1 |6 g
  May be used in sections :   defaults | frontend | listen | backend1 q! O! D1 N6 ]9 X$ ?
                                 yes   |    yes   |   yes  |   no- E$ m2 y) p; v; i" _
  Arguments : none
" s4 F2 O9 X5 u/ C) ^) p, D4 n8 M) l. N; W/ K
  By default, counters used for statistics calculation are incremented
; s( @9 Z- I" |3 X+ Y  only when a session finishes. It works quite well when serving small
5 A  h1 w( x* ]* l0 l  objects, but with big ones (for example large images or archives) or
3 d7 v  a- J! B. s; Z  with A/V streaming, a graph generated from haproxy counters looks like* o5 E- l$ l. k
  a hedgehog. With this option enabled counters get incremented continuously,, K5 G! F4 t, b
  during a whole session. Recounting touches a hotpath directly so
" |: O* b* J+ s' v  it is not enabled by default, as it has small performance impact (~0.5%).) P) b6 W- U/ V9 z1 \4 }. A; k
) R/ u2 K" h+ x# q8 s9 L

4 S4 t1 x% F6 K$ ]  A; Uoption dontlog-normal
# G! c2 e, b; T- k) a) nno option dontlog-normal
+ d  @& j/ H$ G  Enable or disable logging of normal, successful connections
( V# e  C7 q1 G2 b1 T: o9 Q  May be used in sections :   defaults | frontend | listen | backend# r0 g, R  W% J- v/ L, G2 ?* [+ d) F
                                 yes   |    yes   |   yes  |   no/ _; }  j9 _# q, D: m0 d4 d1 w
  Arguments : none1 \& R8 l$ L5 R2 n" f

0 R; }* r3 R  K+ `+ ?  There are large sites dealing with several thousand connections per second) j0 \! U- D8 v# h2 d
  and for which logging is a major pain. Some of them are even forced to turn
# b. T, K( I. N  logs off and cannot debug production issues. Setting this option ensures that: G; p/ o' ~& |% ^/ F
  normal connections, those which experience no error, no timeout, no retry nor
) W( \+ A* }3 w( J  redispatch, will not be logged. This leaves disk space for anomalies. In HTTP$ X3 m  b2 l2 H& P  O# {
  mode, the response status code is checked and return codes 5xx will still be% H; C+ Q1 F& R3 r6 t7 S+ b
  logged.' V& s: n  G" ~1 D: R& J3 E" u
- B) b/ w: z: w2 q2 |# c- V
  It is strongly discouraged to use this option as most of the time, the key to
( W$ U: J, e4 A. \' f  complex issues is in the normal logs which will not be logged here. If you
5 p+ `2 w9 T- H7 k% A' ]9 E  need to separate logs, see the "log-separate-errors" option instead., u2 X) f! |7 e
1 L- }; Y' C/ O3 R& i
  See also : "log", "dontlognull", "log-separate-errors" and section 8 about# Z( H& @* c4 N# \) r
             logging.
3 K* K1 y! l# q, \- M
% i3 T( r, P, A0 O" L* T  h
9 b5 ^+ H5 w" _% t/ doption dontlognull
: D  K8 T3 x& S6 R. Kno option dontlognull5 Z( T) \0 R% I0 S  |
  Enable or disable logging of null connections
4 x  Z: H1 ~- u/ A! [( {  May be used in sections :   defaults | frontend | listen | backend
% ^# H1 R2 H1 [/ E6 z                                 yes   |    yes   |   yes  |   no
: v# n3 s. V7 }  T& C! t  Arguments : none
, m( m4 Y; B% {' P# t7 f4 v* |5 u
) y) A& N  I' P" V  In certain environments, there are components which will regularly connect to
( l+ r6 ^" o0 K  q/ ?- j* C  various systems to ensure that they are still alive. It can be the case from0 p) p" N1 e, U. x9 D% x! c
  another load balancer as well as from monitoring systems. By default, even a, Z/ {  R7 k0 h4 ]7 S
  simple port probe or scan will produce a log. If those connections pollute
; `+ A! a; [; x  the logs too much, it is possible to enable option "dontlognull" to indicate
* _* I' P$ L, o1 t  that a connection on which no data has been transferred will not be logged,$ I+ z8 m  W4 T% X7 g1 L
  which typically corresponds to those probes.8 `) x0 ?1 u0 H

) b$ ?1 r2 O. Z) G: ~$ Y; Y  It is generally recommended not to use this option in uncontrolled( K( a" L/ H) [2 t
  environments (eg: internet), otherwise scans and other malicious activities
( L8 {; N3 i0 A" k0 o  would not be logged.
$ k0 M# {9 T/ M5 }9 [, q8 L) S% j" e9 _/ k  Y9 j+ S
  If this option has been enabled in a "defaults" section, it can be disabled; p, T: |7 q( [$ K# g$ d/ E
  in a specific instance by prepending the "no" keyword before it." ^) {" z; c9 B

  U1 w1 w* U% Q  See also : "log", "monitor-net", "monitor-uri" and section 8 about logging.
- b7 M  u5 J# G5 X  G
2 y7 `! B8 |+ i' H7 M; |
* K2 N" [; ?' e% koption forceclose
* H6 a- a5 Q: R1 E: B5 p9 r: ?, [) Jno option forceclose+ _  A; z; y9 G2 _( ]" P  W
  Enable or disable active connection closing after response is transferred.
0 l: f7 P& [+ F% w' _+ h6 c  May be used in sections :   defaults | frontend | listen | backend
, s; q) S# ]# t2 U1 ^; {                                 yes   |    yes   |   yes  |   yes
9 x& e% H( M/ p# M6 `, p+ O  Arguments : none' Y- w+ E% b0 @9 O

! h5 K9 k: C& G4 @! L1 F! G8 L. M  Some HTTP servers do not necessarily close the connections when they receive
, _4 f; [4 }+ O# K5 |, N, q  the "Connection: close" set by "option httpclose", and if the client does not( |$ {# J, t, R
  close either, then the connection remains open till the timeout expires. This
+ x) e6 N) a2 t+ ?/ O/ s  causes high number of simultaneous connections on the servers and shows high
2 T0 b: D2 ]3 n* n# U* X' o+ ]9 w  global session times in the logs." ]% Q: ?" N9 t

4 U/ }7 K$ q. v" g  J" Z& r. B  When this happens, it is possible to use "option forceclose". It will
  `8 {$ N6 b- D' n1 j5 @  actively close the outgoing server channel as soon as the server has finished
. d/ m) Y  N0 n$ t6 a  to respond. This option implicitly enables the "httpclose" option. Note that
3 o" c5 s6 p( Q( X0 d  this option also enables the parsing of the full request and response, which
6 {0 `" Y3 i* a! {9 Q5 E7 D- ~' Z  means we can close the connection to the server very quickly, releasing some2 \* r5 _# H9 z4 N
  resources earlier than with httpclose.  s" i, ~% W% q9 j9 V6 f
) q: }2 V8 D9 Y6 _8 K( K" t
  This option may also be combined with "option http-pretend-keepalive", which8 j% S1 i! ?, P) e8 M
  will disable sending of the "Connection: close" header, but will still cause. s- L- t  z( q6 H; {. A6 H
  the connection to be closed once the whole response is received.
9 S4 ~1 T3 t3 P( p) d& G
; O- D" ^9 |3 r$ U/ [+ p2 D7 U  If this option has been enabled in a "defaults" section, it can be disabled
" }; M8 n) r/ [  in a specific instance by prepending the "no" keyword before it.
2 H& k% ^/ K' T9 T7 b* U) d6 V/ L1 q( {7 h: c+ f7 ^
  See also : "option httpclose" and "option http-pretend-keepalive"
  p* _- Q% d% O: X1 G# P8 x) w* ^
" x& H( W1 t7 }3 U
$ f0 B* B5 K3 a: F, poption forwardfor [ except <network> ] [ header <name> ] [ if-none ]3 q5 A: o' F1 ^+ G. V
  Enable insertion of the X-Forwarded-For header to requests sent to servers+ j- N( I) w5 e4 F
  May be used in sections :   defaults | frontend | listen | backend8 r# ]6 J1 I! J# `  y$ S
                                 yes   |    yes   |   yes  |   yes
& V: D& i; K1 i' C! q) j6 y  Arguments :7 t8 {0 l6 |7 g% x5 d" ]6 n% n' L0 d$ b
    <network> is an optional argument used to disable this option for sources
+ ^) v, m) T. {+ |; a              matching <network>' z: P' ^$ F- w0 B/ l
    <name>    an optional argument to specify a different "X-Forwarded-For"
/ C1 l! I: \2 u) o5 B              header name.* p: D3 N" p6 c/ F

/ K- l; F. A4 |, e  Since HAProxy works in reverse-proxy mode, the servers see its IP address as
  c9 S: s1 m: y, ?& B- Q) ^# P  their client address. This is sometimes annoying when the client's IP address
2 {( ?8 W0 g' Q1 I1 R' s4 r+ g  is expected in server logs. To solve this problem, the well-known HTTP header7 T" p2 I6 ]% [" ^. b0 C
  "X-Forwarded-For" may be added by HAProxy to all requests sent to the server.4 O- |: m7 W" w3 K7 i; x! Q! G
  This header contains a value representing the client's IP address. Since this
# i4 |# h/ H9 w# r! r; Q2 m$ e  header is always appended at the end of the existing header list, the server. p4 c  Q( o1 E% k
  must be configured to always use the last occurrence of this header only. See
# m; `; ?/ d" D  the server's manual to find how to enable use of this standard header. Note# p3 V. D, o( K: P" _" l
  that only the last occurrence of the header must be used, since it is really% T- ~" @- b. {# y0 b, l9 A
  possible that the client has already brought one.
! u5 c1 C4 a9 J" j$ _
, [8 z# L! M& ]& q  The keyword "header" may be used to supply a different header name to replace" n6 w* n' E7 k3 C9 T1 u
  the default "X-Forwarded-For". This can be useful where you might already
; K" X/ X9 d4 P$ H( _  have a "X-Forwarded-For" header from a different application (eg: stunnel),
8 ~: Z$ L! \, C  y& j  and you need preserve it. Also if your backend server doesn't use the. P. V9 _$ R( ?( X  F" S' M- W0 d
  "X-Forwarded-For" header and requires different one (eg: Zeus Web Servers
+ z/ v4 b& z8 f  K$ z) N$ R4 N' I- D  require "X-Cluster-Client-IP").
) \" g8 V+ j- z- F- Y6 Z% @, N- Y, g, \4 S
  Sometimes, a same HAProxy instance may be shared between a direct client' S# S( Y. M0 |6 w+ i
  access and a reverse-proxy access (for instance when an SSL reverse-proxy is
& z5 I5 \& ^" o4 a- e  used to decrypt HTTPS traffic). It is possible to disable the addition of the+ ?: u+ V) \1 h
  header for a known source address or network by adding the "except" keyword
1 ~% F, b$ [/ I# ]3 L  followed by the network address. In this case, any source IP matching the9 Q7 {0 k* R/ O, X% K7 O9 Q
  network will not cause an addition of this header. Most common uses are with
- L2 \3 V; f" j/ c0 W  private networks or 127.0.0.1.
  C  e/ l9 i3 i7 r$ x( T! L% w# g9 m; Y% \5 F' ?9 [
  Alternatively, the keyword "if-none" states that the header will only be
, J1 P9 B; K% z/ O3 m  added if it is not present. This should only be used in perfectly trusted
6 _) G: {) K# E5 e/ ]  [0 Q  environment, as this might cause a security issue if headers reaching haproxy2 R' p! C7 J9 \) w: }
  are under the control of the end-user.- W% J; N: L3 D8 Y2 g( O

5 L3 ?; H/ a; G# Z- L/ y  This option may be specified either in the frontend or in the backend. If at$ l, a* f! X6 @& U; E/ ~
  least one of them uses it, the header will be added. Note that the backend's/ W1 V# N5 k0 a) }% l, j9 }  c
  setting of the header subargument takes precedence over the frontend's if8 G% \( F4 _- C' j. |, a1 K' u+ y
  both are defined. In the case of the "if-none" argument, if at least one of" O' _4 s5 {+ [* W
  the frontend or the backend does not specify it, it wants the addition to be7 f& h! w5 d3 @- t
  mandatory, so it wins.' A8 ]$ t& D  u& E) X# Z$ b  a; }
5 s& s2 c) G+ d3 @" o* Q
  It is important to note that by default, HAProxy works in tunnel mode and1 U8 R) x& a4 Z& b1 m4 |3 o! I
  only inspects the first request of a connection, meaning that only the first
0 @4 \! T4 n7 I$ y2 @) Z  request will have the header appended, which is certainly not what you want.: ]6 C. M5 M+ C; g9 ?- [- m% l. I
  In order to fix this, ensure that any of the "httpclose", "forceclose" or3 ~. f, @# V- z/ _, D
  "http-server-close" options is set when using this option.
! R  a. M) }" I' A+ G1 u5 K. l$ x: J' ]$ Z' D+ R
  Examples :
4 x- u; R! k/ ^* W1 y6 x5 t    # Public HTTP address also used by stunnel on the same machine
7 l7 C9 j' N( G) e8 f% M- E; E    frontend www1 H; K$ q8 i4 F
        mode http
3 e7 L3 ~% r4 a1 K. I0 u6 P; f        option forwardfor except 127.0.0.1  # stunnel already adds the header' d+ _3 P$ G7 [- p: k/ p+ S$ J" f

% s  M( }0 ?  r1 @5 s, m7 Y    # Those servers want the IP Address in X-Client8 v! K2 b$ M7 S; |
    backend www
! D& X7 `$ i6 O5 ~/ u        mode http
+ D1 i: [- m+ y" N        option forwardfor header X-Client! \: q8 {6 A6 E, o* m6 q- T
0 C2 v1 L# }3 m- d! a$ N, {
  See also : "option httpclose", "option http-server-close",) z4 Y9 E# @& H6 t% Q" m
             "option forceclose"2 ]/ g5 w: [. W7 |
5 n; B' v3 c" ?; z# R. x
6 ]% f$ t5 B7 _/ \
option http-no-delay
1 N5 {5 h8 e* P+ w0 ?. Xno option http-no-delay
3 [) [3 j$ ~. b. W4 K  Instruct the system to favor low interactive delays over performance in HTTP
% y9 g& e, v5 P# C  May be used in sections :   defaults | frontend | listen | backend4 T7 @+ _6 m, P( O, S" |3 M
                                 yes   |    yes   |   yes  |   yes9 @7 h4 O6 f4 x, W
  Arguments : none
2 t% g0 w! r4 U! p1 K9 E0 s* Q: ]2 @5 u6 f% r) a
  In HTTP, each payload is unidirectional and has no notion of interactivity.+ z# C7 o) e5 f& i! Y
  Any agent is expected to queue data somewhat for a reasonably low delay.7 h; R& ?3 M, P1 q  Q& h( @
  There are some very rare server-to-server applications that abuse the HTTP4 N2 [# b3 N# s8 ?
  protocol and expect the payload phase to be highly interactive, with many0 Z5 ]/ o( K4 u/ v* u
  interleaved data chunks in both directions within a single request. This is5 q6 G6 `: d6 G) n) e, E
  absolutely not supported by the HTTP specification and will not work across
! o$ @4 b3 [8 M; k) O  most proxies or servers. When such applications attempt to do this through
( i9 m0 I& w- ]  o1 j# U1 C  haproxy, it works but they will experience high delays due to the network/ ]2 }0 r( J0 T) h" Z0 e4 l
  optimizations which favor performance by instructing the system to wait for; w$ I- J8 N6 I
  enough data to be available in order to only send full packets. Typical+ Y3 f0 m% T5 k
  delays are around 200 ms per round trip. Note that this only happens with' I& V8 [  X. N8 d7 ?1 Y) Y- U. H5 u
  abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
' d! h' V" b/ s9 Q8 G. u, H  affected.' ]& f+ r) \& Z& w0 z

2 ]; x" T# O# B' d7 \  U  When "option http-no-delay" is present in either the frontend or the backend
6 V  w7 I( g* E: i, @0 C' `  used by a connection, all such optimizations will be disabled in order to
/ Z' t1 v7 A  j" `+ Y* E* Q  make the exchanges as fast as possible. Of course this offers no guarantee on/ k& ]7 `0 B6 F9 T: O; Q+ ^+ @& ]
  the functionality, as it may break at any other place. But if it works via
0 a/ k5 r$ f1 |) E" Z* A# p  HAProxy, it will work as fast as possible. This option should never be used# L0 B# p4 y* k9 l8 b
  by default, and should never be used at all unless such a buggy application
5 J, b, s; \* P  is discovered. The impact of using this option is an increase of bandwidth7 R5 s# N6 b. s2 |; }
  usage and CPU usage, which may significantly lower performance in high; `2 ^7 N( D. V" J
  latency environments.( k, [* \1 }9 q9 F. k  d) d: u
; I+ R) N8 P3 F: q4 V: R

# ^& u- R8 H3 U- S$ zoption http-pretend-keepalive. @3 x! D  L2 x
no option http-pretend-keepalive+ {: I) t4 `- }; d& w
  Define whether haproxy will announce keepalive to the server or not
+ Y: P; C4 H/ I  May be used in sections :   defaults | frontend | listen | backend* k$ q) y5 X8 K8 A7 S0 e
                                 yes   |    yes   |   yes  |   yes
8 I2 @  m. N! v' L# q  Arguments : none
3 l) O/ t3 ~/ N* f- i" W4 W1 y. t' }" O+ u
  When running with "option http-server-close" or "option forceclose", haproxy" k% M8 q5 i  r2 z- h
  adds a "Connection: close" header to the request forwarded to the server.# j! Q- C0 f; i8 n. o
  Unfortunately, when some servers see this header, they automatically refrain. y: z0 z! `  s( X. j4 {$ w
  from using the chunked encoding for responses of unknown length, while this
# ~% K! R0 {* W0 @3 E* H0 W2 K4 W  is totally unrelated. The immediate effect is that this prevents haproxy from4 z+ D$ v5 ]( }3 H/ Y
  maintaining the client connection alive. A second effect is that a client or5 W# E$ R8 K, A4 b: Q! @8 w9 `1 Z# }
  a cache could receive an incomplete response without being aware of it, and. U& [  T9 ?. N, H  A; ?
  consider the response complete.
0 b8 @: T9 H2 z2 l& W/ R! \
4 E! c8 _' I: S2 x" n  By setting "option http-pretend-keepalive", haproxy will make the server4 d8 P' S6 l4 b2 M1 ^
  believe it will keep the connection alive. The server will then not fall back& D$ E+ Z( R/ O9 V
  to the abnormal undesired above. When haproxy gets the whole response, it6 j" {, m0 w, Q: {( w/ L
  will close the connection with the server just as it would do with the
$ a" z6 c9 Z9 v  "forceclose" option. That way the client gets a normal response and the
0 z' s+ s" a) c0 j# A  connection is correctly closed on the server side.. o) O0 P/ ~8 Y4 r: c

. [* q' _6 k- Q  It is recommended not to enable this option by default, because most servers, h5 H' n/ z6 c, P2 Y
  will more efficiently close the connection themselves after the last packet,. a% P, t  m  ~8 v2 f3 }
  and release its buffers slightly earlier. Also, the added packet on the
$ y9 `7 ~' l  N  network could slightly reduce the overall peak performance. However it is
( R# r# |+ ]8 ?, M8 D2 i  worth noting that when this option is enabled, haproxy will have slightly
& b: Z3 F$ a9 F. j$ T9 I  less work to do. So if haproxy is the bottleneck on the whole architecture,% b% `8 U" }$ W; \- A0 H
  enabling this option might save a few CPU cycles.' e. `4 C8 N3 v' v, m1 l2 J

  M; C% B3 F1 z9 V0 Q7 |  This option may be set both in a frontend and in a backend. It is enabled if( Q- g& t5 v) H; D2 k0 C# n$ ~
  at least one of the frontend or backend holding a connection has it enabled.9 l6 L2 S& V% O: J
  This option may be compbined with "option httpclose", which will cause
; a+ e# z0 D% q) J/ ~! J: T  keepalive to be announced to the server and close to be announced to the
: `: \8 h) o8 ?$ z+ b  client. This practice is discouraged though.
# b$ W$ d1 \, C2 C' \8 x! H: c- y6 D+ |; L1 j
  If this option has been enabled in a "defaults" section, it can be disabled
) H8 R' e) I2 S; ~( w+ {3 e  in a specific instance by prepending the "no" keyword before it.
. o# g+ ~" M8 z8 O% M" ^0 L# X8 U$ y/ w$ y$ e/ o/ A# z
  See also : "option forceclose" and "option http-server-close"9 m0 m, G! M6 ^' x; Q1 T
# r* q6 U; G$ q) A# ]8 Y

( B) S4 J; n1 c1 joption http-server-close3 Z! B2 B$ {3 k6 q" Q# J
no option http-server-close
* u' p  c. o4 @0 G+ I- f( P* M  Enable or disable HTTP connection closing on the server side
" B/ A4 h- D0 h* a  May be used in sections :   defaults | frontend | listen | backend
3 m5 |' L9 P  y9 {& a) G3 _: f3 V                                 yes   |    yes   |   yes  |   yes
7 z4 F* }  Q- l, J6 Z7 [+ @' V6 A  Arguments : none0 i, H4 `" ]/ J

( D  f. {# f7 c4 t  By default, when a client communicates with a server, HAProxy will only* v( I, S$ s5 T% B* U
  analyze, log, and process the first request of each connection. Setting
2 K  N3 ~0 O" U  "option http-server-close" enables HTTP connection-close mode on the server4 r% M4 ~0 q2 w3 z8 H
  side while keeping the ability to support HTTP keep-alive and pipelining on. ]- a+ Z; c. C1 u- |! u4 @! V) M
  the client side.  This provides the lowest latency on the client side (slow' r0 @" U/ Z; t% ?7 G* y
  network) and the fastest session reuse on the server side to save server
' t6 z# S4 s7 q4 i& `  resources, similarly to "option forceclose". It also permits non-keepalive8 q6 ~- A' E/ w
  capable servers to be served in keep-alive mode to the clients if they
) Y7 z; b# U# k) z7 y  conform to the requirements of RFC2616. Please note that some servers do not
4 e3 ]5 v+ L% \$ B4 m5 {0 x, z  always conform to those requirements when they see "Connection: close" in the
6 g5 E; m% o" N/ c- n  request. The effect will be that keep-alive will never be used. A workaround
1 ]5 \* H' ^( U0 D. g' {  consists in enabling "option http-pretend-keepalive".
8 P* U, F  h6 E. z' a( [) l5 t* a
( q5 Q( u/ l( ]1 s4 C6 j  At the moment, logs will not indicate whether requests came from the same5 D, a  a/ ^: e
  session or not. The accept date reported in the logs corresponds to the end
7 ~  t# {# z9 L% O& Z  of the previous request, and the request time corresponds to the time spent+ V9 n. _1 J7 b: w; {- D% m
  waiting for a new request. The keep-alive request time is still bound to the
* G: v# H! L9 O) f8 }$ c4 D% s" D  timeout defined by "timeout http-keep-alive" or "timeout http-request" if: A7 p3 B5 w' q0 B
  not set.3 t5 E. C$ d* H- H" P

( m* c1 o& w" F% C  This option may be set both in a frontend and in a backend. It is enabled if
) v: c! D1 w* k  at least one of the frontend or backend holding a connection has it enabled.5 J# V! w# W5 S; J" d5 {
  It is worth noting that "option forceclose" has precedence over "option
+ p5 q7 _$ v! j: x$ y  http-server-close" and that combining "http-server-close" with "httpclose"
: K% j  R% Y% z" H2 L4 \' V  basically achieve the same result as "forceclose".4 c: Z1 ^5 n  J. O7 {
$ b: {9 \2 @# c# B$ O- P& i
  If this option has been enabled in a "defaults" section, it can be disabled
9 P- m2 v5 R9 m1 t& ?/ x  in a specific instance by prepending the "no" keyword before it.
! C7 X" n& e2 [8 a, q& c* e
. _; O9 j* }9 u/ K  See also : "option forceclose", "option http-pretend-keepalive",$ s0 w& N1 A6 X' B: r
             "option httpclose" and "1.1. The HTTP transaction model".
8 ]5 ^! I: T. p5 G# Y% F$ v( E( i) l7 Y* i' g0 \
6 C$ l/ L1 n) |5 {' y
option http-use-proxy-header5 a0 T3 E. r; d
no option http-use-proxy-header) X$ W: r& Y0 j; K3 n" Z3 D( e
  Make use of non-standard Proxy-Connection header instead of Connection
* a, N1 @8 o' s" c/ V  May be used in sections :   defaults | frontend | listen | backend7 Q. B1 J1 I; f: B' \7 w3 A) P
                                 yes   |    yes   |   yes  |   no% R" \' s+ Q0 G& R7 w
  Arguments : none
4 ^2 Q; x% Y2 v9 b% j
  |+ i4 o; B% ]& w  While RFC2616 explicitly states that HTTP/1.1 agents must use the5 O: H4 J" L- y. D2 }
  Connection header to indicate their wish of persistent or non-persistent
: {. i/ I; y& F# B( {  connections, both browsers and proxies ignore this header for proxied3 b' s$ f; k& A! t8 g, o3 b
  connections and make use of the undocumented, non-standard Proxy-Connection
. I+ p: A* Q9 x% d* g1 M7 s" R  header instead. The issue begins when trying to put a load balancer between4 P) y% G( H& I1 D) B. z% g) L. D
  browsers and such proxies, because there will be a difference between what/ c/ Z6 ]3 v/ ?
  haproxy understands and what the client and the proxy agree on.9 ?+ K0 r% ~5 P" ?
9 r, e1 @" Y; z  M7 s1 t7 Q
  By setting this option in a frontend, haproxy can automatically switch to use7 M/ W; ]- B8 \" f8 e- b. C' v
  that non-standard header if it sees proxied requests. A proxied request is
6 b! d7 U5 |1 g) E- H# T2 C0 ?+ f3 E  defined here as one where the URI begins with neither a '/' nor a '*'. The1 \( S" \1 g1 N% T* C
  choice of header only affects requests passing through proxies making use of
( J& G- Q; ^! t" N  one of the "httpclose", "forceclose" and "http-server-close" options. Note
  X; \, V; ^' R; ]# B8 n4 A& ?  that this option can only be specified in a frontend and will affect the, V4 J, g3 ~& ]
  request along its whole life.- j- A% J! h: p$ a6 Q8 C2 m  ]

0 A, f; Q, I$ H% I$ l  M  Also, when this option is set, a request which requires authentication will8 n& q3 D; c$ {
  automatically switch to use proxy authentication headers if it is itself a/ A  ]6 v4 Q8 r- c* V+ v! @
  proxied request. That makes it possible to check or enforce authentication in
" ?3 l. t- i2 I( w3 x1 ?  front of an existing proxy.4 T! D% v4 b3 [  |3 F- @" |' O
4 j7 d+ y& O  J
  This option should normally never be used, except in front of a proxy.5 q# d9 m- x8 Z  M5 Q
2 l4 b" m1 i- c1 j) w2 c* L
  See also : "option httpclose", "option forceclose" and "option- ]+ f  z9 d, Z6 i' ^
             http-server-close".
* l* [$ q6 m: ^! y* p  @& Y- x8 Q9 j& C# H' ^, d$ v  W
5 |; N1 U# ~" k
option httpchk8 i. n; d7 c6 T7 _4 F8 C
option httpchk <uri>/ R, W4 c" X: S2 Y) i+ ?: S* v7 Y
option httpchk <method> <uri>
6 H' }+ j' a( ~9 u1 Qoption httpchk <method> <uri> <version>$ i5 W: S' O. n. J
  Enable HTTP protocol to check on the servers health
' G8 b; e* L+ B. t/ |  May be used in sections :   defaults | frontend | listen | backend2 P: k. E& q/ M4 N; y
                                 yes   |    no    |   yes  |   yes
; L/ t  K7 m' r0 U0 U  Arguments :! Q3 V' [% Y5 Q8 ?  g% H% P  z
    <method>  is the optional HTTP method used with the requests. When not set,
, _/ }: A& \; Z# w4 n              the "OPTIONS" method is used, as it generally requires low server
2 s- q, Y$ ?2 n' |3 m" k- J' p              processing and is easy to filter out from the logs. Any method
) X0 ]* }& m6 a! a, i: N6 T0 _8 I              may be used, though it is not recommended to invent non-standard1 H7 P8 u& M2 F6 h7 x
              ones.
' X1 X' f: }8 p6 [# r" ^  h/ ]' N
4 ~8 a, z( J3 j0 g! U  ~4 n    <uri>     is the URI referenced in the HTTP requests. It defaults to " / ": D! V. n% m% f  E
              which is accessible by default on almost any server, but may be! e) Z' n+ ~6 C# a& j+ W
              changed to any other URI. Query strings are permitted.
/ d- |% _+ \: T- r: |$ V: F0 T; a; n* y) [, V9 w+ j
    <version> is the optional HTTP version string. It defaults to "HTTP/1.0"' z" g2 O  ~7 `+ i
              but some servers might behave incorrectly in HTTP 1.0, so turning
$ g4 U1 Y9 V: q" L+ K; s              it to HTTP/1.1 may sometimes help. Note that the Host field is
% P5 O2 _0 h7 y              mandatory in HTTP/1.1, and as a trick, it is possible to pass it. b8 R. u2 A& a6 y
              after "\r\n" following the version string.
$ P0 T/ C( Y2 [4 N! [; a0 n/ Y0 R5 }$ ]1 D
  By default, server health checks only consist in trying to establish a TCP
, q) Y0 v. |$ z$ T  connection. When "option httpchk" is specified, a complete HTTP request is" y6 g* L* g3 u2 {8 X% z
  sent once the TCP connection is established, and responses 2xx and 3xx are. \! }, |3 r! E; K6 d5 y7 t7 N+ l; Z
  considered valid, while all other ones indicate a server failure, including
3 V- |8 N- P/ s0 P8 u& }8 Q& z$ W  the lack of any response.
( e) R. ?! f! k% }; A! U* X! [) i- t% J* {* \3 U: X' w
  The port and interval are specified in the server configuration.  R5 p' f( @" O" F0 n# E) f4 }

" r& o4 y& u# P# J  This option does not necessarily require an HTTP backend, it also works with
6 E! l1 M2 q2 z# O  plain TCP backends. This is particularly useful to check simple scripts bound' X. A( f! n' H& A. I+ J
  to some dedicated ports using the inetd daemon.
5 i3 T& k$ M: I. E# ]0 y) N7 t) D$ w0 Q& g. l
  Examples :
1 A. W% l0 x# Y! s      # Relay HTTPS traffic to Apache instance and check service availability% |) K* Z. _5 V8 s  _+ ^. ~+ E% d
      # using HTTP request "OPTIONS * HTTP/1.1" on port 80.
- J2 E$ N) p, W# G& f, ?+ o3 T2 \! A3 x      backend https_relay7 T+ h) N$ ]$ W" m0 W: P8 s
          mode tcp
+ Q% a; O; {: F3 D          option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www& t- o; O8 r8 Y' B1 Z
          server apache1 192.168.1.1:443 check port 80' t, b0 ]( M* I8 C* @6 L" `
% L' s! l- c0 J, E. B; ^
  See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
$ I2 D& m/ A$ m& \             "http-check" and the "check", "port" and "inter" server options.
+ P  @- k, Z- p9 a* O7 {+ W. k' L7 `& x- J. G" @# n
, a7 ?" {0 P+ I3 X' S
option httpclose* m9 C: f' T/ T& H" u
no option httpclose; n7 J8 K3 R3 v! Y4 b- t% N* y/ q4 q
  Enable or disable passive HTTP connection closing
5 Q' d( H6 `; T# y  May be used in sections :   defaults | frontend | listen | backend2 `- @$ D* y/ S  J5 }2 k- ~
                                 yes   |    yes   |   yes  |   yes5 a2 V( F4 N; v  Q' m& K
  Arguments : none
; Q8 h" d# ]! i% ?* ]% y5 y
1 N/ O% h% d9 o$ {' N! b; a  By default, when a client communicates with a server, HAProxy will only
: f# X5 b, W6 |! `  analyze, log, and process the first request of each connection. If "option
9 C1 Q% g+ n5 p- _  httpclose" is set, it will check if a "Connection: close" header is already7 G  A% ~7 R) j( W, j2 x/ a& n6 G
  set in each direction, and will add one if missing. Each end should react to
/ X& p8 h6 |4 f( C; J4 o2 C! s2 b  this by actively closing the TCP connection after each transfer, thus
8 _2 V$ j+ x1 B# |' k' B  resulting in a switch to the HTTP close mode. Any "Connection" header
; x* b: {  l7 D5 Q: F# p  different from "close" will also be removed.
4 S( k! i+ `0 H) R1 f- N5 i7 r
" U! U: _8 S* u3 J* Z9 q& C  It seldom happens that some servers incorrectly ignore this header and do not
7 B+ a6 [- B# l- C  close the connection eventhough they reply "Connection: close". For this
* Z, ?/ r. V1 d% f( G8 t) g5 }# ]  reason, they are not compatible with older HTTP 1.0 browsers. If this happens  B7 K. n% D- \" n
  it is possible to use the "option forceclose" which actively closes the
' H% P  Y1 \3 J7 {% i  request connection once the server responds. Option "forceclose" also
! y6 z$ N( N3 ^" i5 O  releases the server connection earlier because it does not have to wait for
: g1 U; O; f+ A/ I8 p/ t  the client to acknowledge it.
4 G* Y7 g& b1 P/ T& r) i: T
6 e$ D/ ]) g- c$ {2 \  This option may be set both in a frontend and in a backend. It is enabled if
* o7 }! k2 T7 C$ I5 E  at least one of the frontend or backend holding a connection has it enabled.
- K( A# w1 t% f  a% B. c6 v0 D  If "option forceclose" is specified too, it has precedence over "httpclose".
, I4 j1 U% I0 g" I0 v* R( q1 s$ K  If "option http-server-close" is enabled at the same time as "httpclose", it
. H1 c+ Z0 t& B  basically achieves the same result as "option forceclose".( q% }  S3 l4 G; K
' k  P+ q6 ]- Z6 x7 _% w/ X
  If this option has been enabled in a "defaults" section, it can be disabled
) m4 j2 U" r& z# P# y9 O  in a specific instance by prepending the "no" keyword before it.& K! w/ a7 [8 x0 Q- e4 b# E; _! y% K
4 Q( b/ R- o. o3 m& N1 T
  See also : "option forceclose", "option http-server-close" and
, I$ W; i- C! B9 s5 K6 y8 Z             "1.1. The HTTP transaction model"., ~; ~; [" B- m* H7 `& n

% B7 h8 ]% J9 Z+ }' u" C+ ]( o9 t" {/ ^+ P. F
option httplog [ clf ]* `0 k, s- L" o$ l: x  V. R0 C
  Enable logging of HTTP request, session state and timers
9 K) m4 X  C" W; `6 H2 i  May be used in sections :   defaults | frontend | listen | backend, Q( y) b8 C& n' }
                                 yes   |    yes   |   yes  |   yes
8 ]' K6 G  s; K/ D  Arguments :* d3 M: v9 P0 m7 a0 Q( z$ Z8 x1 U
    clf       if the "clf" argument is added, then the output format will be
" q( n& x. |( y  b+ H( }, B! A              the CLF format instead of HAProxy's default HTTP format. You can8 w+ l- n# u! O# e
              use this when you need to feed HAProxy's logs through a specific
& ]. L# b8 V- w7 M1 V3 ^+ ], o! D              log analyser which only support the CLF format and which is not. [$ w) J! Y( k! \
              extensible.  X) l. v0 ]3 g8 t( U- l; q
: G9 b7 l- u/ D5 u3 z6 t9 k
  By default, the log output format is very poor, as it only contains the
& o. i2 n# H; @" ~  source and destination addresses, and the instance name. By specifying
; Q) _6 D+ W6 {3 Z3 p% ~  "option httplog", each log line turns into a much richer format including,$ y  F- s5 V; \9 Y) v& B# s, ?# E" _1 X
  but not limited to, the HTTP request, the connection timers, the session2 I( M" r& d& i
  status, the connections numbers, the captured headers and cookies, the
5 m1 a4 n, Z# y5 s4 ~  frontend, backend and server name, and of course the source address and9 f0 w+ j4 b% O' {2 V0 F
  ports.
& @, ]9 o# J& y( a) ]$ |
4 W8 L! u4 ]& r# m- z0 w& f  This option may be set either in the frontend or the backend.
! t  B% x0 _: _0 }9 N
6 H: R9 ]0 ^: v$ L1 Q+ Q0 c: ?  Specifying only "option httplog" will automatically clear the 'clf' mode
! B" v* ^  k3 v" ]+ E3 j8 N  if it was set by default.# I6 K/ C, d9 m6 x

. s9 L- J4 }# e& X( b  See also :  section 8 about logging.
+ U5 @2 p7 ?" I' \$ ~  g  B; V# p0 i9 R$ }2 }! b, E% t
( r( w% R% k5 S+ ]
option http_proxy- |: H$ [* {7 I: j  C, i. W
no option http_proxy8 X4 f% f1 o/ p5 I$ [
  Enable or disable plain HTTP proxy mode
! r, z+ d6 j% @, W) V- s  May be used in sections :   defaults | frontend | listen | backend8 T, W" t( X" j7 q1 d' T
                                 yes   |    yes   |   yes  |   yes6 y: U4 u0 _) k" h: C
  Arguments : none
; v  o4 Q# o1 v6 q% r
- d2 N# X; v* J4 @! ?  It sometimes happens that people need a pure HTTP proxy which understands- Z) I% M- z+ L$ `1 n
  basic proxy requests without caching nor any fancy feature. In this case,0 h: m; T' [" c& o; C
  it may be worth setting up an HAProxy instance with the "option http_proxy", ^1 H' F5 W% {# |! d/ ]$ T7 T# H
  set. In this mode, no server is declared, and the connection is forwarded to3 c: S6 V( g5 K7 l+ y
  the IP address and port found in the URL after the "http://" scheme.; T; D4 y6 g% N) k9 R5 ?
# G; P, p7 ~# P
  No host address resolution is performed, so this only works when pure IP3 ?# h  D# V# K
  addresses are passed. Since this option's usage perimeter is rather limited,
6 P4 {( H) }- v, K1 |8 {  \  it will probably be used only by experts who know they need exactly it. Last,- h. R" i! v9 I1 C9 o2 y$ A6 A
  if the clients are susceptible of sending keep-alive requests, it will be
* @1 c5 J2 k3 k6 V% B  needed to add "option httpclose" to ensure that all requests will correctly0 g1 K* _  K& {  w4 n
  be analyzed.+ t! U/ f- o; }7 h8 f: F' N0 p

" J( @+ X1 l( v/ I: p. f3 {* o  If this option has been enabled in a "defaults" section, it can be disabled
  s1 U( B) E, N% S3 E" Z) W% c  in a specific instance by prepending the "no" keyword before it.
. C8 h  ]9 a0 g4 G) H' q( d+ I( n* K  ?! z
  Example :+ F; J0 h5 ^5 l& [% I+ A* i& q
    # this backend understands HTTP proxy requests and forwards them directly.
5 H; K% A: e3 [; s7 `! p    backend direct_forward
, g" u' R3 h  Z. Z: M, t% F3 M9 B        option httpclose
* z- U! u( i% q: r: N: D: Q7 m, O; E! O        option http_proxy
. o& y/ X9 g( N9 X! C9 u8 F2 O/ @  z1 L! J
  See also : "option httpclose"
: W2 {5 n5 [1 p5 x# D: r' s  E! w4 o/ |5 A: J9 O! }- R
, C8 |, r. J" D0 G- a
option independant-streams
& l7 B: n0 c" P4 U* Vno option independant-streams! P) T8 s  v; s& i$ e* w
  Enable or disable independant timeout processing for both directions
$ E% N, k6 F$ u- U5 g$ n  _/ w  May be used in sections :   defaults | frontend | listen | backend
1 Z5 N1 j7 O3 O  E$ H8 S2 `                                 yes   |    yes   |   yes  |  yes
) w. s. A  r# J, {  Arguments : none7 }# O/ V8 x2 J' h/ I% H2 o* T0 p

" w8 J& q$ S) I  By default, when data is sent over a socket, both the write timeout and the
& n4 y/ b$ v9 r$ a: ]. i  read timeout for that socket are refreshed, because we consider that there is
  L+ l( K1 }/ |0 Q1 s6 S  activity on that socket, and we have no other means of guessing if we should
, r* }' u6 i. Z% P- R* }8 ~  receive data or not.
3 Q4 ^2 E3 q) H
2 \& o3 L. n2 o" `, F, p  H! a  While this default behaviour is desirable for almost all applications, there3 ?. {0 ]- G  ^( l' N
  exists a situation where it is desirable to disable it, and only refresh the
8 U' A+ s" z" J! {5 ^& ?  read timeout if there are incoming data. This happens on sessions with large& f1 A+ x) D" k2 Y: e7 g0 h
  timeouts and low amounts of exchanged data such as telnet session. If the& ^* H( ]/ h$ E9 H1 y# I% m6 z
  server suddenly disappears, the output data accumulates in the system's# F. G; J4 q$ R! E- a- n" v
  socket buffers, both timeouts are correctly refreshed, and there is no way
0 V' B% C* w# l" U4 S9 S' w1 f/ U  to know the server does not receive them, so we don't timeout. However, when$ E! `- E( N/ K( M
  the underlying protocol always echoes sent data, it would be enough by itself# @* B9 k, k: U' c
  to detect the issue using the read timeout. Note that this problem does not
8 ]9 I) n% ^" W+ k& ]  happen with more verbose protocols because data won't accumulate long in the) y3 j- m& U: M
  socket buffers.
6 i1 D: S) e& D* }5 o3 Y
# O  F" z% c5 u! U  When this option is set on the frontend, it will disable read timeout updates+ T! J8 y% Y4 k9 y
  on data sent to the client. There probably is little use of this case. When6 V) j& T0 G" ]- Z5 }
  the option is set on the backend, it will disable read timeout updates on
2 W+ p8 ]1 I4 D$ v- r' _; U! p( |  data sent to the server. Doing so will typically break large HTTP posts from
6 N' r& ^9 r! h9 [1 K$ Y& r  slow lines, so use it with caution.0 h4 t8 q; a, p/ w9 I# a
, t( N3 F7 m4 z! }; k( i
  See also : "timeout client" and "timeout server"
$ X  r+ N, p+ }; h7 J) ^7 w
7 U/ Q* z, p  B0 M1 `' E2 o( f8 d
, C) a7 i1 O3 |$ i; W% u/ W8 R: poption ldap-check  p/ j* `* O) I/ F6 k
  Use LDAPv3 health checks for server testing/ r- t# V, E; a$ D3 A! P0 z: c
  May be used in sections :   defaults | frontend | listen | backend
- \* j+ H! C7 f2 ?) X' t                                 yes   |    no    |   yes  |   yes( i2 e4 k1 \2 `) J
  Arguments : none4 Q1 ]8 i, G7 W+ ~7 }' p5 n
+ e8 \/ ]# t/ y0 L/ ]: Z# E) N6 {
  It is possible to test that the server correctly talks LDAPv3 instead of just
: \. G# n$ Q" ^- B& y6 {, q$ C  testing that it accepts the TCP connection. When this option is set, an
% I5 S8 m3 ?+ }* W  LDAPv3 anonymous simple bind message is sent to the server, and the response
% m! E- D8 r* n/ |- P5 z  is analyzed to find an LDAPv3 bind response message.
& b$ h8 G* H5 V5 W& S" S/ H& _, ^% [2 c7 p
  The server is considered valid only when the LDAP response contains success  @/ E& I( `% }2 m4 Q& ^; P8 K
  resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).& o3 X0 X5 }( [9 E
: v$ X9 t# l; B$ b$ k' v, r9 L- M
  Logging of bind requests is server dependent see your documentation how to: M& o: f: n- V: s) t
  configure it.
  u3 \3 \) T/ m2 c) {  F9 q* Z' Q/ F; d+ H* n
  Example :
' D/ _! ~% t6 v, T4 i* C        option ldap-check' |) h5 y5 Z! w  l4 Q4 X2 D
' c8 K( M1 k8 k5 A; J
  See also : "option httpchk"
0 o" r- `  D. }5 i! {- B: v' |
% j5 c! M9 o( b. q- n, Z
option log-health-checks' U, Z$ p% D+ l! K8 X$ y- u
no option log-health-checks
4 s7 f, J3 F" [, A0 |, c/ S  Enable or disable logging of health checks9 l* {0 t+ [* B# R% a3 ^, P1 M: k7 J0 L
  May be used in sections :   defaults | frontend | listen | backend
$ O: ~. m4 C/ x6 N  E* @1 Z7 R                                 yes   |    no    |   yes  |  yes
! i/ E# q/ k( D9 D  Arguments : none
- i% `& G, D  e! p) Z
& c) q  }! B1 t  Enable health checks logging so it possible to check for example what: e! D0 e; Q8 P' o' n& Z# R! N0 x
  was happening before a server crash. Failed health check are logged if
0 E. ]4 a) A9 v8 Z  server is UP and succeeded health checks if server is DOWN, so the amount' x8 ]! T& h! S: q9 v
  of additional information is limited.
1 g* y6 z6 V" \4 u: @+ m: y# q8 L" ~/ j0 t. o. ^% b
  If health check logging is enabled no health check status is printed
# k% q# h' q/ p" J+ s8 z  when servers is set up UP/DOWN/ENABLED/DISABLED.3 V) h) N5 E; p. i" A* y' |# L
$ }' c& I9 W( \9 @9 Y
  See also: "log" and section 8 about logging.
; e0 @# e4 x2 I2 U! w0 {! `0 t1 X9 o- c; ^, X- a

: z8 r$ M$ e4 S1 Z5 Z& G# Q) Roption log-separate-errors
2 q. i# p" ~1 n9 ?' e( Tno option log-separate-errors" `2 d. }4 S# Z. ^0 s) k
  Change log level for non-completely successful connections
" P' D6 C. ~/ W! X$ H2 M  May be used in sections :   defaults | frontend | listen | backend1 P% D; |, N+ ?+ o! f) w# H
                                 yes   |    yes   |   yes  |   no3 u! C' Z* z9 s2 ?; p
  Arguments : none
1 P! Q9 r) h( l3 }- ]- i8 W; C" C: D
% K  k8 @2 s$ v" n9 p  Sometimes looking for errors in logs is not easy. This option makes haproxy
5 Q% [  _, @( g" S- X  raise the level of logs containing potentially interesting information such5 m+ ?: L- V0 t* m7 v. t  E/ p! a$ [
  as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The
; B/ J+ ^; u; T+ k" q" p  level changes from "info" to "err". This makes it possible to log them# b5 c- D) r  I* {
  separately to a different file with most syslog daemons. Be careful not to
' \' F. I9 F. ^" Q* [# Z  remove them from the original file, otherwise you would lose ordering which5 |" ~; t" l1 y# I% J
  provides very important information.
- ~9 B/ S2 b8 p" {9 s) R0 K2 I* t- {
  Using this option, large sites dealing with several thousand connections per0 S0 B* C, c" c6 h+ J
  second may log normal traffic to a rotating buffer and only archive smaller
! T2 K5 e* }2 }9 ?+ L  error logs.
8 L- c: |# F# i3 z: H9 q8 W2 u8 z( Q0 o
  See also : "log", "dontlognull", "dontlog-normal" and section 8 about
, ?! J2 f: O) o             logging.
' w, |; n0 Y9 K7 I' G' ~0 }0 O, [9 ?8 |6 M( Y+ r
# @+ ~4 L/ k4 H$ B7 e
option logasap! l! |3 O1 R- A* K  N
no option logasap; D. F6 k" G: e1 Z1 V$ m. M
  Enable or disable early logging of HTTP requests; V6 c+ Q8 C7 a6 w
  May be used in sections :   defaults | frontend | listen | backend
. ]$ z! r& h# e! T" I/ B                                 yes   |    yes   |   yes  |   no( L3 f3 Q2 w, g
  Arguments : none, p+ L' z! v: O8 e

& O$ f- J& D$ H7 U) ?0 T6 U  By default, HTTP requests are logged upon termination so that the total
2 {- ?% \& L# b( m, X" Q. Y8 N  transfer time and the number of bytes appear in the logs. When large objects
. h; P7 O( X  @3 @  are being transferred, it may take a while before the request appears in the
/ S+ s& |6 C0 r  logs. Using "option logasap", the request gets logged as soon as the server; E. B! _2 I' R" {, z# ?1 r, j( C
  sends the complete headers. The only missing information in the logs will be; B5 k( U4 u) B1 x" D  v8 Q
  the total number of bytes which will indicate everything except the amount
5 K$ l' m1 \* A% b0 T+ ?+ q8 B  of data transferred, and the total time which will not take the transfer6 |4 }& _0 `+ s
  time into account. In such a situation, it's a good practice to capture the
$ H$ [, Q6 o" C8 T) A  o; X  "Content-Length" response header so that the logs at least indicate how many5 j2 V- W4 @& w: P( |' i
  bytes are expected to be transferred.4 ]* d/ A% x9 a8 |  X% Z
; W3 d( W8 p: S/ ^5 x! x
  Examples :5 ]  T. K" D* G8 y
      listen http_proxy 0.0.0.0:80
8 D  ?2 Z  `: E7 i& l          mode http( Q( @% H6 X$ C3 \' |
          option httplog; Z' n5 D( w0 g/ z
          option logasap
$ d/ G" o2 {# ], v4 @) o' B          log 192.168.2.200 local3
3 D1 a6 r! T9 j# L; d) J+ D- H! V# @& `7 T& y
    >>> Feb  6 12:14:14 localhost \
# w! Y/ t. ~8 V6 M          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
  O* {; l$ }$ S1 e& }          static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \; @. p: \+ V+ o! `- {% d
          "GET /image.iso HTTP/1.0"* z" p4 D0 y* X2 d4 {$ R& d
0 c+ X: I5 A& V6 t7 ^
  See also : "option httplog", "capture response header", and section 8 about
0 z; o; y% I/ ~             logging.# X6 X3 R, I9 w) n
, N5 g8 j& {  w7 m0 q+ w8 |3 n
$ r* [: q7 H' h' _: H; K4 _9 X
option mysql-check [ user <username> ]
, h' R& Y* D. N( y6 Y% F! u  Use MySQL health checks for server testing1 B& u7 X7 U- S2 l
  May be used in sections :   defaults | frontend | listen | backend
) \# Z. K: R: l                                 yes   |    no    |   yes  |   yes
, v) b# u0 f- [9 f0 t* P  Arguments :
0 K+ r( z6 f; c1 l& z    <username> This is the username which will be used when connecting to MySQL; F& B0 ]4 j  C' g' V  `
               server.
  B- M- B6 J8 s
8 ?: d0 H& X* u7 L. r* P  If you specify a username, the check consists of sending two MySQL packet,
! x* l7 s5 a& o& J  one Client Authentication packet, and one QUIT packet, to correctly close
: G; c' ^% l: u; l8 B- E  MySQL session. We then parse the MySQL Handshake Initialisation packet and/or
9 I, _8 }; V! ^. k. @  Error packet. It is a basic but useful test which does not produce error nor
" ]  s, }# g# w2 `1 B/ Q# ?  aborted connect on the server. However, it requires adding an authorization
/ A- H: t6 {7 ?5 W  in the MySQL table, like this :
# p6 W1 j" F8 h' U2 s* p& L* e3 `2 L! K4 [
      USE mysql;
: Z9 x4 z! Z' F( P      INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
& ^4 c5 }! s  N+ q" X      FLUSH PRIVILEGES;
: h5 v- E9 f0 F4 \; a2 X: I* B0 {2 s0 @* `1 d
  If you don't specify a username (it is deprecated and not recommended), the/ e: Z6 i. C# S8 Q3 X( c0 c
  check only consists in parsing the Mysql Handshake Initialisation packet or
7 v2 r9 G0 {0 F- B, J- g  Error packet, we don't send anything in this mode. It was reported that it
- {  e! [5 z0 _* v0 r0 r' E0 Z  can generate lockout if check is too frequent and/or if there is not enough/ t7 U; ]4 O* N  s2 w' t6 h. j) X, `
  traffic. In fact, you need in this case to check MySQL "max_connect_errors"
/ w0 H7 ?- c/ z, E2 N  value as if a connection is established successfully within fewer than MySQL6 P; H4 N) S& N- b( b/ E3 w
  "max_connect_errors" attempts after a previous connection was interrupted,% D9 n9 v: w* O" h' D, h
  the error count for the host is cleared to zero. If HAProxy's server get
; ~8 Y" o9 F( j/ p  blocked, the "FLUSH HOSTS" statement is the only way to unblock it.
0 p  i. `: P9 W' ]% Y3 T; y$ c  h0 y5 o
  Remember that this does not check database presence nor database consistency.  h6 {" q4 o$ U3 S8 L; G+ j
  To do this, you can use an external check with xinetd for example.6 [3 P! \. F& j9 v  A; D
' _1 w5 E# L! [
  The check requires MySQL >=3.22, for older version, please use TCP check.
% y1 {1 B$ b' N' N7 |. b% c5 M# f% g9 C. |! r8 g
  Most often, an incoming MySQL server needs to see the client's IP address for
; G7 x+ G0 N" X9 X* c  various purposes, including IP privilege matching and connection logging.
% r9 S6 T/ |7 ]$ c4 ?5 w% Z9 ]3 n5 t- u( o  When possible, it is often wise to masquerade the client's IP address when/ X: O3 j" j5 K9 s6 n! N: _
  connecting to the server using the "usesrc" argument of the "source" keyword,# ^5 j# j  ?# d; y1 {# i
  which requires the cttproxy feature to be compiled in, and the MySQL server, [% Z' G" r7 X
  to route the client via the machine hosting haproxy.
0 W. R. y' O; }* r, v
- l! H: P6 t! i0 K" m0 Y( S  See also: "option httpchk"& r  o( g/ r4 Z( l0 G) P

9 D, c! f' i4 q- X3 Z- D; y1 z0 e" z- s
option nolinger  D/ _# z' I/ i* v& k/ n9 @; W
no option nolinger4 N( }4 O6 y9 U, j: z: Q  A
  Enable or disable immediate session resource cleaning after close
9 L! N& `8 W) N5 U6 J2 Y6 @  May be used in sections:    defaults | frontend | listen | backend2 F% L  f$ u+ b5 F* r0 \% h- n
                                 yes   |    yes   |   yes  |   yes
1 F7 S0 ~* h2 q4 Y: ^  Arguments : none
# a% a9 d  l" }( t: \  V
" ~1 I, D0 X1 r. {3 I  When clients or servers abort connections in a dirty way (eg: they are
+ D7 X$ j, O) T5 t- c' q3 E# I  physically disconnected), the session timeouts triggers and the session is4 R- D4 z4 I0 G% B2 E' I
  closed. But it will remain in FIN_WAIT1 state for some time in the system,& m+ b. ^+ \& n' a6 N+ D' U
  using some resources and possibly limiting the ability to establish newer( o; q- n2 z2 N3 c
  connections.
% G7 ~  c  m1 F3 s5 r6 t4 ^& z* q. B+ S0 I: w
  When this happens, it is possible to activate "option nolinger" which forces
1 s4 d+ G  w! M9 F; Z  the system to immediately remove any socket's pending data on close. Thus,, b0 D7 T3 r' T: ]) ~( _
  the session is instantly purged from the system's tables. This usually has
& F6 U" G& y" f3 B/ F( D  side effects such as increased number of TCP resets due to old retransmits5 Z7 u/ ^5 a7 Q# o( H3 f
  getting immediately rejected. Some firewalls may sometimes complain about5 T7 U- f: M# Y2 \% z9 g5 o! O( p+ S
  this too.* Q" ^* U9 w/ N  {0 _: b
# n! |) H! a$ G- H) h3 B$ Y: P8 q' K
  For this reason, it is not recommended to use this option when not absolutely
. {0 U$ Z4 k, o  needed. You know that you need it when you have thousands of FIN_WAIT1
; n" G* x* w) v1 v* m7 l  sessions on your system (TIME_WAIT ones do not count).
4 w6 L! y7 V$ }8 d+ t
+ y3 D- t: a  Q9 _$ e  This option may be used both on frontends and backends, depending on the side
: g# I$ y& D$ T, t2 e% P  where it is required. Use it on the frontend for clients, and on the backend+ f6 }1 h! ^8 \# a
  for servers.
2 r( X9 y7 Z! E9 f2 y0 E5 F
; m& e, Q  u. p  If this option has been enabled in a "defaults" section, it can be disabled! Z3 V) n" _/ h) [2 ?8 ]$ e
  in a specific instance by prepending the "no" keyword before it.
4 q# S! }" t- t3 Q0 J9 O* w
3 [: l, F0 B' h! |+ I3 ^
/ D7 l- o/ l. x4 c$ q2 a$ ~5 C! Koption originalto [ except <network> ] [ header <name> ]
' J7 u/ b3 O8 e3 w  Enable insertion of the X-Original-To header to requests sent to servers) H4 ?2 K- e- i  e% i
  May be used in sections :   defaults | frontend | listen | backend. h- Q6 Z! S1 u* X! Q& D
                                 yes   |    yes   |   yes  |   yes
; ?' Q+ [9 O  T+ ?- N0 Y% z' `  Arguments :7 E# J8 x% M7 ~' N9 a
    <network> is an optional argument used to disable this option for sources
0 W. m6 y2 E8 a              matching <network>
+ Q1 [6 W, ]: m* W8 K    <name>    an optional argument to specify a different "X-Original-To"' S% g( O# V! d
              header name./ q$ K9 ^! |! r% ?4 u
! S5 k! p: Z; d" y
  Since HAProxy can work in transparent mode, every request from a client can
9 P2 r9 @. o5 ]! [  be redirected to the proxy and HAProxy itself can proxy every request to a+ j, G( g+ v& P3 E; b3 e! r, `2 t
  complex SQUID environment and the destination host from SO_ORIGINAL_DST will
( ]' x5 Z& U" H9 U  be lost. This is annoying when you want access rules based on destination ip& f# u* Y6 Z5 P, p4 F4 c/ o) D, x
  addresses. To solve this problem, a new HTTP header "X-Original-To" may be
& F& b) Q! o8 x; h! T  added by HAProxy to all requests sent to the server. This header contains a
0 W! ^. G/ V: g& r7 |0 W$ M  value representing the original destination IP address. Since this must be
8 V9 a" g9 n2 A4 w; l  configured to always use the last occurrence of this header only. Note that
; e; `2 J8 y5 {+ _0 J+ s  only the last occurrence of the header must be used, since it is really
+ `, r$ J) @3 P4 p/ o) L3 G  possible that the client has already brought one.
0 I) A4 `! \% f, \4 k
$ h5 p1 |0 \% ~" U  The keyword "header" may be used to supply a different header name to replace
: I- k! C. f7 [" G  the default "X-Original-To". This can be useful where you might already, g- ~9 f5 r8 n; e3 }
  have a "X-Original-To" header from a different application, and you need( B) U' _/ _6 ~4 a+ S) }
  preserve it. Also if your backend server doesn't use the "X-Original-To"
/ p7 \9 P5 e: s  o5 V  header and requires different one.
  }* Z4 B3 k; C! X$ o
) f7 w% ?0 f4 c( a% l/ P  Sometimes, a same HAProxy instance may be shared between a direct client
: F4 _( H7 e2 {/ d* t* T+ r0 M  access and a reverse-proxy access (for instance when an SSL reverse-proxy is! [, x1 l8 M3 }  \! l/ X6 C
  used to decrypt HTTPS traffic). It is possible to disable the addition of the
8 w3 P5 _; [/ ~3 S8 E  header for a known source address or network by adding the "except" keyword9 Z; w4 w8 i. l6 H8 A
  followed by the network address. In this case, any source IP matching the
1 h$ k' _7 i) h" F: Z% B- o5 k  network will not cause an addition of this header. Most common uses are with
* h/ s* r- W* t- q$ S0 G0 N  private networks or 127.0.0.1.) o/ i9 {& B+ v, y1 v

. Z2 y8 F: \* W$ V  This option may be specified either in the frontend or in the backend. If at  }  u% j- z/ E% c9 m6 v7 \
  least one of them uses it, the header will be added. Note that the backend's
/ X3 B" }0 x1 O" f& g  setting of the header subargument takes precedence over the frontend's if
: k- C/ {# `- r& P& y* f  both are defined.: r3 J* D& N# U2 K. j# v2 s

, s$ N" m' i+ w) Y1 {  It is important to note that by default, HAProxy works in tunnel mode and
- L, x' j7 q% S/ j  only inspects the first request of a connection, meaning that only the first
) B5 m7 H% ^; B6 N2 r8 B8 {8 s/ |/ p  request will have the header appended, which is certainly not what you want.
$ I) p: m" x6 W2 W  In order to fix this, ensure that any of the "httpclose", "forceclose" or+ f7 e7 p0 c! G! a  W
  "http-server-close" options is set when using this option., n7 a& }. G* a- j  @! {  w
! {4 F6 c, m/ Y( [- ~& N+ q
  Examples :, ~, D* z& m8 W
    # Original Destination address
! ^; p7 E8 P5 d8 O! F    frontend www
. C& t3 O( s5 d' M( Y. g% R# `        mode http# N" y, |3 o: e$ Y  B
        option originalto except 127.0.0.1
% J8 t! E; O. }+ [9 Y
" P5 |9 s! h6 M; P- ?    # Those servers want the IP Address in X-Client-Dst) s8 m: a* ^, [$ Y( x" w3 V- k; y8 F. A
    backend www4 w: A) J! P4 n7 j2 y; F
        mode http
: E5 T4 i6 [; S: |        option originalto header X-Client-Dst
: D* `( ^/ L0 `1 ?4 R' V
3 W1 G5 Z7 B5 {+ r1 K8 Y6 E  See also : "option httpclose", "option http-server-close",
) \9 G. R% R* k: e& Y             "option forceclose"
3 X' I) L# A2 W: o# H# Y: H% _' d" c. K+ h/ i; l; F; M4 _9 Z

2 F6 k; I/ V: u. n* k# ooption persist$ m+ ~; X) E3 `. W( m7 i+ l% n- [
no option persist8 `+ n/ P7 F6 c2 |2 W
  Enable or disable forced persistence on down servers9 B) F2 n) O# h, X# ^
  May be used in sections:    defaults | frontend | listen | backend
; L( e' r' C" o7 w5 U/ I, k                                 yes   |    no    |   yes  |   yes$ T, a6 h4 S5 j" _8 g9 T  q/ {
  Arguments : none
6 V1 l/ Y  r4 {% I. K2 _; |" Y9 _' A- c- w, C
  When an HTTP request reaches a backend with a cookie which references a dead8 w  T" _0 Y7 j& A# o7 F: K9 Y
  server, by default it is redispatched to another server. It is possible to% e; C) k" M6 ?( D# k+ p; E
  force the request to be sent to the dead server first using "option persist"
* }& D% k' o: w2 y  if absolutely needed. A common use case is when servers are under extreme, h/ v$ X+ ]+ L, Q6 p% c+ B, ~
  load and spend their time flapping. In this case, the users would still be/ s5 M1 |3 q" M, d$ o" p! [. I
  directed to the server they opened the session on, in the hope they would be) ?8 u2 N7 j2 |) C
  correctly served. It is recommended to use "option redispatch" in conjunction( C  E2 |: s; V* I6 v& j: m
  with this option so that in the event it would not be possible to connect to3 _& ~& n, G. J9 U
  the server at all (server definitely dead), the client would finally be+ P2 @1 k/ ~4 n: }
  redirected to another valid server.
5 k' e  M# _6 I: O- w1 f9 }, Q, @+ M- p# e
  If this option has been enabled in a "defaults" section, it can be disabled
7 n. e0 {! L& X3 H  S  in a specific instance by prepending the "no" keyword before it.# l% X7 y' g- D% L2 f7 U
" s2 t! O1 R9 p, y- `
  See also : "option redispatch", "retries", "force-persist"
! Y/ V( v/ N7 |: s3 }. U4 r/ ^+ o3 ]- ]) v$ F

! P! y& ?& T/ _  e" noption redispatch, l1 v5 Q) p$ `- c5 ?
no option redispatch8 W/ h; j$ m0 i; j5 U
  Enable or disable session redistribution in case of connection failure- U7 e9 r  j) z. V. ^) ^6 y
  May be used in sections:    defaults | frontend | listen | backend
4 `  a; Q# a) Y1 a$ h9 [                                 yes   |    no    |   yes  |   yes; N/ ^& @2 I. A
  Arguments : none
) p$ @- y# `! G2 B% Z9 [: w  M. t
' x+ \  R& F5 ^8 J" P  In HTTP mode, if a server designated by a cookie is down, clients may8 R! ^, m) d5 F+ Z9 e. x
  definitely stick to it because they cannot flush the cookie, so they will not
, ?5 g7 M, |7 ~, m, B0 m$ j$ d0 |  be able to access the service anymore.
8 m) J% R1 k6 M/ z$ G- T+ l/ Z- p& ?' m7 U, I  V8 o
  Specifying "option redispatch" will allow the proxy to break their
! N* f- v. x. ^1 V8 a  persistence and redistribute them to a working server.
( g$ L7 L3 K0 a( ]  v( s
8 q/ P! l% K9 M) D  It also allows to retry last connection to another server in case of multiple3 U3 a# [" S/ m
  connection failures. Of course, it requires having "retries" set to a nonzero
' k% d% M% Q7 _+ x: j$ @  value.( ?; ^) a  [' H4 q! z, J
" g+ S+ A2 n2 U9 l; G
  This form is the preferred form, which replaces both the "redispatch" and* n8 ^7 T" Y# F9 J5 Y4 h, }* y6 K
  "redisp" keywords.* \: X; ^0 z3 y; [2 ]) Y, ~

" T4 I/ x! q8 Q5 w0 V  If this option has been enabled in a "defaults" section, it can be disabled$ X$ n, d: W! L2 K8 |8 c
  in a specific instance by prepending the "no" keyword before it.9 P4 `. G, k* u! E, u' f, p5 S
) ~! c6 P/ C8 i& _- x& _1 o
  See also : "redispatch", "retries", "force-persist"+ s4 n  X$ @8 x. H7 u! r& [* v& V
# }& s( n7 _2 I

3 _. v- [: @1 b. Q! b& w* M1 [option smtpchk3 D0 A: v' A* F
option smtpchk <hello> <domain>9 C8 }8 D' q. @, ?, J
  Use SMTP health checks for server testing! a+ ~  q0 Z" R9 Y3 _3 ]6 l& [/ P
  May be used in sections :   defaults | frontend | listen | backend
! |# d- k9 h# ~; T% d: l                                 yes   |    no    |   yes  |   yes
9 K1 E7 w: [) B' E' L" D  Arguments :- `* P% w1 N: D9 ~( p# S
    <hello>   is an optional argument. It is the "hello" command to use. It can7 |4 q) V) [# n% g% ^/ ^5 s, N
              be either "HELO" (for SMTP) or "EHLO" (for ESTMP). All other2 O& o, q. w9 o3 r& J2 e' m
              values will be turned into the default command ("HELO").4 E8 U* Y, i; Y" M$ Z& M, r
* i$ e- k/ Y3 H/ @; r
    <domain>  is the domain name to present to the server. It may only be9 @: Y5 g. s5 J$ M" |* v: i$ C
              specified (and is mandatory) if the hello command has been
- y8 C$ |( g1 S7 @7 p              specified. By default, "localhost" is used.: _9 v- t3 I- l; j% g; N) I
* \$ v$ d: Y4 c
  When "option smtpchk" is set, the health checks will consist in TCP
+ d0 q' ?: E0 _+ {  i  connections followed by an SMTP command. By default, this command is0 _( N1 U: i  ]" E& R
  "HELO localhost". The server's return code is analyzed and only return codes: E/ F, k, l0 i" C3 k4 ~- w- o8 R" K6 m+ F
  starting with a "2" will be considered as valid. All other responses,1 o" O" e% C6 i" f: k
  including a lack of response will constitute an error and will indicate a+ V$ |; t& E: H, p7 ?1 V2 \; z
  dead server.) R  }  a0 k1 a* U5 }

& }+ S/ O6 [- c$ h$ W# q7 W9 X3 g  This test is meant to be used with SMTP servers or relays. Depending on the3 _8 B* {% O. `& U& G% H
  request, it is possible that some servers do not log each connection attempt,
& |0 D1 _+ N; U3 X/ z( z  so you may want to experiment to improve the behaviour. Using telnet on port( ?0 A2 Q! Z: I- L+ \$ ]
  25 is often easier than adjusting the configuration.* Y: y2 s- C5 H# Q- w
: a6 I' a# N. D4 {7 ~5 f# V
  Most often, an incoming SMTP server needs to see the client's IP address for
7 E3 g2 Z& e8 R" ?( j8 e' M% u  various purposes, including spam filtering, anti-spoofing and logging. When$ @+ Y( ~$ m% r0 D3 B* o" g
  possible, it is often wise to masquerade the client's IP address when) w7 o# T/ H' |. U
  connecting to the server using the "usesrc" argument of the "source" keyword,
* n" {! }; S1 G+ |$ M  which requires the cttproxy feature to be compiled in.
8 g& R" ^+ p" b9 P% J) O
7 D: }% E/ p9 h3 E5 S+ z/ Q  Example :
' w6 R0 e  j9 [        option smtpchk HELO mydomain.org
+ |) L+ d& v# U/ y
8 [5 [* m. [9 A6 [) A1 p# |  See also : "option httpchk", "source"
5 C" b9 t: a7 b, t$ h2 y1 Y2 f( H& ~3 r, w8 Q
" E) o4 w- Z4 s9 p
option socket-stats
& m' _+ m7 w( J: G  V1 @( `! zno option socket-stats# ?: e+ e) r% V' }* f( x7 D3 o. `! v& `

0 b; B3 r; H; t  Enable or disable collecting & providing separate statistics for each socket.
3 S0 F# z* P7 J7 q; e( d* R  ?  May be used in sections :   defaults | frontend | listen | backend3 |; t# X4 ~/ j. p
                                 yes   |    yes   |   yes  |   no
# o( c' j' O" |3 p
- c- N& A* H& l" e0 {6 S& M  Arguments : none( U1 T! g* a9 S$ B  N! D6 A2 T& n

. o5 p* g/ y8 X; W  H! I5 X/ k+ v/ _: ~
option splice-auto
' Q7 ?, F( J, K6 R6 Pno option splice-auto
$ s6 s; k* e0 |8 V) ^+ Q  Enable or disable automatic kernel acceleration on sockets in both directions
& Q8 g2 B+ M  y; ?+ I  May be used in sections :   defaults | frontend | listen | backend# M" M$ v+ J9 r+ Z
                                 yes   |    yes   |   yes  |   yes
  m4 x" }  ^5 a0 H' ?" v  Arguments : none/ \# T1 X, n3 h

8 y. a2 C/ Z& g) e/ {  f* ^  When this option is enabled either on a frontend or on a backend, haproxy
" h4 G. y" z: |) `  d( @! U+ L  will automatically evaluate the opportunity to use kernel tcp splicing to1 W* i  T) H3 a
  forward data between the client and the server, in either direction. Haproxy
, a/ e& E  g  g+ [$ @# X; o  uses heuristics to estimate if kernel splicing might improve performance or8 n  o  k6 U. j; q2 a$ n# ~' S
  not. Both directions are handled independently. Note that the heuristics used
8 s9 I5 ~3 s9 M5 y1 |9 s  are not much aggressive in order to limit excessive use of splicing. This
! U  ?. R% l: d* t4 o7 ~  option requires splicing to be enabled at compile time, and may be globally# Z9 {* y  j$ c6 L' D
  disabled with the global option "nosplice". Since splice uses pipes, using it
2 d& l6 j& F. D' R, E  |! l$ S- G8 S  requires that there are enough spare pipes.# d! ^4 J- ^* X( p. @, p. ?9 i
+ Z  [' U1 l% }
  Important note: kernel-based TCP splicing is a Linux-specific feature which+ f+ t+ I" C8 ]8 n* ]2 e
  first appeared in kernel 2.6.25. It offers kernel-based acceleration to
' L/ T- f6 E7 ]  transfer data between sockets without copying these data to user-space, thus' j# o4 X, z: z% K" r
  providing noticeable performance gains and CPU cycles savings. Since many
5 c8 J  T; D* @6 i+ y/ |: S& F  early implementations are buggy, corrupt data and/or are inefficient, this
; r: T7 ?  W' q5 x# r  feature is not enabled by default, and it should be used with extreme care.
. |' Y( U  S- a3 u# p  While it is not possible to detect the correctness of an implementation,
" x: [5 J+ L5 G, C" }% |2 J1 W# C  2.6.29 is the first version offering a properly working implementation. In
, a& P8 {& W2 g; T8 b* V# U8 F  case of doubt, splicing may be globally disabled using the global "nosplice"
& ~" c- p2 p0 ?: `  keyword.
; B3 q/ p  ]- c2 c+ w' L2 W  U3 l- n% v+ K7 E" c+ ?# r
  Example :- a6 A# @& p! X* P5 a
        option splice-auto
0 i9 Q: T' U6 l% o% f+ Q) a; k% X3 h, V- l. ?
  If this option has been enabled in a "defaults" section, it can be disabled* o8 }8 Y1 a6 ?5 }7 [2 T
  in a specific instance by prepending the "no" keyword before it.8 X6 S, t6 ^$ C
) _& A1 x: g/ d- c) U. H* \0 Q
  See also : "option splice-request", "option splice-response", and global
1 |7 ?5 s! h8 h3 }; B* N$ v" ^             options "nosplice" and "maxpipes"' X$ P" I, Z: `3 X1 N) d$ C% ?
. x4 S" z, V0 C7 r, M! o
" D+ h( c" |2 l, T# t
option splice-request8 i9 p+ Q# F! x3 H; p' O. C1 Y
no option splice-request% r9 O8 ^- b# R- M
  Enable or disable automatic kernel acceleration on sockets for requests/ d4 f2 H  j$ L) ~
  May be used in sections :   defaults | frontend | listen | backend
* R: R# Q; v5 Q5 E. t2 e                                 yes   |    yes   |   yes  |   yes
; }7 ^7 ?1 @; \$ D, ]  Arguments : none/ ~3 r! s, b% @9 x- D
) c# V- l! w' A# @2 Z2 z
  When this option is enabled either on a frontend or on a backend, haproxy
# W- f# A" b) ]4 f  B  will user kernel tcp splicing whenever possible to forward data going from& }- O  v: J. h' H
  the client to the server. It might still use the recv/send scheme if there
  K& R/ H  B$ ^% v4 {; ~( w* ^  are no spare pipes left. This option requires splicing to be enabled at: Q3 n2 k7 f2 y! i- j
  compile time, and may be globally disabled with the global option "nosplice".0 N4 Y( p/ S$ q3 Y* M$ |
  Since splice uses pipes, using it requires that there are enough spare pipes.8 S, s  V* \! i; c, L1 L
0 s! |$ K6 e  O' D2 N" t( U
  Important note: see "option splice-auto" for usage limitations.
/ Q; t* T, D( X) P' c+ @! h# M. T1 ?
  Example :
2 D# O, b1 g1 t        option splice-request
5 _+ y' O( V# j8 |0 n6 l( _" e8 ?9 S! ?
  If this option has been enabled in a "defaults" section, it can be disabled- }; o4 Z( R( N
  in a specific instance by prepending the "no" keyword before it.. `; h- ~) y; z5 o; ~$ p% J

! w) N+ E; N0 P& e. i. o: }  See also : "option splice-auto", "option splice-response", and global options
1 P& z. y- H  F- f( o7 Q             "nosplice" and "maxpipes"$ a- F: x$ b% o# e6 k
& f' m, t' }  t; W7 W1 o  U

% C" B: R( m; A( _" H, Voption splice-response
' o. [+ J7 ~0 t, Qno option splice-response2 s5 _4 [# _- X2 l+ p$ Y" Z' w2 h2 s
  Enable or disable automatic kernel acceleration on sockets for responses' |& _7 V1 C1 Y" z+ A1 j# o( l: e
  May be used in sections :   defaults | frontend | listen | backend7 w8 g9 |6 V7 x$ n. \  ~
                                 yes   |    yes   |   yes  |   yes
- S& Z7 x, l$ q, ]7 f  Arguments : none/ H& ^9 l7 l6 d3 S( F$ H0 u; j6 l
2 v8 j- k, X' m/ E; P4 w
  When this option is enabled either on a frontend or on a backend, haproxy
$ y* r0 x6 v2 Z2 N! P  will user kernel tcp splicing whenever possible to forward data going from1 f# O; o5 H# C+ L, b+ P/ g1 ?* j) w
  the server to the client. It might still use the recv/send scheme if there
) ?6 w3 g. w$ }0 _- t8 b) W  are no spare pipes left. This option requires splicing to be enabled at
/ D  @! N$ a6 M. `# }  compile time, and may be globally disabled with the global option "nosplice".
" r0 D3 Y( \0 {  Since splice uses pipes, using it requires that there are enough spare pipes.
% C4 P& U4 P% [$ @7 A$ s
- C4 g* R) |6 B6 b  Important note: see "option splice-auto" for usage limitations.
8 ~# W+ U, `3 C8 ^. A
) a# x2 ?' p2 @, A" `  Example :$ F# R5 n5 a7 \1 G
        option splice-response
  s# P+ A" a5 t# W5 y' [
8 X5 x5 z. l. D2 `$ y+ v: N  If this option has been enabled in a "defaults" section, it can be disabled
; {" i- I& [: B; n# ~  in a specific instance by prepending the "no" keyword before it.
- B2 b  d  D% c1 M- J
) y% B; V/ u/ w1 W) q2 C  See also : "option splice-auto", "option splice-request", and global options" L) P( v0 r6 P9 r- C
             "nosplice" and "maxpipes"3 P( }/ k8 ]0 e9 f# W+ S
/ _0 z; N' Y( U

2 j5 \! `' c: s+ H; U. Q" ioption srvtcpka* y2 j  B  K  N7 C2 Z5 @8 j$ y
no option srvtcpka
7 A& ]7 ^/ G# B  Enable or disable the sending of TCP keepalive packets on the server side
9 L' |; {2 H, C0 }0 W  May be used in sections :   defaults | frontend | listen | backend  N0 I, C% p0 C/ w. Y
                                 yes   |    no    |   yes  |   yes9 q4 g1 X) P, ]
  Arguments : none
! c6 g$ s: _$ B# H6 w! W% \- {$ z0 K
3 n5 g8 ?9 Y; e" E7 J6 h& \  When there is a firewall or any session-aware component between a client and
! z9 @+ {$ ^, p! Z  a server, and when the protocol involves very long sessions with long idle, P6 |) f: b# j( ^8 A& `5 `
  periods (eg: remote desktops), there is a risk that one of the intermediate
2 I6 z5 C  c( {6 v  components decides to expire a session which has remained idle for too long.
7 n- K6 v4 g- [+ c" ?+ H4 J6 O) F/ @+ X% P8 p: _# |) A/ u5 }
  Enabling socket-level TCP keep-alives makes the system regularly send packets
- h: Q0 p3 }. k0 @  to the other end of the connection, leaving it active. The delay between5 X% h! J7 Q5 n  A4 Z
  keep-alive probes is controlled by the system only and depends both on the% }" |: H2 h0 r. g
  operating system and its tuning parameters.
. {  Y7 n& S7 K9 `9 L* x+ j0 k& s- M5 d- c
  It is important to understand that keep-alive packets are neither emitted nor9 T+ \* z! c& c( R# c. Q# D
  received at the application level. It is only the network stacks which sees
* y: v+ U6 u) \! y" c6 a5 h( b  them. For this reason, even if one side of the proxy already uses keep-alives
5 I" S" Y0 F! B* Z$ T( T) `  to maintain its connection alive, those keep-alive packets will not be
, t0 m* b- E" t1 S; s5 M: b  forwarded to the other side of the proxy.
7 n8 N9 {* O: C+ \6 ^
. m; }. U; M$ I3 [  Please note that this has nothing to do with HTTP keep-alive.
$ l$ u. z/ o4 {% j7 A' x# M$ N- q4 T5 s7 A6 t. f" _
  Using option "srvtcpka" enables the emission of TCP keep-alive probes on the9 W: h: t9 N) K) C
  server side of a connection, which should help when session expirations are' P$ v% f: P4 n+ P' S7 V2 h8 D
  noticed between HAProxy and a server.
( c. m: S4 {% x! \4 c
; U4 G8 {, ~. e0 n0 Z4 B  If this option has been enabled in a "defaults" section, it can be disabled1 k- r/ J1 e$ U5 j8 s: ~
  in a specific instance by prepending the "no" keyword before it.: O: i/ I$ ~/ y* s

" S$ b# t, t: R0 ^  See also : "option clitcpka", "option tcpka"  P5 D4 F' z- |# ~9 W- L

0 Q5 ^+ F" u0 L1 i  n" U1 l& Z
% u/ o( ]" L) @( u+ w+ U, Ioption ssl-hello-chk
4 `- g) W7 K, B; Y2 S. F  Use SSLv3 client hello health checks for server testing1 z8 F+ ]. T; o* `' d3 L
  May be used in sections :   defaults | frontend | listen | backend  K- S4 ~) Q- Q4 B, P
                                 yes   |    no    |   yes  |   yes
8 X: l$ }$ ^# Q8 T3 f9 G; T4 V7 @  Arguments : none
7 D0 F% L3 u, u" U
! K' p2 s7 Y. q5 N$ n  When some SSL-based protocols are relayed in TCP mode through HAProxy, it is6 s. y  A$ H- A' }( i) N) A( M0 S
  possible to test that the server correctly talks SSL instead of just testing0 n  |) v5 L. N7 w
  that it accepts the TCP connection. When "option ssl-hello-chk" is set, pure1 X4 R% m# _3 Y6 }9 b; P2 t4 D
  SSLv3 client hello messages are sent once the connection is established to
# Q/ p1 E7 C! Q  Z  the server, and the response is analyzed to find an SSL server hello message.
% z/ z) V, U& k4 u, W; ?, Z0 W  The server is considered valid only when the response contains this server
& H! I3 @. ?0 C1 s  hello message.
* {; ~0 q: b& l# }' J7 S7 a" v( x- q' V% H* `! }
  All servers tested till there correctly reply to SSLv3 client hello messages,! N- [: D* I  r) |
  and most servers tested do not even log the requests containing only hello
5 [. K3 D3 I: D6 S; H# _% h9 @  messages, which is appreciable.& c3 S) }7 L# W+ x3 g5 q

/ V: T6 @9 P) _  See also: "option httpchk"" Y  o" i: ]3 M1 y/ ~/ R2 ]
3 S2 V% K9 {4 W+ g" y( q! E
$ n4 Z* }# x( e9 D. A
option tcp-smart-accept
: _- T, }  Q7 U9 vno option tcp-smart-accept
; k  k( }! l( I; C8 ]0 o5 {  Enable or disable the saving of one ACK packet during the accept sequence
1 R% f# i* l' x/ S0 Z) k' U  May be used in sections :   defaults | frontend | listen | backend* {8 f2 v6 U9 G7 [
                                 yes   |    yes   |   yes  |    no
# S  z5 }# i6 S2 f) X* w3 _  Arguments : none, e$ B+ {2 k3 D

: v' V& G1 R+ i! ^; ]" g: Z: V/ C  When an HTTP connection request comes in, the system acknowledges it on- ^. K+ G1 I3 O9 h& D0 U
  behalf of HAProxy, then the client immediately sends its request, and the/ T2 k; n4 Y9 w4 w/ `
  system acknowledges it too while it is notifying HAProxy about the new
8 i2 _" V( r: F4 o  connection. HAProxy then reads the request and responds. This means that we
" T" d& ~; w! f" X- z  have one TCP ACK sent by the system for nothing, because the request could5 ~$ I5 M! _9 I9 ^( ~9 s/ k
  very well be acknowledged by HAProxy when it sends its response.' D; H) w" q+ [/ V! n" d8 k# Y! t
& R" ~5 @9 B+ H! V  N9 R
  For this reason, in HTTP mode, HAProxy automatically asks the system to avoid
* j# w; m, `% R  sending this useless ACK on platforms which support it (currently at least: s4 q" Q( j. o# a7 L! l1 ~
  Linux). It must not cause any problem, because the system will send it anyway- G: S9 G1 q. N( `; I
  after 40 ms if the response takes more time than expected to come.( Q: x+ M8 l7 ?; h6 V& F! @

" V3 I9 U' ^/ W8 x9 R# u$ P3 `6 p  During complex network debugging sessions, it may be desirable to disable
  ?/ b  O7 K8 u. |  this optimization because delayed ACKs can make troubleshooting more complex9 T8 X# W5 q1 u+ r
  when trying to identify where packets are delayed. It is then possible to
, g3 ~% o, h. {6 d, @+ P  fall back to normal behaviour by specifying "no option tcp-smart-accept"." q# v7 ^" T- J( \3 n# h
! l1 |) c. K) v/ W% ]  [, n
  It is also possible to force it for non-HTTP proxies by simply specifying: Y% S" x+ b2 W4 k3 z' r
  "option tcp-smart-accept". For instance, it can make sense with some services
9 d1 x$ ]2 K2 t5 b  such as SMTP where the server speaks first.
( z  Q8 x8 B* |
. z3 \- b( K) T& j  It is recommended to avoid forcing this option in a defaults section. In case
5 Q- k' {* j" \- k  of doubt, consider setting it back to automatic values by prepending the: k) s. j+ k9 C1 v7 e
  "default" keyword before it, or disabling it using the "no" keyword.
  \8 F" Y1 M& q5 o, i/ I( }
* S. P2 C7 P- F  See also : "option tcp-smart-connect"- _9 N- b. |: E2 F( A

7 V3 K7 c2 S; C$ i7 r4 ?1 P& T9 c  B* l3 H& [- a
option tcp-smart-connect! W* w" t: s$ F+ L
no option tcp-smart-connect5 `1 t5 T5 g6 e+ v1 W+ y
  Enable or disable the saving of one ACK packet during the connect sequence8 K( L! {8 ?- U
  May be used in sections :   defaults | frontend | listen | backend+ e/ x$ e( X. ]% n, J6 E
                                 yes   |    no    |   yes  |   yes
9 [# G. s! A9 m9 O5 s7 H& ~. @; y  Arguments : none
! q* Z* a( T- L# V% j+ P0 U+ {8 Y. q- C; w
  On certain systems (at least Linux), HAProxy can ask the kernel not to9 p7 j) U% N, X( w* i" q/ O+ t
  immediately send an empty ACK upon a connection request, but to directly
  z. _& W1 _* q. o( E9 Q  send the buffer request instead. This saves one packet on the network and2 g; K0 [* |) v( z1 m$ @. u
  thus boosts performance. It can also be useful for some servers, because they, f' R' T, h3 N- s
  immediately get the request along with the incoming connection., e# d- H- K4 ]' {' Q' u6 ^: T

9 ~' h: Y; d" f, a# N! a+ o  This feature is enabled when "option tcp-smart-connect" is set in a backend.+ ~1 O, w3 q# N
  It is not enabled by default because it makes network troubleshooting more
* C! i1 C" k/ W1 g' K$ c  complex.( I; }5 u/ ^; }' |3 R4 o# s4 c
* E: ]8 b4 h& F  R& `* w% G
  It only makes sense to enable it with protocols where the client speaks first. y. c/ U: ?; |: h4 K5 U
  such as HTTP. In other situations, if there is no data to send in place of
1 R$ d0 X( F9 j+ c$ ^7 E+ O  the ACK, a normal ACK is sent.+ E& X0 m5 M" w8 n

6 B8 L0 d; ^7 C  If this option has been enabled in a "defaults" section, it can be disabled$ K2 W& o3 l9 c4 M. T
  in a specific instance by prepending the "no" keyword before it.( O/ h1 I/ A% Y5 c) M

- }: [( L$ H3 d: C) i  See also : "option tcp-smart-accept"
5 i: F7 B( e2 ^; r5 z: F3 X3 d8 G  H2 n) R% M# @* Z5 E2 l
" z5 e/ Q) b; Y
option tcpka* V* M% I; r% W6 F7 @, Y
  Enable or disable the sending of TCP keepalive packets on both sides
: F8 k8 C. r' n# ~/ I! j  May be used in sections :   defaults | frontend | listen | backend
* C! K3 y1 X" d" f/ G$ n                                 yes   |    yes   |   yes  |   yes
# u2 w; l/ {/ r* L  Arguments : none
6 j9 x1 g$ e$ c1 d7 @- k
2 W' R& G, D: z. I  When there is a firewall or any session-aware component between a client and
, A0 D5 R& ~% S" b! y6 Q: n5 J' e  a server, and when the protocol involves very long sessions with long idle6 R/ \7 b% U; E
  periods (eg: remote desktops), there is a risk that one of the intermediate
6 p% {0 L/ @' o! `! f  components decides to expire a session which has remained idle for too long.
4 D' C9 V6 q0 i2 v; g4 t2 N4 v# P
4 x7 f8 ^# Z9 m" w3 X7 t2 D  Enabling socket-level TCP keep-alives makes the system regularly send packets& A4 N8 T% W0 ?6 ?( ?
  to the other end of the connection, leaving it active. The delay between4 \8 {, \# g+ _# e
  keep-alive probes is controlled by the system only and depends both on the4 Y5 `& h4 v# W. V  C
  operating system and its tuning parameters.
9 j% \+ _+ a7 p0 q# }" q9 _4 R) H
  m- J, C- q$ T  It is important to understand that keep-alive packets are neither emitted nor
/ y. r& e3 H; ]& |5 Y2 y8 h  received at the application level. It is only the network stacks which sees0 i3 M: n9 c  \* M1 a& u
  them. For this reason, even if one side of the proxy already uses keep-alives0 J* _4 S+ B: l% W' |! W4 ?' L9 Z0 E
  to maintain its connection alive, those keep-alive packets will not be$ O/ j) Z8 _- i
  forwarded to the other side of the proxy.( ]) _  Q  v- u7 b6 x

8 O7 H3 L5 H2 G) |  Please note that this has nothing to do with HTTP keep-alive.
; m/ N5 @; T  t' V. e
- a4 D) R- G, r; ?6 `$ W) I( ^  Using option "tcpka" enables the emission of TCP keep-alive probes on both
) |2 r4 z0 z  l2 \3 L  the client and server sides of a connection. Note that this is meaningful
+ B8 N0 p& ~# Y. y  only in "defaults" or "listen" sections. If this option is used in a, C1 E! ]! a" U* V& f
  frontend, only the client side will get keep-alives, and if this option is1 C$ d4 _( k$ K6 d6 h5 C
  used in a backend, only the server side will get keep-alives. For this
8 ^' c8 d( ~7 v8 f* o9 k  reason, it is strongly recommended to explicitly use "option clitcpka" and
- V' b1 Z4 \4 a0 v5 r( E  "option srvtcpka" when the configuration is split between frontends and
/ e$ D& }. M+ r; q5 I: B  Y8 B  backends.9 U( y! g5 [! _( V1 c! U  t
( }$ s$ r9 z/ X( m  }0 P4 [
  See also : "option clitcpka", "option srvtcpka"$ V9 a8 k1 S$ b: M' O
& k6 K! S1 V1 D) o1 C' h# ?% ]

$ u& {0 r" w) k: poption tcplog* Y- n$ u* ]( k+ x* w
  Enable advanced logging of TCP connections with session state and timers( m8 b) ^2 H9 s- z+ t
  May be used in sections :   defaults | frontend | listen | backend1 b; ~+ T/ k6 Y/ S* k- s/ J, ?9 e
                                 yes   |    yes   |   yes  |   yes. z9 D$ r! k% j
  Arguments : none+ H7 Y; g# w+ I3 h/ {3 I: S

% I! h5 g( B- p3 W  By default, the log output format is very poor, as it only contains the
5 x6 O1 r" E% k3 k; d( _7 ~  e  source and destination addresses, and the instance name. By specifying
! T9 [( G2 |6 t4 z$ h3 l  "option tcplog", each log line turns into a much richer format including, but
& E; Q; {, x! t( ]; h1 b) ]  not limited to, the connection timers, the session status, the connections- p3 ~' b. m: Q2 ]4 l  ]$ A
  numbers, the frontend, backend and server name, and of course the source" \3 N' A' S* H
  address and ports. This option is useful for pure TCP proxies in order to5 S0 V" _: I% o! ]
  find which of the client or server disconnects or times out. For normal HTTP+ e- i% P* t! o7 P% T' @
  proxies, it's better to use "option httplog" which is even more complete.1 S" i! x9 E7 k( E
( h( a( }* @. x* e' i
  This option may be set either in the frontend or the backend.
9 B* k* ^+ O: \5 y, S* L1 }
7 i, T9 D7 ?8 H+ V  See also :  "option httplog", and section 8 about logging.. a7 W& `. F) }- a4 E) u" `, b

0 X( F2 f1 C! g) l( B" R6 W! d- {) L3 h2 ]% i( m
option transparent
; ^/ Y) a/ s+ }4 f$ F  l% Mno option transparent0 c! ]! b  B6 P5 T% F$ m1 J/ k: }
  Enable client-side transparent proxying
: z6 q& v+ _  S9 E  May be used in sections :   defaults | frontend | listen | backend
' Y; m$ }* c# d5 b( {                                 yes   |    no    |   yes  |   yes8 l# O* g/ j' S
  Arguments : none# \' \4 h+ t9 C- M7 m7 ~
# Y5 j$ Z& i3 [
  This option was introduced in order to provide layer 7 persistence to layer 3  J" a6 Y0 u5 q( S+ x
  load balancers. The idea is to use the OS's ability to redirect an incoming/ G) K/ Y9 l2 w1 l- W" y
  connection for a remote address to a local process (here HAProxy), and let
/ L( W- Y% g2 L/ r  this process know what address was initially requested. When this option is
( b+ F! Y! J; s8 Y& l7 i  used, sessions without cookies will be forwarded to the original destination9 E4 F% g" S5 I- y; g
  IP address of the incoming request (which should match that of another
0 Z: ?9 n% l9 K* g  equipment), while requests with cookies will still be forwarded to the
0 t) s0 R* p, i$ z  appropriate server.9 K+ F, [. o, [

0 ^! z9 U0 K1 |+ j* U  C* z3 D  Note that contrary to a common belief, this option does NOT make HAProxy1 i, M4 {8 v/ @
  present the client's IP to the server when establishing the connection.
5 E6 g! m' G' j# a  x: w0 V/ u3 k6 g0 C
  See also: the "usesrc" argument of the "source" keyword, and the
5 L; V! V0 Y: M$ b; J! d* U2 H            "transparent" option of the "bind" keyword.
4 k) j% y7 r% T1 T
+ ]4 Z; P" ]& b9 p- T
; V) h+ J% p2 @persist rdp-cookie
( C8 ~( J8 h6 U- xpersist rdp-cookie(name)
$ @# O2 ^0 U, C, j: J  Enable RDP cookie-based persistence
. u; L6 w# G- F  May be used in sections :   defaults | frontend | listen | backend- d! f7 V# ?4 p: ]3 a
                                 yes   |    no    |   yes  |   yes# E  ?0 G- Z5 C+ M
  Arguments :9 M, X8 ?4 n+ T6 x; \8 M
    <name>    is the optional name of the RDP cookie to check. If omitted, the) k! r: Y( K1 c7 n
              default cookie name "msts" will be used. There currently is no, T- C& x5 p% u* W
              valid reason to change this name.
! N6 k+ _. v6 i) d# `8 J# N+ }& O5 i) Y' p, \( ?1 [, r2 d
  This statement enables persistence based on an RDP cookie. The RDP cookie
: w5 |- O/ ~, J9 P2 u" U  contains all information required to find the server in the list of known
% P. `! U* B8 ]5 t6 T- w  servers. So when this option is set in the backend, the request is analysed" x# n& F2 ]) r/ ~7 q) O
  and if an RDP cookie is found, it is decoded. If it matches a known server
3 ^2 e6 `# @! A  e8 i+ {% u0 l$ _  which is still UP (or if "option persist" is set), then the connection is
3 E. M9 s1 Q- ^- s3 ~9 g  forwarded to this server.
# R* H! O4 M) n, u- U" e2 G# \  H% ?+ H; x
  Note that this only makes sense in a TCP backend, but for this to work, the
4 j6 N% {8 M+ d# L; Y/ ^' \  frontend must have waited long enough to ensure that an RDP cookie is present
/ y; W  M- o$ ]# ~  in the request buffer. This is the same requirement as with the "rdp-cookie"! T7 K. G0 [1 [  n7 P) c
  load-balancing method. Thus it is highly recommended to put all statements in* e0 K& [5 n1 n" v" ^
  a single "listen" section.
+ a+ X* V9 C. o4 N# N& G, n6 j$ v! K
  Also, it is important to understand that the terminal server will emit this
6 Q# R7 N  P  Z+ x  RDP cookie only if it is configured for "token redirection mode", which means7 x' A$ v; n+ E1 }" n0 N
  that the "IP address redirection" option is disabled.
2 U$ T  d) F7 v0 L  k0 T6 s$ e
9 \* T5 p3 {! g; g! W3 q  t  Example :
: v1 |  L. [: h- R9 W        listen tse-farm
" T2 V: `$ C- w- u3 i" @            bind :3389
, S& [& I( x+ A) R! B            # wait up to 5s for an RDP cookie in the request
3 h- Z9 I8 i+ `4 l/ R            tcp-request inspect-delay 5s) C( G! U( L2 B6 g& u
            tcp-request content accept if RDP_COOKIE7 F4 t0 S. d' H
            # apply RDP cookie persistence. u5 I- F; ~: F1 S
            persist rdp-cookie" R/ p. @* V5 s6 y( r% V4 L
            # if server is unknown, let's balance on the same cookie.( I6 p; N6 p, G3 E
            # alternatively, "balance leastconn" may be useful too.
* ~6 o, l- k: m1 B            balance rdp-cookie: i. a' Z% h) S* a( F) v  }# h1 M- H
            server srv1 1.1.1.1:3389
; Q+ }  d6 U' }- w5 i            server srv2 1.1.1.2:3389
9 o* s, d" z) D. f9 ^* S% B$ @/ f) p& J  y5 t% p7 j) N
  See also : "balance rdp-cookie", "tcp-request" and the "req_rdp_cookie" ACL.. u9 T! Q- H/ W5 r8 `" G0 p
3 l6 }' f7 D1 \

2 F9 A6 J4 c  j* irate-limit sessions <rate>
$ @9 e  M& H( U5 ^: v$ @: @7 f  Set a limit on the number of new sessions accepted per second on a frontend# o) X0 f3 l5 S, s1 `) n0 O$ J
  May be used in sections :   defaults | frontend | listen | backend0 z/ j9 s6 E! c8 W6 @7 h
                                 yes   |    yes   |   yes  |   no
( i1 Z; b( e6 V( `6 P- I" Y6 X  Arguments :% c. r( O6 j' e# D
    <rate>    The <rate> parameter is an integer designating the maximum number
/ m2 G, M: B  [' Y) Z& w" |              of new sessions per second to accept on the frontend.
% I+ `% q/ x" c" R& D$ N, |
# y% i2 S) I. R  B( b& `  When the frontend reaches the specified number of new sessions per second, it
5 _5 M# n5 x- X* |9 r$ m) o  stops accepting new connections until the rate drops below the limit again.
/ I; ~" C& t7 C9 h$ U8 U9 G  During this time, the pending sessions will be kept in the socket's backlog  ?( V* y% H/ W/ T
  (in system buffers) and haproxy will not even be aware that sessions are* C8 \) Q( M5 z6 j
  pending. When applying very low limit on a highly loaded service, it may make
- X5 e+ E9 H8 b: U' m' O  sense to increase the socket's backlog using the "backlog" keyword.
; M# p1 F$ ]# Z; j3 M- `  q. F0 L
  This feature is particularly efficient at blocking connection-based attacks
8 L- G: t7 \5 v* G  or service abuse on fragile servers. Since the session rate is measured every
) V) p2 O1 t+ \3 U. F/ Q# a  millisecond, it is extremely accurate. Also, the limit applies immediately,
+ x6 \  O2 j9 l7 k) w  no delay is needed at all to detect the threshold.
# F- T  I. ^+ {9 E- |
* Q( |2 A( S' X  Example : limit the connection rate on SMTP to 10 per second max
) {5 g2 I5 V5 N        listen smtp# t% B8 k: F$ h. e8 |
            mode tcp
% E+ R2 D1 Y! ^            bind :25
: x# Z6 F- v  b8 x' |2 B" f, }            rate-limit sessions 10
( U% M: m3 K( h  n/ L# D$ b            server smtp1 127.0.0.1:1025
3 E6 T& w5 n: F& j+ A$ Q) ~, G
/ n6 I( u' }2 E  X1 t) h! P  Note : when the maximum rate is reached, the frontend's status appears as, l9 \$ ^  ]$ E8 N9 ]6 j# k  R
         "FULL" in the statistics, exactly as when it is saturated.) j* r  ~7 A7 l3 A; p
) U$ x$ O6 O" ]$ m- X
  See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion./ S/ q, w7 W, U( t' h; V! m! F# _

& q4 t9 G1 ]  d3 y* |$ _
7 r4 u# U3 G0 o- Predirect location <loc> [code <code>] <option> [{if | unless} <condition>]: R8 f5 e6 L2 O( C5 ~+ Y
redirect prefix   <pfx> [code <code>] <option> [{if | unless} <condition>]$ q/ D: a4 h9 W/ u2 D
redirect scheme   <sch> [code <code>] <option> [{if | unless} <condition>]
! D- i6 T; n( e8 T/ t  Return an HTTP redirection if/unless a condition is matched7 p: |2 h. I9 p$ o
  May be used in sections :   defaults | frontend | listen | backend% d3 G" e5 z3 W. S2 E+ t
                                 no    |    yes   |   yes  |   yes
4 ~, T( s2 \) s5 X; P8 V, l+ j& m& J1 T; ^
  If/unless the condition is matched, the HTTP request will lead to a redirect% N1 P. ~9 z5 Z, z2 p+ T2 i
  response. If no condition is specified, the redirect applies unconditionally.. `( k5 `6 x6 E' ]1 L5 d: g6 S# _
( c/ O/ w" V3 `! {& Z
  Arguments :
! f. a, l, S; d1 Q- S7 T    <loc>     With "redirect location", the exact value in <loc> is placed into; ]9 Y4 E: `) a" u! q2 ~
              the HTTP "Location" header.: x  t( R. A& F8 l
3 Z$ K6 M$ N8 `
    <pfx>     With "redirect prefix", the "Location" header is built from the
- {6 w% P& i6 ]/ m              concatenation of <pfx> and the complete URI path, including the* o* m. p, C$ E9 E
              query string, unless the "drop-query" option is specified (see
6 ~, X3 n6 R) b% _6 G              below). As a special case, if <pfx> equals exactly "/", then+ g, g) {& V: h! Z: ~
              nothing is inserted before the original URI. It allows one to
/ S4 L5 s  ]  n2 c              redirect to the same URL (for instance, to insert a cookie).
3 M2 v1 s; x5 t; n4 d- M5 l9 |
+ e1 a5 s- m8 n2 H5 X  c    <sch>     With "redirect scheme", then the "Location" header is built by
1 |/ v- P  [6 @7 [              concatenating <sch> with "://" then the first occurrence of the" W, C/ P( ~4 t+ M, G8 E
              "Host" header, and then the URI path, including the query string
. _# C  _! L' b- @9 l9 T4 r& |              unless the "drop-query" option is specified (see below). If no* w1 Q% Q7 }( D  _& S1 c/ T
              path is found or if the path is "*", then "/" is used instead. If! B8 y# I  @, O  I- L0 D) z
              no "Host" header is found, then an empty host component will be
9 l4 }/ o6 `/ H! ~  _              returned, which most recent browsers interprete as redirecting to% ?! k; R$ W4 `6 E% t! e/ c9 a
              the same host. This directive is mostly used to redirect HTTP to1 L9 H( |" ^3 [
              HTTPS.$ b+ s/ y8 [, p) H
6 Y$ |: ~4 S5 G- ~$ H. j1 ?
    <code>    The code is optional. It indicates which type of HTTP redirection# L& z, d, j2 q% j1 }
              is desired. Only codes 301, 302, 303, 307 and 308 are supported,
& W# U* k- q" P, _) @6 C' I              with 302 used by default if no code is specified. 301 means. H2 |, e% V% T  v: b  d% i
              "Moved permanently", and a browser may cache the Location. 302
5 P3 R1 ^) s( J9 {$ n( ]" i1 E( l              means "Moved temporarily" and means that the browser should not; e( f6 M7 t3 L2 g" h( {
              cache the redirection. 303 is equivalent to 302 except that the
5 T/ ?( y9 m# H* I! L* L  a              browser will fetch the location with a GET method. 307 is just/ o  f4 [( T: T+ `9 ~) k3 F
              like 302 but makes it clear that the same method must be reused.
8 x  Y+ a$ u: a$ \8 h              Likewise, 308 replaces 301 if the same method must be used.5 @7 {8 w5 d2 t

( z! l0 \$ N' _    <option>  There are several options which can be specified to adjust the
. B7 d' ~" R$ T  F3 n. C  S& ?              expected behaviour of a redirection :) j/ ?  Y' k0 c; {
7 j& {! I1 R( b$ ?1 B, j* Q
      - "drop-query"
( t! _2 V8 c* i# I, B1 B        When this keyword is used in a prefix-based redirection, then the$ H4 g6 j% `2 J; e+ q. E
        location will be set without any possible query-string, which is useful
" v4 F0 T7 h, C' U* l        for directing users to a non-secure page for instance. It has no effect
% O: h5 `1 z1 j) F  K        with a location-type redirect.! z/ t  B; Y2 ~0 F1 d8 U
$ h+ r& U4 q. z. K
      - "append-slash"4 I# h0 ~; b) J4 e- P1 w* o
        This keyword may be used in conjunction with "drop-query" to redirect9 F! }' f- S8 B( r
        users who use a URL not ending with a '/' to the same one with the '/'.% ^( D, k3 r) {4 M' ]
        It can be useful to ensure that search engines will only see one URL.
" Z: h  ^( C7 F0 b* m6 {# `8 L        For this, a return code 301 is preferred.2 s2 f, ?2 O7 ~1 `
) V0 _) Y% M* `' a1 _" Z
      - "set-cookie NAME[=value]"( a1 Z2 w) i! i3 t2 a- G% ?  A
        A "Set-Cookie" header will be added with NAME (and optionally "=value")1 B: Q1 e% S8 C3 L
        to the response. This is sometimes used to indicate that a user has
2 l9 D2 V3 y* O& c6 M+ E        been seen, for instance to protect against some types of DoS. No other
+ c+ Y) u  L8 K- _3 i        cookie option is added, so the cookie will be a session cookie. Note
% B: _4 S; M6 c        that for a browser, a sole cookie name without an equal sign is: n" f  X6 B. C. n3 Z3 P
        different from a cookie with an equal sign.
+ p3 u2 K" F9 D9 h6 P. M5 ]3 \4 r0 W' E0 H
      - "clear-cookie NAME[=]"5 Q# S' L3 i+ h/ x4 o# t
        A "Set-Cookie" header will be added with NAME (and optionally "="), but0 B$ N" l" D2 V/ W; t
        with the "Max-Age" attribute set to zero. This will tell the browser to- @" d- t" U* R3 k' ?
        delete this cookie. It is useful for instance on logout pages. It is  s0 t, [9 K! b& Z% H( Y$ J; v, F
        important to note that clearing the cookie "NAME" will not remove a
( R8 ]0 X) F% ]  ~, U6 W        cookie set with "NAME=value". You have to clear the cookie "NAME=" for) g' t2 K. I  L
        that, because the browser makes the difference.. {, E% A* ^5 p: n

8 p+ W" R$ R' ]4 ~$ n- v( o  Example: move the login URL only to HTTPS.* X7 x. r. O: Y/ m8 w
        acl clear      dst_port  80
, u% Y) d! ?, S( W9 s( n        acl secure     dst_port  8080
7 Z: L5 @( B) _% {* w( O        acl login_page url_beg   /login
  \- m6 Y4 `+ \* H+ s# K        acl logout     url_beg   /logout
/ t; x! u( Q% E9 i! N5 a- t        acl uid_given  url_reg   /login?userid=[^&]+
3 C% |9 j% m% R& z; C5 I/ G+ J        acl cookie_set hdr_sub(cookie) SEEN=1% |% l8 }( s( w" x. ?2 A3 t
* M  f" J0 O' {# D! f3 X+ ^
        redirect prefix   https://mysite.com set-cookie SEEN=1 if !cookie_set! M3 v$ d; V( l/ t6 U" i
        redirect prefix   https://mysite.com           if login_page !secure
4 T( {- T0 @, Y' m5 }) ~3 e' e        redirect prefix   http://mysite.com drop-query if login_page !uid_given- r1 P" Z3 w& i* Y* v/ x
        redirect location http://mysite.com/           if !login_page secure
5 b; M) _0 m* A- o4 ^/ X  l        redirect location / clear-cookie USERID=       if logout4 H4 O( i: ^  u- c% s1 Q/ f

, G8 u( m' f9 |$ W1 Q' W  Example: send redirects for request for articles without a '/'.* v* W+ M7 k( N3 E
        acl missing_slash path_reg ^/article/[^/]*$
8 q7 |6 h8 S) Q$ B$ W; }( p        redirect code 301 prefix / drop-query append-slash if missing_slash
  t5 i7 L) f7 _% m3 w$ {' P
3 g$ q. ]- Z- w& K  Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.# m' i3 A/ p% w6 Z
        redirect scheme https if !{ is_ssl }/ N8 W# I# D& ^; J3 n0 u

* V' Z% o$ V. q; [0 V7 f) x  See section 7 about ACL usage.
+ M) K/ a* b! S+ t$ c! a
5 T, \2 P' ^" K: D. C$ K1 j0 V; _) s: q7 z' S/ e7 S
redisp (deprecated)+ d4 X/ l8 E8 c; @1 j6 C4 i
redispatch (deprecated)
) c. `& V% ~8 o5 Z& b* i. i  Enable or disable session redistribution in case of connection failure& N% _' ^" [6 p* f% g' U' `& O3 Y7 O
  May be used in sections:    defaults | frontend | listen | backend
3 t8 |" u$ F2 ~/ v3 y( r$ c                                 yes   |    no    |   yes  |   yes7 S( C$ T  X5 v3 c( z' G
  Arguments : none, y) v* z7 B9 y( O( `% q8 M0 X8 t
; j/ L, |) A* L/ @
  In HTTP mode, if a server designated by a cookie is down, clients may
! `5 K4 c/ [3 p8 y' N7 b* y  definitely stick to it because they cannot flush the cookie, so they will not" x7 e% z$ k* s0 a/ w7 n
  be able to access the service anymore./ S' R" g" m! I* g4 S/ n& Q3 A, h8 k

5 o5 k, j- E: U1 z  Specifying "redispatch" will allow the proxy to break their persistence and7 j2 f0 `4 N- n1 G9 m5 {1 n5 t
  redistribute them to a working server.
' u/ m/ u# w* G9 `& B
, b+ I1 }; |7 p8 }  It also allows to retry last connection to another server in case of multiple
# y. ]8 @  K7 P0 ?' C  connection failures. Of course, it requires having "retries" set to a nonzero
& ]  M) n- U: ]- @/ U  value.
, p) n9 {. {3 ~& z$ S) m6 {. F' E- ]% R) f
  This form is deprecated, do not use it in any new configuration, use the new
" O* v5 S" J$ j$ L1 W  "option redispatch" instead.4 l  U8 I8 w- P3 Q; m7 K: B

6 n3 ?: g. d5 n/ h) @, K6 o- x4 _# j  See also : "option redispatch"& q! Q6 e- O' K5 i/ O
* I8 h! }- Q8 ]: F: g" s* }

5 Z8 |/ A& B  w, D* ]reqadd  <string> [{if | unless} <cond>]
; ^: D4 P5 L: [- `  Add a header at the end of the HTTP request9 z3 [7 v% M% D, ]) v
  May be used in sections :   defaults | frontend | listen | backend% v* J. m! t% _* Z7 W/ v
                                 no    |    yes   |   yes  |   yes
( y- p* l, ^5 r  Arguments :
, y" i& y: \( e# b) ]* v    <string>  is the complete line to be added. Any space or known delimiter
7 }* o5 g8 r# x* ^, ]; A              must be escaped using a backslash ('\'). Please refer to section' U* e+ m/ ]* F8 m
              6 about HTTP header manipulation for more information.
2 ]$ M, q5 z& j* E' L
7 }8 [5 E( G4 ?9 X    <cond>    is an optional matching condition built from ACLs. It makes it
. `! W/ A% g5 w3 W. I! r+ o1 t              possible to ignore this rule when other conditions are not met.
6 {$ s6 K1 q+ R. F: e8 c
# O8 h3 ^8 u# v0 U0 R% k" s4 V# O8 f( y  A new line consisting in <string> followed by a line feed will be added after
  N2 [; w- }1 W: Y  O+ O  the last header of an HTTP request.
7 M- D( _8 ?1 W
- @# c2 i' h- G9 P  Header transformations only apply to traffic which passes through HAProxy,
  q0 [  U% P- m6 f- o8 a4 a) i  and not to traffic generated by HAProxy, such as health-checks or error7 G8 q' J' s3 x; |, y9 q8 p+ }) G
  responses.
8 K! A  U4 J' M/ r4 |( X' f2 L
- r1 A& o# ?( c4 z1 x, i. w  Example : add "X-Proto: SSL" to requests coming via port 817 {# c( v5 R1 \0 }2 I  W
     acl is-ssl  dst_port       81/ H+ B' P9 a6 T1 E
     reqadd      X-Proto:\ SSL  if is-ssl
( J# |! K4 x# l  ?$ S$ M
' t& P) Z/ s7 ]! K' w+ ~  See also: "rspadd", section 6 about HTTP header manipulation, and section 7) l4 E) Z6 d: }% e8 P9 t
            about ACLs.
, F: W8 J: @0 M0 H  a; u2 T5 h

" C1 l5 c4 R. S1 x" R- w$ P0 lreqallow  <search> [{if | unless} <cond>]
3 g  `# x6 r6 M# H# Y/ K: sreqiallow <search> [{if | unless} <cond>] (ignore case)
9 j' V' G8 T5 X7 ?# V  p0 |  Definitely allow an HTTP request if a line matches a regular expression" T( \" t0 b# F& j2 R
  May be used in sections :   defaults | frontend | listen | backend
/ J* W9 o+ d9 ]- F5 W0 g( {/ D5 B                                 no    |    yes   |   yes  |   yes( _: A7 Z5 O+ k
  Arguments :" o4 y+ x& [8 `, u/ L( d% z* |
    <search>  is the regular expression applied to HTTP headers and to the2 L$ Z6 c( V& x, |; S# A5 U
              request line. This is an extended regular expression. Parenthesis
9 a7 `4 k2 }6 J7 H7 F% y              grouping is supported and no preliminary backslash is required.
- |, o3 h/ j" `. r% |              Any space or known delimiter must be escaped using a backslash
1 w( {! P, Y  G5 Q& J2 l2 t$ _  `5 P              ('\'). The pattern applies to a full line at a time. The. E( t- T+ f4 X+ a: \, B
              "reqallow" keyword strictly matches case while "reqiallow". ]$ u. Y+ f2 m- r& e. _7 V
              ignores case.8 i) Y. h' E' R/ Q6 e( X# e2 R' S& ]
% u; g4 m- G  h, k! Y- v
    <cond>    is an optional matching condition built from ACLs. It makes it
3 l8 h4 v- |5 X, ?# ^              possible to ignore this rule when other conditions are not met., |+ Q+ y7 W: v5 |! L
, l7 W, v2 g7 j4 G# B  l5 z
  A request containing any line which matches extended regular expression; B9 N, l" n, U4 ]
  <search> will mark the request as allowed, even if any later test would4 F/ n/ Z* g2 W! f, n- {. {; R. f
  result in a deny. The test applies both to the request line and to request
1 P/ O+ N" Y8 p; ~/ U2 M  headers. Keep in mind that URLs in request line are case-sensitive while4 j- x" u5 q  q" \
  header names are not.
+ Z0 x% j0 B& N* y% D: `/ g
8 D  Q- U2 N" G7 c; Z  It is easier, faster and more powerful to use ACLs to write access policies.
4 n( E. ^* u2 i/ Y% _$ D5 [1 ^; H0 u  Reqdeny, reqallow and reqpass should be avoided in new designs.' K- @7 q& `& b0 T$ O
$ t0 W& ]- u0 ]4 x5 |1 m
  Example :# _" i+ j+ c+ {3 E/ [2 V9 z2 B' y* ^
     # allow www.* but refuse *.local
3 s( F* t# Y0 U2 r  U0 G' z     reqiallow ^Host:\ www\.
  w9 i# c8 I8 S( v* Q: d$ Y     reqideny  ^Host:\ .*\.local+ r- B, e* j" U; R% x

. M: M1 u' ^6 Q; J. C/ Y2 w  See also: "reqdeny", "block", section 6 about HTTP header manipulation, and/ Q, I! ]0 r( j% F% r. \! n, _
            section 7 about ACLs.& ]" o5 |6 ~% i! R8 [2 \& c# t0 |
1 R: C1 b* _$ v* R; _4 b9 j
6 U4 u- W9 I: t# Q
reqdel  <search> [{if | unless} <cond>]
" ]; n  \8 `6 G- k/ {+ Rreqidel <search> [{if | unless} <cond>]  (ignore case)
' n' q, [& r1 y4 ]  C  Delete all headers matching a regular expression in an HTTP request8 {# |( h1 N  L9 ^* e& _) H) g5 Q. M; @
  May be used in sections :   defaults | frontend | listen | backend
7 O7 b7 F$ b. O( p! H+ k                                 no    |    yes   |   yes  |   yes4 o( _! y5 M7 i* G! }5 T% ~1 A$ l
  Arguments :
1 H1 W( c3 u* u) m3 R    <search>  is the regular expression applied to HTTP headers and to the$ `8 R, K2 l% q. a' _' p
              request line. This is an extended regular expression. Parenthesis4 b/ m  K9 O6 P5 m# O( t
              grouping is supported and no preliminary backslash is required.
, d) k& Q4 Y% m: g( Y              Any space or known delimiter must be escaped using a backslash# X; i' [% L" r+ M; v' @0 R: z
              ('\'). The pattern applies to a full line at a time. The "reqdel"
# V2 x0 Y7 P; J1 R  f9 o! l. d- C              keyword strictly matches case while "reqidel" ignores case.
; Z. ?# h5 N, S, B. S7 y; i  ]  f' a  q$ ^$ Z" e9 T) g4 S. ~
    <cond>    is an optional matching condition built from ACLs. It makes it/ N" t/ r; _" a# y
              possible to ignore this rule when other conditions are not met.7 {5 U" @% U+ d7 v4 w6 J" e

" y- q+ A; V- w* J  Any header line matching extended regular expression <search> in the request
* P% @3 S; c+ q4 i; F" j& l% d  will be completely deleted. Most common use of this is to remove unwanted
5 s( F4 L( h$ O# U/ F  and/or dangerous headers or cookies from a request before passing it to the9 D3 f8 Y% G' A0 m  O5 O5 x. ?
  next servers.
) Z5 Y2 |5 x7 ?" N& C
4 y; h8 }7 E' a# p/ m& I: z: i  Header transformations only apply to traffic which passes through HAProxy,
9 ?4 [1 l- P3 ?8 k; Y+ \5 ]  and not to traffic generated by HAProxy, such as health-checks or error+ C! u2 R3 p8 {' `' O' G
  responses. Keep in mind that header names are not case-sensitive.0 Y/ e6 U  a) X. k

1 @. l8 E' f9 f3 z# r4 ~2 q% E  Example :2 p7 W% q( W! z, I! z( T& ?: {
     # remove X-Forwarded-For header and SERVER cookie& w! o6 q8 g/ S6 ?2 D
     reqidel ^X-Forwarded-For:.*
+ S- ?( \/ I5 J+ m! a+ Y     reqidel ^Cookie:.*SERVER=
4 q+ V- p) S& l$ y+ s4 \
; M' ]% I2 ^# f  `/ q& z3 b7 b5 b. j* W% m  See also: "reqadd", "reqrep", "rspdel", section 6 about HTTP header0 A  h8 [  f2 d9 ^2 C# R+ G+ X( B
            manipulation, and section 7 about ACLs.( r0 Y; C& E. Z. T1 o

" L, c+ I- c2 F5 u9 ]' d0 r4 z) T, @0 p3 B" |0 ?8 J  e
reqdeny  <search> [{if | unless} <cond>]
! M+ Z; [8 P# B% E- I1 Rreqideny <search> [{if | unless} <cond>]  (ignore case)
5 N; G# d& K" V" u* U& M8 o  Deny an HTTP request if a line matches a regular expression  F# R" ]  w; P# B0 D! W
  May be used in sections :   defaults | frontend | listen | backend- `' v2 ^" i  @1 i- ]5 Q6 @5 g% T
                                 no    |    yes   |   yes  |   yes* O0 w/ T: r& R  Q9 A' E) [, x
  Arguments :
; q8 \9 t& t. y' F; d; }    <search>  is the regular expression applied to HTTP headers and to the
9 }  f' s9 J4 E0 n              request line. This is an extended regular expression. Parenthesis7 m( a4 O1 }+ E9 x7 V
              grouping is supported and no preliminary backslash is required.
" G3 {- Q! ^* d7 u              Any space or known delimiter must be escaped using a backslash
; [+ o7 v) s, W  D. u  z; L              ('\'). The pattern applies to a full line at a time. The
4 r& c1 D4 `' y9 X              "reqdeny" keyword strictly matches case while "reqideny" ignores
: a! V% K. \  L3 |- H              case.. @0 N! x4 h( \! t; S

1 S, b; g- X0 q: I    <cond>    is an optional matching condition built from ACLs. It makes it
) i9 x4 c" {; I              possible to ignore this rule when other conditions are not met.
( b* ^6 `( D' j" I
9 P( D: V/ B5 p. r  A request containing any line which matches extended regular expression
8 y8 c% p! r2 ?7 R5 ~4 A7 i  <search> will mark the request as denied, even if any later test would' v* c0 B5 H( }& S5 I' S
  result in an allow. The test applies both to the request line and to request
; {; k6 @, O) P# f  headers. Keep in mind that URLs in request line are case-sensitive while
# }/ G3 k. _( E8 f; N  header names are not.
$ A1 j- J  M; c( ^# H+ O2 h4 C6 C
8 v. L+ w% c6 H; D  A denied request will generate an "HTTP 403 forbidden" response once the7 E; C3 m4 h* J  R0 K8 v, n2 w% Q, w
  complete request has been parsed. This is consistent with what is practiced
3 n% y5 u, B) n6 G6 m  using ACLs.
( \( C5 `& V9 _' c
* s/ _) R4 z7 v& ~( }6 A  It is easier, faster and more powerful to use ACLs to write access policies., o5 d- Q1 u  o7 ~; z. i
  Reqdeny, reqallow and reqpass should be avoided in new designs.8 T: ?5 A8 y6 x, a' [6 K6 n$ \

# i) l$ B& J. m8 f* Z; H  Example :' ^) m+ o# D2 m! h
     # refuse *.local, then allow www.*3 [& C$ y+ n  Z
     reqideny  ^Host:\ .*\.local% a% R3 Y- s: ^  Z' f
     reqiallow ^Host:\ www\." A: s; D1 N6 O! E8 w

* H! M+ z- T6 A' ]  See also: "reqallow", "rspdeny", "block", section 6 about HTTP header7 ?5 N7 s0 @# ^& ^
            manipulation, and section 7 about ACLs.$ n9 J8 O, n1 ?* U; g- w% y! g& S

8 E* r& R, O& d" r' A0 e' C
! d+ W; X* T* Zreqpass  <search> [{if | unless} <cond>]: C" l; [) C: [% ?
reqipass <search> [{if | unless} <cond>]  (ignore case)( Z- e" c% n' v3 x8 ~0 p$ S- n! B
  Ignore any HTTP request line matching a regular expression in next rules
- m6 a2 w. @) \7 w/ p  May be used in sections :   defaults | frontend | listen | backend- n! I/ {9 p4 y3 M& p
                                 no    |    yes   |   yes  |   yes; D8 R. ~5 z- w: C8 `
  Arguments :
& x8 b/ S0 M4 D, b5 u; J5 B" K0 O3 B9 B    <search>  is the regular expression applied to HTTP headers and to the; V: r! z% n% y! [/ F/ m- k
              request line. This is an extended regular expression. Parenthesis/ ^/ O( ~+ N3 C& P' F" x8 F4 C
              grouping is supported and no preliminary backslash is required.$ a6 f4 g6 ~7 e1 a* k
              Any space or known delimiter must be escaped using a backslash- Z) F6 j* S& @) ^, B3 f4 s- X; e
              ('\'). The pattern applies to a full line at a time. The4 C% l/ ?, C4 l  W$ i  B) H8 d
              "reqpass" keyword strictly matches case while "reqipass" ignores
6 y7 g6 ~. B& j$ I: Q. V" G              case.
$ i, V/ Q* R: O  v8 R6 @/ y* O3 v9 B: K3 g7 n/ [; ^
    <cond>    is an optional matching condition built from ACLs. It makes it
5 i8 [4 h4 z4 B% n              possible to ignore this rule when other conditions are not met.
8 Z' v9 m+ J, x4 P. ]" _  k6 F4 l3 m+ _& k/ F$ t
  A request containing any line which matches extended regular expression
5 W- |+ R1 D. P+ n- ^1 M* C  <search> will skip next rules, without assigning any deny or allow verdict.
4 I+ z: N  W) n9 @% x  The test applies both to the request line and to request headers. Keep in
/ V! m0 Z+ S+ r, u2 }4 W  mind that URLs in request line are case-sensitive while header names are not.: _0 G6 i3 B* R4 _' ^  j4 a/ V9 E

; ?8 T" I1 ^( G) A* `4 [3 }  It is easier, faster and more powerful to use ACLs to write access policies.
( G7 n( A1 e) R& J, z" a6 |  Reqdeny, reqallow and reqpass should be avoided in new designs.0 f3 z* q( c8 g5 J) |/ l; q
& H, w9 D" K! \7 B7 N) B& V* e/ u
  Example :
8 i2 |" Y, f* H, \     # refuse *.local, then allow www.*, but ignore "www.private.local"
" l5 F. \9 H: U     reqipass  ^Host:\ www.private\.local8 [$ B$ d9 u* J5 R1 Q
     reqideny  ^Host:\ .*\.local# B! {; Z- H( K: y
     reqiallow ^Host:\ www\., ~7 s; @" a0 U

0 {# O* }! t, i5 `! o  See also: "reqallow", "reqdeny", "block", section 6 about HTTP header
& ]* A: C! R& t% X            manipulation, and section 7 about ACLs.; U5 }2 G- ~5 m; F

+ |4 i9 [5 H# ]2 t$ l3 B4 b7 `0 S
reqrep  <search> <string> [{if | unless} <cond>]% o2 `- I. S) b+ m
reqirep <search> <string> [{if | unless} <cond>]   (ignore case)  l) W% B: B! d0 V  E
  Replace a regular expression with a string in an HTTP request line# Z# p4 Z7 g! v# i8 _, a! f* q
  May be used in sections :   defaults | frontend | listen | backend
! {6 F& ]8 P* i# J/ J- C5 h3 Q. S                                 no    |    yes   |   yes  |   yes
$ R7 E. s* }  p0 Q4 ^1 r" d  T: s  Arguments :9 j8 F' K6 w0 I, f, r
    <search>  is the regular expression applied to HTTP headers and to the0 G0 A2 \5 M" v7 O; \, M9 z8 w
              request line. This is an extended regular expression. Parenthesis
, z; {8 D% g, z+ B5 z              grouping is supported and no preliminary backslash is required.4 D) K1 H6 c7 ~; e1 L7 Z5 d
              Any space or known delimiter must be escaped using a backslash
) `! ~) [, }4 P9 m  X3 ?% l              ('\'). The pattern applies to a full line at a time. The "reqrep"+ g. b4 {, [3 [6 f% W( v. S8 y0 z9 \
              keyword strictly matches case while "reqirep" ignores case.
7 ~$ ?# n" T, c0 N! X9 @. v: v" m0 u) O/ `( W
    <string>  is the complete line to be added. Any space or known delimiter# J+ }. o% z: s% V
              must be escaped using a backslash ('\'). References to matched# Q) X, b7 U* K; [
              pattern groups are possible using the common \N form, with N
6 ~5 Y" y& X5 A2 k              being a single digit between 0 and 9. Please refer to section2 W5 ]& i$ t! y; h2 Q
              6 about HTTP header manipulation for more information.
( h7 y! q; X+ c+ I0 s
/ P- m$ p! W. @2 \    <cond>    is an optional matching condition built from ACLs. It makes it9 g0 q0 y' M# O; n
              possible to ignore this rule when other conditions are not met." T8 I( {' b2 ~4 n. |# o( K! O3 \

4 x" p9 m1 F+ t! H# C- p& A4 y  Any line matching extended regular expression <search> in the request (both
* V5 k- N0 f. A, e  the request line and header lines) will be completely replaced with <string>.
" G8 ^% H& T  g. u" {  Most common use of this is to rewrite URLs or domain names in "Host" headers.1 r9 t5 b' ^/ m0 q
: A* U; \( Q% j5 [1 R+ b8 ^
  Header transformations only apply to traffic which passes through HAProxy,) v5 v) O9 J/ m7 p& m$ M
  and not to traffic generated by HAProxy, such as health-checks or error, E1 G8 y' n% ^  p  C+ w6 B/ X
  responses. Note that for increased readability, it is suggested to add enough
5 z& v% N# x% ^. C3 `5 T# x8 D  spaces between the request and the response. Keep in mind that URLs in
8 i$ q4 l8 m" S6 q  request line are case-sensitive while header names are not.' r% r: i0 P! [; P' F4 q
9 L* w' A# n) w; `
  Example :
) p  n! s( j2 `: R3 \9 n( ?     # replace "/static/" with "/" at the beginning of any request path.+ ?, j& X% r& p3 f3 c
     reqrep ^([^\ :]*)\ /static/(.*)     \1\ /\2
# r" s" _( L6 {6 l" ]1 @! A! T     # replace "www.mydomain.com" with "www" in the host name.4 }6 v! P& n2 K
     reqirep ^Host:\ www.mydomain.com   Host:\ www* c; K* l' P/ h1 g4 W

* k4 A* V9 @  Q0 k  See also: "reqadd", "reqdel", "rsprep", section 6 about HTTP header" r/ `) q7 E  k# G5 i
            manipulation, and section 7 about ACLs.
9 h0 h) h7 ^' H6 w/ @  c. w& K
( {% \! x& v* Q& Q/ a. l
& i; b3 c* s: E; S1 z9 I+ ]reqtarpit  <search> [{if | unless} <cond>]  H# F) [1 {5 w, u0 @2 n
reqitarpit <search> [{if | unless} <cond>]  (ignore case)
5 v. E2 a7 r6 s9 Z2 y  Tarpit an HTTP request containing a line matching a regular expression
* l& O8 F0 p  N7 b3 T( @  May be used in sections :   defaults | frontend | listen | backend+ }+ B# ?+ n2 o
                                 no    |    yes   |   yes  |   yes/ O. V- U8 L* A; P
  Arguments :
  h4 S, V' @2 o7 w& k: L! \    <search>  is the regular expression applied to HTTP headers and to the! q( x5 A0 }' M$ D
              request line. This is an extended regular expression. Parenthesis: c. \% y: [9 X9 t
              grouping is supported and no preliminary backslash is required.# i! r3 u: [5 v2 |) e
              Any space or known delimiter must be escaped using a backslash
7 z. s; }  W! s0 @% C, B1 {9 l              ('\'). The pattern applies to a full line at a time. The5 y, T2 F; V5 \( i( E& B; F. b
              "reqtarpit" keyword strictly matches case while "reqitarpit"- L  a' U3 l  c8 K3 {, Q7 T0 @
              ignores case.: q* @1 d6 c. }% g1 K) c
& m* o. x! ^: B% r( r1 ^% t6 f
    <cond>    is an optional matching condition built from ACLs. It makes it
, M# s7 ]3 M, V/ _6 ?' k" N, J5 N              possible to ignore this rule when other conditions are not met.
: a6 {! r. l- g( o
  ~. [# H' o+ b' i! _- t8 R  A request containing any line which matches extended regular expression
- [( k0 Y1 J: y2 U  <search> will be tarpitted, which means that it will connect to nowhere, will; h# D% P+ ~+ f3 D
  be kept open for a pre-defined time, then will return an HTTP error 500 so/ t' X6 x( B3 [6 Z0 M7 o
  that the attacker does not suspect it has been tarpitted. The status 500 will
7 l9 J) S4 V$ ~3 |  be reported in the logs, but the completion flags will indicate "PT". The
' D! V( G3 A  r$ s0 n% m& g  delay is defined by "timeout tarpit", or "timeout connect" if the former is* v0 f; J- a- ?' g; M9 o/ o4 d
  not set.
- Z2 U. C. Z. j  F
( V# Z5 S0 W; \% Z  The goal of the tarpit is to slow down robots attacking servers with& t1 [2 S1 _" k: D8 n
  identifiable requests. Many robots limit their outgoing number of connections
$ c$ M% c9 v5 I6 y  and stay connected waiting for a reply which can take several minutes to
& g* @+ H; P" p9 R+ Q  come. Depending on the environment and attack, it may be particularly9 L1 d& j' R3 I5 J' F# ?9 O/ \3 j
  efficient at reducing the load on the network and firewalls.: f9 V% L& u4 s( d

3 E* K2 E/ c, d1 S; i  Examples :
- m" o, y6 X; Y  @% w1 g% B     # ignore user-agents reporting any flavour of "Mozilla" or "MSIE", but
, J' T7 Z2 e& A& O2 @     # block all others.8 B/ ]+ c1 e& g) f, f8 E
     reqipass   ^User-Agent:\.*(Mozilla|MSIE)" o6 d& b" ~* C" `* ]/ L9 q
     reqitarpit ^User-Agent:
% t/ l8 l% s) W2 @# s7 [
, C/ w9 q) A0 V# q     # block bad guys+ A6 }0 k) [  g4 z9 x; Z
     acl badguys src 10.1.0.3 172.16.13.20/28$ Z% }% K1 j* ]! R
     reqitarpit . if badguys3 L$ }$ B% k& J- F9 H# E& ^/ q

" c1 g# c; ^. B: X; q$ w+ t  See also: "reqallow", "reqdeny", "reqpass", section 6 about HTTP header, T5 i# F6 w/ M& i6 o3 i" S* H
            manipulation, and section 7 about ACLs.
; A6 n! O7 V: V
' b5 ]: F4 U! W+ A! p! E* v; L9 S5 i# Y' ^% o
retries <value>
+ o. x0 N& K! \6 O4 _6 `& G  Set the number of retries to perform on a server after a connection failure
3 M$ K8 ^+ z8 k; e+ I9 w- j  May be used in sections:    defaults | frontend | listen | backend0 x: S/ f) W- Z0 \
                                 yes   |    no    |   yes  |   yes& X9 a) s" c3 ]8 ?+ m
  Arguments :
. k9 D: x% ~9 z    <value>   is the number of times a connection attempt should be retried on
, ]% ?0 V0 O" O) [2 A$ [) J              a server when a connection either is refused or times out. The% E8 w- s! a, J# g0 Y6 M# _: [
              default value is 3.8 ^1 D& T: u3 s+ c
$ |" b2 x" [3 S
  It is important to understand that this value applies to the number of8 }9 t3 l/ G- {* _; \% Y6 i/ h2 ^5 U
  connection attempts, not full requests. When a connection has effectively
# N+ k* w/ n# O  ]8 j/ Y0 ~" T  been established to a server, there will be no more retry.
* g8 m& y- ?$ }( H% w% d# v' j) V( c* D% O0 n; I& ]) F. F
  In order to avoid immediate reconnections to a server which is restarting,+ K3 ]) G. E6 @; A% U! r6 S
  a turn-around timer of 1 second is applied before a retry occurs.
# W" j. c# d+ U" g, h) l/ S8 D
. z& ^0 R. h' C( d3 V+ A  When "option redispatch" is set, the last retry may be performed on another% a# p5 }  {, Z" G8 b+ j
  server even if a cookie references a different server.5 J5 @2 X( K: ]5 ~( n- }1 v. {

- f3 t5 v) g$ J% S1 I+ p  See also : "option redispatch"& J3 c6 E+ t% Y" t
6 ], o6 E' n  G. T

1 ~) \  J: R/ K' T' i- Drspadd <string> [{if | unless} <cond>]- E3 ^$ f# d$ q
  Add a header at the end of the HTTP response
' g0 h, C( c" E2 R( V7 n  May be used in sections :   defaults | frontend | listen | backend
1 Z& `) ^- H- k- L- p% p                                 no    |    yes   |   yes  |   yes. J2 P, J  Z7 q" J4 q  R, a
  Arguments :
, ^* p2 x: ?5 I8 ?( Y. P    <string>  is the complete line to be added. Any space or known delimiter: i4 U* d+ d* H7 A
              must be escaped using a backslash ('\'). Please refer to section
2 `/ K. v, h" i0 s, T              6 about HTTP header manipulation for more information.
) T( J5 Z3 {' W: S1 b" ]) H/ D- [% ]% W: h! L1 ?, I* j
    <cond>    is an optional matching condition built from ACLs. It makes it3 h1 ~+ Y. d" F5 `# r' ?8 d6 q. s2 p
              possible to ignore this rule when other conditions are not met.
: C3 C9 E+ E; y' v3 k8 R
$ S9 ?& i! @; U, g5 a. M  A new line consisting in <string> followed by a line feed will be added after4 Q0 ]" H( P* i. [; A4 I
  the last header of an HTTP response.
7 k! o, K6 k' K" \. @: s0 o0 E  N  [: {, B4 j6 a% G
  Header transformations only apply to traffic which passes through HAProxy,
# O1 a$ n' `# @9 n0 P( u% z) K  and not to traffic generated by HAProxy, such as health-checks or error7 O1 g  {  |. n+ j; c2 t
  responses.7 C1 ^$ f/ U% ~

. P' c& C2 ?- F( t( Z' [  See also: "reqadd", section 6 about HTTP header manipulation, and section 74 w% O$ f0 Q) o) B* p5 Q% ?
            about ACLs.
0 F3 n2 `' w7 l( I: S/ n
" f# i* o, d2 P) G% r5 A  w
' R- l2 H& C8 r2 y* f4 Jrspdel  <search> [{if | unless} <cond>]6 _: z! H8 ]+ @* G/ Z6 D
rspidel <search> [{if | unless} <cond>]  (ignore case), b3 e- X0 a8 h+ |
  Delete all headers matching a regular expression in an HTTP response
- C+ X, c8 u/ f* e% n* W  May be used in sections :   defaults | frontend | listen | backend
$ _+ R$ \- i- I# T/ h                                 no    |    yes   |   yes  |   yes, \; m9 g& f) J+ N
  Arguments :( P/ V! w( `, r8 r
    <search>  is the regular expression applied to HTTP headers and to the
4 f1 f6 y& E% L4 A5 h. i              response line. This is an extended regular expression, so( y; B9 K5 j% |% s. g+ |2 Q3 \& M
              parenthesis grouping is supported and no preliminary backslash
4 \% D. k: V* @4 X6 z% h              is required. Any space or known delimiter must be escaped using* }( U7 i8 a* Q* z0 u
              a backslash ('\'). The pattern applies to a full line at a time.. x1 P* N; U& `
              The "rspdel" keyword strictly matches case while "rspidel"
) Y0 p* ]  h' J4 P7 E0 r' f              ignores case., x4 F  O7 C4 k; {- K$ L1 l( f3 U
& i0 r, I/ B$ `; D9 V
    <cond>    is an optional matching condition built from ACLs. It makes it7 h- @9 y, {9 n+ @  D1 h6 B: {
              possible to ignore this rule when other conditions are not met.# @. c% B0 q; f2 `/ G
( N# F& O  L( J6 w6 P6 I! ^! E
  Any header line matching extended regular expression <search> in the response
5 ]/ A: {2 I; S7 H1 M  will be completely deleted. Most common use of this is to remove unwanted
7 k% v  ]; ^0 T7 J8 K  and/or sensitive headers or cookies from a response before passing it to the0 b# C4 X- ?& c- \5 Y
  client.
& {8 F0 A# ?" V5 I' E" `" d# F
6 ~2 ^. T  k+ F. b8 H  Header transformations only apply to traffic which passes through HAProxy,
" a  ^. q& |" m3 @* Z9 ~! e  and not to traffic generated by HAProxy, such as health-checks or error
7 S* G' w: E( y  responses. Keep in mind that header names are not case-sensitive.
( G( J, V2 c% t4 v/ ^
! O* s) Z. U. O9 o" u) h  Example :. g; Z  n- ^* D
     # remove the Server header from responses
$ q1 j. I5 ^3 r+ J1 c. O% A* w8 n     reqidel ^Server:.*
# ]" x% z7 m0 j3 \' z3 E: s
& e) C3 E$ M2 m6 c7 ^0 \  See also: "rspadd", "rsprep", "reqdel", section 6 about HTTP header  n# d6 o& L  T$ R; j
            manipulation, and section 7 about ACLs.
/ S0 B8 _( G7 q" P* D& B' h% M% g
% X, ~' Q1 Q4 R2 |2 r4 x. j' H, g4 m/ w
rspdeny  <search> [{if | unless} <cond>]
; ~) ~, f1 R0 Xrspideny <search> [{if | unless} <cond>]  (ignore case)
/ K1 ~- A! [* p: }$ _5 x  Block an HTTP response if a line matches a regular expression) k: r8 [' H' r, W  [+ ?9 _+ L
  May be used in sections :   defaults | frontend | listen | backend, @/ g) }4 I# c
                                 no    |    yes   |   yes  |   yes0 I( ]) ?5 p. y6 c+ ^3 b, W9 j
  Arguments :
# N5 ~' N3 T  P$ K7 j    <search>  is the regular expression applied to HTTP headers and to the
# l. T4 i1 Z7 W' a4 k              response line. This is an extended regular expression, so* B4 H! N0 A5 D# x/ J
              parenthesis grouping is supported and no preliminary backslash5 d$ Q0 K' f, j$ r& S! \* k8 q0 _0 [
              is required. Any space or known delimiter must be escaped using8 M. [. J' g& v" L8 m
              a backslash ('\'). The pattern applies to a full line at a time., F$ Y& m( C5 t; [, Y% u3 B
              The "rspdeny" keyword strictly matches case while "rspideny", p1 U+ O  _. a. R
              ignores case.* @9 B/ s4 c/ p# M- y  c4 o

: f( b. ?  A3 D) m1 L! `    <cond>    is an optional matching condition built from ACLs. It makes it
: i( o0 v5 r+ W6 |7 c              possible to ignore this rule when other conditions are not met.
0 ^; P- r0 ~2 H' w8 K# [; t: v3 U$ e# Q/ t* a3 C
  A response containing any line which matches extended regular expression# B1 A7 Q; R$ o0 p! Z/ y
  <search> will mark the request as denied. The test applies both to the
9 P  X4 T+ T7 q, k  response line and to response headers. Keep in mind that header names are not2 C  r9 C& m" W# j+ E' H& B$ J
  case-sensitive.. D2 ^0 |* y" J2 A

! i+ r  n* L) D9 x3 m  Main use of this keyword is to prevent sensitive information leak and to
; W% N/ u/ h% K' m) x' l  block the response before it reaches the client. If a response is denied, it) x9 X. n! G% F: i- h
  will be replaced with an HTTP 502 error so that the client never retrieves
* X5 g( ^, [9 b# g% t/ u  any sensitive data./ n) S* ^' U! u( f1 n
, `2 I) h! F6 [; O% J  g& A
  It is easier, faster and more powerful to use ACLs to write access policies.
5 T& }' n, i+ U4 F  Rspdeny should be avoided in new designs.) w+ t2 w5 W" q& q

# |/ w- `& b+ l5 Q" O9 I  Example :: w. R/ L- n) [/ C
     # Ensure that no content type matching ms-word will leak
% ~6 b3 |2 ^, X7 `! @! `' ?     rspideny  ^Content-type:\.*/ms-word5 R  r7 R7 D3 y' J8 _1 n( N
4 H! z2 J) M- L7 V& H
  See also: "reqdeny", "acl", "block", section 6 about HTTP header manipulation6 k8 R6 n3 M$ d
            and section 7 about ACLs.
0 x+ V& c6 W/ Q+ Z3 j! e6 e! A; P( _) g; z; P& E$ s2 f+ b* y

& p0 o6 y+ |( n! P( I% d) Irsprep  <search> <string> [{if | unless} <cond>]; R9 O4 {9 A& [4 X2 k- \
rspirep <search> <string> [{if | unless} <cond>]  (ignore case)
$ i8 _1 a# G% Q- _, r9 s  Replace a regular expression with a string in an HTTP response line9 [: z  W  z8 y& E! @
  May be used in sections :   defaults | frontend | listen | backend: N  ]8 \$ g0 f/ ^
                                 no    |    yes   |   yes  |   yes
# B5 C1 p" o( Y0 E; h$ b- [+ b. H0 n  Arguments :: o2 N8 ?0 `( q% e; h
    <search>  is the regular expression applied to HTTP headers and to the) O; A9 K- A; _7 B% W
              response line. This is an extended regular expression, so8 k" d; `  R( N; X5 A# S0 W( u5 p
              parenthesis grouping is supported and no preliminary backslash3 E/ U/ C" n6 `% \
              is required. Any space or known delimiter must be escaped using+ \" {; Q; s& d! ?
              a backslash ('\'). The pattern applies to a full line at a time.
/ _6 b, C# m$ I% L              The "rsprep" keyword strictly matches case while "rspirep"2 D( H+ l7 A) l! W, t9 J% S# u; H
              ignores case.
0 E7 }5 T& V3 V1 N. F
/ v2 U" f: ?  n# p5 g" U    <string>  is the complete line to be added. Any space or known delimiter% u* y. R# Z5 y- `! W; c
              must be escaped using a backslash ('\'). References to matched& g7 a4 D, v# |& E
              pattern groups are possible using the common \N form, with N
3 w9 z# D. h- E2 U8 X  Y              being a single digit between 0 and 9. Please refer to section8 K0 t- y" ?" H- p- ?; D6 h+ R
              6 about HTTP header manipulation for more information.
* e$ n# h( E  B  G5 L2 @  Q$ X; T
    <cond>    is an optional matching condition built from ACLs. It makes it
/ ?3 P+ m- K8 h" G              possible to ignore this rule when other conditions are not met.
- I! m! V8 W: n  |* \5 j# J8 H
' H0 i) x6 c! B  Any line matching extended regular expression <search> in the response (both* K8 ~( D% H* p$ L1 K6 C# w6 B
  the response line and header lines) will be completely replaced with
  |% Y: ~4 f; _% v! m6 _- R/ L: x  <string>. Most common use of this is to rewrite Location headers.. P9 @1 [4 i4 b3 K4 E
. V$ d( T/ |+ }) n0 \4 F# g
  Header transformations only apply to traffic which passes through HAProxy,
2 _3 a7 q1 ~6 ?8 j9 y# ]* _  and not to traffic generated by HAProxy, such as health-checks or error
; @$ }& j: r- i4 V7 K  m% `5 a  responses. Note that for increased readability, it is suggested to add enough1 X- D0 [( g/ G
  spaces between the request and the response. Keep in mind that header names8 Y% D2 D2 R+ Z( `2 X4 M7 X0 {
  are not case-sensitive.
: Z' E5 \$ d! z& r- n8 k+ I9 W% f* N5 `
  Example :( I4 H/ ?* s. y) z! @
     # replace "Location: 127.0.0.1:8080" with "Location: www.mydomain.com"& y8 `! w# F6 L1 C" J
     rspirep ^Location:\ 127.0.0.1:8080    Location:\ www.mydomain.com* J% |; G; r0 P$ Q
% C+ c7 ?+ U1 z5 N; u1 c; B
  See also: "rspadd", "rspdel", "reqrep", section 6 about HTTP header
4 N& ~: G# B) t9 Q            manipulation, and section 7 about ACLs.) u! t" r% B% x# G& Z3 x$ B- g

7 Q  L3 ?" ?" N8 [
5 i; a; [1 \0 I' Z' Y+ \+ o2 ~server <name> <address>[:port] [param*]$ y( x& T( y% {# K
  Declare a server in a backend
( c9 T. N0 D6 ?& G) @4 F  May be used in sections :   defaults | frontend | listen | backend% y" _* P! L# c7 ?
                                 no    |    no    |   yes  |   yes
: j/ r8 s0 B# y  Arguments :0 n' G0 W0 C& [/ L) D) I
    <name>    is the internal name assigned to this server. This name will+ ?" D1 `8 h4 k. K
              appear in logs and alerts.  If "http-send-server-name" is8 h( K0 I! @6 r9 D4 ^. g$ c
              set, it will be added to the request header sent to the server.9 K4 t. R( L7 @! }
6 u- |4 k% ~# }+ T
    <address> is the IPv4 address of the server. Alternatively, a resolvable8 f& z( N/ Y( `" P9 T& C! C/ W
              hostname is supported, but this name will be resolved during
( e6 h$ g0 g+ P% Q              start-up. If no address is specified in front of the port, or if* J9 O$ k  T( `( O
              address "0.0.0.0" is specified, then the address used will be the
2 g% `$ }% [2 f              same as the one used by the incoming connection. This makes it( P) m, a  S6 p/ T4 e! K5 L  s/ b
              possible to relay connections for many IPs on a different port or
8 S3 K1 S3 m& G9 J4 ]  j              to perform transparent forwarding with connection limitation.
( }( G* a9 e( C" P) a( j# c" W5 O7 j) n( ?) v9 ~
    <ports>   is an optional port specification. If set, all connections will, j8 I8 s$ P* B/ ^# a
              be sent to this port. If unset, the same port the client
) q4 `% g* {, M              connected to will be used. The port may also be prefixed by a "+". j% X( n+ x2 \
              or a "-". In this case, the server's port will be determined by1 P" m) |& S7 ~& @) P2 M3 f" m$ h
              adding this value to the client's port., ?6 L! W4 G; R( @8 a/ B/ D) K! {/ a
6 L7 L( C  {: E2 a
    <param*>  is a list of parameters for this server. The "server" keywords9 m0 c& k% f8 E& Q
              accepts an important number of options and has a complete section' G7 t5 j$ j  p# ?9 D/ E
              dedicated to it. Please refer to section 5 for more details.
1 r( @2 j7 }1 B; E
2 }% ]+ ~  B/ Z  Examples :
4 w7 _+ K, C5 N* b3 T        server first  10.1.1.1:1080 cookie first  check inter 1000
8 [. w* ]+ Y( T7 l5 U, L6 m        server second 10.1.1.2:1080 cookie second check inter 10000 S7 h( v1 t. E% l, {( }
! @- i; K1 q) V, x) n  R; A
  See also: "default-server", "http-send-name-header" and section 5 about
1 W7 q9 a* \  k* l" S. A. X6 W             server options3 e2 L! E3 _3 w* _* b
& q- b( v1 u8 q1 J( N% ^+ F
0 y0 a" d0 d9 C+ G9 w* g
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
! g( D$ o) J0 F3 F& e* T2 g3 }source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
  R6 u8 I) S. A7 w& e2 x, ~  {2 bsource <addr>[:<port>] [interface <name>]
# {8 O' U, L) ~6 n  Set the source address for outgoing connections
8 {5 T+ D! c8 w- O+ e  f  May be used in sections :   defaults | frontend | listen | backend" `) X/ v. u- b3 Z- ]) D5 `
                                 yes   |    no    |   yes  |   yes' y$ s9 l4 ]5 F' t
  Arguments :
# o% d; q- X! Y% b6 R    <addr>    is the IPv4 address HAProxy will bind to before connecting to a6 E. x( t( I# Q" s1 p
              server. This address is also used as a source for health checks.
# [( v! t9 a. n6 t  f: q; p              The default value of 0.0.0.0 means that the system will select# G5 t( B! f; |1 k7 f* Y+ I
              the most appropriate address to reach its destination.
  @0 L  J/ q, f
) `/ ]* P% U7 a, L. S    <port>    is an optional port. It is normally not needed but may be useful
' F. }, d: P2 y" {              in some very specific contexts. The default value of zero means
, G0 `/ M: G3 i: {( Y3 f. {              the system will select a free port. Note that port ranges are not
$ V. v. k5 v% q              supported in the backend. If you want to force port ranges, you
6 g5 L7 ~( }  P+ T3 T" O6 Z0 r              have to specify them on each "server" line./ L3 z/ T0 n! O+ B7 z

. X) K5 x' |0 t8 ^3 T    <addr2>   is the IP address to present to the server when connections are+ x0 V6 O6 {- v' r2 o6 \4 N8 h
              forwarded in full transparent proxy mode. This is currently only
  u+ p& ?4 M  Q7 g, K              supported on some patched Linux kernels. When this address is6 E6 ~" z3 y# \
              specified, clients connecting to the server will be presented) n3 ]+ u1 V2 V- l- o9 G( s9 S
              with this address, while health checks will still use the address
, W) r6 x& r- g( n( c8 y              <addr>.
: s) R/ q- |& p8 B1 K% F
" }7 `# @2 `6 R. q. v    <port2>   is the optional port to present to the server when connections$ F6 E( G, o- [- j8 ~6 [
              are forwarded in full transparent proxy mode (see <addr2> above).
: E' W5 b4 @$ g9 f              The default value of zero means the system will select a free
( }1 c, N1 B" f% O) ~1 }5 S& p9 n              port.6 v! o1 \) S: B7 ]1 V6 V4 `
. {$ d( G! f  s, x' H) G% T
    <hdr>     is the name of a HTTP header in which to fetch the IP to bind to.8 w. G  z1 X7 B( R( S' N
              This is the name of a comma-separated header list which can
% U" M# G- W2 ~              contain multiple IP addresses. By default, the last occurrence is1 W% H6 Z' {/ i3 ^0 t: l2 M# d9 A
              used. This is designed to work with the X-Forwarded-For header% x% R; l9 c' N, J! ]
              and to automatically bind to the the client's IP address as seen
- p& W( d+ k; R" W1 Q5 c# g              by previous proxy, typically Stunnel. In order to use another! K+ q# Y/ \3 B$ k3 j* j
              occurrence from the last one, please see the <occ> parameter# z: e: u3 o  Q% e5 Y4 a' H
              below. When the header (or occurrence) is not found, no binding
  S! O2 n& Q4 w% ]              is performed so that the proxy's default IP address is used. Also: P) w8 r/ j) S( r$ H
              keep in mind that the header name is case insensitive, as for any& F/ Y, ]& _* t
              HTTP header.1 Q( h# ]& V4 o/ ?0 ~

* G1 Y1 y- T9 Y! Y    <occ>     is the occurrence number of a value to be used in a multi-value
0 ^9 d6 J( N+ a  O              header. This is to be used in conjunction with "hdr_ip(<hdr>)",0 o9 l" `+ ^3 F$ c1 T+ Z) L& c% j
              in order to specificy which occurrence to use for the source IP
  u5 H1 e5 D; b) X- Q; G              address. Positive values indicate a position from the first  O8 R3 _) D4 k* }$ P; g
              occurrence, 1 being the first one. Negative values indicate
4 y- a# C, j% }7 D  u4 w% T0 r( [              positions relative to the last one, -1 being the last one. This
& a7 \2 D1 f4 }' U) S" Z0 g              is helpful for situations where an X-Forwarded-For header is set
$ Y- D) D; y( C8 D              at the entry point of an infrastructure and must be used several
1 ?5 |% h% {" Q& Z              proxy layers away. When this value is not specified, -1 is8 Y0 T7 `4 z3 M# C# B% {8 Q
              assumed. Passing a zero here disables the feature.0 d! E& t6 x0 x

/ j# k4 z* T6 V% r, Q) j7 m' P! b    <name>    is an optional interface name to which to bind to for outgoing
0 p* N' Z# m; y- {' n# \  l8 k              traffic. On systems supporting this features (currently, only* M" T6 h- |2 K. a. C( s/ |
              Linux), this allows one to bind all traffic to the server to( i7 g( \! a5 a* t8 s! ^- |
              this interface even if it is not the one the system would select7 Q& E7 @# Z9 {8 d
              based on routing tables. This should be used with extreme care.
& a! j" H% `5 P# O) f) Q              Note that using this option requires root privileges.
" C3 [* d  M& f9 N" U
/ F9 V( O- f- v- w9 O1 c  The "source" keyword is useful in complex environments where a specific
3 I8 j- O) H) p  c& ]  address only is allowed to connect to the servers. It may be needed when a3 C2 `; C- @3 P: [5 P
  private address must be used through a public gateway for instance, and it is
7 m' H2 O# l* f! e3 d  e9 N& _7 X  known that the system cannot determine the adequate source address by itself.7 H5 \( R6 G6 v' c; C

% d9 [4 x5 p$ C7 M6 J/ x  An extension which is available on certain patched Linux kernels may be used
3 m3 O$ }  y$ |4 b9 k, F( M( n  through the "usesrc" optional keyword. It makes it possible to connect to the; q$ ?. J$ V( ]" D' t% ~5 f2 U9 O
  servers with an IP address which does not belong to the system itself. This- N' |, T  v% A
  is called "full transparent proxy mode". For this to work, the destination
/ K4 W' s; I2 f6 t$ M+ `. K, H( _! w  servers have to route their traffic back to this address through the machine
" O+ B" I/ s8 D/ j0 g& z$ {  running HAProxy, and IP forwarding must generally be enabled on this machine.  I! \/ N. L3 Z4 @. q) f! F5 u

6 Q0 j; g; B) j- L7 X" @4 u. \" M  In this "full transparent proxy" mode, it is possible to force a specific IP/ ~! E/ a$ J4 N! m, a; N) D, e
  address to be presented to the servers. This is not much used in fact. A more
& ?( k! N3 B0 G" u% G2 K3 C  common use is to tell HAProxy to present the client's IP address. For this,  n  k; h* L0 O) L3 S1 x
  there are two methods :
" o  `. b, W3 m+ J
+ ~" v# {0 J3 A/ O: w/ u    - present the client's IP and port addresses. This is the most transparent0 `1 _: W: ?% T* V7 }2 C9 H
      mode, but it can cause problems when IP connection tracking is enabled on
9 Q: I- n9 d3 t, F/ Z2 `/ G      the machine, because a same connection may be seen twice with different4 s* K2 y" r0 i. h& {7 G
      states. However, this solution presents the huge advantage of not) V8 r. E! D( F. r  z
      limiting the system to the 64k outgoing address+port couples, because all
+ j% F6 Y0 I/ f      of the client ranges may be used.0 J+ u7 X* Q9 J

* |( H- \5 A9 C) \7 |    - present only the client's IP address and select a spare port. This/ j9 ?/ l" q' T/ P  m( R3 v
      solution is still quite elegant but slightly less transparent (downstream
  x8 D. g2 V6 X) @2 _      firewalls logs will not match upstream's). It also presents the downside8 j% W) T4 a; H
      of limiting the number of concurrent connections to the usual 64k ports.
' L1 R4 q  B; d1 D      However, since the upstream and downstream ports are different, local IP
6 d0 `* q- d1 [2 B! O      connection tracking on the machine will not be upset by the reuse of the
" U* ]& N* b9 f) {' Y8 a      same session.
2 V, h3 i' ^' v% H2 t+ W% x3 g0 \' C
  Note that depending on the transparent proxy technology used, it may be
3 Y9 l$ d4 j% X' P2 @& Q  required to force the source address. In fact, cttproxy version 2 requires an( \, j8 E) U( U; H- D% W
  IP address in <addr> above, and does not support setting of "0.0.0.0" as the3 t' y* l8 r0 @0 b: z0 }
  IP address because it creates NAT entries which much match the exact outgoing* }; x3 N5 `" C) {% y3 B
  address. Tproxy version 4 and some other kernel patches which work in pure7 ]9 Y& C* Z; K9 ?, G+ i5 @! D0 h
  forwarding mode generally will not have this limitation.
9 T( |4 H& M" U
4 j) H% K- \5 N% a1 i  This option sets the default source for all servers in the backend. It may; n* d5 F$ b- {" F* o8 g
  also be specified in a "defaults" section. Finer source address specification
. `+ P4 ]/ ]% h; X& Q' g$ y* j  is possible at the server level using the "source" server option. Refer to
( W6 e: [% H6 R+ m, V6 H  section 5 for more information.& r" C1 c- y/ F
9 \: J3 s+ P: G9 H  v: ^! ^
  In order to work, "usesrc" requires root privileges.
# J9 ^( V. a2 j1 u; q! }
% V' F+ m2 I  k' e) E1 y1 A, F2 u0 z  Examples :! ]3 v! W( m: o
        backend private6 c. K$ ]! R  U0 I; h8 ]. g8 \
            # Connect to the servers using our 192.168.1.200 source address! w" o2 Q- {+ U  X, `5 ~/ ^% ?$ }
            source 192.168.1.200
' @! m! j( @( ~+ Q3 Q! y1 x$ u9 M# G  a( m1 h  y& b& \& T% |3 c
        backend transparent_ssl1
3 z5 f# l8 |! @5 y% v            # Connect to the SSL farm from the client's source address
/ z% C4 h$ t2 A3 V5 ^: o            source 192.168.1.200 usesrc clientip) H6 ]" O/ r$ }" r7 r

: R# E5 K2 e$ l  s% R7 _        backend transparent_ssl2
" y5 f- \/ M3 f3 D8 S            # Connect to the SSL farm from the client's source address and port) m7 f3 X& x1 b1 E! o# O
            # not recommended if IP conntrack is present on the local machine.# U) w) V; f* j5 \9 [; v; w
            source 192.168.1.200 usesrc client
. P/ L3 E9 R7 X: A; e( H7 Q& y9 [
- B" Y2 m, d. f$ X! u+ e: A9 i/ n        backend transparent_ssl3
- S" r$ j1 a! \* e            # Connect to the SSL farm from the client's source address. It6 k) {0 w: a0 V  V
            # is more conntrack-friendly.8 b9 m$ s  b1 ~8 q% _8 X
            source 192.168.1.200 usesrc clientip3 W3 U& X# t3 m9 W! z5 k0 Q; w7 E$ n* t

, \! J9 E9 W. n( s/ F        backend transparent_smtp, h8 |4 Q' ~3 Q8 h; Z: D3 Z* P
            # Connect to the SMTP farm from the client's source address/port, x. {- @% H% m# ]( H& H! H
            # with Tproxy version 4., W* \, w5 r0 D7 j4 G* K) R
            source 0.0.0.0 usesrc clientip
/ S& h/ V. n/ Y3 P7 V  [. R$ N) D3 d' G, M
        backend transparent_http
5 Y, R7 m" W  A8 C( t, r/ o( ?            # Connect to the servers using the client's IP as seen by previous% N9 e! x/ K  V7 i4 g$ p% s
            # proxy.) p: z' D4 }% V6 |: ~. p3 e# S
            source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)
$ e8 X# o6 \1 q1 w' ?$ w% @+ g: `2 Q* ?+ _
  See also : the "source" server option in section 5, the Tproxy patches for
, \, x' I2 G2 c/ t: o             the Linux kernel on www.balabit.com, the "bind" keyword.$ T2 Z/ s* w. e5 [# r
& D: A5 q# q3 J

( V1 T$ F$ e+ M# z- P* R$ Bsrvtimeout <timeout> (deprecated)4 l- @8 a9 t, x, H; @2 |
  Set the maximum inactivity time on the server side.; v* s+ j6 \  A
  May be used in sections :   defaults | frontend | listen | backend- ^8 U+ i9 @3 O$ d; \. d, X
                                 yes   |    no    |   yes  |   yes4 W3 G6 n" f) |
  Arguments :
; |$ [/ c. F% V    <timeout> is the timeout value specified in milliseconds by default, but7 z& C/ j: n2 J) x  A
              can be in any other unit if the number is suffixed by the unit,$ R) {, C1 r' U8 h, T7 j" l* y
              as explained at the top of this document.3 v# |6 e1 {+ ]: w! P! k

( v; b/ K; @/ H  The inactivity timeout applies when the server is expected to acknowledge or
; y) \6 m8 e' B7 c  send data. In HTTP mode, this timeout is particularly important to consider
9 }3 P( ?  v. N4 C* b+ W  during the first phase of the server's response, when it has to send the( _" w3 T7 h& p' d0 K, ^
  headers, as it directly represents the server's processing time for the
2 Q1 y6 Y! o, p4 I9 L  request. To find out what value to put there, it's often good to start with
( Z6 n4 A1 g- _  what would be considered as unacceptable response times, then check the logs
* U: ~& K  g$ W- \# F3 U  to observe the response time distribution, and adjust the value accordingly.
+ N/ W, Z- n. \1 |3 h+ p  G& z9 w" R# Y$ N9 \" C/ A
  The value is specified in milliseconds by default, but can be in any other
- t* ?8 ?! W+ G; O% r  unit if the number is suffixed by the unit, as specified at the top of this
% e- x: U# j6 b3 Z  document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly, l& M" }. e9 Y5 m" P& P, X
  recommended that the client timeout remains equal to the server timeout in* Z  i6 k; Q7 o. G0 z' Q
  order to avoid complex situations to debug. Whatever the expected server
) }5 |& g- p$ [  response times, it is a good practice to cover at least one or several TCP' U" @* D* W; C. h
  packet losses by specifying timeouts that are slightly above multiples of 35 x3 Y& {" m3 J5 {' `9 H- D
  seconds (eg: 4 or 5 seconds minimum).5 d( D) Y  k/ q4 t: N5 t
  ]' Q3 ^  M0 C" [3 l
  This parameter is specific to backends, but can be specified once for all in
, h* U2 z, j  o) o+ C  "defaults" sections. This is in fact one of the easiest solutions not to: |3 [. F8 G, o& N, d* h
  forget about it. An unspecified timeout results in an infinite timeout, which
- h& b6 \! u6 @5 `  f  is not recommended. Such a usage is accepted and works but reports a warning6 Z1 d8 c% @: K1 E' r
  during startup because it may results in accumulation of expired sessions in0 q" V4 I) }( L2 I
  the system if the system's timeouts are not configured either." A( f0 o. \- p& T0 _1 U
2 _4 x) ~2 }; o. Z
  This parameter is provided for compatibility but is currently deprecated.
' q' O. Y0 t, l1 h" y  @6 r# k8 @2 {  Please use "timeout server" instead.  V# V# A8 L" n9 `/ ~# Z9 c

4 p) x0 S& A% W3 o  See also : "timeout server", "timeout client" and "clitimeout".* [' V% }6 {. K

. {+ b2 R; Q# T! M+ `4 ^0 J: ?4 q! Z  _5 `% e/ y# Z
stats admin { if | unless } <cond>
7 y# n: Q6 P( h- n0 t; I  i/ Z& o  Enable statistics admin level if/unless a condition is matched
/ _  K/ |1 C7 X6 h( G' P. |# B  May be used in sections :   defaults | frontend | listen | backend
" p/ [) ]$ a; n1 p! g                                 no    |    no    |   yes  |   yes
9 c6 |, d- j% u" I! D
$ F2 n9 |: N3 v# S  This statement enables the statistics admin level if/unless a condition is
/ e+ B* A- t: |- y7 i  n  matched.
7 y3 Y- }2 z% F7 O$ {( r
- n6 M1 ], ?! z0 [  i3 v8 S' |0 u: }  K  The admin level allows to enable/disable servers from the web interface. By
+ t. I2 g" V/ o7 ?  default, statistics page is read-only for security reasons.
& T- S4 H3 Y( y* T5 ^9 |1 k  I( K8 r0 k  A9 M' P* U# D+ L
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
+ I4 W7 s$ y; C- ~$ d% E         unless you know what you do : memory is not shared between the
3 B! W) N0 U( ?         processes, which can result in random behaviours.6 b1 `, ?/ {% K

  F6 {& k& D7 K- g+ Z, ]  Currently, the POST request is limited to the buffer size minus the reserved$ T  a7 f2 I" N: P+ h
  buffer space, which means that if the list of servers is too long, the
: i( C/ z  Z( d' }, q7 V; P  request won't be processed. It is recommended to alter few servers at a* i& Y  T. |9 O: ]+ E
  time.
. r  @4 w$ p$ ^
% P9 s! u" f& D3 D8 R  Example :
7 R' y3 l' t3 k2 J    # statistics admin level only for localhost6 t1 B) S$ T) b3 i3 E9 n# O6 j
    backend stats_localhost
3 X2 P6 {0 X( r6 R% j8 g& G        stats enable
7 [0 B6 }- [3 X& K5 [! J( N2 f1 x# `        stats admin if LOCALHOST; h4 V  s3 ~) l. j* z- B

  s) y' `* Q5 w  ?$ ^% S. A  Example :; U. x: r- [6 t; p9 G' {3 a1 b( }
    # statistics admin level always enabled because of the authentication
- n9 S4 ~  D5 `! k, G1 X) W% [    backend stats_auth# j; ?. j& S& |+ `5 @4 N; O
        stats enable
* I7 g: n( q) L! V3 P$ _4 n        stats auth  admin:AdMiN123
+ z% ?! Q: M3 z. P. p( d( [( i% H        stats admin if TRUE8 i9 I6 S5 s% E' O# y4 j. E
+ b; u/ }) J0 X* ~: O0 W" N
  Example :8 \+ o9 h5 z1 ?3 _# u: p
    # statistics admin level depends on the authenticated user) c" d9 ~4 H# r, M' b
    userlist stats-auth$ c+ ~2 a' X& H. n
        group admin    users admin7 G2 v1 t5 ?9 N& }0 D6 `
        user  admin    insecure-password AdMiN123
2 d9 p0 K) [: a        group readonly users haproxy
) y9 }9 ?" R9 q: K  j        user  haproxy  insecure-password haproxy
0 h4 t4 c2 Z- x
& T+ ]9 a! m% D1 u" |    backend stats_auth
  O( H% X/ J0 @" E7 o5 c" `        stats enable
5 H/ O* N  w5 b: ], Z# Y        acl AUTH       http_auth(stats-auth)
' t( p3 ~4 q- g: ^8 s        acl AUTH_ADMIN http_auth_group(stats-auth) admin; c( r4 v0 y, m3 N
        stats http-request auth unless AUTH0 S; \' @+ g! G( c# a, s* }7 C8 E: p
        stats admin if AUTH_ADMIN# y" ], V; B9 A% q% }
' ~+ }+ S7 q* I  \$ F0 {
  See also : "stats enable", "stats auth", "stats http-request", "nbproc",
7 s$ S0 i9 @4 H# h5 y9 x" ?             "bind-process", section 3.4 about userlists and section 7 about
- `6 \6 u4 G  ]; x& Y* l             ACL usage.
0 N* K% J) t  ?# x- K
; x1 S, ^; h7 @! M4 i
; a# ]0 R- ]8 D% }& Y# wstats auth <user>:<passwd>
5 R% @1 X: Z2 `+ b2 W; |1 O8 I  Enable statistics with authentication and grant access to an account
' J3 t9 A; H$ I9 J# V/ ]  May be used in sections :   defaults | frontend | listen | backend( I/ M% k# c8 h$ y3 _
                                 yes   |    no    |   yes  |   yes
( I8 r( ?1 C8 \' o  Arguments :
! q8 I! x4 O0 Q9 h2 N: P  N1 H' H  m) m& f    <user>    is a user name to grant access to8 p. N$ U+ b' n

+ }7 O) T' h7 h0 Y* H    <passwd>  is the cleartext password associated to this user7 l1 U! F4 e7 a

/ L+ O& k" V% d! T  This statement enables statistics with default settings, and restricts access. y" \4 y, n! Z5 [3 Y. X4 @. M
  to declared users only. It may be repeated as many times as necessary to0 s5 k" Q! q  m( A4 C1 h. V9 y
  allow as many users as desired. When a user tries to access the statistics4 o- D7 i, l% j
  without a valid account, a "401 Forbidden" response will be returned so that8 x2 L* _) V% ]/ x
  the browser asks the user to provide a valid user and password. The real
- e  k; t; y  h* R( R+ F9 O  which will be returned to the browser is configurable using "stats realm".4 d# C' K% }0 V; [
& U& q1 t7 ], `! t. R& L
  Since the authentication method is HTTP Basic Authentication, the passwords
0 d* \$ @  [4 Z' d# b8 V  circulate in cleartext on the network. Thus, it was decided that the
: r( `1 n! v, P2 @& u$ J% Y  configuration file would also use cleartext passwords to remind the users
9 j- V! S3 n# r5 a. a' G  that those ones should not be sensitive and not shared with any other account.
) R2 k5 s* g, D! K
- q/ G  u- j3 n) E- h  It is also possible to reduce the scope of the proxies which appear in the$ [1 n) d- f# I+ s: Q$ |
  report using "stats scope".* T& i% a0 Q7 w% m* s, q
/ t/ q6 f9 P7 [: O5 _
  Though this statement alone is enough to enable statistics reporting, it is
3 O; l! E- Y! E! x5 ]: y  recommended to set all other settings in order to avoid relying on default
& }8 e2 T9 J/ _  unobvious parameters.
0 L1 x8 ]1 a; y, n
$ q- t) v( D! G5 ]  Example :9 s9 l4 }$ E/ G7 c( \- S; o) \
    # public access (limited to this backend only)
7 i. D" k' ]) S# I( r' v    backend public_www
% x/ a! x0 r) o+ ~% d- T        server srv1 192.168.0.1:80
$ C- o! S. F* g2 p        stats enable
5 `5 w8 S4 D' ?/ V  X" I& @2 e        stats hide-version
  T- L" K6 K& h, g6 J, O; ^' s        stats scope   .
2 B$ [- \; z' F        stats uri     /admin?stats! U7 W* R8 B; c
        stats realm   Haproxy\ Statistics. P( l# s8 n3 K5 K. P8 B+ O
        stats auth    admin1:AdMiN123
& e" _" x6 F# H8 d        stats auth    admin2:AdMiN3216 ^8 A) o$ J7 w- a

! t0 d8 \6 W6 T" X    # internal monitoring access (unlimited)
) ^) Y3 Y! N7 _' ~( a- Q8 i    backend private_monitoring8 @1 X. E' S: B& o' g1 }
        stats enable
6 W& K5 D# g0 _        stats uri     /admin?stats
2 t2 i+ a) x  A$ _/ A- W        stats refresh 5s
/ {5 O, Z9 C: A# A$ |, X6 U: i
2 U. }5 |, k# Y  See also : "stats enable", "stats realm", "stats scope", "stats uri"
  ]  N: W6 @, ?% l: V7 U: P) S: h9 v' S6 P/ p, C5 `2 y4 m

: a( `4 I4 S  ]: m( Z5 R8 hstats enable9 E% {  e7 ~6 y" `* g2 \# V9 o
  Enable statistics reporting with default settings7 H! O8 t7 F! A
  May be used in sections :   defaults | frontend | listen | backend
  v( V; ~6 W; s: Z. x7 m+ J                                 yes   |    no    |   yes  |   yes
- K- v! S) ]# h7 X. O  Arguments : none, w+ r; s  g" H, O$ F, o; r
* k7 r; o1 S9 R8 B+ l
  This statement enables statistics reporting with default settings defined
* R. n2 Z9 D# b& b  at build time. Unless stated otherwise, these settings are used :
- ^' p* \# j6 |- w3 h; @/ c! S) L    - stats uri   : /haproxy?stats
# o0 o* H+ f% a7 C    - stats realm : "HAProxy Statistics"/ T9 K- ]* A4 P" j0 z0 S5 w
    - stats auth  : no authentication1 f! Z8 ]2 }) A- P. D
    - stats scope : no restriction
$ s8 }7 y" e2 H$ @  H  N* n8 x, q/ u6 O: R+ D, Z
  Though this statement alone is enough to enable statistics reporting, it is! F9 D7 n; x  _0 _: q2 w. P5 n
  recommended to set all other settings in order to avoid relying on default7 X& v( W. ~) _. O2 J5 d. Z
  unobvious parameters.
4 I$ a8 b  l' A' L
9 R6 e/ S+ q6 z7 }2 D& e8 Y& _. `  Example :
& ~, e' M* \9 ]  m& A# T    # public access (limited to this backend only)
6 j2 V0 G2 ~4 B; J% D! X( V    backend public_www
* Q. M0 z% X7 O1 M8 z" b7 _# u        server srv1 192.168.0.1:80
2 J3 x/ T9 @6 H8 _        stats enable) b2 K" y5 U* G5 n
        stats hide-version
+ o7 K4 l" A6 |; c5 E5 ^        stats scope   .: ^4 p* J# n' C. a
        stats uri     /admin?stats
1 @1 Y: E; S. J5 E8 N        stats realm   Haproxy\ Statistics, Z( u0 K9 D5 ]* C3 Z9 I5 J
        stats auth    admin1:AdMiN123# n, k/ j1 O& T- [0 @! W
        stats auth    admin2:AdMiN321
8 y8 c6 c* `5 ]
3 Y7 g" Q7 ~1 U# @& h    # internal monitoring access (unlimited)0 [9 r% p# q. z/ R" s' L' |3 ~
    backend private_monitoring
3 X) V: c; ^+ f        stats enable
1 G( \! v5 _. x        stats uri     /admin?stats
8 h* `1 k  A% A. j  ]2 }        stats refresh 5s2 X) N; ^2 Y; o
- L6 V2 G( k4 b
  See also : "stats auth", "stats realm", "stats uri"! H/ a; E+ Y3 `2 P+ A. ?0 L% X6 o: J
9 h- r6 q& J( O7 h$ m  U: H7 A3 l
0 v# v7 r  L) h: }  S" `( E
stats hide-version
3 ]" C/ E9 k9 `4 [0 P  i  Enable statistics and hide HAProxy version reporting
- H3 @1 b) _1 u. \) S  May be used in sections :   defaults | frontend | listen | backend
" E3 G$ Z; Q$ D+ a; j* c& \# _3 |" f                                 yes   |    no    |   yes  |   yes0 Z, S$ y) r" U" H" Q0 S8 Y
  Arguments : none
- M4 R( T$ G5 u* t' q9 h% K( `
, A/ Z0 t' d8 b2 f6 O  By default, the stats page reports some useful status information along with
* \- U: ?6 s6 X! l* |- f4 G0 Y' L  the statistics. Among them is HAProxy's version. However, it is generally5 f0 K$ ~$ ^9 V# R
  considered dangerous to report precise version to anyone, as it can help them0 V: M. Z$ R* B7 E2 o, M) X
  target known weaknesses with specific attacks. The "stats hide-version"
  a9 n3 t: R7 A- r3 p  statement removes the version from the statistics report. This is recommended
( T3 M, L5 ^. i: G  a; @  for public sites or any site with a weak login/password.9 n) U) X" Z9 d" @1 n5 k7 B; d# h' z

- [+ I7 I' l; Q9 T& b  Though this statement alone is enough to enable statistics reporting, it is
8 R- A* X, a6 l  recommended to set all other settings in order to avoid relying on default
9 o/ s: J8 e$ M2 u7 Y% Y6 |: k$ Q  unobvious parameters.
" f- Q4 J! `: m6 O, t* w8 u+ |7 m8 q2 p# P
  Example :
, x5 W, k5 U! B6 E" l    # public access (limited to this backend only)
/ R: {$ c7 |- F( {+ z    backend public_www; {6 k% U3 y, W1 W  i4 B
        server srv1 192.168.0.1:80
- @! d( O7 H6 s  M4 x        stats enable; A# q) ]$ i3 b
        stats hide-version$ a+ q$ P3 `: \: U2 G+ R2 i
        stats scope   .
& B, z6 J9 C* G8 D        stats uri     /admin?stats* O* w) C5 C  p
        stats realm   Haproxy\ Statistics
+ X( C- I) }: K" X% W+ I        stats auth    admin1:AdMiN1238 ?8 [, B+ L# h) u) V$ m! g3 O, o1 v
        stats auth    admin2:AdMiN321
0 c3 y7 D; q  z8 ?
1 J" a- z% M" o) T3 k% [    # internal monitoring access (unlimited)) o# N* j/ B0 K: b# L- Y8 `
    backend private_monitoring/ Q* `5 o0 s; G9 o( n: Y
        stats enable8 x$ [: O% m: a" X8 A4 L
        stats uri     /admin?stats! L' G8 q- ?. o( [
        stats refresh 5s
; a% u4 Q- }# q
- E+ V0 D8 \/ b, N  See also : "stats auth", "stats enable", "stats realm", "stats uri"
% x' R% t. y' b. ~. m- T3 a" q0 _7 ~( X$ n
! _; j2 C' S% [; ^
stats http-request { allow | deny | auth [realm <realm>] }
5 Z+ _# Y/ ?: `3 ]3 \             [ { if | unless } <condition> ]
8 L4 b  `! |; Y9 a! R0 n  Access control for statistics& q- b0 N( A4 D& \( M: B

7 z/ k2 x9 g9 f4 \  `  May be used in sections:   defaults | frontend | listen | backend
# V9 C1 a4 w& g& w8 g. B                                no    |    no    |   yes  |   yes# B$ r( C. y2 e

- A/ K# x* w% k7 c/ i  As "http-request", these set of options allow to fine control access to
& X' A3 Q) w+ o" H5 ?& |/ ^- t  statistics. Each option may be followed by if/unless and acl.  E  d  \1 x" j/ A4 i; a# \! X/ T
  First option with matched condition (or option without condition) is final.8 i' D- f! w) t2 P$ _8 a- O6 ?
  For "deny" a 403 error will be returned, for "allow" normal processing is
9 Y4 P( u8 O, a$ G" ^) [* E5 a  performed, for "auth" a 401/407 error code is returned so the client
7 ~- O# \/ T+ K. k' @  should be asked to enter a username and password.
7 I/ x! v) ]( ^5 F% i
/ ?( d: M4 X9 O+ G3 ?  There is no fixed limit to the number of http-request statements per9 D6 C* x( M' r  }3 W, v; T/ |+ v
  instance.* y7 d9 B  h+ n8 `+ Z7 e

+ H  [6 {8 R, t# x  See also : "http-request", section 3.4 about userlists and section 7" p6 U+ E5 j2 U: w& E/ L4 {/ X
             about ACL usage.
8 P: Z! g' p3 i0 [+ C
0 k+ \% N/ c- H/ F
5 y* a: W; X5 @, k# Z4 s6 d! Estats realm <realm>
0 \" a: ~( _, f3 h. B" _) R# H, H+ l/ _  Enable statistics and set authentication realm
/ f* C) X$ T7 D& ^" r  May be used in sections :   defaults | frontend | listen | backend- ^, ^: c' P5 G  s) U
                                 yes   |    no    |   yes  |   yes3 Q5 D9 h; ?- F7 t1 f
  Arguments :0 k6 `) d+ l( t6 ?1 P0 h
    <realm>   is the name of the HTTP Basic Authentication realm reported to( L  [: V2 u1 _  v2 }2 g# o
              the browser. The browser uses it to display it in the pop-up3 g( H$ s# J$ y# g. l" s) ]
              inviting the user to enter a valid username and password.
9 v1 R' ^1 s  Y
7 Z6 W/ E; m0 l. Y5 `5 o- {' S  The realm is read as a single word, so any spaces in it should be escaped
! y; e7 q; r" S5 d3 z  using a backslash ('\').
. }* r& H1 H$ R9 B+ G2 d  q, f1 l1 z
  This statement is useful only in conjunction with "stats auth" since it is
/ [: I3 B6 u; W6 z, V2 B. R/ @9 l  only related to authentication.
* D# ^3 A5 d' _( A
- h8 N6 G1 l2 G( o0 z0 x4 o  Though this statement alone is enough to enable statistics reporting, it is
5 S3 @, `/ P* f+ Q+ F# t4 i  recommended to set all other settings in order to avoid relying on default) n( F6 E3 P$ o" h) ~
  unobvious parameters.
: Y9 P  {( X/ v
; S3 D: X" A4 s9 o  Example :
: g6 O. `4 {( K1 e6 W    # public access (limited to this backend only)
/ N8 U! @6 H1 A4 P    backend public_www
4 J% O% C& ~0 D% y5 Q6 Q& ~        server srv1 192.168.0.1:80
$ w; F5 s# a* M1 }' N( ]        stats enable/ ]: N- V9 m1 u2 K' T
        stats hide-version
/ o0 f3 B: Q9 ]% f- S        stats scope   .% w, J8 t& k' I+ j2 L
        stats uri     /admin?stats4 ^' t' n) N7 j5 X
        stats realm   Haproxy\ Statistics. v& L" ?/ E6 M% _) X6 H1 ^
        stats auth    admin1:AdMiN123% Q5 O' K' U! O$ m! N
        stats auth    admin2:AdMiN321- o+ Z- r8 k0 b

* U  f+ o  }4 R. n4 R  v    # internal monitoring access (unlimited)( L/ G' B; M0 n+ O* q
    backend private_monitoring
% E1 t- k  {6 X6 c! c$ T% s        stats enable# Q; ^% j% Y1 z. b! O
        stats uri     /admin?stats! Q( K4 o$ Q9 ]2 N
        stats refresh 5s  T8 n9 ?! k2 |* t
1 ~8 D  _- B+ b
  See also : "stats auth", "stats enable", "stats uri"; i# D7 G/ j9 F) J& Y8 v4 l$ R
0 L. ]" K7 P( ?

( G# v# o4 R0 q. }# J) r1 Lstats refresh <delay>( ?. k" ]9 x2 s7 F  g
  Enable statistics with automatic refresh$ b# Z8 d! a5 P5 K  f
  May be used in sections :   defaults | frontend | listen | backend
5 ~3 Z0 _+ w8 c6 I& @& K2 N                                 yes   |    no    |   yes  |   yes. [) H  J  n6 Q* W3 X; f# g# ?! l
  Arguments :9 x0 S+ ^8 H* k  P/ G' B$ s
    <delay>   is the suggested refresh delay, specified in seconds, which will; _0 ^# g! t+ ^8 e. d) s
              be returned to the browser consulting the report page. While the
; h) Z8 B$ P2 Z7 \; R              browser is free to apply any delay, it will generally respect it, }6 h1 F# B6 ~' N' o* P
              and refresh the page this every seconds. The refresh interval may  K7 d; r( ?. w. T8 H
              be specified in any other non-default time unit, by suffixing the* ^4 b- }& ?! x+ o! c3 q
              unit after the value, as explained at the top of this document.9 k$ C( u3 w  g3 B$ A7 |
8 k) T4 P4 x2 ?$ Q- T* J
  This statement is useful on monitoring displays with a permanent page$ s  t" }1 P! o* ^7 X0 Z
  reporting the load balancer's activity. When set, the HTML report page will
: P# V0 Q" O! Y, ^5 {" [  include a link "refresh"/"stop refresh" so that the user can select whether
1 j6 X. h: J0 w! `. T8 O% w  A  he wants automatic refresh of the page or not.) }7 Y( D" q8 R8 |" j9 c4 W8 n
2 n$ i$ k& Y8 K0 @, j4 n3 J8 P9 c
  Though this statement alone is enough to enable statistics reporting, it is
( Z6 r7 v  M" i7 N7 `  recommended to set all other settings in order to avoid relying on default0 V& o4 ~7 x" s/ w4 T3 K
  unobvious parameters.
' A8 ~; s9 N% W' `; R0 s' M% {) Q- V/ K
  Example :
3 ~  f- B0 P) V6 K+ p# J    # public access (limited to this backend only)6 m0 N; y: ]& T4 g9 A2 j1 l
    backend public_www9 [; y  e3 ?* k
        server srv1 192.168.0.1:80' d9 k0 |  X+ f  W. S7 m; w) h% ^
        stats enable( c0 B& K; B$ n7 ?% q% y
        stats hide-version
: c. T3 L9 E% o        stats scope   .
1 s! v* T- [5 w; P# [) W: M        stats uri     /admin?stats
4 q) I6 M+ j/ x        stats realm   Haproxy\ Statistics- m3 }, Y. z6 ^( Q
        stats auth    admin1:AdMiN123' G7 n& J( l3 s- S6 \/ x( S
        stats auth    admin2:AdMiN3215 `9 I7 f: l4 a6 N
3 `4 G7 l9 U4 Y3 S
    # internal monitoring access (unlimited)
6 Z5 I' o0 r3 q6 R0 Q    backend private_monitoring. s) s6 _4 l% B7 t; n
        stats enable
! ?' [9 G/ f( x" M1 y' E        stats uri     /admin?stats
8 }! ]- @9 l# c! M, Z        stats refresh 5s
7 Z3 V9 `/ X8 r# {( e; b$ l8 x$ m  |$ h, P, P$ Y( J2 X. j
  See also : "stats auth", "stats enable", "stats realm", "stats uri"
, u2 I9 h" a; {: O2 z* Z# c
) v5 D* e, i( F! |; o) Q# R$ @% D
- E! M0 `& i3 [1 ~3 g6 ?stats scope { <name> | "." }
6 T, P) d) B$ {6 m9 k' o  Enable statistics and limit access scope1 N- A8 p9 V% P3 R( T2 {% E! @) j0 K
  May be used in sections :   defaults | frontend | listen | backend. q5 X& I8 k: n3 s" P# l1 F3 \
                                 yes   |    no    |   yes  |   yes0 \3 a( [9 B5 R$ J9 I9 n& ?
  Arguments :
* _: L* h. g! y2 q. k, A8 f    <name>    is the name of a listen, frontend or backend section to be
: f# n7 Z7 g' V5 T              reported. The special name "." (a single dot) designates the
& k- `; T& b% l( B$ y              section in which the statement appears.0 G* I( F  D0 M) X% Y  R$ O- k; c+ _
  w! \% m; D# Y4 `% _( |- v2 {
  When this statement is specified, only the sections enumerated with this
2 @) t; y  q. h& `" m; e3 @. R  statement will appear in the report. All other ones will be hidden. This4 w, T2 n9 O0 X# ?" h
  statement may appear as many times as needed if multiple sections need to be
+ y: W; X2 X2 i% J1 u  reported. Please note that the name checking is performed as simple string8 X8 m4 f" p' ~' a
  comparisons, and that it is never checked that a give section name really- |4 \  r5 z) k' f
  exists.
+ v# f; c7 x* c4 {$ Q( ^
# E' M7 u5 y/ O" v$ q7 I  Though this statement alone is enough to enable statistics reporting, it is
0 z! a8 c  j) A' v! `. `  recommended to set all other settings in order to avoid relying on default
% f4 V  o, O! \+ b' K8 S, t# n  unobvious parameters.8 b( v5 _6 j7 [3 _1 T+ _

2 n8 A* Q+ g  I* T- H  Example :. u. F5 |' _1 p
    # public access (limited to this backend only)
& _! c# u# i  {+ B2 \) K/ W1 ^    backend public_www
; d- @9 `; R4 C: |  ^* N        server srv1 192.168.0.1:80
0 W0 y6 U3 ?' z/ k        stats enable
& ?( p! X; d3 h2 [8 N3 ]/ g2 n4 |+ g        stats hide-version
6 p& c, k2 O" F- I        stats scope   .* j" Y# I. Q$ m: r% |5 x
        stats uri     /admin?stats1 x' Y3 x* u- b$ T- i9 [! i
        stats realm   Haproxy\ Statistics
6 {! m) f, ?* [, m& C, H2 u3 h$ B        stats auth    admin1:AdMiN123
0 u6 b; M3 y: X( `9 |        stats auth    admin2:AdMiN321
! X" R# J5 u2 L' h$ X' A& ~0 H0 s+ \/ F# r9 a
    # internal monitoring access (unlimited)
9 l8 S% w( N0 i  z; E: R    backend private_monitoring% U$ k& i8 B8 |1 n5 D* u4 T0 x, U
        stats enable
& j9 _4 [+ y. v& _, i+ v        stats uri     /admin?stats
/ Z# ?+ S* U% t( U5 m        stats refresh 5s
0 j6 t% {! c/ Z: y9 U
6 K$ I3 h  C8 R' R* c  See also : "stats auth", "stats enable", "stats realm", "stats uri"; W6 n# O" Z* d. _
8 A! |4 ~0 L' a5 ~$ Y, Z
9 Z$ A9 k/ z" C. J6 z
stats show-desc [ <description> ]
! K: D/ |6 Z+ Y- r  Enable reporting of a description on the statistics page.) R: e7 b3 k7 n) h2 N
  May be used in sections :   defaults | frontend | listen | backend
1 k+ V$ k  r6 Y) T1 m                                 yes   |    no    |   yes  |   yes
5 z6 S! ?. L+ w! U* ?0 }" }4 Y5 A& `6 C, ?
    <name>    is an optional description to be reported. If unspecified, the: \: x; ?  ?3 u# B) |
              description from global section is automatically used instead.
+ ~9 J8 S1 y7 a# j: z0 E$ [9 F$ }1 @7 R
  This statement is useful for users that offer shared services to their, _, Q% F7 T" X- d. B4 C. j
  customers, where node or description should be different for each customer.. ^  x# v) y2 B8 T& l2 t' d. h( N
' x+ h7 e$ `% B/ e; p9 \8 h) ~
  Though this statement alone is enough to enable statistics reporting, it is
; Z" H0 h) x, Z* b0 z: j- U  i+ s& i7 O  recommended to set all other settings in order to avoid relying on default
( \" H2 A) b# j9 \9 H  unobvious parameters.  By default description is not shown." D7 b5 |7 A. i2 X, S

7 [( R( x6 b+ @0 o  Example :
+ C3 @/ V6 A+ k) s" q    # internal monitoring access (unlimited), [7 i5 ^' G6 i" q7 ?& ]; {
    backend private_monitoring
8 L6 B) K8 J# t( }. B0 G  I; V# \6 H        stats enable
, Q$ v$ Y% M4 N+ \/ y4 t; `        stats show-desc Master node for Europe, Asia, Africa
5 a% m, ?6 T, U0 P) v        stats uri       /admin?stats
# k3 M/ c- P# t4 q9 z9 S- w        stats refresh   5s
9 T; y( q# c: ^# {0 e0 J: T8 X" z! r/ ?: c: B
  See also: "show-node", "stats enable", "stats uri" and "description" in
& ]6 r: x2 h7 @/ ]            global section.2 m  b8 o* E, S2 ^
& H+ l" q& }* w9 Y+ |  |

* Q2 Q9 l7 d; c. M" bstats show-legends8 H5 A: e$ F! m% z) b, z1 V
  Enable reporting additional informations on the statistics page :
- |% _3 R. e) A. @5 r# m- t6 \    - cap: capabilities (proxy)
) T* w! D# W+ r    - mode: one of tcp, http or health (proxy)
# I" D# b* h* ?8 j1 Y4 P    - id: SNMP ID (proxy, socket, server)
1 I6 z& B! }8 g' \    - IP (socket, server)
, a" T1 P0 n+ f0 V+ H! n8 O    - cookie (backend, server)0 l2 i" d" I- d' A

! k0 G8 N/ w! o, z3 D" X6 ?  Though this statement alone is enough to enable statistics reporting, it is
5 ~: d3 M* x( H7 ?: W* U* p  recommended to set all other settings in order to avoid relying on default
- b, O- u' }" e  unobvious parameters.  Default behaviour is not to show this information.$ c2 V0 O# n0 [7 Y
0 K$ L. |6 I: S9 f
  See also: "stats enable", "stats uri"., G! K/ e7 ^1 E' ~) @8 q" `
( N7 p; o6 @7 x# H- Z0 v

! g3 Z% b1 `9 `, q- k, istats show-node [ <name> ]& k# T" J" r. }- ]! S
  Enable reporting of a host name on the statistics page.3 e- p# V% u1 h: U
  May be used in sections :   defaults | frontend | listen | backend* P% y9 |% o; ^' n$ w( N$ {7 U6 M
                                 yes   |    no    |   yes  |   yes* u. ?/ \. s7 ]3 u9 y
  Arguments:
  y8 y8 n" e+ l* C$ c+ \3 U' n    <name>    is an optional name to be reported. If unspecified, the
; P3 r" _: A; u/ D2 s; f' l              node name from global section is automatically used instead.
( ~+ ?" z7 t. \5 _- G! n: k- |9 ]1 T, L* M' x
  This statement is useful for users that offer shared services to their' g6 r. p! }9 s' x; ]
  customers, where node or description might be different on a stats page9 [7 t7 H) ?4 Y, k: J( l
  provided for each customer.  Default behaviour is not to show host name.5 T% D+ J1 |( `5 x' n

! m! `+ l, q2 C+ r  Though this statement alone is enough to enable statistics reporting, it is+ J# p# H; R$ I: l& b
  recommended to set all other settings in order to avoid relying on default
. u/ p! M8 O2 b. z8 x  unobvious parameters.
( m6 C! |- X1 b$ w! S3 R& d) w' X* V  q( T; @
  Example:1 T% n# u1 L% q/ I4 }) ~1 X
    # internal monitoring access (unlimited)! W5 @" [" G4 d- S/ D
    backend private_monitoring7 R! L- [# \& M/ p; \# t% e( l: i
        stats enable# F2 {7 G* D& I7 T& t+ v
        stats show-node Europe-1! n- q; k/ B+ V# O$ W
        stats uri       /admin?stats" C! q* t; c6 V6 K( m
        stats refresh   5s
# U) {2 c+ |. c# b0 ~4 A" s& M6 m0 I
  See also: "show-desc", "stats enable", "stats uri", and "node" in global
( x; i5 M0 a. j7 T4 u5 z7 E            section.+ c+ t, p# Z  ~, b$ G, t3 |2 C

! p  K+ J4 u' {5 v( S- b: A: I1 o" Y5 O* s7 t- r/ Y
stats uri <prefix>
8 o5 h3 i0 X* W+ k* J  Enable statistics and define the URI prefix to access them3 ]) A2 `" V* i# C9 d
  May be used in sections :   defaults | frontend | listen | backend
5 E' E6 V( O/ {1 N9 U* O+ T! z( g                                 yes   |    no    |   yes  |   yes
1 h( h0 v8 R) }2 g. B7 ^" `- R  Arguments :0 y! C2 f- E, `6 K, m
    <prefix>  is the prefix of any URI which will be redirected to stats. This
" O2 w6 ^1 T% [! p. [- M              prefix may contain a question mark ('?') to indicate part of a, L2 Y9 f; n8 f8 o+ z
              query string.
0 h. u' D5 J# J! u( T; ~0 ^/ m/ \2 M8 V/ p# E, B# U
  The statistics URI is intercepted on the relayed traffic, so it appears as a
8 `+ P# E5 x- Y  page within the normal application. It is strongly advised to ensure that the
, T9 d+ x, k2 x  selected URI will never appear in the application, otherwise it will never be
: N% b0 p9 T! H+ K- t4 o  possible to reach it in the application.! Y! ?4 @2 L/ B1 _% Z0 Z4 Y+ F
( z$ T2 R; H8 H3 p
  The default URI compiled in haproxy is "/haproxy?stats", but this may be" n- ~9 E8 @' X9 O' c3 L
  changed at build time, so it's better to always explicitly specify it here.7 o: |0 ?! m) R3 M. S- e- j6 K
  It is generally a good idea to include a question mark in the URI so that
, Y! A* c! G( g% B  n  intermediate proxies refrain from caching the results. Also, since any string
& g) A7 ^0 n9 x3 c7 b2 e* h  beginning with the prefix will be accepted as a stats request, the question
( t2 z' F2 }& U0 I" P  mark helps ensuring that no valid URI will begin with the same words.
; q: z+ s% i, ?) s# `% U/ [
" V' u7 \" i, Y% }1 P  It is sometimes very convenient to use "/" as the URI prefix, and put that
/ v8 z- d9 E: t; U) v4 d  statement in a "listen" instance of its own. That makes it easy to dedicate
. {1 L7 H/ i4 I: x  an address or a port to statistics only.+ e2 k  b4 y4 ?* G3 r& @0 [. h" ]
9 G7 a8 j5 b& m7 x9 x
  Though this statement alone is enough to enable statistics reporting, it is
# w: w! o' M' j* |8 J" ]  recommended to set all other settings in order to avoid relying on default
; Y, \. z! ]5 p  ^: w7 i  unobvious parameters.
9 J7 m# f& v# V: Q* {2 |& Y4 y3 `* ?; @' B4 @
  Example :
6 z8 O2 w+ o' t7 G* O& C" H    # public access (limited to this backend only)
& t6 V' ]# b7 U0 i    backend public_www
. l) t  H! L" x: ?* v  _% x        server srv1 192.168.0.1:80( R/ }9 w8 K9 {/ ?& p5 V8 I
        stats enable6 j# ~# }! U  H' S; G. y) J7 m
        stats hide-version0 G. b+ C, D) V( _7 Z: s: t+ l
        stats scope   .
% J  h4 O6 x  e: C        stats uri     /admin?stats$ z1 G& {6 |* @$ x) c1 i$ l
        stats realm   Haproxy\ Statistics: f$ F9 T' l4 x# c3 Q/ x9 {
        stats auth    admin1:AdMiN123
- k, M* r3 |; w        stats auth    admin2:AdMiN321
, C/ f  b/ U6 M; V: x" B% p- L7 `( s& ?# T  t) w' o
    # internal monitoring access (unlimited)+ }1 [4 u5 A3 R! _+ L3 ^
    backend private_monitoring: J: l- Q, i! }% L+ D3 I' A
        stats enable3 H! u8 E1 V  K4 J1 E
        stats uri     /admin?stats. d' f& m! ~& F( K! I* Q  L
        stats refresh 5s* x- a! a! y! M6 h6 N$ u

- K( m* t0 l+ X7 c- G7 N  See also : "stats auth", "stats enable", "stats realm"1 y) d( s) @; Q4 p# U% }
% N+ k0 `; W7 t( ?) m2 |* D

: ?4 `+ K9 U% hstick match <pattern> [table <table>] [{if | unless} <cond>]
9 F( J& N: O: W" z  Define a request pattern matching condition to stick a user to a server
2 `. d2 k2 I; c  F% [1 c+ ?  May be used in sections :   defaults | frontend | listen | backend) l! I9 f6 g# z+ [8 L( ^. r6 Z
                                 no    |    no    |   yes  |   yes
6 N7 h- S) J. n+ V7 y  A4 l4 k
- A% I! S' M9 s% D: w3 k  K  Arguments :
: O' \* X! [6 }/ r. Q" X" e* k6 A    <pattern>  is a pattern extraction rule as described in section 7.8. It
0 k8 W7 d1 A5 `1 \' u4 H               describes what elements of the incoming request or connection
- R: B- m! [+ V! S: d4 g               will be analysed in the hope to find a matching entry in a
/ r% k2 F0 O! B6 @2 g               stickiness table. This rule is mandatory., t+ O& O5 N9 f4 P3 `

7 g6 R8 s& }% v0 O/ a, e4 W9 ?/ c    <table>    is an optional stickiness table name. If unspecified, the same; w! g1 G! y5 A* q/ }+ T2 I- C
               backend's table is used. A stickiness table is declared using
  g. J' ^" a7 r! _/ T               the "stick-table" statement.
( u( X6 v* {1 ]' e8 b
8 |. u/ O$ K8 [    <cond>     is an optional matching condition. It makes it possible to match
* w% r( a3 }2 ?; v9 W2 o               on a certain criterion only when other conditions are met (or
& K7 s' t, }7 q2 e$ f               not met). For instance, it could be used to match on a source IP
% u0 ^( f+ P7 R% ?1 }0 M) l               address except when a request passes through a known proxy, in4 E: Y* b% ^' ~
               which case we'd match on a header containing that IP address.2 S8 ?/ {: J# N! ~) ~+ t
6 r) h7 K/ H# L/ E4 ]
  Some protocols or applications require complex stickiness rules and cannot- D" M- J; f: Z8 _- B' E+ j; V7 A( n
  always simply rely on cookies nor hashing. The "stick match" statement* x2 `3 |7 F# j% l, u/ D
  describes a rule to extract the stickiness criterion from an incoming request
  J- p  P9 a9 c5 x+ U  or connection. See section 7 for a complete list of possible patterns and
3 c4 r( m- B. ], n( r# r6 e9 ^  transformation rules./ O* A9 Q! j! R5 p/ W

2 N( q/ Z. o7 s* ]  The table has to be declared using the "stick-table" statement. It must be of
  J7 o% @+ D2 l, n# k5 C) ]* [  a type compatible with the pattern. By default it is the one which is present) q0 H; @+ g, `/ W$ G  g
  in the same backend. It is possible to share a table with other backends by5 q% h' ]4 d7 g5 K
  referencing it using the "table" keyword. If another table is referenced,
0 k/ U8 C9 k1 Q( n! G0 J* C  the server's ID inside the backends are used. By default, all server IDs
% v5 G! d% c% x' p* g* |9 C6 t# {  start at 1 in each backend, so the server ordering is enough. But in case of. f( X( ~4 u6 S+ K( O1 l
  doubt, it is highly recommended to force server IDs using their "id" setting." c! w; M3 G  F8 t$ T, ?" q. ?* I
* `+ W: V) t- X4 Y
  It is possible to restrict the conditions where a "stick match" statement5 t: R# Q- f* f. P! m
  will apply, using "if" or "unless" followed by a condition. See section 7 for
& R/ @$ B  F' {8 D  ACL based conditions.) m4 l4 E3 Q2 v

2 r& M3 _5 g7 ]  There is no limit on the number of "stick match" statements. The first that$ N) Q; f( V( h9 T
  applies and matches will cause the request to be directed to the same server
; v! b- o* M4 f7 a* d7 d' ~4 d  as was used for the request which created the entry. That way, multiple# M. z& r8 S* x& C
  matches can be used as fallbacks.
, g7 T6 C* U  P+ A2 j
, G" Q4 n& G: C- R& r  The stick rules are checked after the persistence cookies, so they will not) [& }2 G1 f* \2 r
  affect stickiness if a cookie has already been used to select a server. That" O. M" e* L/ W# n& c
  way, it becomes very easy to insert cookies and match on IP addresses in
& u7 c7 H. ~9 H" y: |& T9 w  order to maintain stickiness between HTTP and HTTPS.+ X0 v) a* F# x

# k* S& ~' P. J! S  Note : Consider not using this feature in multi-process mode (nbproc > 1)* U: I! r. H/ o
         unless you know what you do : memory is not shared between the
/ [2 P# n4 u8 g( ?) }9 I         processes, which can result in random behaviours." f1 |5 R. O7 \
7 B- D9 r1 S  ^
  Example :
: t/ j. v  O, x1 Z# E# A    # forward SMTP users to the same server they just used for POP in the  B, u# x* v  a" @" h
    # last 30 minutes  F2 g, W0 k* b; M) V. k% \! k  h
    backend pop: j, R1 J. b$ s5 N
        mode tcp2 j3 k9 Y/ B2 G9 y0 c
        balance roundrobin
- M2 }) F1 n7 p        stick store-request src4 n4 |1 [! Z' S3 d5 g6 @
        stick-table type ip size 200k expire 30m
4 v( S2 ^. V) B  K" |( Q( g& u        server s1 192.168.1.1:1106 I/ Y* c; E; L, M
        server s2 192.168.1.1:110
& r5 p& w6 d% k$ O" \# w; N8 ?; G5 U" P, p
    backend smtp  r- a% \* g( {3 t7 i, q- t
        mode tcp
& {# u! r" z+ ~+ z4 O        balance roundrobin
" r1 h* |8 O) U2 T  \        stick match src table pop
4 H2 X, A0 l/ {: M        server s1 192.168.1.1:25
# b- F6 d6 P! ]+ ^( m) a        server s2 192.168.1.1:25
# k( ~" e, }0 e7 d$ \+ _1 B) `
! {$ K: c$ N) x) ]  See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7; r1 }" j& p: X- p
             about ACLs and pattern extraction.( v" R( N) n! }" P0 n$ ]/ d

1 I8 K* M0 f+ V7 ~( ?# ^
4 p/ y  A7 j! b+ `) B5 v) Zstick on <pattern> [table <table>] [{if | unless} <condition>]
+ Q4 E4 }" L  f( ^  Define a request pattern to associate a user to a server; P. i* N6 N1 k4 L: w3 N
  May be used in sections :   defaults | frontend | listen | backend
/ t% y, \% R; n/ l; F6 w                                 no    |    no    |   yes  |   yes
3 u1 X& a7 k+ r4 ]  W# @& W
1 f4 W  }. q% `7 f9 h  M  Note : This form is exactly equivalent to "stick match" followed by
9 u& ]$ Y( k2 v2 P         "stick store-request", all with the same arguments. Please refer8 w# n0 [* H+ d( W# K" D% _, @
         to both keywords for details. It is only provided as a convenience
% q, [  _' S$ ]+ p; [         for writing more maintainable configurations.3 l4 u2 I' F' S5 K$ c
+ I* o* Z2 a- V/ d3 R1 O
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
6 X% U* y2 {& f5 K! U' G         unless you know what you do : memory is not shared between the
7 G! y6 a+ C  M7 M1 \: m. [) B& z         processes, which can result in random behaviours.
, {' Q  ~5 ?6 }7 u' [; G& \
# D3 [- [% i2 U  Examples :$ H: x+ Z7 Q; u: P2 M. S
    # The following form ...9 U* i6 s2 O! C4 n( M. O- D
    stick on src table pop if !localhost1 p+ ?/ U1 z5 a1 S
8 b! F5 q( }* t
    # ...is strictly equivalent to this one :2 q- C* {3 A2 f' s! l
    stick match src table pop if !localhost
1 f. I# ]+ d0 H, n    stick store-request src table pop if !localhost
6 N( v$ G9 [% G
  C: @2 T3 a8 T* o/ r( Q' C
7 a% V; l3 Z+ b: r9 B9 e  ]- b/ f    # Use cookie persistence for HTTP, and stick on source address for HTTPS as) j2 k/ @7 \# t+ P- G7 j& [% I' S
    # well as HTTP without cookie. Share the same table between both accesses.
  F4 @% V. ~/ e    backend http/ L! A3 z6 D& q. {0 w
        mode http2 k, C4 m1 m/ f, ~1 G
        balance roundrobin. C/ E/ c: [6 Y& f7 a2 a
        stick on src table https& M' v' t- W! w! M8 A' p9 q# f1 O0 g
        cookie SRV insert indirect nocache
4 f. |5 A0 K+ b9 V+ @8 `( {        server s1 192.168.1.1:80 cookie s1" o8 E: j# U  X, f7 L
        server s2 192.168.1.1:80 cookie s2
' k3 S7 I- f  E2 {
8 A6 S7 f% O( M" Z    backend https. r+ x+ j! I. Y
        mode tcp& \8 s  e- i0 _/ V4 r! E  D' a3 j1 x
        balance roundrobin7 E. I1 Z' p/ e5 f/ y9 Z
        stick-table type ip size 200k expire 30m( Z8 e  O$ V& |" ]. ?
        stick on src
9 z4 P, g8 L3 w        server s1 192.168.1.1:443
- B2 T# a6 ?6 \# ~0 g/ j        server s2 192.168.1.1:443
$ V0 ^" o3 u( [
0 H4 P7 [% k$ @" [  See also : "stick match", "stick store-request", "nbproc" and "bind-process".
, ~1 h, z+ S2 R: b! c2 w6 u' h/ W  H1 M" {6 q8 I" z
( a% D3 `3 I# U
stick store-request <pattern> [table <table>] [{if | unless} <condition>]2 V6 _3 e- T8 k! I. o' u
  Define a request pattern used to create an entry in a stickiness table
2 Q' B- X( T( W- ~4 D+ Y  May be used in sections :   defaults | frontend | listen | backend
- a. v0 ]  j! A0 @( ]* y$ R                                 no    |    no    |   yes  |   yes
" I! `4 q) G: u0 [% j: q, K  r7 B; [: F! K' y3 r( ~
  Arguments :$ J  b; E' I  E8 p! B. J' ]" d
    <pattern>  is a pattern extraction rule as described in section 7.8. It5 E* g! l9 V0 r* N& W
               describes what elements of the incoming request or connection
  I: @: L8 U5 l, m: @1 I' o               will be analysed, extracted and stored in the table once a/ u  q+ C/ o8 Z
               server is selected.4 y4 e; ?. w$ }/ f
7 M, n) J9 j$ P- k1 W
    <table>    is an optional stickiness table name. If unspecified, the same
% s) n/ @/ L3 v& P               backend's table is used. A stickiness table is declared using1 k* R0 [. z  n) p% M! \
               the "stick-table" statement.) X1 x" y/ d9 x' {+ r7 _

1 P* ?( C4 [  ]1 U7 \: L    <cond>     is an optional storage condition. It makes it possible to store
; T# ^- C3 u: y5 n$ A# ~- W               certain criteria only when some conditions are met (or not met).
* ^( n, ]9 U% R! a2 z               For instance, it could be used to store the source IP address
+ x4 l. w% t* V! x               except when the request passes through a known proxy, in which" Q$ T- Q9 M6 `- a2 t
               case we'd store a converted form of a header containing that IP& n4 O/ I  W5 `' ^# I) T9 j
               address.
& [' W& T- u, `( C# T! `& r5 l# y' v( a' n' G
  Some protocols or applications require complex stickiness rules and cannot- S2 L) A8 C+ N9 W: K1 p
  always simply rely on cookies nor hashing. The "stick store-request" statement  o5 j3 Q& d) [' u
  describes a rule to decide what to extract from the request and when to do
, D( L; G& N2 q8 o* V$ {, ?  it, in order to store it into a stickiness table for further requests to) T% F" j0 H, n4 k
  match it using the "stick match" statement. Obviously the extracted part must, V& ~# j; R) N; J' j2 z
  make sense and have a chance to be matched in a further request. Storing a
8 g5 p( ?' {# t0 s! k9 p  client's IP address for instance often makes sense. Storing an ID found in a
! s0 c% H3 s2 U  N* [4 r$ y  URL parameter also makes sense. Storing a source port will almost never make) O7 q/ v7 s$ Q8 _
  any sense because it will be randomly matched. See section 7 for a complete
0 N4 L* `, m0 E0 @1 z' c  list of possible patterns and transformation rules.
9 o- j$ O! Q6 ~8 R" l3 g; Z* ~9 _
% |3 O/ h. i, s7 f( _  The table has to be declared using the "stick-table" statement. It must be of8 F, Z8 O) I* ]4 L5 C" O
  a type compatible with the pattern. By default it is the one which is present
0 |; J  v$ S+ N  [$ x' Y  in the same backend. It is possible to share a table with other backends by2 R- d; }8 C! j1 v) \  {0 K' d
  referencing it using the "table" keyword. If another table is referenced,
  Y/ X' j3 F0 v* d  the server's ID inside the backends are used. By default, all server IDs
% u; V, e9 f* w$ g+ U8 S% I. ~+ Q  start at 1 in each backend, so the server ordering is enough. But in case of
1 M$ f; {' ~$ |/ s( }  doubt, it is highly recommended to force server IDs using their "id" setting.
+ @4 ?# B$ G6 x' X' N" ?* [" L& @. ]3 _1 Q; z! _
  It is possible to restrict the conditions where a "stick store-request"
* E3 \: t3 {% z6 |- T7 V  statement will apply, using "if" or "unless" followed by a condition. This
! \( ?& _; D% q7 n/ R& j" x; F- z  condition will be evaluated while parsing the request, so any criteria can be. ]3 k2 o( X4 X& V  m
  used. See section 7 for ACL based conditions.
6 |* n. r& w: T. p' T
) t% Y/ Y! R$ j* m, H, ~, R  There is no limit on the number of "stick store-request" statements, but3 u( E0 _5 v- ^# f( S
  there is a limit of 8 simultaneous stores per request or response. This2 F1 y( ^, Y, W% B. k" ]
  makes it possible to store up to 8 criteria, all extracted from either the
+ N% s! Q/ o5 P2 ~5 p. [  request or the response, regardless of the number of rules. Only the 8 first5 {6 X) h. F; }" y+ C5 B
  ones which match will be kept. Using this, it is possible to feed multiple; C! i2 O& d/ N( f& E9 [& C7 I+ `
  tables at once in the hope to increase the chance to recognize a user on9 g" v( f* L: w
  another protocol or access method. Using multiple store-request rules with
$ Z7 ^8 l( t! q+ y7 \  the same table is possible and may be used to find the best criterion to rely  p/ m& \+ G* w. \1 N0 ~
  on, by arranging the rules by decreasing preference order. Only the first
3 T& B% V9 L: Q4 E: t  extracted criterion for a given table will be stored. All subsequent store-
$ l# S- ~, g. J  request rules referencing the same table will be skipped and their ACLs will
1 J4 D8 i9 g% ~5 W+ u1 s3 r  not be evaluated.
5 k% B" r. N3 ~7 w
4 J  j$ i$ a/ H- {1 J2 ~4 J  The "store-request" rules are evaluated once the server connection has been
3 T/ Q' k& u( ~9 e+ Z" M/ k3 W8 v; X  established, so that the table will contain the real server that processed
* s! i: e( Z6 f  d  R0 m  the request.
6 x) `3 m% J& B& f+ V6 B' u. X4 w/ b2 _( [- u2 q1 S! s9 M
  Note : Consider not using this feature in multi-process mode (nbproc > 1)7 w) ~6 }4 z# t8 ^8 G* j
         unless you know what you do : memory is not shared between the9 y  h2 D; i6 q2 R5 L5 A7 {1 a
         processes, which can result in random behaviours.
9 y+ A& v0 @/ l( M5 K/ {" `4 z
! F9 I1 ]; g( J* t  Example :
; \' N1 j4 }( L' w: V; G    # forward SMTP users to the same server they just used for POP in the2 {" _- [. F5 [/ P, x3 F: P/ ?0 L
    # last 30 minutes
4 J: Q0 `! F( s7 F% a( v7 n. j    backend pop
" p$ X# N3 S  p7 |" N' Y* w+ F        mode tcp& X+ X8 o1 `8 J9 n
        balance roundrobin
9 c0 |8 @1 \6 `* \1 m( R! f7 Q        stick store-request src" D$ I3 ^7 t" W3 l# W0 L
        stick-table type ip size 200k expire 30m
+ u& @0 G- O8 a% b9 {9 t7 X        server s1 192.168.1.1:110
  l4 y  \% \$ ]$ p! I        server s2 192.168.1.1:110' O: X# }: X9 J; y
8 V+ L7 G. |8 H& L. z: J+ W
    backend smtp  \8 o5 X9 Z9 K6 `5 g( [
        mode tcp0 p, M1 M/ p8 b) A; n
        balance roundrobin
4 ~* m# |  M7 D6 x/ N        stick match src table pop
7 K1 q" \2 X  Q) k; N        server s1 192.168.1.1:252 c, G+ ]* Z; k9 ?$ \
        server s2 192.168.1.1:25+ e: P( A. |: d* I! Q

. z: |& Y3 s" n, B  Y- v/ r  See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7
1 X5 p$ A) C( |' F9 B8 D             about ACLs and pattern extraction.- Q+ b2 {+ s6 W' n( c* j* M

$ ]( I7 N8 k. U# Y+ L9 V; I) u9 Z' e, I9 m; A6 j. F
stick-table type {ip | integer | string [len <length>] } size <size>6 C, p/ J- Z, [; N/ r/ ^
            [expire <expire>] [nopurge]% B/ l, a6 g4 p/ T: ^
  Configure the stickiness table for the current backend
+ u  \7 r9 n3 f# V, t, g8 {, g  May be used in sections :   defaults | frontend | listen | backend6 h) W% g$ p  h. M+ }+ S5 P3 D
                                 no    |    no    |   yes  |   yes
9 @. w" X/ Y1 Z1 Z, X; }5 i4 s
* a/ D9 `3 u% F# E0 Z+ \' _9 s  Arguments :( [3 s% W% A3 W+ {7 S1 g
    ip         a table declared with "type ip" will only store IPv4 addresses.8 {) \- m2 v! M8 I9 ^6 `) }/ m; _
               This form is very compact (about 50 bytes per entry) and allows& n$ d" P/ }+ i& r7 H3 M
               very fast entry lookup and stores with almost no overhead. This
. J; z( o$ m, a; i7 p5 P- ^               is mainly used to store client source IP addresses.
0 A6 x  P! g- H& ^- L; r% ^! Z5 [! T, s$ V9 h; d& q
    integer    a table declared with "type integer" will store 32bit integers* s3 T0 T$ Y9 ~% b1 S( U
               which can represent a client identifier found in a request for
/ M; k$ A2 `( B) Y. ^               instance.
0 r; K* L& [; V% |: |
. g  S# R: m5 W5 [1 ^+ P    string     a table declared with "type string" will store substrings of up
, h; H, X% y4 u3 a               to <len> characters. If the string provided by the pattern, z1 c0 Q' ?# r. v7 W/ O! ]9 C2 g$ f
               extractor is larger than <len>, it will be truncated before& W2 r7 f* q. e% w
               being stored. During matching, at most <len> characters will be' y( w& c& K- d+ N* q
               compared between the string in the table and the extracted
, y& B: R4 u" r+ h, d4 ^               pattern. When not specified, the string is automatically limited
  m' c! ^9 g* {/ y4 [0 k" L               to 31 characters.
. d" c1 n4 x/ k1 ?9 ]2 }1 \* e* C0 |4 ?
    <length>   is the maximum number of characters that will be stored in a
# ]  @+ f- Q2 h# k' Y( `# Z               "string" type table. See type "string" above. Be careful when3 ]2 E: W" v$ x
               changing this parameter as memory usage will proportionally/ r' E1 Q; Z8 m: D. {: a
               increase.
: w6 H* @: j5 h1 C# _2 _* T$ X
( Q0 W, I  C& e8 d; Q4 [    <size>     is the maximum number of entries that can fit in the table. This" j0 f& o  B( v4 x  H. ?! u
               value directly impacts memory usage. Count approximately
0 V3 D5 m: B4 Y" m  y               50 bytes per entry, plus the size of a string if any. The size# \; U1 i, ~" N$ @: ]) m9 E; m
               supports suffixes "k", "m", "g" for 2^10, 2^20 and 2^30 factors.
8 Z% h4 d& q4 l0 j% J7 j; n+ r, i2 y- I7 E% }( p" T6 r: N
    [nopurge]  indicates that we refuse to purge older entries when the table
8 G4 |- [2 |& \+ ]               is full. When not specified and the table is full when haproxy+ {6 ]3 U0 O. I6 p  F. m
               wants to store an entry in it, it will flush a few of the oldest
; p/ u% f' @. C; Q% }" R( ~. Z               entries in order to release some space for the new ones. This is
. Z5 {  N. q7 u3 z) b               most often the desired behaviour. In some specific cases, it
( J1 F$ H4 {  [% ^               be desirable to refuse new entries instead of purging the older
9 F# z; ~! B% W! t               ones. That may be the case when the amount of data to store is
' c- M5 h8 c$ O               far above the hardware limits and we prefer not to offer access. t3 w" z  s% f: w
               to new clients than to reject the ones already connected. When
5 G8 v; D( ?3 v               using this parameter, be sure to properly set the "expire"
% B4 {; _7 p) @+ s# u6 x, S               parameter (see below).4 L$ Y, p& A7 ^) d% a9 F
  P9 G8 E* J8 S
    <expire>   defines the maximum duration of an entry in the table since it/ |. E* W, M% p4 g
               was last created, refreshed or matched. The expiration delay is: a! q$ |. R" s, Y3 I* q7 }* L2 J
               defined using the standard time format, similarly as the various
2 f9 ?& m3 f# [5 X/ T               timeouts. The maximum duration is slightly above 24 days. See  g, p6 B. X, z% ~) z5 X
               section 2.2 for more information. If this delay is not specified,
0 {& S; {; ~1 ^               the session won't automatically expire, but older entries will% W! ~5 U% g  y( `
               be removed once full. Be sure not to use the "nopurge" parameter4 @) _, @: y0 f
               if not expiration delay is specified.
! L3 [" @8 v8 O7 e1 h1 ~  k7 f  W* F: t' S* o
  The is only one stick-table per backend. At the moment of writing this doc,
5 U8 ~, c1 I& n. }! x5 Y/ {/ Y/ z  it does not seem useful to have multiple tables per backend. If this happens
5 M/ t! K9 s$ t7 y* k/ k4 i9 k  to be required, simply create a dummy backend with a stick-table in it and5 G3 O0 |6 G; g# W
  reference it.
$ N( [* F0 j% e, y
* D. {% B; a7 d! _' `  r  It is important to understand that stickiness based on learning information
8 R" v2 i; }* v. J. d  has some limitations, including the fact that all learned associations are2 T" a+ k$ ^2 S3 R3 _8 L
  lost upon restart. In general it can be good as a complement but not always
- C/ z7 {, j! q$ {, B) g. G' _" [% I  as an exclusive stickiness.& r  d- g7 e0 }1 C3 S
# P# U) l+ y6 B- t* N
  See also : "stick match", "stick on", "stick store-request", and section 2.2
7 E- K3 D9 ]5 n3 n! T9 `" k; X. m( M             about time format.
2 w8 b' w/ c6 ]- D" K
% l9 D0 f4 ^- q% Q3 d8 P. }0 A2 z+ C- K9 K# w
tcp-request content accept [{if | unless} <condition>]3 ?# b$ s4 ^2 g
  Accept a connection if/unless a content inspection condition is matched: ~( w1 u% K' _5 c6 S. h
  May be used in sections :   defaults | frontend | listen | backend3 i7 e7 `) c' d8 z* v5 P8 [6 |
                                 no    |    yes   |   yes  |   no
& P3 M0 h# u$ M
0 p" e. ?% e  j: c4 o  During TCP content inspection, the connection is immediately validated if the3 t, M$ I. O1 D2 q' ^) J
  condition is true (when used with "if") or false (when used with "unless").- @) c% E: s' v3 t8 i
  Most of the time during content inspection, a condition will be in an: Y8 ?8 v  b/ Z# {0 R
  uncertain state which is neither true nor false. The evaluation immediately
. j3 a2 ]. i3 K* M1 B( Y/ N  stops when such a condition is encountered. It is important to understand! R% z9 N- u8 f, s
  that "accept" and "reject" rules are evaluated in their exact declaration! T! t8 z1 W& s: W& q* t; @: i) ~% r
  order, so that it is possible to build complex rules from them. There is no
, p/ {1 {, e8 Y4 b  specific limit to the number of rules which may be inserted.; i+ i/ v) @3 r7 I
6 [: }2 P! F" S2 [+ s" J
  Note that the "if/unless" condition is optional. If no condition is set on
, W7 k9 G- K. l  R  the action, it is simply performed unconditionally.
" O" |7 h8 T! p2 ^" w% b$ }0 O1 a3 @- n1 l4 v; b
  If no "tcp-request content" rules are matched, the default action already is
( K" s" M" @( T8 B/ g8 t  "accept". Thus, this statement alone does not bring anything without another& M+ ?8 a( K. [$ u- b
  "reject" statement.! D9 i9 L, r9 V9 r, R: H
; B# N$ f8 x% ?! A
  See section 7 about ACL usage.; w( [8 {" D; r. }) G8 U4 v
) A6 M" M/ o; W  w/ ?% B
  See also : "tcp-request content reject", "tcp-request inspect-delay"
+ R2 A3 z  s- ]( G6 g: [. H7 \5 x: y9 D
& b* j. M5 x) y% ?9 e! x: ^
tcp-request content reject [{if | unless} <condition>]$ x5 [) _2 m6 G! S; n
  Reject a connection if/unless a content inspection condition is matched3 l4 g! t* p1 \, b$ e3 q
  May be used in sections :   defaults | frontend | listen | backend
" \( V  J1 i2 P                                 no    |    yes   |   yes  |   no5 R3 I+ u3 f  x# [# E" J+ i, J9 D
( K0 k& C5 {- u$ |0 a
  During TCP content inspection, the connection is immediately rejected if the4 z8 q' W  V/ K0 [# ]$ h
  condition is true (when used with "if") or false (when used with "unless").! C- G7 p6 f7 J3 I: ?
  Most of the time during content inspection, a condition will be in an
0 c" X) K8 H$ M& O& ^1 q' |  uncertain state which is neither true nor false. The evaluation immediately# e3 `+ J: J: O) I0 u
  stops when such a condition is encountered. It is important to understand1 A- _2 z) {, l3 _' a4 N
  that "accept" and "reject" rules are evaluated in their exact declaration
: }/ \5 w. @( u  J8 k  order, so that it is possible to build complex rules from them. There is no
$ c' \  E: P, u  specific limit to the number of rules which may be inserted.' M. [; E, n4 G; m: I* c1 r! q) Z

: i& Z6 T1 ]1 q% y  ~$ n! @' O  Note that the "if/unless" condition is optional. If no condition is set on
! i3 B9 D( c5 S" V7 K* ?% p& n  the action, it is simply performed unconditionally.8 W( `! k' b: q$ j

4 D' F. Y) X0 `+ e5 U  p+ P7 n  If no "tcp-request content" rules are matched, the default action is set to
/ g# q+ v* x& ~; K" I3 \$ B  "accept".2 \; S3 u9 w+ x# W0 t

- N0 y/ p5 X" U* I3 F8 _  Example:
  |4 i/ M5 P. C  ~) g6 m3 i        # reject SMTP connection if client speaks first
' ?0 ^4 R) J" Z. b  ^        tcp-request inspect-delay 30s7 h: {- i+ s. e  r
        acl content_present req_len gt 0- e/ k0 a& p3 o# G1 ~
        tcp-request reject if content_present
' e1 g0 T: ?# S( [1 H* t' g6 s0 S3 ?. v8 c. S# x
        # Forward HTTPS connection only if client speaks
: a% [$ d8 r( I/ E        tcp-request inspect-delay 30s
2 m! f- w8 B: {7 \        acl content_present req_len gt 01 f/ S( r* V  u7 |% Q
        tcp-request accept if content_present: h% q+ ], ]! B+ P/ R7 c7 p
        tcp-request reject& ^" a( ]) s, f# }
$ g- t! [3 }% Y2 C1 i
  See section 7 about ACL usage.! }6 \0 W2 v3 M! N* r& Z8 ]
* e* [% e- @7 n4 `3 e2 |$ p
  See also : "tcp-request content accept", "tcp-request inspect-delay": @$ P2 Q7 \2 |, N0 l" o

; U1 d( f5 f; J5 i, i8 F
  m6 p8 M0 N" X5 x$ O  q$ E2 itcp-request inspect-delay <timeout>1 F4 g+ C. P4 ?" y% }: v; X
  Set the maximum allowed time to wait for data during content inspection  K# }; B$ i0 c$ n; v6 S: Y
  May be used in sections :   defaults | frontend | listen | backend
2 N2 Y& _4 _4 Y0 n; Q. f4 h                                 no    |    yes   |   yes  |   no) b& I1 |2 b. K8 I+ o' d
  Arguments :
6 m9 `8 [* C& F9 }. f, a& l    <timeout> is the timeout value specified in milliseconds by default, but% V' \$ u, f: Y( i% A, E9 R5 I$ h
              can be in any other unit if the number is suffixed by the unit,
$ z# Y- h' e: ^              as explained at the top of this document.5 [9 D: m. @6 r( q1 k" c. ]8 C( V

/ n5 m* `- a" E) u# g# E  People using haproxy primarily as a TCP relay are often worried about the
2 K$ ]7 s# v! c1 q5 w+ o2 L  risk of passing any type of protocol to a server without any analysis. In
2 M8 t5 L% z' p! N5 t4 x! h  order to be able to analyze the request contents, we must first withhold
/ O% X/ l  v# f+ }  the data then analyze them. This statement simply enables withholding of2 R  X# X; ], j/ U5 q% L% f/ X
  data for at most the specified amount of time.% u! _$ o9 z$ m& c5 Q2 y
7 ^) j: f# J$ t9 ^  E# k, Y
  Note that when performing content inspection, haproxy will evaluate the whole) n# L$ \; N+ E# V( n  z1 F
  rules for every new chunk which gets in, taking into account the fact that& E+ z* s- u& O6 c" y4 H
  those data are partial. If no rule matches before the aforementioned delay,! P- l1 D* X# E5 R8 E6 i" u
  a last check is performed upon expiration, this time considering that the  {+ ?1 X+ d6 j* Y; h+ T. A5 w* B; S
  contents are definitive. If no delay is set, haproxy will not wait at all3 q2 x- ~3 `% m9 Z  a0 D! q
  and will immediately apply a verdict based on the available information.+ t/ G. c1 I3 {0 b1 _% X
  Obviously this is unlikely to be very useful and might even be racy, so such3 o$ p4 {. |2 `6 g' S
  setups are not recommended.( R; O& j8 h" Q9 c% O. e  Z

$ Q7 H* V- i+ F* B( \  As soon as a rule matches, the request is released and continues as usual. If# C+ L& c" N, L- v9 x
  the timeout is reached and no rule matches, the default policy will be to let
" Q! _1 F; o% A; e* |  it pass through unaffected.$ g8 h$ {: F/ m
7 D8 N3 ~, `/ o) D1 b
  For most protocols, it is enough to set it to a few seconds, as most clients
3 \1 H% O$ S( i# P- ^  send the full request immediately upon connection. Add 3 or more seconds to
5 M  ?! \* [: W; w8 F5 X  cover TCP retransmits but that's all. For some protocols, it may make sense
8 W# J4 [% M1 a  to use large values, for instance to ensure that the client never talks
3 Y  i' j4 a% T  [5 T2 h% j8 q  before the server (eg: SMTP), or to wait for a client to talk before passing, ?: r5 W% Z' o  O1 A
  data to the server (eg: SSL). Note that the client timeout must cover at
) O* y9 J" M; u- R# P' K, n  least the inspection delay, otherwise it will expire first. If the client# w$ [$ t6 Z  j! y1 `6 \+ N* Y/ U
  closes the connection or if the buffer is full, the delay immediately expires+ H# r. I. V% x6 m
  since the contents will not be able to change anymore.+ T- x4 E: `+ S. r& I- I

* @* D* a, _2 N4 \7 @5 E6 o) O3 G, \  See also : "tcp-request content accept", "tcp-request content reject",! g# N1 K/ G! c  U3 S" n# J2 s
             "timeout client".
6 c$ P. i9 u5 Y
" k5 f* N6 d$ s* ^
+ ?' f2 u* G8 i& ~timeout check <timeout>
) {( m! w; ^. ~- ?5 k  Set additional check timeout, but only after a connection has been already( @' n0 [7 n% b' c& P
  established.1 h; u  ]% Q9 n

  p: m& Q; V  D: X, J$ E/ X3 q  May be used in sections:    defaults | frontend | listen | backend6 [& S: k2 [8 f; J8 u; U6 ^
                                 yes   |    no    |   yes  |   yes& j% w6 ?3 j4 |7 P
  Arguments:: C$ W$ B4 l: \6 D& c
    <timeout> is the timeout value specified in milliseconds by default, but+ z' f0 [( U' U8 Q
              can be in any other unit if the number is suffixed by the unit,
2 E" O: b# o/ j9 s$ a+ \* T6 d              as explained at the top of this document./ D: f3 c  \5 ^; ?6 j2 J9 v3 n
9 M4 a1 a% m# f+ L; j# u# E$ C+ a
  If set, haproxy uses min("timeout connect", "inter") as a connect timeout
& g  f8 V; e$ U8 k) K* G  for check and "timeout check" as an additional read timeout. The "min" is# o) k7 `# D2 Q8 f3 o) n: i# Y
  used so that people running with *very* long "timeout connect" (eg. those
: {4 x  ?5 g5 T7 c  who needed this due to the queue or tarpit) do not slow down their checks.
! G! K. J4 Z; g" G7 G, p  (Please also note that there is no valid reason to have such long connect
0 {) c9 V" I" V  m  timeouts, because "timeout queue" and "timeout tarpit" can always be used to
3 y+ l5 a! A/ I7 ]- y4 f' L  avoid that)., V2 ~3 n# Y6 E5 M

$ U9 j6 @* p! r8 T" |  If "timeout check" is not set haproxy uses "inter" for complete check
4 i' P' |. m1 h5 @' H  timeout (connect + read) exactly like all <1.3.15 version.& ]& c1 W% o1 Q9 S; E) ^) l

; H3 R1 l' g  l+ _* h  p) O  In most cases check request is much simpler and faster to handle than normal
" g$ M  @2 G8 R2 m  requests and people may want to kick out laggy servers so this timeout should
: G& E( i7 y* q& }+ P) d# j! _  be smaller than "timeout server".
2 B+ j" t# {. w& L& ?+ W3 @: a# N8 r( U/ g" k# L
  This parameter is specific to backends, but can be specified once for all in
$ }. }: n# o. K) o0 A, H7 T& N, [  "defaults" sections. This is in fact one of the easiest solutions not to
  c; Q; @# s7 S8 ~$ K  W9 J" k  forget about it.
: w; F; `  @- F' y! g. k' E# r+ ?8 `1 I7 z$ ~
  See also: "timeout connect", "timeout queue", "timeout server",
2 J' a' Z2 \6 l3 l" B; n9 I  U            "timeout tarpit".$ r; r  n* H3 I- H
: o3 B. K. H7 {6 n2 _. g9 C" T' p; G

' C* u7 K; S/ q& z: S2 Ntimeout client <timeout>
8 m# F# u8 g8 C) ztimeout clitimeout <timeout> (deprecated)
5 ]# t! k3 }. Q2 t  Set the maximum inactivity time on the client side." V; J" A& p( Z- F+ m
  May be used in sections :   defaults | frontend | listen | backend
' H6 w' g+ y$ U% P* ?. R0 A1 x                                 yes   |    yes   |   yes  |   no
4 B$ M5 c) f$ ~5 ^  Arguments :' }1 ?6 ?% r2 [% h' M8 P. z
    <timeout> is the timeout value specified in milliseconds by default, but: x! e$ I3 C( R; @+ k
              can be in any other unit if the number is suffixed by the unit,
) i4 |  }+ G8 y6 ~3 K: h              as explained at the top of this document.' w4 \! G! Z1 x8 K% ^2 E
2 r& R+ Y$ k( j' y
  The inactivity timeout applies when the client is expected to acknowledge or% n# ~; B' t1 O
  send data. In HTTP mode, this timeout is particularly important to consider- q3 k6 y/ x4 R4 {* u7 l$ V
  during the first phase, when the client sends the request, and during the( }! ~6 [; I" g2 m
  response while it is reading data sent by the server. The value is specified
) j3 s" @9 I* Y3 @3 `' }- H; J  in milliseconds by default, but can be in any other unit if the number is* k; [4 }2 m! P6 i/ ]' y
  suffixed by the unit, as specified at the top of this document. In TCP mode
: B7 T* o& j0 k0 C3 Q$ I8 V1 J  (and to a lesser extent, in HTTP mode), it is highly recommended that the' v0 E& W' n5 M, }
  client timeout remains equal to the server timeout in order to avoid complex0 [6 B. n# l1 a* ^- D
  situations to debug. It is a good practice to cover one or several TCP packet
9 c1 \4 T6 V$ B* I, T9 m  losses by specifying timeouts that are slightly above multiples of 3 seconds) C" v0 P0 s8 F: V$ S+ t
  (eg: 4 or 5 seconds).
% X$ p# M- [' m2 B$ G
# O9 z$ G0 x/ d! n/ I( h  This parameter is specific to frontends, but can be specified once for all in3 Y. W  t  e: r4 ?# c+ Y+ a4 V+ E
  "defaults" sections. This is in fact one of the easiest solutions not to
8 {1 T2 D5 z8 ~: Q' V) v  forget about it. An unspecified timeout results in an infinite timeout, which7 u( N- u* a2 q. ^" n9 T
  is not recommended. Such a usage is accepted and works but reports a warning/ ?3 _5 N; [: D2 \$ S  C
  during startup because it may results in accumulation of expired sessions in
, |2 |. [6 G$ `  the system if the system's timeouts are not configured either.
& t1 _$ u1 V0 u) r; y  r& l$ p- w  {( l6 `
  This parameter replaces the old, deprecated "clitimeout". It is recommended
6 D) t. z8 q8 j# Y6 A4 J! T  `  to use it to write new configurations. The form "timeout clitimeout" is
  e( @& m6 R- e' O  E( {  provided only by backwards compatibility but its use is strongly discouraged.2 p. |. F& J. y5 P5 a7 k* H

4 c: Y! @9 M( p4 g) P  See also : "clitimeout", "timeout server".% c: I3 Z3 r2 ]7 ^

  d- B, m2 O8 G+ ~7 n( N" F7 w( c0 p& R) M5 M' r  y9 R7 }' J
timeout connect <timeout>
& |) E+ g9 g% ~. |! Btimeout contimeout <timeout> (deprecated)
) i: [5 w9 d  W& W  Set the maximum time to wait for a connection attempt to a server to succeed.
1 f  C- p$ \, I. P4 u  May be used in sections :   defaults | frontend | listen | backend
( Q0 ~7 O3 {/ o9 R6 C! E                                 yes   |    no    |   yes  |   yes
5 T* z5 q6 d) X# t/ f  Arguments :
: c. [$ y6 X  U# F$ |9 N    <timeout> is the timeout value specified in milliseconds by default, but
2 H  X* P* h5 ^) w" }  _              can be in any other unit if the number is suffixed by the unit,- v, z, _! M5 a/ @8 }8 L7 S: c
              as explained at the top of this document.% r6 \7 S. ]; V

( `5 P4 V" U- n* j* R3 H$ [  If the server is located on the same LAN as haproxy, the connection should be
1 J& n$ f- M2 {1 U  w9 x3 h) E: y* x  immediate (less than a few milliseconds). Anyway, it is a good practice to3 u( G. }3 V: E( Y. O
  cover one or several TCP packet losses by specifying timeouts that are
. p4 r5 K9 A* r. K( q( \4 n  slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the
9 X/ F* w6 d% ^' A  T% a  connect timeout also presets both queue and tarpit timeouts to the same value
. p& e* l* x5 F8 o' q$ k! D( \5 y' q  if these have not been specified.
. c9 P1 ^, S$ v# G4 M3 C8 P. v0 H6 }$ [0 `
  This parameter is specific to backends, but can be specified once for all in7 W/ x- a* q- ^+ L
  "defaults" sections. This is in fact one of the easiest solutions not to/ t& w1 ^- ]0 P- [4 w
  forget about it. An unspecified timeout results in an infinite timeout, which
+ K; r0 ~) \  S3 a. n  is not recommended. Such a usage is accepted and works but reports a warning& ~$ D  C3 z1 N3 a
  during startup because it may results in accumulation of failed sessions in
5 k$ O/ x$ v, w  the system if the system's timeouts are not configured either.
, A9 j% u7 B7 b# r8 [, V! J( {9 n4 c0 C' D+ s. U/ }
  This parameter replaces the old, deprecated "contimeout". It is recommended
8 c1 y( }$ f: q4 C2 h  to use it to write new configurations. The form "timeout contimeout" is
2 {6 w6 k1 y4 E2 i0 U3 P: _" f  provided only by backwards compatibility but its use is strongly discouraged.
! V/ s% }* W$ l1 Q" h
- T& d( s! f9 P: R" @4 R  See also: "timeout check", "timeout queue", "timeout server", "contimeout",* S2 |) N# b- @( O) n: v
            "timeout tarpit".
' T; r# W: ~3 P6 O/ o2 @9 s3 L/ K$ j' V( ?

2 z5 Q) |  [8 rtimeout http-keep-alive <timeout>4 K( q* [" S3 d& I: E0 y
  Set the maximum allowed time to wait for a new HTTP request to appear
) T$ U% B6 s9 y' U4 C  May be used in sections :   defaults | frontend | listen | backend
- N: `) U/ k' c* w7 R. K* q                                 yes   |    yes   |   yes  |   yes) [9 c8 s1 J/ O
  Arguments :" }: U1 A' c, w$ X: z
    <timeout> is the timeout value specified in milliseconds by default, but9 T6 v- w8 H. f  t6 O- T
              can be in any other unit if the number is suffixed by the unit,( Z5 b' K! H9 T# U; I6 a
              as explained at the top of this document.9 w0 g. }4 y$ z; I: [. v

, D6 x! [! q4 c  By default, the time to wait for a new request in case of keep-alive is set
0 @! v& A( Z! U* {  by "timeout http-request". However this is not always convenient because some
' ?8 C) ^1 T+ [* N  people want very short keep-alive timeouts in order to release connections. _, s/ t; g7 \: C/ @- q  p0 F
  faster, and others prefer to have larger ones but still have short timeouts( x4 j2 e1 R) ?7 T2 N
  once the request has started to present itself.
& p3 @2 ?6 N2 @- h' |# X
) Q0 u8 r  i9 u) x3 u6 T# f  The "http-keep-alive" timeout covers these needs. It will define how long to9 F/ \5 w, H+ l/ t. P
  wait for a new HTTP request to start coming after a response was sent. Once
7 c0 d: E9 N  l! A- @$ W& r  the first byte of request has been seen, the "http-request" timeout is used- n  L% j3 J! X0 a
  to wait for the complete request to come. Note that empty lines prior to a" P0 i: Z; p4 ]
  new request do not refresh the timeout and are not counted as a new request.) m! s1 N; {- }9 ~) V2 j
% }' j: v  v  \8 t7 B# J4 {
  There is also another difference between the two timeouts : when a connection
2 ?- w/ p) X2 f$ {: O- T, m  expires during timeout http-keep-alive, no error is returned, the connection
$ L3 t2 e$ h. Y) H  }% T  just closes. If the connection expires in "http-request" while waiting for a6 I$ V' f- I0 u0 n
  connection to complete, a HTTP 408 error is returned.% Z# Z2 N% [$ W( C

8 k5 x7 g+ G0 o3 q5 A$ m+ x. O  In general it is optimal to set this value to a few tens to hundreds of9 ~0 y9 v. b- E* M4 F% q
  milliseconds, to allow users to fetch all objects of a page at once but
- L- x  N8 S9 F# o  without waiting for further clicks. Also, if set to a very small value (eg:
5 {$ S% `$ j7 D+ A) O3 i9 r  H  1 millisecond) it will probably only accept pipelined requests but not the: S/ ]$ R1 k6 p
  non-pipelined ones. It may be a nice trade-off for very large sites running, U0 f3 k3 t6 a) P/ e, E9 _' ^& B
  with tens to hundreds of thousands of clients.2 ]5 Z3 i  T& X/ v3 A# }9 e9 p4 P" ~
2 e9 l2 B: L9 b* Z+ c3 J+ E
  If this parameter is not set, the "http-request" timeout applies, and if both! _- @6 R% f5 {3 B
  are not set, "timeout client" still applies at the lower level. It should be. P& h, `1 B1 C6 S( F1 K: G
  set in the frontend to take effect, unless the frontend is in TCP mode, in) s$ u! v% v. F( {& M6 B
  which case the HTTP backend's timeout will be used.3 {. c2 d  i0 s9 m2 {- I/ {

' f4 t. m1 \, ?. N4 e5 @  See also : "timeout http-request", "timeout client".
2 _! e; X( `- A, b
9 x, n/ a. j, f2 d% X2 c! E) o& c
1 i  s) H3 ~8 C# q& H. jtimeout http-request <timeout>: F; P. u' v" K! {. w
  Set the maximum allowed time to wait for a complete HTTP request
- J+ c3 j# |& k5 H) H  May be used in sections :   defaults | frontend | listen | backend
  p2 F. p, A6 y) L2 @                                 yes   |    yes   |   yes  |   yes
, E# Q% @1 t4 j: O) {  Arguments :
0 f7 M2 z9 d+ e3 v    <timeout> is the timeout value specified in milliseconds by default, but. D, G; ~9 X8 [9 ?3 z. _8 X2 }
              can be in any other unit if the number is suffixed by the unit,
9 n/ {+ {7 V8 k  t3 z2 b! j              as explained at the top of this document.! X! {- M+ ?! c2 {; p  Z
' ^( Q1 L) s, u
  In order to offer DoS protection, it may be required to lower the maximum$ }* I  O; J) h# q
  accepted time to receive a complete HTTP request without affecting the client
# y1 Q. i# L( |( i* x9 ^% ]  timeout. This helps protecting against established connections on which9 a% R) T6 X8 ?7 J& X: V- X2 U
  nothing is sent. The client timeout cannot offer a good protection against: i+ g/ I' p" y( X# F
  this abuse because it is an inactivity timeout, which means that if the
2 R+ U' A! t9 H. _8 t) j  attacker sends one character every now and then, the timeout will not
3 l" g$ l4 q9 n+ p" ]  trigger. With the HTTP request timeout, no matter what speed the client, @. O4 `$ Y$ F0 N6 A( c. K8 H
  types, the request will be aborted if it does not complete in time.
4 Z9 f9 L7 x7 C: m1 I9 a5 X$ M+ e! ^2 M" p& S0 y6 Q
  Note that this timeout only applies to the header part of the request, and
1 ^* o) u9 n& P, W, v, z  not to any data. As soon as the empty line is received, this timeout is not
$ p# [% h+ j6 O6 E1 N; t8 d7 R8 I  used anymore. It is used again on keep-alive connections to wait for a second
' |, e: U4 [0 v# B  request if "timeout http-keep-alive" is not set.* e: W  B, i% C0 A

- C  S4 `/ I* s5 ~  Generally it is enough to set it to a few seconds, as most clients send the$ c) _( H! G; u7 w- I
  full request immediately upon connection. Add 3 or more seconds to cover TCP# h1 d- \" g: U! Z: ~  t
  retransmits but that's all. Setting it to very low values (eg: 50 ms) will
& ^! d; b! t9 E4 _! S2 E  generally work on local networks as long as there are no packet losses. This
# h; G. W' i; r- [0 w/ M  will prevent people from sending bare HTTP requests using telnet.
2 `. N7 e0 F9 |, s3 @+ n! _7 ]
( E/ }& m- K' m9 o. @) n7 \8 d  If this parameter is not set, the client timeout still applies between each
4 C8 e& X+ M) W2 u  chunk of the incoming request. It should be set in the frontend to take
; ~1 ~* p- H  s2 Z" s. }  effect, unless the frontend is in TCP mode, in which case the HTTP backend's. z3 B" Z9 I  k# ?! T6 n; `1 d$ T! M
  timeout will be used.5 P4 ~* w2 ^3 w/ n& ^) _2 H. v- N& S1 ?
' T! p% Y; A% T0 }% k
  See also : "timeout http-keep-alive", "timeout client".
7 I6 Y/ t8 h/ ?9 y% A5 o; G: ?: T
1 C0 c* z! D7 O/ u8 M+ k8 I9 }5 D" }0 _9 m$ ~: H
timeout queue <timeout>0 o* S( D0 A+ K
  Set the maximum time to wait in the queue for a connection slot to be free$ V* O7 K7 o4 R( y3 \$ j6 k
  May be used in sections :   defaults | frontend | listen | backend
+ u' a1 W  a' f# X: w                                 yes   |    no    |   yes  |   yes
3 I2 M# ^  N8 ~9 H3 b9 s9 B  Arguments :
: a8 l1 N0 V$ D4 ~$ R    <timeout> is the timeout value specified in milliseconds by default, but
  w- H9 W5 B9 K' ~0 O# o, o              can be in any other unit if the number is suffixed by the unit,
" @# U) p! H; k1 R              as explained at the top of this document.
& k# u) n& G% g; b; I; g# h9 D7 ?" g: {! j
  When a server's maxconn is reached, connections are left pending in a queue
) o+ J5 O4 \8 ?$ c) ?7 ]7 b  which may be server-specific or global to the backend. In order not to wait- s$ h( D/ Q, b5 B" u0 F: y. K
  indefinitely, a timeout is applied to requests pending in the queue. If the" T6 A0 j, w% a1 F1 z4 f! \
  timeout is reached, it is considered that the request will almost never be
8 O% H8 d- _8 j  R  served, so it is dropped and a 503 error is returned to the client.) @% b8 }; h. T! B2 k

  S0 M* s! W: C2 L! o( N- K  The "timeout queue" statement allows to fix the maximum time for a request to! b/ l) b, b4 f  V2 @- ?
  be left pending in a queue. If unspecified, the same value as the backend's
2 s4 D8 F. _3 Y8 q4 Z  connection timeout ("timeout connect") is used, for backwards compatibility" {1 Q, n' @" C8 K7 M
  with older versions with no "timeout queue" parameter.# d1 }6 ~) O: n* H

& ]. I1 w0 \5 j2 u6 R' {  h1 F  See also : "timeout connect", "contimeout".
) m- I3 A5 H5 K" g  G4 o0 y9 Q' P; B% b; [

+ M% }! M* i  M  M2 ?8 stimeout server <timeout>
0 u4 {: C' e0 k' u3 n" B' h( K9 vtimeout srvtimeout <timeout> (deprecated)
$ h$ M$ ~4 L; l' @# e6 g  Set the maximum inactivity time on the server side.4 l& h1 a( _& x! S1 Z
  May be used in sections :   defaults | frontend | listen | backend& D$ K1 g1 x$ N1 p& D( L
                                 yes   |    no    |   yes  |   yes
4 ]  D% a3 o+ W: o: U" z  C  Arguments :$ Q3 c3 U  w7 s# b& F* \
    <timeout> is the timeout value specified in milliseconds by default, but+ y# T! b4 q6 H$ L6 G% ]
              can be in any other unit if the number is suffixed by the unit,
1 B' r0 }: F9 H3 E              as explained at the top of this document.
3 V% X& ~% M9 _- L: q
5 _3 U* A" t& j" b  The inactivity timeout applies when the server is expected to acknowledge or3 D( r( \/ K, k  L1 Q8 c1 t6 `- T
  send data. In HTTP mode, this timeout is particularly important to consider
- Y! X$ ^2 |8 `% o  during the first phase of the server's response, when it has to send the; A5 L5 c- L6 h5 l# R
  headers, as it directly represents the server's processing time for the3 t, T9 X& L% F+ t& {9 N( O, s# I/ o
  request. To find out what value to put there, it's often good to start with
8 R* _1 q- Y. u4 p# v  M5 G: k  what would be considered as unacceptable response times, then check the logs1 D6 L0 ^* ^  G+ ?9 d' V, |# }
  to observe the response time distribution, and adjust the value accordingly.2 k* [/ k8 G! Q0 o! @
9 V! o1 L0 p6 O
  The value is specified in milliseconds by default, but can be in any other
4 Q$ |0 o$ P, Y4 t/ S1 f% r  unit if the number is suffixed by the unit, as specified at the top of this
5 T6 B  x+ ?# L& `5 P  document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly" v/ ?% U- L  s2 H
  recommended that the client timeout remains equal to the server timeout in* V2 c( a0 d) Y# K) ?, N3 s  p
  order to avoid complex situations to debug. Whatever the expected server
2 b' @- x/ }$ |/ F  response times, it is a good practice to cover at least one or several TCP
- o" l' N6 w' r& j5 O+ d  packet losses by specifying timeouts that are slightly above multiples of 3
. C( F- ?) g8 B- u; N) K( q  seconds (eg: 4 or 5 seconds minimum).0 @" U0 ^8 \9 T& A, F

& v$ w; V: c1 [8 {* G  This parameter is specific to backends, but can be specified once for all in8 H/ H6 |- T: }1 Y; A
  "defaults" sections. This is in fact one of the easiest solutions not to+ [1 {+ c2 D+ w; z* e) G
  forget about it. An unspecified timeout results in an infinite timeout, which
8 {8 m" F# m4 r+ j8 b  is not recommended. Such a usage is accepted and works but reports a warning7 {1 B% ~! B# p* W/ _0 w
  during startup because it may results in accumulation of expired sessions in
9 b7 |  |2 F, _. g. G. K8 P  the system if the system's timeouts are not configured either.
! O9 j% ?9 `; t$ s, [7 S" }3 }' i8 R6 W
  This parameter replaces the old, deprecated "srvtimeout". It is recommended
) l* v+ S; F  D8 w8 D) S! s  to use it to write new configurations. The form "timeout srvtimeout" is! T( \' D. _. a% N5 o0 h/ K
  provided only by backwards compatibility but its use is strongly discouraged.# r. k  a; n5 @% k5 a/ r
3 q* o/ B! }* b$ \3 L5 g: C
  See also : "srvtimeout", "timeout client".
" X! s. z9 J( l9 i" F6 \
, o/ R7 H6 b  v8 x) j6 w. m
2 a8 N! ^4 I3 z, \timeout tarpit <timeout>
2 c6 r! u. i1 z0 K- u  Set the duration for which tarpitted connections will be maintained! `$ j7 L8 o6 N/ W
  May be used in sections :   defaults | frontend | listen | backend
3 _* p- \  q( E" w" F) j                                 yes   |    yes   |   yes  |   yes
' C" h! f8 |( L) H  Arguments :
3 y% p  d2 J- O3 x+ U! f    <timeout> is the tarpit duration specified in milliseconds by default, but
* \4 v$ A1 x) R& I; }% B7 f              can be in any other unit if the number is suffixed by the unit,0 j! i$ r; Y4 R4 M% T3 ^& s
              as explained at the top of this document.
- C! z' c6 H! e6 y8 f  o0 p0 q' ^* g
9 f( Q- g/ W" r  I+ U) Z5 z  When a connection is tarpitted using "reqtarpit", it is maintained open with
  {3 a% M8 O/ t/ y7 f! o  no activity for a certain amount of time, then closed. "timeout tarpit"
) d1 a, l* v8 L0 l  defines how long it will be maintained open.
6 n: I( ?4 \6 [
% Q4 p( b, n  S- q) b  The value is specified in milliseconds by default, but can be in any other( s* i3 D, E, `) v& k6 A
  unit if the number is suffixed by the unit, as specified at the top of this9 F, v* E! a) Q8 T6 {6 A
  document. If unspecified, the same value as the backend's connection timeout: p( {) L) ^  r' K
  ("timeout connect") is used, for backwards compatibility with older versions- _  B. D1 D1 l1 l% z
  with no "timeout tarpit" parameter.
0 V8 `/ ^% I- {& h4 m& K
; @+ u) t$ M) c3 S  d# ~  W4 `  See also : "timeout connect", "contimeout".
' O2 \3 M8 L/ Y; ]
" F0 U4 u7 M/ y6 H& G
& M; [% r/ G: j8 N0 j5 }transparent (deprecated)
7 U1 c$ f3 d5 E  Enable client-side transparent proxying, K+ k' Q+ U0 r1 b  a! P
  May be used in sections :   defaults | frontend | listen | backend
: d/ H8 y$ F  P0 G. y6 k7 }                                 yes   |    no    |   yes  |   yes9 b' l) C; X1 K+ K6 M
  Arguments : none
6 r4 {+ d0 z7 T% i7 W3 \5 F: X  M! }- i4 g# @1 {  _6 L
  This keyword was introduced in order to provide layer 7 persistence to layer, q6 W* Y1 m' |
  3 load balancers. The idea is to use the OS's ability to redirect an incoming1 p9 ?; T* Z3 U1 u: e
  connection for a remote address to a local process (here HAProxy), and let, `6 j! {7 Z9 p+ g1 g; _
  this process know what address was initially requested. When this option is
& _& [+ J5 h5 d  used, sessions without cookies will be forwarded to the original destination
8 b/ O# u! V& l" M8 o! A* N  IP address of the incoming request (which should match that of another0 A# z+ [  g& j, U
  equipment), while requests with cookies will still be forwarded to the) G5 G3 n: P9 j  I+ k' u$ S& i2 O
  appropriate server.4 c* L2 Z/ B0 q) ]+ ~- c0 Y

/ X0 G4 s' f9 E4 P6 H; B  The "transparent" keyword is deprecated, use "option transparent" instead.
, m% a9 q: |5 o5 H3 Q& C
: s1 {* y+ q3 p  Note that contrary to a common belief, this option does NOT make HAProxy
  j, V  f* ]+ z- {: Q7 Q* x" j# p  present the client's IP to the server when establishing the connection.
$ s, k! ~' R' R: Z( W/ k8 x; I+ L/ ?, L# e: t7 m1 i" a
  See also: "option transparent"
2 C+ X3 a0 Y* c* I
0 Z8 X" r1 o+ H/ x; ]- \( b; I
4 h- b6 t& j" Guse_backend <backend> if <condition>% q0 c% Y# B$ I" y# @
use_backend <backend> unless <condition>3 k. |  r( [% J( f* q
  Switch to a specific backend if/unless an ACL-based condition is matched.
  e0 M  p7 g2 z8 O& H; C  May be used in sections :   defaults | frontend | listen | backend
. `4 e# t' Z6 V* q1 Z: m4 }8 E                                  no   |    yes   |   yes  |   no
3 X8 E. t0 P- w& y: m  Arguments :
/ O3 W- t6 Y! i$ x  x% r% j. G/ G& Y; W# R    <backend>   is the name of a valid backend or "listen" section./ x8 r" f2 Q/ U
$ s- O- {  V; C) P$ N4 R1 B8 X
    <condition> is a condition composed of ACLs, as described in section 7.
9 y( m& t; K2 n3 H% P
8 |. h  Y9 D% x* q% j) t, P/ A5 \8 i* A  When doing content-switching, connections arrive on a frontend and are then2 I1 i- L4 u2 d
  dispatched to various backends depending on a number of conditions. The- ]4 b+ q: s! `8 V' J
  relation between the conditions and the backends is described with the4 @& `! J3 G& v: V- d
  "use_backend" keyword. While it is normally used with HTTP processing, it can! G1 B3 i( p* y3 a
  also be used in pure TCP, either without content using stateless ACLs (eg:
2 M: P( @8 N2 P- P: B- V) `4 P) y  source address validation) or combined with a "tcp-request" rule to wait for5 }5 N8 ^2 q: L: d. `7 q+ G
  some payload.7 t% j" B( h% r& R$ Y+ v
, K' ?/ k( [1 S  r6 F8 J5 Y
  There may be as many "use_backend" rules as desired. All of these rules are
: `$ S$ H3 P& C% D  evaluated in their declaration order, and the first one which matches will
; x" d% v# I  r) {8 ?. p! b  assign the backend.
& f+ ?: T. K. J2 Z/ S! P5 \" g
& w0 v/ @5 I# z8 b# ~  In the first form, the backend will be used if the condition is met. In the
% R' W; W" Y/ t1 W# k. d" r  second form, the backend will be used if the condition is not met. If no
+ o/ W5 h4 L: g1 R! [& W, A  condition is valid, the backend defined with "default_backend" will be used.% g* \. h; \: x' b9 i# F
  If no default backend is defined, either the servers in the same section are
" a- E/ ?/ g( q7 h* K. o8 e7 E- f5 W  used (in case of a "listen" section) or, in case of a frontend, no server is; e8 \4 o. ^9 r0 E/ D3 q, W3 r
  used and a 503 service unavailable response is returned.6 s3 F: f. M, ]  g
( u# I5 O: y1 u
  Note that it is possible to switch from a TCP frontend to an HTTP backend. In
% I, E0 ~1 r; H7 O  this case, either the frontend has already checked that the protocol is HTTP,
0 H9 f4 ?- c! Z: P" j- Z  and backend processing will immediately follow, or the backend will wait for
/ J# M# e: F: h. q+ L% E- [  a complete HTTP request to get in. This feature is useful when a frontend
' Q1 d& l1 U. w$ w5 ?  must decode several protocols on a unique port, one of them being HTTP.
/ g5 j. V% v" R' @4 c$ z& k) v: |- u7 _% x) t. c
  See also: "default_backend", "tcp-request", and section 7 about ACLs.
' }5 d/ z; U- w1 `+ B
+ d2 K& m( T) H' P% d( O
( {; J, j) r' f1 q5. Server and default-server options
. m1 d& Y  N4 F7 h/ G1 U------------------------------------' s/ M8 N- e9 O# d+ H; ~

7 q3 e- o* R6 [4 XThe "server" and "default-server" keywords support a certain number of settings$ [1 t8 I. f5 s0 p& X+ i+ V
which are all passed as arguments on the server line. The order in which those
% ~/ n' }9 H6 j7 g  Darguments appear does not count, and they are all optional. Some of those
  {) F; B5 Z) F  x% t9 ~settings are single words (booleans) while others expect one or several values$ h& J* x9 J2 \" o2 d8 F3 j* }! h
after them. In this case, the values must immediately follow the setting name.
) i2 p/ c4 O5 A* v' vExcept default-server, all those settings must be specified after the server's1 B3 q- K& n2 ?8 ^! Y7 |1 v: p" J
address if they are used:
" c5 e4 |5 h+ f- M% }( O& i8 H6 B/ U( q* A! Q3 i
  server <name> <address>[:port] [settings ...]% T  e$ E0 p" R  ~5 o1 ]; v
  default-server [settings ...]
* a* j5 C$ \: a: v. p
( N) |  i1 a& U" g7 G( ?- ^The currently supported settings are the following ones.3 R2 X* D! V' Y9 c
/ |$ _) x, B7 s
addr <ipv4>$ q8 ^' N3 X% ~" H/ x
  Using the "addr" parameter, it becomes possible to use a different IP address4 ]% E. N4 M9 ^+ W  {* r. ?( x  w' \
  to send health-checks. On some servers, it may be desirable to dedicate an IP
* g2 x4 A6 K& X; G  address to specific component able to perform complex tests which are more
  w& Y3 `0 h5 b8 ?# I" q' u  suitable to health-checks than the application. This parameter is ignored if
( ]6 T! B+ L) }& j+ n  f2 J5 i  the "check" parameter is not set. See also the "port" parameter.4 ^! v' I( k- H0 z2 u# [7 v6 s
" K% ?" W9 I' Y) ^5 r8 P9 ]$ w
  Supported in default-server: No" ^0 V( E3 o( p. W- e4 Z+ W4 W

# N( \9 n8 O1 u( I, V: _4 |4 }backup
* v( r. v0 D$ `* z1 \. I  When "backup" is present on a server line, the server is only used in load9 d" ^' R2 s4 K( z: C
  balancing when all other non-backup servers are unavailable. Requests coming* f$ y& b5 X) L( f
  with a persistence cookie referencing the server will always be served& d; e" ~, u/ W( L; U. B; K
  though. By default, only the first operational backup server is used, unless
( R8 ~7 \# c9 F; K. s7 \  the "allbackups" option is set in the backend. See also the "allbackups"
4 o9 p7 e; x3 R7 u" q- S  option.
% l' A) J) z' o9 l6 r2 ?0 S9 u7 R8 P7 q2 |
  Supported in default-server: No
- Q: [: O$ w2 W+ n! x# K  g6 j4 _$ g8 ?
check1 n: z5 G$ X; E" O
  This option enables health checks on the server. By default, a server is
& W2 ^# e  \) @/ N4 b& n7 T  always considered available. If "check" is set, the server will receive$ w5 [: k1 q! u/ R4 b2 H! f
  periodic health checks to ensure that it is really able to serve requests.0 G) V" r2 {/ C( \/ h; |6 y
  The default address and port to send the tests to are those of the server,2 v% N8 Y5 p$ T2 O: Z/ p
  and the default source is the same as the one defined in the backend. It is
; D8 n" T! {: ~9 j4 v  possible to change the address using the "addr" parameter, the port using the- X+ F# Q8 V0 Z) r5 a
  "port" parameter, the source address using the "source" address, and the5 P& g3 W, O4 f) @
  interval and timers using the "inter", "rise" and "fall" parameters. The
! [3 ~. O1 I: G% K  request method is define in the backend using the "httpchk", "smtpchk",/ a/ o* F$ _* {) p( w
  "mysql-check" and "ssl-hello-chk" options. Please refer to those options and! \  s% g; @0 E+ z* J  h
  parameters for more information.7 H4 ]/ T+ i' R% Q) n, D5 Q5 A

, y( |/ M+ w+ g% w7 p1 R5 e  Supported in default-server: No+ F9 `2 Y6 o& D; O
) X5 I  J. d! z, {
cookie <value>; b; m5 I/ H" _" y2 D2 K
  The "cookie" parameter sets the cookie value assigned to the server to2 G% j! V% t5 q# }- l/ {+ M3 t
  <value>. This value will be checked in incoming requests, and the first% k; E4 ]8 ]8 h
  operational server possessing the same value will be selected. In return, in
/ C$ i; [2 P3 ]) j/ ?- t* r  K  cookie insertion or rewrite modes, this value will be assigned to the cookie
- ~2 }* m1 q% F+ ~/ N  sent to the client. There is nothing wrong in having several servers sharing, b- `6 \& e! n9 V3 x/ F0 _: U
  the same cookie value, and it is in fact somewhat common between normal and
+ {/ O" H4 x# s. A" v# R/ b5 C: j  backup servers. See also the "cookie" keyword in backend section.) e+ y' a3 K7 `8 S) s2 ^
. K' O/ Y2 h# c4 @' T0 J
  Supported in default-server: No
! n" y$ k1 F7 R/ J6 ~! r( n2 f9 o( N
disabled0 k& u$ `8 r% h6 a' s# Z: A0 _
  The "disabled" keyword starts the server in the "disabled" state. That means
8 V2 X+ ?# D! o5 X) W  that it is marked down in maintenance mode, and no connection other than the
2 v9 D( o" Y9 [) o3 q2 p  ones allowed by persist mode will reach it. It is very well suited to setup
' \, f& L; z" h6 e; G' `( p  new servers, because normal traffic will never reach them, while it is still, L0 l8 R! `% V  W
  possible to test the service by making use of the force-persist mechanism.
, x9 t  N$ D2 t! q! i9 s2 i( s( Y! |
! s3 q3 I# E5 @; |  Supported in default-server: No
- ^% n0 d" q+ L6 X$ k$ D' @) Q2 s5 K0 n: Q; A# \* t$ V! l" i
error-limit <count>
. E9 `5 K0 x7 A, y( S( v  If health observing is enabled, the "error-limit" parameter specifies the
/ c5 W9 q7 l& l/ g8 A2 E  number of consecutive errors that triggers event selected by the "on-error"5 n4 Z# i- X. d2 ^
  option. By default it is set to 10 consecutive errors.
) H% ]; ]! ?8 |9 X; o9 o. ~
3 S$ s' y3 y- S* H6 Q7 ~  Supported in default-server: Yes
9 ^4 E, h, `9 b" e5 @8 E) }) K! k, C# [, V- d# Q$ W1 b# Q* T
  See also the "check", "error-limit" and "on-error".
9 J3 t9 Z) V8 m' ^& k
: f, e1 }' y" j" Ofall <count>+ w) _) C! o, e7 ?& ~% ?
  The "fall" parameter states that a server will be considered as dead after
, M- V& x" B2 r% {0 q+ `  <count> consecutive unsuccessful health checks. This value defaults to 3 if; Q+ h6 @$ l. s4 b
  unspecified. See also the "check", "inter" and "rise" parameters.
: c/ U9 {! R2 W/ W+ w, q6 C9 z' v/ m2 R
  Supported in default-server: Yes0 S; f3 ?% U$ n3 [. l% a1 B& C* y7 `7 Z
4 S5 t* `: _' j, j& d4 g( j
id <value>; |7 G$ |! K2 g7 S! E: g
  Set a persistent ID for the server. This ID must be positive and unique for
) f- i) x% W) h  the proxy. An unused ID will automatically be assigned if unset. The first6 Y' B6 a8 B% V& |" y3 L4 a
  assigned value will be 1. This ID is currently only returned in statistics.: @* T- @* \6 M4 O. [4 u3 R

- O8 b& ?$ V: r) H& i: g$ p4 f  Supported in default-server: No
7 D% I& q2 a  H
4 R1 G& T8 U6 ]- ?: ^$ cinter <delay>
/ Y9 U* N  e  rfastinter <delay>
( p  L7 ]" m* l$ ydowninter <delay>
: ?* l5 ]' a4 o5 v  The "inter" parameter sets the interval between two consecutive health checks
# ~) J% `9 E9 |* M% G4 m' }  to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms.
3 Q; I1 S" F8 E7 n# `  It is also possible to use "fastinter" and "downinter" to optimize delays/ D$ U) x$ l% ^
  between checks depending on the server state :+ |5 p6 F, F1 n1 ^' _3 ~/ ~

# Y' O# M7 m3 k6 f1 G" k7 c4 M             Server state            |             Interval used
+ O+ x' ~9 N% C* ~: X. u" t2 r    ---------------------------------+-----------------------------------------
6 A* K3 R# {  u% j2 u0 g; D" b- A     UP 100% (non-transitional)      | "inter"
: L# ?/ b2 X9 O7 _5 O    ---------------------------------+-----------------------------------------
1 g' F6 C; _! t; i- w2 y: S     Transitionally UP (going down), |$ i* ^1 P+ k  r$ p' T3 y: I
     Transitionally DOWN (going up), | "fastinter" if set, "inter" otherwise." t% ?& T  P* ]  S4 ]- J. S
     or yet unchecked.               |
  J1 P$ e! [( ~    ---------------------------------+-----------------------------------------
4 e. u6 l4 K$ T# O1 b     DOWN 100% (non-transitional)    | "downinter" if set, "inter" otherwise.; _$ j! Z; j* D; x/ I
    ---------------------------------+-----------------------------------------
7 g, g. P7 T7 Y9 V
8 f2 o. H2 ^, G7 s6 i5 R  Just as with every other time-based parameter, they can be entered in any4 h. o6 v" v  x8 }2 J
  other explicit unit among { us, ms, s, m, h, d }. The "inter" parameter also
; p! a7 f8 G5 H0 [' C" o. O8 C+ R  serves as a timeout for health checks sent to servers if "timeout check" is6 m: s6 Z  k3 a  T
  not set. In order to reduce "resonance" effects when multiple servers are2 _* Z/ b" \* ~  f) l& c) a3 v- m
  hosted on the same hardware, the health-checks of all servers are started
& a1 D3 Y- F3 z+ }  with a small time offset between them. It is also possible to add some random
1 [. ^& c# c  X4 d$ j/ |  noise in the health checks interval using the global "spread-checks"
9 }2 c% q# m' v4 h  keyword. This makes sense for instance when a lot of backends use the same
7 m+ S+ x# P- [; u  servers.: l: T9 C- \4 f- {  w6 l
* m* I( z. `+ q# s8 g. h- j" a
  Supported in default-server: Yes
( {) H7 j$ O. J% [7 k
) @* T- d' X0 M: u+ e# R9 h# Tmaxconn <maxconn>2 r5 r# \9 z9 N' S  q
  The "maxconn" parameter specifies the maximal number of concurrent4 V" Z/ J% e5 T( E/ g
  connections that will be sent to this server. If the number of incoming
1 _* [4 R7 I8 w. U  concurrent requests goes higher than this value, they will be queued, waiting- f; r! u' a( T. L
  for a connection to be released. This parameter is very important as it can! e# |& v  j0 |- M
  save fragile servers from going down under extreme loads. If a "minconn"  F3 V: [( v7 A8 J1 R) e
  parameter is specified, the limit becomes dynamic. The default value is "0"
0 X, `7 K- y5 \2 R5 T- G  which means unlimited. See also the "minconn" and "maxqueue" parameters, and) D" X3 G. r  e% ?2 ?8 P4 i
  the backend's "fullconn" keyword.  S* M6 b: @# n2 E7 q" Z0 _

/ _' @5 {* \( x: J3 k  Supported in default-server: Yes
2 l- [; G& U. j2 |6 o. d$ q5 W4 F& R- a4 D- y3 i/ m
maxqueue <maxqueue>
  S- v% k) ?! C$ K. u+ h' V: A3 [  The "maxqueue" parameter specifies the maximal number of connections which, E6 W; z4 C4 U' h2 H7 `) B
  will wait in the queue for this server. If this limit is reached, next' t8 R8 n2 `! R2 T# ]4 Y% c
  requests will be redispatched to other servers instead of indefinitely# Q- P; D! Q' W5 v; t
  waiting to be served. This will break persistence but may allow people to  h% E+ `, I5 J/ P0 M% E
  quickly re-log in when the server they try to connect to is dying. The: V1 M$ A# U- }9 ]5 n" S/ {
  default value is "0" which means the queue is unlimited. See also the8 ~2 J2 ^& [8 i6 v- ]4 e
  "maxconn" and "minconn" parameters.) o( P) I, H, U# p
5 i9 d% Q% z% @, B
  Supported in default-server: Yes, i: I  _$ Y9 B/ i# m& v, V7 {
* z, V0 B! [$ {9 n2 D
minconn <minconn>
4 u2 ?/ R8 U  ~* \, \  h# {" `4 d  When the "minconn" parameter is set, the maxconn limit becomes a dynamic* H; ~7 y/ |9 K, a) U% x- `6 _
  limit following the backend's load. The server will always accept at least
( V* u7 n: {/ }% a2 M& g5 ]  <minconn> connections, never more than <maxconn>, and the limit will be on$ x7 j- I8 d) _6 v! e4 G( L
  the ramp between both values when the backend has less than <fullconn>
& g$ T" b$ N+ {- I/ i: }. M  concurrent connections. This makes it possible to limit the load on the! [: U; U; ]  b- ?1 M
  server during normal loads, but push it further for important loads without8 W$ O+ y$ F( R* b
  overloading the server during exceptional loads. See also the "maxconn"2 g/ d/ B  \' d0 @: c% w
  and "maxqueue" parameters, as well as the "fullconn" backend keyword.# ]0 ?. y3 e( y

, d& a" W% E, y4 x, R) d  Supported in default-server: Yes5 B: f- W' n; I( X3 h

/ Z( A; o% p- w; Z( k5 o$ Y0 c8 S0 Q  I$ robserve <mode>% z* {5 M6 T# z1 U" q5 E; ^% V& l( p/ M
  This option enables health adjusting based on observing communication with+ e' t$ r3 G) W' w6 d
  the server. By default this functionality is disabled and enabling it also
  S7 h9 z1 u: j2 P7 s$ w) D* l  requires to enable health checks. There are two supported modes: "layer4" and
9 _4 `( `, V) J/ x  "layer7". In layer4 mode, only successful/unsuccessful tcp connections are4 G$ K$ w$ ^% ]
  significant. In layer7, which is only allowed for http proxies, responses# K; }( s- c' ]9 h( v6 ]: J# U0 w
  received from server are verified, like valid/wrong http code, unparsable
# v/ z/ d5 R4 h8 x* B1 h" m2 W  headers, a timeout, etc. Valid status codes include 100 to 499, 501 and 505.
# A7 b: @  |* r# {1 N" k: N, W4 b& C
" ]4 r4 @/ G4 f2 ^. h& |% F  Supported in default-server: No
6 L8 n0 k# M: F1 @
9 e0 n8 O$ `; W) G9 |8 e! h/ Z  See also the "check", "on-error" and "error-limit".) G9 o+ W4 P! c/ D: I

: O! l2 S$ v% e3 l# Son-error <mode>
/ O$ {0 j# A; {/ n& x  Select what should happen when enough consecutive errors are detected.3 {* m% m% c9 t
  Currently, four modes are available:$ _. l/ r2 \  O; @- ?# [
  - fastinter: force fastinter
- R* k" K/ s0 K% y  - fail-check: simulate a failed check, also forces fastinter (default)& L0 S, B, O- b. A
  - sudden-death: simulate a pre-fatal failed health check, one more failed+ p' X1 \6 A2 D. z+ M( Z
    check will mark a server down, forces fastinter+ t* L! M# y- [+ I0 `! w
  - mark-down: mark the server immediately down and force fastinter* ^/ s5 S( @- t: @1 k
& s2 L0 f) @% S! f, S0 K/ p% r$ e& F) L
  Supported in default-server: Yes0 J" A" d. e, z/ z

* ]1 d/ {# j% p) y: v% n  See also the "check", "observe" and "error-limit".
) b9 O8 t1 u8 G. ]4 ?0 d, Q5 U* @) ~- R* w) X5 m
port <port>
1 I& p. T) ^4 h0 I5 R. y8 }  Using the "port" parameter, it becomes possible to use a different port to
2 Q: |1 ~  Q" q! c$ M& v# y  send health-checks. On some servers, it may be desirable to dedicate a port
2 T$ ^, J* d% b3 C  to a specific component able to perform complex tests which are more suitable, m" R9 i( q  c
  to health-checks than the application. It is common to run a simple script in
/ i* I/ ~6 ]4 I  inetd for instance. This parameter is ignored if the "check" parameter is not7 p4 m4 ~; b( X" I
  set. See also the "addr" parameter.
1 e1 |5 {; }- C5 x% Z3 x2 L$ t  u5 z$ `, W/ }! S
  Supported in default-server: Yes
# F# H, i) i. L$ ^6 {2 R- h
" i& q. ^. \/ t, L8 B4 L' _redir <prefix>" t- Q; s5 _" Y2 C/ h
  The "redir" parameter enables the redirection mode for all GET and HEAD
" `. T% N- a* s  r4 f+ m' m  requests addressing this server. This means that instead of having HAProxy
1 |2 v% n+ L" j2 |6 P6 w" V  forward the request to the server, it will send an "HTTP 302" response with
& v  |: V/ {% m: F5 a  the "Location" header composed of this prefix immediately followed by the
/ Y# w: ^& ]9 f; \4 F3 g  requested URI beginning at the leading '/' of the path component. That means
% `, y& Y2 H6 ?; B4 U% V  that no trailing slash should be used after <prefix>. All invalid requests
+ z- l) V( v8 Y  will be rejected, and all non-GET or HEAD requests will be normally served by
* Y4 j- m. A/ \5 @  the server. Note that since the response is completely forged, no header
$ j" p# v8 ^0 H  G/ ?2 J! d/ O  mangling nor cookie insertion is possible in the response. However, cookies in/ o- j- X) t4 m& Q
  requests are still analysed, making this solution completely usable to direct
. ^! |- l: M3 z5 K! @- G6 m  users to a remote location in case of local disaster. Main use consists in7 q) \/ V7 k" {% s2 [
  increasing bandwidth for static servers by having the clients directly" T1 N/ k; ^/ d
  connect to them. Note: never use a relative location here, it would cause a" S5 U* D# E' F  [  }% m' b
  loop between the client and HAProxy!
. T+ c" |9 H. L  N* W" g
1 P6 S% n) Y$ j  Example :  server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
$ o4 J6 j5 ^9 E/ z2 P. P# c
% m- u/ k" X# s$ o  Supported in default-server: No' z9 S+ |5 r- z. T: T' r3 v

" h: C# u& e( Y) m9 j9 yrise <count>
3 w5 L( H2 h; y4 P1 _7 E/ X0 E, Q4 ^; I  The "rise" parameter states that a server will be considered as operational; @, F9 q9 b2 c5 p% n& Z
  after <count> consecutive successful health checks. This value defaults to 2
2 G  v. Q8 ~: O7 D8 K% a  if unspecified. See also the "check", "inter" and "fall" parameters.
+ P4 S6 N0 g+ `3 g1 t, {) g9 h- ~) e4 f! ^5 N# L& `- {4 P
  Supported in default-server: Yes
" Q2 a  u. l9 A! ]' V! y  D( x
  ?; A9 t' v1 {9 |0 vslowstart <start_time_in_ms>
8 U( G6 K0 ~+ o8 `4 s, b% L  The "slowstart" parameter for a server accepts a value in milliseconds which5 q8 x4 B$ f  N3 U5 i
  indicates after how long a server which has just come back up will run at) X) n! `! o$ a: |+ Q7 c: f) \2 b$ |$ g
  full speed. Just as with every other time-based parameter, it can be entered9 n' W2 Z! r: u- Y9 I
  in any other explicit unit among { us, ms, s, m, h, d }. The speed grows9 T) o& R( x, C6 j* H+ }) U. h) l( }
  linearly from 0 to 100% during this time. The limitation applies to two
0 y. \+ |  T. l8 y7 h7 K- p  parameters :( h) q! F; }3 a8 u. B

8 B. D& h; X  e8 \& o; Z  - maxconn: the number of connections accepted by the server will grow from 1
1 R9 N3 f- y: H" \4 ^    to 100% of the usual dynamic limit defined by (minconn,maxconn,fullconn).. S* g9 L7 n  B7 I3 g! G% ~

2 |6 j% \4 C" o, |  - weight: when the backend uses a dynamic weighted algorithm, the weight; g: H7 B) \$ M1 }
    grows linearly from 1 to 100%. In this case, the weight is updated at every  z7 T  n* z8 M% }5 Z3 R
    health-check. For this reason, it is important that the "inter" parameter4 C5 m% q8 X4 o8 }5 U
    is smaller than the "slowstart", in order to maximize the number of steps.
2 L* n' ?; K. Z3 Q% q$ S1 ^+ D
  The slowstart never applies when haproxy starts, otherwise it would cause* l. ?9 c% Q: G1 J+ q# B. j
  trouble to running servers. It only applies when a server has been previously& x, S% j: ^% i) b9 w
  seen as failed.  b* v( M( k* w8 l( F

$ l4 t! V: b( [& H0 u# }  Supported in default-server: Yes
) n6 D# r- L2 o& X+ g/ t# o2 y+ I
$ r, e- B: t% ~source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]3 C4 L3 _. U* S& u. `
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
3 A  S: G1 e6 }9 l+ i6 t. qsource <addr>[:<pl>[-<ph>]] [interface <name>] ...7 e) B$ A1 c% W. U! b7 R
  The "source" parameter sets the source address which will be used when3 h6 P: U4 H' p
  connecting to the server. It follows the exact same parameters and principle
6 H8 p% b0 ?: `  as the backend "source" keyword, except that it only applies to the server
8 ~# J. M4 K7 L4 l* A+ z  referencing it. Please consult the "source" keyword for details.
( c8 t/ X' ^& C7 L! h2 m- r; k) x' ^/ E1 b7 H' t
  Additionally, the "source" statement on a server line allows one to specify a* x# r1 M( K( G: a' I: d
  source port range by indicating the lower and higher bounds delimited by a
* ^% |5 `! b1 ~3 K  dash ('-'). Some operating systems might require a valid IP address when a( ?) L, ^9 X6 D- F
  source port range is specified. It is permitted to have the same IP/range for" v6 x+ U" y- t" C2 S8 D
  several servers. Doing so makes it possible to bypass the maximum of 64k, B' J, O4 d; w2 A, C
  total concurrent connections. The limit will then reach 64k connections per6 z( W. f! |+ F5 g5 t2 B: k3 {% M# n
  server.
8 J  m; `1 h/ H  P7 X4 |% {
0 J. t" a3 R- g$ J  h  Supported in default-server: No
) b: a& N8 K* q. }5 V* T1 r& R+ s1 }+ e! ?+ U  G
track [<proxy>/]<server>- e9 t5 B  X1 E5 j2 f
  This option enables ability to set the current state of the server by: C3 R2 B( `/ Z( y2 O5 v; M
  tracking another one. Only a server with checks enabled can be tracked0 z) N& O' t; y7 h, _) Y& i
  so it is not possible for example to track a server that tracks another; {1 h. M' r: i3 @
  one. If <proxy> is omitted the current one is used. If disable-on-404 is
8 |8 {7 V) }5 Y( p% x" U  used, it has to be enabled on both proxies.
$ N2 z. T6 H! z9 ]  r% P
$ f8 S+ @: E; j$ k" ]  Supported in default-server: No
; G- Q+ p6 P* k0 x
; O' V% I' m( D+ y% O, b6 f. @4 ?weight <weight>
6 p: G* |* }' J  The "weight" parameter is used to adjust the server's weight relative to
$ I3 k3 e; U% s$ D: }  other servers. All servers will receive a load proportional to their weight2 |$ p; B) ^0 j! P- N0 W1 ^* v9 E. U
  relative to the sum of all weights, so the higher the weight, the higher the* z# Z$ `/ U0 s2 J2 {% a
  load. The default weight is 1, and the maximal value is 256. A value of 03 n; d8 L7 ~$ p: M5 C2 q5 Q* j4 K
  means the server will not participate in load-balancing but will still accept5 z, o: V7 u# R
  persistent connections. If this parameter is used to distribute the load' E6 n; y" S# _+ d- s' d) N2 _4 J
  according to server's capacity, it is recommended to start with values which1 ]5 @/ A4 q& Y  _3 W
  can both grow and shrink, for instance between 10 and 100 to leave enough
4 Z- D7 v# H3 g+ H  \  room above and below for later adjustments.) O  o4 A4 m" h8 M

6 T! l% ^" ?) ?, J- Z2 ]  Supported in default-server: Yes
" n2 @- j' J6 b6 q) F' R! [, i
# g# e) G% f) ?) e. A  A
3 b+ Q7 s, O, T) K7 |6. HTTP header manipulation8 I% v; m3 x- R4 C9 P6 x" Y
---------------------------- h7 |5 g5 ]- @' t+ G

2 T0 u: b& E, Q2 g+ s* B$ {In HTTP mode, it is possible to rewrite, add or delete some of the request and
) K# m1 F( y; S* \, aresponse headers based on regular expressions. It is also possible to block a
6 m! q1 F9 ?. _: l* y- W5 Brequest or a response if a particular header matches a regular expression,4 H2 l* N4 [! P4 m" D  c& X  w
which is enough to stop most elementary protocol attacks, and to protect
1 g! T% D7 ?  _8 s3 vagainst information leak from the internal network. But there is a limitation
* h, N% |5 Q* g. a! m& Dto this : since HAProxy's HTTP engine does not support keep-alive, only headers$ d( @$ \# {$ n: d2 N
passed during the first request of a TCP session will be seen. All subsequent
# G+ @. s5 @# {4 p' K' D7 qheaders will be considered data only and not analyzed. Furthermore, HAProxy
( i* L: A6 j9 a% F/ _never touches data contents, it stops analysis at the end of headers.
5 N3 {0 B+ @. J! Y2 B" C6 E
4 S) G! t' o7 t9 z! Y# r/ CThere is an exception though. If HAProxy encounters an "Informational Response"
/ I) f1 x( X" _' Z* `(status code 1xx), it is able to process all rsp* rules which can allow, deny,4 G! D7 z; e# I: B
rewrite or delete a header, but it will refuse to add a header to any such$ Z! }/ M2 H" |, t  n4 k
messages as this is not HTTP-compliant. The reason for still processing headers4 J! J- u4 d. m0 ~, {
in such responses is to stop and/or fix any possible information leak which may
2 M/ x! A; W  thappen, for instance because another downstream equipment would unconditionally
, Q& G% p7 Q4 V4 G, B6 Ladd a header, or if a server name appears there. When such messages are seen,# x6 m& v6 s  O- `
normal processing still occurs on the next non-informational messages.& `) K3 y9 K3 T/ @

5 X4 a6 h5 g) [* i; {This section covers common usage of the following keywords, described in detail2 p0 o6 `$ m, [" g2 y' k
in section 4.2 :
8 G9 u/ K1 \" U5 v8 f7 ~# f4 w( I- Z. S5 q- R. d
  - reqadd     <string>8 A0 [3 q5 `: N* T% v
  - reqallow   <search>$ K, S" J* u& ]$ T
  - reqiallow  <search>& V, V6 U+ e7 T
  - reqdel     <search>: k- D* U# w; X3 G
  - reqidel    <search>% A8 e3 b  J' ~* }* M
  - reqdeny    <search>5 m' E. Q9 Z9 a. M. v
  - reqideny   <search>
* N/ Z. t0 f& X& Q' B  P( X  - reqpass    <search>
0 e' J* g5 z. @' f6 w6 a1 F  - reqipass   <search>
! {$ [8 u( v* t2 d1 C- x+ T, P  - reqrep     <search> <replace>
* @  L9 H% v' v" L* ^  - reqirep    <search> <replace>
: X- z' x, B; |& r% h. g4 x& R2 i  h5 m  - reqtarpit  <search>1 G* W7 v. E! e9 p& J. Y+ J
  - reqitarpit <search>, X1 H( \5 A4 i
  - rspadd     <string>3 J( l3 a* a9 W+ m/ r5 g) W
  - rspdel     <search>3 T& L6 B' x' O1 Y& B' z1 e
  - rspidel    <search>) L0 e7 M) t9 r; {& O/ D) T
  - rspdeny    <search>& V  U5 g  ]; q. \
  - rspideny   <search>
: b# A8 N" G4 r- Q; O: p0 j  - rsprep     <search> <replace>, R1 e9 g1 S' A$ @
  - rspirep    <search> <replace>
/ P! j/ |' S$ w+ l9 K! a) F/ k! b
With all these keywords, the same conventions are used. The <search> parameter- H7 m- d0 Z+ u4 ?& H5 W
is a POSIX extended regular expression (regex) which supports grouping through8 ~$ b& X' B) l" w
parenthesis (without the backslash). Spaces and other delimiters must be5 Y3 }9 M* W5 P' G
prefixed with a backslash ('\') to avoid confusion with a field delimiter.4 ]" U# p& ^8 X; R1 G' r
Other characters may be prefixed with a backslash to change their meaning :
1 F8 k% @; Q. p" r+ A
& j' y5 u. K& W. P  \t   for a tab3 T) B0 P2 H4 G( q% u( _' w
  \r   for a carriage return (CR)
% N/ Y* T0 u- z; ]2 y  \n   for a new line (LF): Q& R* N- t) D
  \    to mark a space and differentiate it from a delimiter- {, l5 D7 R  @2 {/ I5 [
  \#   to mark a sharp and differentiate it from a comment% C6 Q# T: Y; |& v
  \\   to use a backslash in a regex
$ ]$ `. S  i$ }0 w$ j3 }  \\\\ to use a backslash in the text (*2 for regex, *2 for haproxy)' J  o+ j: n2 y4 B
  \xXX to write the ASCII hex code XX as in the C language: S7 n5 ?  A1 e& b* Y/ b# d

/ X+ l& Q8 T* X* lThe <replace> parameter contains the string to be used to replace the largest( K' D8 ~% y, j6 p
portion of text matching the regex. It can make use of the special characters
/ ]$ i4 f- }& d1 l& b$ S; B: Eabove, and can reference a substring which is delimited by parenthesis in the
; B7 z  D# L2 z6 t1 K. lregex, by writing a backslash ('\') immediately followed by one digit from 0 to
2 ], R5 ^% F3 y8 A0 t! C9 indicating the group position (0 designating the entire line). This practice' X1 q7 j. F+ v7 ]7 S( ^8 p* ~
is very common to users of the "sed" program.5 I* N+ l9 `& V. k1 D$ e. z% d

7 `% l: M& T  K' g" N/ OThe <string> parameter represents the string which will systematically be added
" ~; U2 m& R4 `6 O$ U  |( dafter the last header line. It can also use special character sequences above.8 B/ u1 K9 U  T( c3 D1 B) b$ ]! h
7 V! N5 x2 R, f) p$ y  [5 t
Notes related to these keywords :
$ B6 z. Z# z" e2 K$ @. Y, Y- j9 U---------------------------------( b- q* F' W2 ^+ B
  - these keywords are not always convenient to allow/deny based on header
+ E1 }$ E& ~4 {2 W    contents. It is strongly recommended to use ACLs with the "block" keyword
- S/ }- |* p9 B    instead, resulting in far more flexible and manageable rules.
. a0 {/ y9 n( g1 N8 q6 F" U4 l1 F, I
  - lines are always considered as a whole. It is not possible to reference
* X7 [4 N4 J- A3 z' J2 T7 m8 ]$ }    a header name only or a value only. This is important because of the way
/ r3 F# k2 `& w# T) C    headers are written (notably the number of spaces after the colon).
5 U* w7 ~3 |+ D1 k* A8 G2 x0 X. z/ y5 ]" N3 w
  - the first line is always considered as a header, which makes it possible to$ O1 p8 }0 ~4 P" B# r# T
    rewrite or filter HTTP requests URIs or response codes, but in turn makes1 \& ^" q9 q8 \$ l& {1 m8 l
    it harder to distinguish between headers and request line. The regex prefix
! X  z. }5 \( G) J0 B" Q9 J8 o9 R4 z    ^[^\ \t]*[\ \t] matches any HTTP method followed by a space, and the prefix- w! b( y; P7 `) f& x) x) F
    ^[^ \t:]*: matches any header name followed by a colon." U; ]* e1 f0 r
2 R' \$ c* U% ]9 V. \9 }% W8 b- a( A1 o) m
  - for performances reasons, the number of characters added to a request or to( e6 e9 o& A& w5 w
    a response is limited at build time to values between 1 and 4 kB. This
8 x: O- q" F$ N! O: N    should normally be far more than enough for most usages. If it is too short2 R& Y2 i1 _8 z" b
    on occasional usages, it is possible to gain some space by removing some
/ ?: i# v5 D8 m$ C- A0 c    useless headers before adding new ones.
# e" k: _$ a! B: y# |( M% H7 G0 d  L4 e
  - keywords beginning with "reqi" and "rspi" are the same as their counterpart+ Q  }# t& V/ L" E
    without the 'i' letter except that they ignore case when matching patterns.5 W0 S8 t6 j/ m/ F

8 p$ M& o) T- P& M  - when a request passes through a frontend then a backend, all req* rules
! z7 L2 `9 I; X6 x: j    from the frontend will be evaluated, then all req* rules from the backend
4 A' E- f  b: n0 ?1 `+ U3 t5 ?7 _    will be evaluated. The reverse path is applied to responses.
& o& `1 @- j- x9 |8 R
' e# n# N8 t% L! X' V& v  - req* statements are applied after "block" statements, so that "block" is4 M9 Y) w, c$ v( b! W( O
    always the first one, but before "use_backend" in order to permit rewriting
2 z( r% F" b& O3 J2 s) ~+ q    before switching.
9 Z% `0 O, P# w* @6 [  s
! D1 d' i- A5 M  `( v% Q
. G" x; G4 y5 y4 q9 B( b7. Using ACLs and pattern extraction8 I6 J( Q& g0 i  {; N; P
------------------------------------  r& G, T" G4 h: P  O- `
3 n; t0 Z2 t& l) a' ^8 T
The use of Access Control Lists (ACL) provides a flexible solution to perform7 l0 K$ @$ ^% E! g
content switching and generally to take decisions based on content extracted
5 j$ C  S- J2 \# K7 n& g4 i# D  n! [from the request, the response or any environmental status. The principle is
  z; U0 ~: Q* Lsimple :3 I3 x* f" W3 P; c

  w$ ^$ |! x9 k  F' m1 {; j  - define test criteria with sets of values' M! j( e1 I  D; \" [! X
  - perform actions only if a set of tests is valid
. R4 @# i7 x3 W
0 I6 _+ }/ Y# f# HThe actions generally consist in blocking the request, or selecting a backend.# `( t, z/ e  D  S' T# }8 H
1 x% R! J8 N* j% d7 a
In order to define a test, the "acl" keyword is used. The syntax is :
7 D: H) G! N3 f0 C% b$ J6 r% T7 h' s2 f3 V1 O$ j) ^, E
   acl <aclname> <criterion> [flags] [operator] <value> ...
( B! ^) v* d! ~+ Q9 m) {  @5 ?, v3 v6 z6 H: ]# X
This creates a new ACL <aclname> or completes an existing one with new tests.. w, i( w1 S  w1 N
Those tests apply to the portion of request/response specified in <criterion>5 t' l* Y& w( Y/ s# G$ F
and may be adjusted with optional flags [flags]. Some criteria also support
+ P1 z, Y0 I$ S- l6 f- man operator which may be specified before the set of values. The values are
2 ]% |2 S4 n6 j" Rof the type supported by the criterion, and are separated by spaces.: @! [5 w3 ~0 I3 F: {( W8 ^/ [
9 d; \5 }  n4 p1 {: _: \9 f
ACL names must be formed from upper and lower case letters, digits, '-' (dash),& ]$ T/ o" q0 j2 g! n4 C* o) U& [
'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,( ~; f+ b1 `) M
which means that "my_acl" and "My_Acl" are two different ACLs.+ p2 S$ @! K- `
# p; k; Z; J5 [: B
There is no enforced limit to the number of ACLs. The unused ones do not affect. O5 E: C% @/ @- `! m) Y6 e
performance, they just consume a small amount of memory.
6 Z( K" g' F7 q+ {0 b4 H0 Q4 k" Z
1 v9 w2 g. E5 c: H  Q8 ~The following ACL flags are currently supported :
0 S% t( k- Y/ `6 E5 W2 E7 h3 Q/ b5 o0 L3 t
   -i : ignore case during matching of all subsequent patterns.1 O& u% m: s0 b) @# P3 y# K# p
   -f : load patterns from a file./ C* V9 R6 [) v
   -- : force end of flags. Useful when a string looks like one of the flags.
- I+ O3 N! `' T
1 L( ?' e  T: YThe "-f" flag is special as it loads all of the lines it finds in the file9 Y" T  k! _! q$ x
specified in argument and loads all of them before continuing. It is even3 x+ b2 R/ d/ Y2 _
possible to pass multiple "-f" arguments if the patterns are to be loaded from! q3 c3 F( f0 c/ V% {
multiple files. Empty lines as well as lines beginning with a sharp ('#') will
' i( ^5 Q/ m6 S- Rbe ignored. All leading spaces and tabs will be stripped. If it is absolutely1 U3 i( D) _7 h1 u& G; @; s- R
needed to insert a valid pattern beginning with a sharp, just prefix it with a( T" O5 Z( V0 k2 g' [
space so that it is not taken for a comment. Depending on the data type and
3 ?1 H6 Y& J* pmatch method, haproxy may load the lines into a binary tree, allowing very fast; P0 w# D) O" N9 i- }" ?: D2 i8 P
lookups. This is true for IPv4 and exact string matching. In this case,+ |5 R" R2 b- P3 T; h, m
duplicates will automatically be removed. Also, note that the "-i" flag applies7 _4 i+ v* O) O, T) ]! I
to subsequent entries and not to entries loaded from files preceeding it. For
' W0 S; V% o- i7 p+ finstance :
% v8 F. u7 v9 q6 g; ]: D) r3 X' _9 Y  b/ s
    acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst  test
* N) z6 n6 J1 I3 o& n3 M1 J8 Y) f% M+ _/ c  @# \9 l" f
In this example, each line of "exact-ua.lst" will be exactly matched against
( B; C7 L: b3 i) X* cthe "user-agent" header of the request. Then each line of "generic-ua" will be
+ h6 T2 u4 l' S( `! L# Ocase-insensitively matched. Then the word "test" will be insensitively matched1 }! k6 S9 b' M, Y/ }
too.8 A3 p4 W4 m+ s& R. h; {! R

/ G5 |8 j- U& E* n5 U, @* t' xNote that right now it is difficult for the ACL parsers to report errors, so if
( x; d: J6 s  g7 Q# z4 @a file is unreadable or unparsable, the most you'll get is a parse error in the
* C* G9 Z# ~) ]. V6 y" nACL. Thus, file-based ACLs should only be produced by reliable processes.
0 K+ O( |, q) i9 X- B
& I  O2 G) q3 m) l# {6 @Supported types of values are :7 _$ ]2 B+ `* H7 M4 P- D4 K) g

5 l* C# x7 ]9 Z  - integers or integer ranges
" G0 ]0 l/ ]1 k) T( Y1 k8 t  - strings) ^$ D; Y9 s+ z6 O
  - regular expressions7 J0 z2 S! u$ U% [" w
  - IP addresses and networks) Q0 e) k# ^, g2 |8 C

6 F8 F$ Y; L  q/ |
4 t8 O) f, ^/ Q7 v7 @6 U7.1. Matching integers3 ?1 B' d) P9 r1 [5 p- M- K
----------------------
7 ]  n( B2 A% `/ w6 f; F8 Z
/ z: }" {* t2 ^! C5 r, Y2 FMatching integers is special in that ranges and operators are permitted. Note
. l; D) T) G) E6 N: Zthat integer matching only applies to positive values. A range is a value
+ Z1 q0 O/ y5 eexpressed with a lower and an upper bound separated with a colon, both of which
4 [- l, d" O/ F6 k. `9 ~/ @0 omay be omitted.
. w/ i8 j% ?5 a, B/ N% \4 V1 O! b" c: I; u. }
For instance, "1024:65535" is a valid range to represent a range of
/ s8 w3 v4 @& @' ]* |0 |unprivileged ports, and "1024:" would also work. "0:1023" is a valid
4 q4 _! U4 t$ |( \# k% i0 i8 {3 q1 _0 Nrepresentation of privileged ports, and ":1023" would also work.
. m, G( t6 O9 g# T# M. D+ I
8 j0 Q, s; K7 `; t% g- j. Q* @( n7 tAs a special case, some ACL functions support decimal numbers which are in fact4 F0 ^0 h+ m# l0 C2 l8 \2 w/ q
two integers separated by a dot. This is used with some version checks for
$ N! [% Q( I4 x9 {" j0 oinstance. All integer properties apply to those decimal numbers, including
: e7 I+ c& Y; R% }, @! hranges and operators.( B- S" K% t* g, x5 s" M+ y! x+ N

; Z3 ]! A3 {" W; N2 _For an easier usage, comparison operators are also supported. Note that using, E$ L4 K6 m9 `$ t. A0 E
operators with ranges does not make much sense and is strongly discouraged.3 [, [  C; I/ I9 M( x# Z
Similarly, it does not make much sense to perform order comparisons with a set
. A% T  F7 ^2 k! H$ k# sof values.9 c/ C. ?* y$ i+ W
& Y3 U( \# X+ E  D$ w5 y; @& F$ N- d
Available operators for integer matching are :
' Y5 t; F6 s' Y+ h$ v9 H
4 z( U. J' j( q) d7 I2 w. r7 Q  eq : true if the tested value equals at least one value
& Y3 B) l" a6 t: S0 }8 i7 B  ge : true if the tested value is greater than or equal to at least one value
# Y  u% K! R( P  gt : true if the tested value is greater than at least one value2 d8 V7 J' Q" `1 H( d
  le : true if the tested value is less than or equal to at least one value
: B- S& Y" u# Q: L+ B  lt : true if the tested value is less than at least one value1 f$ n5 f  O  u( Z+ ?: B( [
! o  n: a& ?8 k# ]" t- L
For instance, the following ACL matches any negative Content-Length header :2 P$ L* J5 B. g8 R

/ y6 q7 N3 W' o" _' c  acl negative-length hdr_val(content-length) lt 0
! Z& t6 S' w. ]% J% @& d9 s& N' C- o
- D! x4 d/ D5 f2 AThis one matches SSL versions between 3.0 and 3.1 (inclusive) :+ x+ C  A0 ^/ t7 s
9 ~  m" x  N1 s
  acl sslv3 req_ssl_ver 3:3.1& w1 a# w6 `$ s* d& y' G, D! C, ]) F

% C2 g) Y/ c$ w# P
8 Q& [1 A: G% z/ S1 x7.2. Matching strings
) B4 J% ~* g; i3 J) Y---------------------7 j5 q- g6 f# r

' a8 A! V$ K! F1 f- C7 ?& O* JString matching applies to verbatim strings as they are passed, with the
7 G/ I1 _3 k/ B  j6 D5 jexception of the backslash ("\") which makes it possible to escape some
/ e* c9 f" e5 Y( s) Q0 `0 R" ~characters such as the space. If the "-i" flag is passed before the first! O* Z6 V4 Q, Q3 b
string, then the matching will be performed ignoring the case. In order5 F  b7 u, Z' }$ [. y  W
to match the string "-i", either set it second, or pass the "--" flag
$ |% L. X! f: \6 S, g& x9 Ibefore the first string. Same applies of course to match the string "--".  p4 F) w6 \, Y1 }7 s
+ M" Z3 x( S' L& {" p7 P2 i3 E: A
' k) k8 v  g8 }& ?/ E
7.3. Matching regular expressions (regexes)7 i% r' T/ U, I) |
-------------------------------------------2 o; p1 Y8 |) N- }

' d: `4 I" B+ ~. [Just like with string matching, regex matching applies to verbatim strings as
! u, T& A& [& c5 O, ythey are passed, with the exception of the backslash ("\") which makes it) ?8 q9 I; D. j! B* ~
possible to escape some characters such as the space. If the "-i" flag is
& U4 N) T6 v: U- V2 Kpassed before the first regex, then the matching will be performed ignoring
. n2 ^/ a' W) j! U: Jthe case. In order to match the string "-i", either set it second, or pass- j9 u. G# P% @) H2 n
the "--" flag before the first string. Same principle applies of course to" j0 a, M& q+ `* [7 B
match the string "--".
* C7 W$ R: q9 x% R# Z2 z
+ \6 P% ]: X" @; ?# Q6 A7 X: k
- N: N( a% v; N8 C7.4. Matching IPv4 addresses
+ H# z0 r" [, {& J8 p----------------------------
3 [( p3 k4 T+ \( k  R% f- l( Q0 ~( C& a/ R
IPv4 addresses values can be specified either as plain addresses or with a* o( y  `" \  t1 j7 }$ r
netmask appended, in which case the IPv4 address matches whenever it is! ]# |) k$ w) s) Z/ s9 q: v
within the network. Plain addresses may also be replaced with a resolvable1 \) }9 }1 J* ^, s+ n$ R. m: E& z
host name, but this practice is generally discouraged as it makes it more; d# X1 R$ a* O
difficult to read and debug configurations. If hostnames are used, you should
. C- J  ?( T. O, Cat least ensure that they are present in /etc/hosts so that the configuration
9 w9 K9 a6 u6 Ddoes not depend on any random DNS match at the moment the configuration is. V- k" o' Z2 G* e
parsed., f2 \; t. l' u2 F1 B- R9 F# W

& x* T5 N) E* O6 D$ _- V! D( a( W6 D) v; X; t  l
7.5. Available matching criteria
! B3 {  V/ T3 `/ F- I1 v--------------------------------( `2 W* Q- ?' q/ W7 m4 G
/ I$ Y' g  i- p
7.5.1. Matching at Layer 4 and below3 L$ H  X2 y  G4 U0 g
------------------------------------: p3 g: a) l: Y8 I0 L2 ]$ Y& L
- t+ M9 _" ]& {  t
A first set of criteria applies to information which does not require any
7 ~2 q+ h  M! ^8 panalysis of the request or response contents. Those generally include TCP/IP" \" Q! P3 c( w* R
addresses and ports, as well as internal values independant on the stream.+ p% r: k" y( M% e! X  C+ f
+ A2 A, `( F' y5 H# `# p( J
always_false
7 Y6 N. [2 ?- S' ^  This one never matches. All values and flags are ignored. It may be used as. w9 V# b7 U' G/ q
  a temporary replacement for another one when adjusting configurations.
& Y/ S, Z7 ~" y% _9 [$ O4 B
2 |- e% X+ [6 ~, D2 W! ]3 @/ V$ Y- `always_true
4 l  @. C# P7 X5 k/ U/ E$ h6 U( X: F+ v  This one always matches. All values and flags are ignored. It may be used as
' o7 O% @1 X0 H1 |  a temporary replacement for another one when adjusting configurations.$ x/ v% j& G7 H1 z  `; i1 L1 G
% N. _' H( T; G
avg_queue <integer>
7 Z3 l7 z6 e$ ~4 l; R9 e: V( y5 H4 Xavg_queue(backend) <integer>, y4 ?4 N: a# M
  Returns the total number of queued connections of the designated backend: b- V6 v' [6 R
  divided by the number of active servers. This is very similar to "queue"& k. ]) l6 ~3 ]4 M! L3 W! H* e
  except that the size of the farm is considered, in order to give a more& w" x( @$ e: J' Q/ g' i
  accurate measurement of the time it may take for a new connection to be7 Y8 `# n! e0 r* A! W; \7 q! y; k
  processed. The main usage is to return a sorry page to new users when it
/ g/ a% s! U- _$ j1 Z9 M  becomes certain they will get a degraded service. Note that in the event% @9 n* b) S9 r8 v
  there would not be any active server anymore, we would consider twice the5 R! D, ?+ F8 C/ J0 q8 ?$ ~) ]/ Y
  number of queued connections as the measured value. This is a fair estimate,  {6 x2 U/ G4 Q& l$ F6 @% W* |
  as we expect one server to get back soon anyway, but we still prefer to send
# ~' |3 [  `/ f& ^" M  new traffic to another backend if in better shape. See also the "queue",
3 z% n0 M& t" H* p- _  "be_conn", and "be_sess_rate" criteria.
: M( ~! S8 {) |( \4 d* R- R0 b) \- f+ z9 b: q  M6 d! l
be_conn <integer>  P) ]. A  \$ z& M
be_conn(backend) <integer>7 h3 X1 W# }8 ?. [; O; X# z
  Applies to the number of currently established connections on the backend,3 P3 Q/ N) J- L2 W/ k. ^6 d
  possibly including the connection being evaluated. If no backend name is
* \$ R( z! {+ U" W  specified, the current one is used. But it is also possible to check another
/ ~: {- m- h6 Z  backend. It can be used to use a specific farm when the nominal one is full.
1 Q1 n% |% a% |6 C4 o  See also the "fe_conn", "queue" and "be_sess_rate" criteria.0 d  ]8 ?3 r0 }& ^4 K1 W3 @5 m

" L$ A/ a% u7 cbe_id <integer>
; ?5 ]$ J/ \1 h; y9 @1 W6 U/ G( g+ e  Applies to the backend's id. Can be used in frontends to check from which  g0 h$ Z9 g% X8 S3 d
  backend it was called.! |! M8 P& j7 O0 R' h

9 f+ o! _0 m$ ^% d: ]. r* y* z4 ibe_sess_rate <integer>; K) Q; G. q; ]1 ^
be_sess_rate(backend) <integer>
4 v( E2 L) i/ k: g( I) j  Returns true when the sessions creation rate on the backend matches the1 Z8 ^1 b5 j# k; D) S
  specified values or ranges, in number of new sessions per second. This is. w  ?  U, o3 Y. u) |( x& d9 C
  used to switch to an alternate backend when an expensive or fragile one8 L. W$ Y5 t  Q- H* T' l
  reaches too high a session rate, or to limit abuse of service (eg. prevent
  k& W# ~' q& R% [' R5 j  sucking of an online dictionary).
; l* S) F% T  q( f6 j
' D" C6 C, C9 A1 N* |- C. w  Example :
8 T& w8 [" _4 P2 E  Z        # Redirect to an error page if the dictionary is requested too often
0 V6 l4 C( E/ X% v9 C$ g+ n        backend dynamic  E  f/ n$ Y5 q' f
            mode http
% t5 C1 P5 Q( g3 Y' c/ q0 W            acl being_scanned be_sess_rate gt 100
* U% _- ~. s7 e7 D0 F            redirect location /denied.html if being_scanned; D9 d' b) o' a" @8 c( G# u0 k) O

, A' v/ n0 H. Y$ b2 v- Econnslots <integer>  Y. X8 t/ _' t
connslots(backend) <integer>
+ e8 b* m; b% G7 q7 C: a  The basic idea here is to be able to measure the number of connection "slots"3 I! J% ]2 n3 C8 f
  still available (connection + queue), so that anything beyond that (intended
. z( ^) @; ]# `  usage; see "use_backend" keyword) can be redirected to a different backend.) e# W0 M8 L* D: N# k( |
) K7 M- [$ x6 b* K
  'connslots' = number of available server connection slots, + number of
7 W9 [5 H1 z0 e  available server queue slots.
, ~3 u& K7 E$ Q" d- Z# C8 h  d" [8 n3 N( L! d9 J, v- E1 z" K
  Note that while "fe_conn" may be used, "connslots" comes in especially
  F/ t7 U4 G* x  useful when you have a case of traffic going to one single ip, splitting into+ e: \8 h# W' ?8 G( Y( C8 c1 L
  multiple backends (perhaps using acls to do name-based load balancing) and
3 Y8 v4 A: K2 a  you want to be able to differentiate between different backends, and their7 L+ D5 K- b, h% V1 U5 j9 o4 l
  available "connslots".  Also, whereas "nbsrv" only measures servers that are& [# d6 V, y, C' Z# a
  actually *down*, this acl is more fine-grained and looks into the number of6 D% r2 ^  W- y: E+ p0 Q
  available connection slots as well. See also "queue" and "avg_queue".8 Z* ?! l3 v! [

6 C4 U- b. k8 q; q  OTHER CAVEATS AND NOTES: at this point in time, the code does not take care
) ~1 y) n4 J& g& d  of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,# Y: ~7 N/ ~" R( H" T
  then this acl clearly does not make sense, in which case the value returned2 N4 a7 r! _6 ~* B8 a! @; V
  will be -1.
) Q& D* b4 T  ?1 \# G; F
7 W, p7 N8 X+ Cdst <ip_address>
( G% M4 r; h* W3 }  Applies to the local IPv4 address the client connected to. It can be used to; _' {, T2 j7 b) P& l" [* Z+ X2 |
  switch to a different backend for some alternative addresses.6 F* r1 \" \9 B+ p' _9 a9 r
. H( h7 a0 l# w% d
dst_conn <integer>0 D) _. \) s# @  r
  Applies to the number of currently established connections on the same socket; B3 l8 O5 H) x6 y) E5 U
  including the one being evaluated. It can be used to either return a sorry$ |' q1 K8 k6 p0 }
  page before hard-blocking, or to use a specific backend to drain new requests
, E$ S1 C* g5 J  Q, `: t  when the socket is considered saturated. This offers the ability to assign, Q! |4 g; S# r. t6 q
  different limits to different listening ports or addresses. See also the- b3 d7 H1 J9 T
  "fe_conn" and "be_conn" criteria.
2 U: o8 _/ L8 E* a+ g. d' L; |
- |% o1 O  k, W) a; Jdst_port <integer>: l. ]+ o! A( }3 y( h* N
  Applies to the local port the client connected to. It can be used to switch, B4 F& D6 {  F0 {4 _/ q+ R0 X% y
  to a different backend for some alternative ports.) D& R8 }. x+ e5 a$ w
! @" s9 l- D3 M+ W; E, K
fe_conn <integer>
8 r, \8 w! F+ ?  D8 i8 ~0 M4 M; afe_conn(frontend) <integer>
/ g9 U% x9 g% Y. S3 ?  Applies to the number of currently established connections on the frontend,
* [. _1 F0 q0 `; o4 ?2 V5 D  possibly including the connection being evaluated. If no frontend name is$ E1 x( m- K4 G$ `" z
  specified, the current one is used. But it is also possible to check another. }8 g4 b9 W9 d& Y7 x
  frontend. It can be used to either return a sorry page before hard-blocking,
1 R# o4 ?9 b. v6 G& W  ?+ n  or to use a specific backend to drain new requests when the farm is( t2 C, d1 o: `( W
  considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"
& a% r% `$ Y* r, c2 B! o3 M+ H  criteria." k' D, S+ _  G3 T
) [1 T% P& e& D6 f, Z
fe_id <integer>7 n8 E: I: Y& z# Z  v) A
  Applies to the frontend's id. Can be used in backends to check from which
) h5 ]4 S% R  R  frontend it was called.
) \7 m; J6 {, }* G; Q: ?: l: a4 }- S3 y) p* g. [
fe_sess_rate <integer>
5 ]# r, Z6 J( a) n, i/ Wfe_sess_rate(frontend) <integer>
; M! d; d3 M  z* k9 E7 s  Returns true when the session creation rate on the current or the named
' Z* X. C" Q4 |1 i: C$ z  frontend matches the specified values or ranges, expressed in new sessions
4 i( ?7 ?' S  R8 i: {& R& ~+ {  per second. This is used to limit the connection rate to acceptable ranges in
* X( ~( J' t# c0 M& |  order to prevent abuse of service at the earliest moment. This can be
  k6 m4 d0 Y4 r7 a+ P2 }  combined with layer 4 ACLs in order to force the clients to wait a bit for
  l" K% x" b1 z5 ]( J  the rate to go down below the limit.
: }; i0 j( d# Q8 p3 o& w* a$ m, S+ h
! z0 Y- ~% L1 f( V7 r7 g9 A  Example :
: p- \/ H. r, T0 a7 e5 b7 ?        # This frontend limits incoming mails to 10/s with a max of 1005 a- k7 s, T* Y% W
        # concurrent connections. We accept any connection below 10/s, and2 m& @& m; u8 M  B8 K' D2 V" C
        # force excess clients to wait for 100 ms. Since clients are limited to
: d, c; C4 v3 \" ?  I' E+ Q        # 100 max, there cannot be more than 10 incoming mails per second./ ?9 X2 t: \% H+ j# X
        frontend mail$ H9 l- ?( G0 Y, ^% v% T0 u( g; S
            bind :250 t8 ?& N$ F- L1 I* m. E
            mode tcp
  ~2 r' W4 A. z) B            maxconn 100
& T1 t) {8 D; b            acl too_fast fe_sess_rate ge 10
' y8 l4 N$ C( b# U            tcp-request inspect-delay 100ms
9 l9 M  {7 a$ X2 D) T7 K0 I; ~            tcp-request content accept if ! too_fast# V; B& c% ^6 L7 _" n: W" `
            tcp-request content accept if WAIT_END  ~. B3 i) O+ K. N3 t8 H

2 E. v; {! `5 V8 s. Tnbsrv <integer>
' t  y3 L. M# j( `- J; n# ^& Qnbsrv(backend) <integer>
" Y3 I! B$ u# Y. C! o' u  Returns true when the number of usable servers of either the current backend
+ Y9 v0 ~, x: H: }% X; Q+ y  or the named backend matches the values or ranges specified. This is used to
; n) w# n4 D7 {, r% g( v* O& B( g  switch to an alternate backend when the number of servers is too low to0 a- V; y/ v& N( s! [' [
  to handle some load. It is useful to report a failure when combined with& U5 M  t. n- l8 C4 `- R4 I/ p
  "monitor fail".  ^/ O2 P2 d  _6 b, o, d
; v9 z$ u3 ~) ?' d& c. L5 Y$ H. v6 d7 Q
queue <integer>
  `+ c3 s0 u3 a( {! rqueue(backend) <integer>& S- L( r2 o( _8 J
  Returns the total number of queued connections of the designated backend,/ F" b' @  c) n/ u2 B
  including all the connections in server queues. If no backend name is6 d6 T3 ^/ K' t5 g! ~
  specified, the current one is used, but it is also possible to check another6 y5 U( R2 _% t
  one. This can be used to take actions when queuing goes above a known level,0 O: ?6 N' h0 z8 o7 R. y1 w8 B
  generally indicating a surge of traffic or a massive slowdown on the servers.
/ S6 ^) y0 q- E1 D+ |& i  One possible action could be to reject new users but still accept old ones.
) P6 p1 z. g- c2 }3 T  See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.8 M# t* b  I( i  }
+ F5 V7 }7 u% O# E7 J
so_id <integer>/ U+ s% g. F- m- R) N
  Applies to the socket's id. Useful in frontends with many bind keywords.% z1 u) E! O! q0 P0 m6 a
6 F9 y, a9 t2 m" ?1 }
src <ip_address>
) l9 y& r0 C- C# q' l% l  Applies to the client's IPv4 address. It is usually used to limit access to
2 W1 `& a% q8 x, o  certain resources such as statistics. Note that it is the TCP-level source
$ z2 _! D2 {0 X5 J& v+ N  address which is used, and not the address of a client behind a proxy.
, \. ?, p3 ~4 S1 T! ^0 Y4 P
4 G- A1 [1 e0 N  Qsrc_port <integer>
' Z* W- |1 \" [& X) p  Applies to the client's TCP source port. This has a very limited usage.
3 L* C4 E  {8 O. S  X, `- j0 s2 Q. J
srv_id <integer>
$ G# Y( d7 i  z. k! F1 I$ P  Applies to the server's id. Can be used in frontends or backends.
9 {4 \" ~- W9 E' h5 _3 y6 ^. ]' n- O7 a, A# q  G" u& Q
srv_is_up(<server>)' b  N1 f. i5 C% x- k, u7 l. [
srv_is_up(<backend>/<server>)
6 A5 Q6 g1 [9 _  Returns true when the designated server is UP, and false when it is either$ f! X$ \( w- w' l' u
  DOWN or in maintenance mode. If <backend> is omitted, then the server is
) `8 ~3 }. Q1 f2 {+ J  looked up in the current backend. The function takes no arguments since it
6 \6 k7 H1 Y$ y' \( P, G  is used as a boolean. It is mainly used to take action based on an external% {! }( M) J/ R
  status reported via a health check (eg: a geographical site's availability).
/ Q3 U) V9 v; b/ \. M: F  Another possible use which is more of a hack consists in using dummy servers- U/ |* i  U" F" a
  as boolean variables that can be enabled or disabled from the CLI, so that
. o) C7 _! Y3 T* f+ s( r  rules depending on those ACLs can be tweaked in realtime.
0 a9 g- [! e3 h0 n, @% C- ^' H# i5 k

! K/ o* T1 L/ _: f7.5.2. Matching contents at Layer 4
, u8 u, n% R/ n-----------------------------------9 ~6 P! g$ \1 v5 d

; U- {7 Z* G+ u/ w' JA second set of criteria depends on data found in buffers, but which can change
! r3 Y' h; g4 H" D2 [. @& uduring analysis. This requires that some data has been buffered, for instance. ~, Q6 U3 t+ A$ b7 {) Y9 f
through TCP request content inspection. Please see the "tcp-request" keyword0 l+ ?) D) ]7 e5 B- n- k, I% l
for more detailed information on the subject.
2 G! D( z) U1 q; d0 ~+ R+ S4 `2 \6 V2 }4 ~
req_len <integer>1 K. ~; @) M5 A7 y8 Q6 t9 }1 M
  Returns true when the length of the data in the request buffer matches the
, h4 U/ U2 W; U3 l  specified range. It is important to understand that this test does not5 }; C  F1 h, s& R/ G' V7 S& y
  return false as long as the buffer is changing. This means that a check with
2 _/ ]2 Q" m' e# v5 n  equality to zero will almost always immediately match at the beginning of the$ J5 x) s' e. K' I4 O" R, v
  session, while a test for more data will wait for that data to come in and
7 i, u( x& L5 W; a) Y/ r* j  return false only when haproxy is certain that no more data will come in.
) {# P8 q4 o2 Z# U% U7 F  t  This test was designed to be used with TCP request content inspection.
+ ^& h/ o4 l4 j+ N) p9 V& i8 Y
' A0 a6 Y5 h1 Z; U  wreq_proto_http
  h- L; h0 C" m7 S  Returns true when data in the request buffer look like HTTP and correctly( |8 G' e% V: Y3 i+ d
  parses as such. It is the same parser as the common HTTP request parser which* |3 J: L( Z: S1 l
  is used so there should be no surprises. This test can be used for instance
9 l/ N# \3 Y; J0 T% t4 J, Z+ ?  to direct HTTP traffic to a given port and HTTPS traffic to another one
! V' p* I( W9 V& J2 D/ }  using TCP request content inspection rules.
' {6 h' b( k" Z+ {" d0 f. ~
8 O2 T* c6 J9 W& q, }req_rdp_cookie       <string>  H- T. C, x4 G" X2 C
req_rdp_cookie(name) <string>
8 A/ u. |3 x! G5 A1 E  A  Returns true when data in the request buffer look like the RDP protocol, and
% O: V  B1 a* v8 _' r% j& H  a cookie is present and equal to <string>. By default, any cookie name is
% Q  ~  {  L  p! |; C  checked, but a specific cookie name can be specified in parenthesis. The
! G# ~: ]* s* E& j* R5 V  w  parser only checks for the first cookie, as illustrated in the RDP protocol
8 X4 h1 r+ D* d  specification. The cookie name is case insensitive. This ACL can be useful
* R% K6 v9 i# m  @, i) e% h* v  with the "MSTS" cookie, as it can contain the user name of the client
9 Y' o, h" ~; |  v  connecting to the server if properly configured on the client. This can be5 ~7 x( e9 W  ~1 J
  used to restrict access to certain servers to certain users.
! \- P! ?/ ?) {" _7 B3 r/ S
2 i% v& y: K% d; x8 o" D+ ~req_rdp_cookie_cnt       <integer>* q/ f8 v2 y/ m3 [
req_rdp_cookie_cnt(name) <integer>& ]6 t) l2 K) k2 ^. |
  Returns true when the data in the request buffer look like the RDP protocol" s( v: x5 e2 c3 N
  and the number of RDP cookies matches the specified range (typically zero or1 H, q; C% `, k( U/ s6 ?8 J% B
  one). Optionally a specific cookie name can be checked. This is a simple way( r( p7 ~  X) X7 B8 H+ J+ [3 S
  of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH, _% h4 ?8 J; N  }; V( P, U% |' F' s
  cookies.
+ V) @7 n8 m  o- y1 u
! s! f% _* o8 d, Vreq_ssl_ver <decimal>! J( [, L- H' O8 c
  Returns true when data in the request buffer look like SSL, with a protocol8 `( c% v7 d) s8 G7 k& L# |/ j
  version matching the specified range. Both SSLv2 hello messages and SSLv3! A" q& @1 z; R# b. k
  messages are supported. The test tries to be strict enough to avoid being
( d( r9 x& r- S6 C8 j8 i  easily fooled. In particular, it waits for as many bytes as announced in the/ @* n/ a0 n8 F, l+ d+ ~
  message header if this header looks valid (bound to the buffer size). Note; o; o5 [, {1 P9 |3 a% J4 v
  that TLSv1 is announced as SSL version 3.1. This test was designed to be used+ y4 G' q! K3 s7 q, s. x) I# B
  with TCP request content inspection.
" S% `# y; H5 _( _* K
9 Q% c9 r: L: Y* E' i& r1 f' Vwait_end7 U. b* [/ \  c, i8 |( Z
  Waits for the end of the analysis period to return true. This may be used in' @# M2 {6 w# O( Z$ W
  conjunction with content analysis to avoid returning a wrong verdict early.& A) r; q+ {" ~; E6 `
  It may also be used to delay some actions, such as a delayed reject for some* o% H, o8 h# ?5 k
  special addresses. Since it either stops the rules evaluation or immediately7 l7 ^) X7 l! A5 Q7 `: q- R
  returns true, it is recommended to use this acl as the last one in a rule.9 R5 u6 B: c1 M, L# |+ o8 o0 q- V, D  N
  Please note that the default ACL "WAIT_END" is always usable without prior
) H: ~' v( P/ S% M2 m4 k  declaration. This test was designed to be used with TCP request content) E0 g1 i1 s0 q  t
  inspection.% p5 F8 d  Q! ~
. Y4 \7 ]+ b4 {' O5 `7 \" n
  Examples :
7 o( x" \0 _4 L9 o( [/ n     # delay every incoming request by 2 seconds8 e6 S4 P5 m( d. L9 i
     tcp-request inspect-delay 2s8 \& M4 W! {, i* ^$ ^* W, \
     tcp-request content accept if WAIT_END1 ~5 @8 p0 A; u) w3 O) f

; i  k9 e5 x* I1 X     # don't immediately tell bad guys they are rejected1 b% ?; p' g; _& P( ]+ ?7 m( f
     tcp-request inspect-delay 10s
7 L1 B# j8 ?1 l     acl goodguys src 10.0.0.0/24
1 I* L/ {8 M5 R& J     acl badguys  src 10.0.1.0/24  ?5 ~: s. H; [: {& U; p
     tcp-request content accept if goodguys9 }6 R. b  \4 ?! H8 A/ d) ^4 |
     tcp-request content reject if badguys WAIT_END
# r6 o, a' F) c( P) O) D: d. l     tcp-request content reject' M% Q9 G) g  `* O% C  g
1 Y! u% D. B% d4 F
0 `( H2 c0 i  O
7.5.3. Matching at Layer 75 D) y9 f0 n+ I/ B3 N: q+ S7 c0 |
--------------------------
8 A. Y. |* M: _7 }% p& u( D, b
6 f( v9 l: V+ s8 L& eA third set of criteria applies to information which can be found at the
7 T# f" m6 O6 @application layer (layer 7). Those require that a full HTTP request has been
( J- M- }/ P/ x( lread, and are only evaluated then. They may require slightly more CPU resources9 }9 v3 ~+ K$ ]1 v7 g9 f1 U+ l9 L
than the layer 4 ones, but not much since the request and response are indexed.
( m! Q& F. A) u+ n! {  U1 Z  ]! R$ D. {$ G4 t" z5 J& z
hdr <string>1 D* A' Z& F1 w* J0 o
hdr(header) <string>
& Q' Z+ F7 n5 T/ k9 V" G  Note: all the "hdr*" matching criteria either apply to all headers, or to a
/ A8 e0 F! V, m6 a/ R5 k5 e2 |9 g  particular header whose name is passed between parenthesis and without any
. b& O/ y9 Q( H$ z, ~% I4 r, O  space. The header name is not case-sensitive. The header matching complies
! F, @' G. L; Q7 ~) G" ?& {  with RFC2616, and treats as separate headers all values delimited by commas.
+ `  x; s# H  J7 x/ n3 H8 m  Use the shdr() variant for response headers sent by the server.  B0 d3 B6 w! F
: Q0 _% s6 n8 f& U6 S- d* t! B6 ^
  The "hdr" criteria returns true if any of the headers matching the criteria
; ~' [3 H9 Y, u  match any of the strings. This can be used to check exact for values. For
3 f$ a! [. t) U$ o3 R. n, e- N  instance, checking that "connection: close" is set :
" g! m) y/ L% |+ g! b
, X* f) o& o' ~2 }; c     hdr(Connection) -i close) C2 e7 L7 x  y- u8 S: ~

8 N" s3 X% o6 M6 V+ |! hhdr_beg <string>9 ?( `: A# I, M* c$ v
hdr_beg(header) <string>* ?! A6 y. O7 k9 ]9 n- D; K0 V
  Returns true when one of the headers begins with one of the strings. See
, i% y8 O# q: P6 I  "hdr" for more information on header matching. Use the shdr_beg() variant for
  ]4 D0 G! `* y# N3 v  response headers sent by the server.5 m; o6 O0 B! w: O1 p9 S
$ p1 t! Y) W2 e. W  e& A
hdr_cnt <integer>
  k4 K0 W0 ]3 a6 L" @- t! Mhdr_cnt(header) <integer>% e3 F2 D% j6 y4 J
  Returns true when the number of occurrence of the specified header matches
+ d5 y1 C9 y% S& {0 V" @  the values or ranges specified. It is important to remember that one header
1 ]- E- S8 C1 j2 |6 |  line may count as several headers if it has several values. This is used to: ^6 E0 z4 R- z8 v
  detect presence, absence or abuse of a specific header, as well as to block
! z" H# h6 g/ c0 Q5 ]  request smuggling attacks by rejecting requests which contain more than one
' f! Z0 g: h; k  of certain headers. See "hdr" for more information on header matching. Use9 H, C5 d" N  i5 u2 N( ^( G4 o9 w
  the shdr_cnt() variant for response headers sent by the server.( q8 a; {- x) S. f: X8 M6 D8 Y

1 [, q- j; x5 z0 Q3 Bhdr_dir <string>/ m+ x/ ^5 N- U% Q3 H
hdr_dir(header) <string>
: {7 B) ^# V- H2 m5 l3 r  Returns true when one of the headers contains one of the strings either
4 c) F$ A* @& f& |. }9 @  isolated or delimited by slashes. This is used to perform filename or
6 l2 P/ \6 s9 z1 Y* a( Z  directory name matching, and may be used with Referer. See "hdr" for more
9 U* h8 a/ V1 `% N  information on header matching. Use the shdr_dir() variant for response! K' `) @/ j* k% X/ }% t5 z
  headers sent by the server.
6 `' _% q. }, x% @# |( ]. Y! i
' F! O4 E; G" J4 S' Jhdr_dom <string>& p4 G) @/ l/ X7 j
hdr_dom(header) <string>
5 \3 a$ S; B. Q6 k7 y  Returns true when one of the headers contains one of the strings either
6 q7 K* M  k4 F8 Q: s2 `$ g& P  isolated or delimited by dots. This is used to perform domain name matching,
  D' a* A4 _, Z1 m  and may be used with the Host header. See "hdr" for more information on
4 R) g9 m0 Q: b6 F  }; E  header matching. Use the shdr_dom() variant for response headers sent by the
% Z5 E2 Z1 N) ?; v! R  server.$ O$ U5 `+ }- E# S" G% H- K- \% l

! y$ j: \4 n( n) G* n" o' }$ @hdr_end <string>
- a# n" j( F- [hdr_end(header) <string>
* D4 a2 W4 y  t. f; Z% N+ o+ C  Returns true when one of the headers ends with one of the strings. See "hdr"
/ x) g' f3 C: K& A' O4 M5 d8 N  for more information on header matching. Use the shdr_end() variant for& K+ ~& h: q5 w- ^
  response headers sent by the server.
2 T- ~" F1 B4 }  \( ^) B# l
) V- D( ~, r9 f( ?, nhdr_ip <ip_address>" p- \6 r- D6 D) A) @( Z0 Y
hdr_ip(header) <ip_address>
, J: {, j) e) g- D1 j  Returns true when one of the headers' values contains an IP address matching2 U7 V6 A. M1 @3 r9 n' C* C
  <ip_address>. This is mainly used with headers such as X-Forwarded-For or
* ^" T1 z2 X. E/ h' m3 {  X-Client-IP. See "hdr" for more information on header matching. Use the6 m) {. Q) d; m0 R# a# K1 x/ B
  shdr_ip() variant for response headers sent by the server.
& L9 b2 v; Y, U- q* ^# Q
  ?1 ~, U/ n* w0 Ihdr_len <integer>& a) x: d8 \6 S* M
hdr_len(<header>) <integer>
  t" _  ?% x; z  Returns true when at least one of the headers has a length which matches the2 i& h$ ]" q' M
  values or ranges specified. This may be used to detect empty or too large* I  [- q8 m+ [; x
  headers. See "hdr" for more information on header matching. Use the& g& A; o5 L& n2 K! i8 g
  shdr_len() variant for response headers sent by the server.* q* |  ~" V7 X( S

. @8 O7 s  P  P: Xhdr_reg <regex>) d" ]7 y+ s5 n' X+ w0 N) F. C  ?
hdr_reg(header) <regex>9 o' w! k5 Z. y( g6 ?
  Returns true when one of the headers matches of the regular expressions. It- `/ H9 j2 m! e% z1 z; Q; q5 A
  can be used at any time, but it is important to remember that regex matching
% D( @% ^' r' P1 W) Z* Y  is slower than other methods. See also other "hdr_" criteria, as well as: d! z( }0 e8 \8 O
  "hdr" for more information on header matching. Use the shdr_reg() variant for: Y; l: j; d) M% L
  response headers sent by the server.4 e* d0 V- y7 Z* P# w% p/ \

- g) a9 w7 A& N2 @6 Y. o4 _7 Thdr_sub <string>
- N4 W& l* s' ahdr_sub(header) <string>: t% ~; Y5 a: ~$ L9 k, P
  Returns true when one of the headers contains one of the strings. See "hdr"9 q' q9 H- _: A6 P* ^
  for more information on header matching. Use the shdr_sub() variant for* R6 Z2 C: m, W: H! E7 p) G
  response headers sent by the server.
4 M2 ^1 }* x+ ?& ~$ u0 h: {1 c) L, [1 l/ d7 u% ?" o- Z
hdr_val <integer>
/ b9 ?7 ^) R2 S8 }6 Ohdr_val(header) <integer>
. O8 O* U7 ]* D  Returns true when one of the headers starts with a number which matches the
+ @' f8 D0 D0 ]2 ~  values or ranges specified. This may be used to limit content-length to
! J; f1 s! O1 C$ T9 v- ?5 z  acceptable values for example. See "hdr" for more information on header, Y1 z/ |  d' z* w3 v4 W' i
  matching. Use the shdr_val() variant for response headers sent by the server.! x6 |+ W+ T! k* I

/ `! B' ~$ ^* q6 w" ^http_auth(userlist)* U0 c% h! M! e* X
http_auth_group(userlist) <group> [<group>]*  `7 r5 R* m8 V8 X7 X8 d
  Returns true when authentication data received from the client matches2 r4 ^0 u1 N& R6 x( F
  username & password stored on the userlist. It is also possible to
$ `( y3 w7 \9 \, j+ D' @  use http_auth_group to check if the user is assigned to at least one
! M9 C/ P) Z% h+ r; {  of specified groups.6 |" {0 D- q- s9 |% s6 k
7 Z! x, `! g0 G/ e% Y
  Currently only http basic auth is supported.
; {1 e* E* B4 T6 Y" s/ k1 o+ W/ w4 `  r: t) _/ F: C
http_first_req$ O  c9 |" ~. {  _% ]8 R' s
  Returns true when the request being processed is the first one of the/ d" W% A, V+ ]4 k/ |
  connection. This can be used to add or remove headers that may be missing
% E% K# ]4 j& A3 \  from some requests when a request is not the first one, or even to perform4 A$ r/ R) b8 H4 h' p7 j
  some specific ACL checks only on the first request.
! s# l: z  n- |
2 Z( z( ~1 j3 T4 p* Q8 |$ lmethod <string>
% \; A: j9 v" p6 d& G  Applies to the method in the HTTP request, eg: "GET". Some predefined ACL" V7 t6 d% _" S) e# c
  already check for most common methods.
: B5 s0 M  u5 `( L5 _
6 K$ ~, a7 \+ A6 t7 c0 P7 f% cpath <string>
" V: J9 N" |4 _! v2 I' l* Q  Returns true when the path part of the request, which starts at the first  f7 s  O5 C1 y: ], F5 w2 V; h" F
  slash and ends before the question mark, equals one of the strings. It may be, U4 g, m; M3 Z
  used to match known files, such as /favicon.ico.
' C8 T. ~7 i; z. q1 q6 s8 o4 f; E1 C
path_beg <string>7 u. P; @. ?7 l5 v" ?6 Q
  Returns true when the path begins with one of the strings. This can be used
" a/ [/ c3 X3 G" ~. R- h  to send certain directory names to alternative backends.3 `' F* H/ z+ m; ~1 ^

! I- A$ @2 X4 @; F" c' U8 ypath_dir <string>, p1 _, k) r% K2 {/ y: }$ W$ O8 S2 m
  Returns true when one of the strings is found isolated or delimited with
8 P! s, j1 t' ~  j* o% ]7 X  slashes in the path. This is used to perform filename or directory name% u- R9 s& F/ q1 L! @& k
  matching without the risk of wrong match due to colliding prefixes. See also
6 v, N, ~) c* o3 j- x( K/ P  "url_dir" and "path_sub".* B" S- X5 y' O  C9 v. U- @
- K* o- A) a% |( X. I
path_dom <string>
3 s/ h) s/ s' N; ]$ k: o  Returns true when one of the strings is found isolated or delimited with dots
- K' Q4 |( n1 C- v) ^5 N0 B+ C3 Q  in the path. This may be used to perform domain name matching in proxy
  f+ v# [4 b4 U( U  requests. See also "path_sub" and "url_dom".
/ l3 K6 R$ N- s6 x+ d1 c1 M+ }3 g; L, q' T
path_end <string>
: y6 B6 l8 T. R! m2 j' k  Returns true when the path ends with one of the strings. This may be used to
8 n5 G( w' X, a% x  control file name extension.
* ]& b! m, B  {6 `; v
+ c! D" R0 v5 A1 ?path_len <integer>
, Q: R" U" J2 B  Returns true when the path length matches the values or ranges specified.
, r1 U$ {* G- _% c- v) e8 |% {  This may be used to detect abusive requests for instance.
+ [1 _. _$ S0 G* ?8 B
* l5 x, }! V7 q( G! w; spath_reg <regex>
, V/ G" ~& D3 Q, n: Z  Returns true when the path matches one of the regular expressions. It can be
! b9 K1 }' q  q  used any time, but it is important to remember that regex matching is slower
  N; L; ~& B7 J4 U8 k  than other methods. See also "url_reg" and all "path_" criteria.) c% l, O  ^' l- d, V* I# a

5 T7 b1 G7 K6 H6 B5 @& Zpath_sub <string>
: _6 n, S4 e( U! g) y1 _) `  Returns true when the path contains one of the strings. It can be used to  }4 g6 K: _2 {2 `( Y& \( S
  detect particular patterns in paths, such as "../" for example. See also
: T$ Q. x* Z4 x, j/ S  o  "path_dir".
( B' B# J* F9 M9 B1 C
9 x% ?* |& ]0 Zreq_ver <string>+ m6 s. l- T; ]( |7 x/ q6 T
  Applies to the version string in the HTTP request, eg: "1.0". Some predefined( h9 L! J) h9 D
  ACL already check for versions 1.0 and 1.1.: D' G* d% M- J4 v1 P9 X6 K
; m- o+ f) f- R2 W# d8 N
status <integer>
( b2 `9 l4 M* C- J, p  Applies to the HTTP status code in the HTTP response, eg: "302". It can be
$ ~) R1 S8 i8 z/ w8 _  used to act on responses depending on status ranges, for instance, remove
6 E* o& W3 |% i7 H9 c  any Location header if the response is not a 3xx.
0 p4 S& o1 I2 o4 y) N* r+ J# O, ^; G5 F  c. v! p
url <string>
- E* ?' i2 a5 Y6 Z0 z+ b, A/ o( N  Applies to the whole URL passed in the request. The only real use is to match
# a/ x) @3 @# }+ ?6 i; C3 t9 N* f& E  "*", for which there already is a predefined ACL.5 m5 f( f- b$ u8 V: }% p
( I- W: F( L; f/ d+ Q$ S
url_beg <string>% b& J5 a8 h+ ?: }- O2 X4 u
  Returns true when the URL begins with one of the strings. This can be used to
9 r- d! @+ h9 v$ n; k9 A4 `  check whether a URL begins with a slash or with a protocol scheme.
- |9 @4 v+ q. H
( S2 _- V* C$ @5 G8 D, o  h: T+ Burl_dir <string>
0 E) T: }5 D- K0 ^: i; F+ T  ^  Returns true when one of the strings is found isolated or delimited with) o! D4 s' ^& n" Z# g, ~
  slashes in the URL. This is used to perform filename or directory name1 p3 G$ }1 t9 p6 ^
  matching without the risk of wrong match due to colliding prefixes. See also
- b/ `/ A$ C9 [/ |. H+ Q; M  "path_dir" and "url_sub".7 t4 G! |* @. V
8 U8 b2 i5 j/ d" ]1 P  V
url_dom <string>. E+ B7 Q* E0 T) d
  Returns true when one of the strings is found isolated or delimited with dots
# @8 D+ U7 n# |5 A" k5 b) w9 w* d( l  in the URL. This is used to perform domain name matching without the risk of, g! l* @* S! C9 U
  wrong match due to colliding prefixes. See also "url_sub".
; ^, B; m( r% X, M7 A3 r
3 e. z9 {; h5 C, V" Gurl_end <string>, y% w- \# [) o8 }% g+ C
  Returns true when the URL ends with one of the strings. It has very limited8 j! E$ I, M. Y
  use. "path_end" should be used instead for filename matching.
" M2 B: s2 K  R0 Z9 K7 r1 t3 C& M% @  h" r+ n, c; m
url_ip <ip_address>9 c' ?4 S* l3 g# ~; O
  Applies to the IP address specified in the absolute URI in an HTTP request.
2 y- j; h2 a3 U  g/ K4 o  It can be used to prevent access to certain resources such as local network.. a" L' h6 p. u/ D! ^: P( e
  It is useful with option "http_proxy".0 s, F, m/ o1 F1 R) z

/ f) a) Z8 T+ `+ W1 wurl_len <integer>
+ e" L2 P* o' r# O: N. A  Returns true when the url length matches the values or ranges specified. This
6 E: N$ \8 L+ @  Q8 g, t; f  may be used to detect abusive requests for instance.
) a  S0 g: G$ [& [9 I- o! |2 y3 Q5 r) n, h1 ?4 g, U/ Y/ h1 J
url_port <integer>
" Z( i9 h! g  |, o2 y  Applies to the port specified in the absolute URI in an HTTP request. It can6 t2 g' b5 n3 S  l1 B: J7 V4 t( |  U
  be used to prevent access to certain resources. It is useful with option- ^7 s( e6 u5 N* `
  "http_proxy". Note that if the port is not specified in the request, port 80# l4 |+ ?$ H3 n. X
  is assumed.
, w' A  ?* C+ T5 V) }9 P7 x; L0 B0 i1 T3 T, i& R! k2 j* l
url_reg <regex>, G7 g5 n6 m$ b* a8 y
  Returns true when the URL matches one of the regular expressions. It can be
( h2 ^! p( A+ s2 Z) |- {  used any time, but it is important to remember that regex matching is slower6 d9 t/ Z, S& c6 h$ |6 P" f
  than other methods. See also "path_reg" and all "url_" criteria.
" M' {0 Y; O$ c- q5 r
) o# m# \- H( E( burl_sub <string># U+ x0 {- |1 L( H2 `- @
  Returns true when the URL contains one of the strings. It can be used to
7 X& `, M. X% D4 l' X/ e' z' _  detect particular patterns in query strings for example. See also "path_sub".# P5 Y- K* |( \7 \8 T+ I3 L

) {+ I! P+ o# g6 H! V
. }; w) m$ Y, X# [- I7.6. Pre-defined ACLs) ~4 P1 q# J) i
---------------------9 W. c; u* O7 s' v& Z8 h
  B8 x$ r: N5 _; U0 `- V
Some predefined ACLs are hard-coded so that they do not have to be declared in; C+ ]$ M/ Q/ F1 w- E) J
every frontend which needs them. They all have their names in upper case in
" i) d* g4 M5 F4 [+ qorder to avoid confusion. Their equivalence is provided below.
3 K  M' t) S1 b+ @$ H
% i9 o: F# y6 h- [( yACL name          Equivalent to                Usage
' b1 `) ?1 E* R---------------+-----------------------------+---------------------------------
- w* Q- A8 ^4 K/ V! n- H. iFALSE            always_false                  never match: b0 w6 o! b4 e$ I% i: C3 V
HTTP             req_proto_http                match if protocol is valid HTTP
+ m7 [7 E3 d, d1 ^, l0 QHTTP_1.0         req_ver 1.0                   match HTTP version 1.0
) p9 L. l: S/ t3 T  N  x& jHTTP_1.1         req_ver 1.1                   match HTTP version 1.1
' b% N; R8 s' P( QHTTP_CONTENT     hdr_val(content-length) gt 0  match an existing content-length0 Q: F, I+ A1 s( i9 X
HTTP_URL_ABS     url_reg ^[^/:]*://            match absolute URL with scheme2 a& p2 Q% B' G# @) G
HTTP_URL_SLASH   url_beg /                     match URL beginning with "/"
5 L: m* J  `) uHTTP_URL_STAR    url     *                     match URL equal to "*"
5 m/ I( e  A" S& O. @LOCALHOST        src 127.0.0.1/8               match connection from local host; o+ q# P# |: f8 P( p. |5 i
METH_CONNECT     method  CONNECT               match HTTP CONNECT method
; G4 U& g  a* E/ b4 y  s/ dMETH_GET         method  GET HEAD              match HTTP GET or HEAD method0 f, x! ]! A7 I5 z6 S' |
METH_HEAD        method  HEAD                  match HTTP HEAD method
& ^7 _( t( G. V8 V2 y/ }2 X" c. gMETH_OPTIONS     method  OPTIONS               match HTTP OPTIONS method
3 x' z3 e6 x( f! s* BMETH_POST        method  POST                  match HTTP POST method. N9 K# o, y+ p/ i5 y, h
METH_TRACE       method  TRACE                 match HTTP TRACE method
" s0 S1 K: h  n7 \5 @0 oRDP_COOKIE       req_rdp_cookie_cnt gt 0       match presence of an RDP cookie2 ?' n4 ?- `- O* F4 W
REQ_CONTENT      req_len gt 0                  match data in the request buffer' V, Y  e4 T( ?; e
TRUE             always_true                   always match+ I- Q* a  E% N0 L, ]$ P; b
WAIT_END         wait_end                      wait for end of content analysis' f6 J9 ~. K) P$ _6 R' C
---------------+-----------------------------+---------------------------------, L9 N0 ~2 F6 S% H( O, b2 ]1 f
: H% ?  Q. U4 Z" f* j

! I7 J. I5 K+ i7.7. Using ACLs to form conditions& s' F5 ~  {" P1 h8 ^
----------------------------------% |7 b2 E& t/ U+ j% g
( E8 G! g+ n6 [* w* U
Some actions are only performed upon a valid condition. A condition is a2 W% c: V& W% ^
combination of ACLs with operators. 3 operators are supported :6 Y) H9 f: G5 f& ^& ?
' [8 z0 h0 I: Q& A/ S% ~- g
  - AND (implicit)
0 U) g+ |/ s$ C1 s  l8 C  - OR  (explicit with the "or" keyword or the "||" operator)( Y3 `6 c- |% e. w  S" F3 P
  - Negation with the exclamation mark ("!")
+ A. W5 Z# U" s. }8 D4 |0 A2 H
& P. P3 B$ X' b, i8 P' _3 S; [+ qA condition is formed as a disjunctive form:
! Y1 G0 h& K. o" t# d* E% s  X9 j2 |' ?
   [!]acl1 [!]acl2 ... [!]acln  { or [!]acl1 [!]acl2 ... [!]acln } ...9 m3 s, w8 b2 h( F0 F8 s
& q1 z7 ]. Q6 i. C( J  l9 n
Such conditions are generally used after an "if" or "unless" statement,: q/ C2 p3 H+ ^! ^
indicating when the condition will trigger the action.) p! D% @6 ?3 G  R% f* z* h
6 [. w# u. ]! ?! |! K: {9 c( O
For instance, to block HTTP requests to the "*" URL with methods other than
0 J, w* i% C! W1 H. D. ["OPTIONS", as well as POST requests without content-length, and GET or HEAD
6 B% L: s& R) Z5 Krequests with a content-length greater than 0, and finally every request which; S1 q. v/ d8 R. i. x# U
is not either GET/HEAD/POST/OPTIONS !! w+ `/ X1 G/ b  `7 T7 r

" F1 K# ]0 q& d- B2 Z! ^! f   acl missing_cl hdr_cnt(Content-length) eq 0
, z" E- I: R3 R4 t4 }, x4 F5 ?   block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl$ Y7 S' c- R! L+ f; K
   block if METH_GET HTTP_CONTENT6 ]5 F, S' {# b2 e
   block unless METH_GET or METH_POST or METH_OPTIONS
' h* ?$ V" J. t
  g; I' o! x7 D8 x! v( ]* KTo select a different backend for requests to static contents on the "www" site2 z) z& a% F* z
and to every request on the "img", "video", "download" and "ftp" hosts :  d" P* D. W9 b2 P$ I* e

+ A7 ?3 G, g3 B) j2 s# v   acl url_static  path_beg         /static /images /img /css
; `9 ^7 _/ Z1 U; W   acl url_static  path_end         .gif .png .jpg .css .js* a2 ~6 \& T- `5 e9 z
   acl host_www    hdr_beg(host) -i www
. m1 b2 A  H& p- Y* B   acl host_static hdr_beg(host) -i img. video. download. ftp.
  f% t+ A( P6 h+ A, k! h6 f( h1 x* T
   # now use backend "static" for all static-only hosts, and for static urls
' @, p% l5 g8 {( I6 q& A5 D   # of host "www". Use backend "www" for the rest.
/ @' o: Z: V- z0 V& v( M) p+ L   use_backend static if host_static or host_www url_static
- m3 ^% ?( y0 \% {2 Q   use_backend www    if host_www" t7 U3 M2 \$ _  u

3 s6 {- `6 g- o4 E5 ZIt is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
1 {8 N. ~, S+ E1 p6 Kexpressions that are built on the fly without needing to be declared. They must
, g' V# h( r1 \$ Dbe enclosed between braces, with a space before and after each brace (because, D% f9 k7 Y9 E3 K! p) `5 B5 B
the braces must be seen as independant words). Example :% c* B2 o! L5 B) X+ t$ O7 l* G* K# D

! d( s, i- ?9 r  W' P2 D   The following rule :8 [' F3 d1 c- A# ~- O

* K1 q+ V/ E# P, D       acl missing_cl hdr_cnt(Content-length) eq 0
. E! E1 |0 k, n       block if METH_POST missing_cl+ M- S) N' _5 s" I/ [& V
/ g4 |: L) G$ \9 |7 o( K( v
   Can also be written that way :
" _3 _" |3 t( v8 I; \
! @  C1 y7 `: p1 {1 y8 O       block if METH_POST { hdr_cnt(Content-length) eq 0 }# A7 Z4 `9 g9 p  _5 y, N: I" W
# R  r7 W8 \/ T0 q7 L, {( Q* s
It is generally not recommended to use this construct because it's a lot easier" z, F* p) n; Y0 N  \; M3 I
to leave errors in the configuration when written that way. However, for very
7 M4 \# S8 X/ B& hsimple rules matching only one source IP address for instance, it can make more
' k0 X) z' Q  g1 n- ssense to use them than to declare ACLs with random names. Another example of
( c/ n: @) a% w+ [! y) g  Ogood use is the following :
6 d3 B; j  Z1 U! v3 i
- x: N- ]( d* `5 \   With named ACLs :
# ^0 b# k# O; U/ _; S  i! J8 c# @( x. P5 B. R  G
        acl site_dead nbsrv(dynamic) lt 2
- h4 P/ z7 K& f4 |9 K        acl site_dead nbsrv(static)  lt 2
# O7 }# [* n" M: l6 d        monitor fail  if site_dead  X$ O1 ]8 K/ J' t6 ?

7 [0 _% K% Q& o6 u3 N   With anonymous ACLs :$ }* g& i$ s, e/ S4 Q+ _7 d! k3 @

) `" b7 `5 b5 L/ Y$ \        monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
9 p2 X" z. _8 ^5 a- j5 i9 T2 Y
) v  z' [- K. L% w& HSee section 4.2 for detailed help on the "block" and "use_backend" keywords.
9 ]& N3 y* i7 j& v( t* O5 F% m+ p5 x4 p8 R+ p

5 d  z. v0 i0 T7.8. Pattern extraction
4 @' K1 f1 g( u) {  \# O-----------------------, |# n( ~# A7 I5 G
5 M) g) P4 P+ \* i: }! |8 K4 ^
The stickiness features relies on pattern extraction in the request and
4 t, ^' S  B3 {# _/ j% P6 H: presponse. Sometimes the data needs to be converted first before being stored,
$ {- M4 n$ S2 a) R. W4 A+ V, ffor instance converted from ASCII to IP or upper case to lower case.- K6 c( e& y) V& s* K( {- T

. Q& d7 S6 \. e9 lAll these operations of data extraction and conversion are defined as9 a. v1 ~5 u8 G
"pattern extraction rules". A pattern rule always has the same format. It
2 O, B2 z" j! Q) ?begins with a single pattern fetch word, potentially followed by a list of
9 u  @1 s0 l  V' Jarguments within parenthesis then an optional list of transformations. As
3 Z1 d* A# y9 _, D2 Imuch as possible, the pattern fetch functions use the same name as their( V+ E, s0 Q/ ?/ o& W
equivalent used in ACLs.
5 e) `% i8 A5 ?! h# P. r3 O; R" |$ h1 p1 F3 x8 I7 I: n2 b
The list of currently supported pattern fetch functions is the following :  ]; O8 ^7 Y' h5 |' v3 v7 s

" G$ j8 p3 l5 z; T- c9 P1 V6 m2 ~( t  src          This is the source IPv4 address of the client of the session.& e7 V: [# m  {7 O
               It is of type IP and only works with such tables.8 K3 k4 n; p  S7 c% j1 A* A+ I

' g6 c2 \3 U+ P9 Q+ |2 I  dst          This is the destination IPv4 address of the session on the
' \' k$ T9 t0 ~# A8 W/ X               client side, which is the address the client connected to.' v8 @! P5 y9 t7 B+ X+ D
               It can be useful when running in transparent mode. It is of+ l$ m  i' y8 v  h- }1 X
               type IP and only works with such tables.- G, \" t# J/ M4 z

, l& g1 i  p. X: `8 x  dst_port     This is the destination TCP port of the session on the client6 v5 `& ^( \9 F, Y9 b
               side, which is the port the client connected to. This might be, h2 X8 _8 X6 Z1 [* ~" C5 l6 W
               used when running in transparent mode or when assigning dynamic
# H3 C1 N8 Z! J& N               ports to some clients for a whole application session. It is of
9 E. R* j. h3 m8 |6 o' g% K+ d% Z, L               type integer and only works with such tables.
" b  b1 J6 j1 x# x9 z; w$ N7 m* S& ]: Q( v) r
  hdr(name)    This extracts the last occurrence of header <name> in an HTTP" N2 |4 q5 l& }6 }
               request and converts it to an IP address. This IP address is
/ H) j" ~2 P  L& c9 r/ @! e               then used to match the table. A typical use is with the8 l, n! l* r- a; s$ D: n7 F
               x-forwarded-for header.9 x( Z( X/ X: A7 ^
  R4 g! j, t% v# w% p0 M. N
7 ~- z+ x" s" n5 j2 ]& F/ B
The currently available list of transformations include :! I; B# a$ K1 p+ u9 l$ p& `

( X& T% F  u+ z; L/ g- L  lower        Convert a string pattern to lower case. This can only be placed
4 H( _! ^8 k  Q# ~               after a string pattern fetch function or after a conversion
+ F- i" o5 }! @4 W* B, z               function returning a string type. The result is of type string.
  ?7 E2 g6 R9 N, B' Q' V; q5 c
! b; A- x4 ^; Z' g. g  upper        Convert a string pattern to upper case. This can only be placed% N* C1 f9 X/ F. r, _; H
               after a string pattern fetch function or after a conversion
1 B5 ]9 J# B$ C3 M- v3 K               function returning a string type. The result is of type string.# r8 l+ A+ G# ^6 T, I( ]

/ a! _. G/ M: m9 l. S4 c  ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups
% G1 b) u$ D( h0 k               and storage. This can be used to make all hosts within a
9 F; Z. k$ P' t4 R               certain mask to share the same table entries and as such use# b; [3 V0 L; }0 }# _/ |! D
               the same server. The mask can be passed in dotted form (eg:
9 X! j2 ]2 ?3 K# ?0 e( L               255.255.255.0) or in CIDR form (eg: 24).
3 z$ ~+ `* Q5 z* J. S$ c6 l
- j- y8 G0 @' c: H* c, I/ E! F0 X: t
8. Logging
3 N0 `& T) e8 o) A----------
( W9 _  o: s  a# v
) A+ M  l( ?# W- VOne of HAProxy's strong points certainly lies is its precise logs. It probably
  I: {0 z3 X$ u/ C( e+ bprovides the finest level of information available for such a product, which is. t, y' B, J2 ~% G% D
very important for troubleshooting complex environments. Standard information4 I& w! l* N7 {2 @4 Z
provided in logs include client ports, TCP/HTTP state timers, precise session+ `, x- m: E6 `1 @7 ]
state at termination and precise termination cause, information about decisions
( V. F0 F2 M1 I& \  H( T2 v/ P8 m, qto direct traffic to a server, and of course the ability to capture arbitrary
9 w& A+ a# R! e" ]headers.
  @$ P0 R+ z( e: R# ~' v$ n% D$ P
% p/ C1 k6 u) @; XIn order to improve administrators reactivity, it offers a great transparency
. |6 M4 w8 j3 Eabout encountered problems, both internal and external, and it is possible to
; z: K! H) t) d+ _send logs to different sources at the same time with different level filters :
8 J/ D  _! A4 L0 J, @$ J" T+ O: J5 R
  - global process-level logs (system errors, start/stop, etc..)3 F: j6 ?3 L( F2 t  [" e
  - per-instance system and internal errors (lack of resource, bugs, ...)( s1 W- j0 m, w+ |/ k
  - per-instance external troubles (servers up/down, max connections)
4 i8 c* r  S9 j' K. T7 s  - per-instance activity (client connections), either at the establishment or
; `7 h1 v6 M0 }/ C9 M    at the termination.
0 x  f! ~4 N/ M4 l2 X+ F! `" Q
, f, l) f0 r# E" yThe ability to distribute different levels of logs to different log servers
. v4 M0 i/ z' Z" x6 \allow several production teams to interact and to fix their problems as soon
9 x* e, Q+ I# ^; f& F! K) [' sas possible. For example, the system team might monitor system-wide errors,
) ~4 Z6 @5 x) i" Hwhile the application team might be monitoring the up/down for their servers in  M  ^! p2 T; v, `; ]% v4 H
real time, and the security team might analyze the activity logs with one hour
" A7 I8 [2 G9 y( |& G) cdelay.# K' m/ z5 F6 [0 h9 f9 k# I

9 v8 M  t/ K8 _( D! R8 u
: f# U) c6 Y9 E4 I4 m/ v/ B8.1. Log levels" V( B' f8 d! p: b' L/ {
---------------( `1 ^& o3 v8 j- e4 p

- t/ ~' f" C9 Z0 g& wTCP and HTTP connections can be logged with information such as the date, time,
3 N; Q" l& g! k' Y  Q! ]7 D( psource IP address, destination address, connection duration, response times,
  D; ]9 V# p0 q% `HTTP request, HTTP return code, number of bytes transmitted, conditions8 _% |$ h) R+ J: ?# N3 P
in which the session ended, and even exchanged cookies values. For example) Z3 S: b, ?9 B- \- ~. R3 ]
track a particular user's problems. All messages may be sent to up to two
9 w* z/ i2 Y0 ~, xsyslog servers. Check the "log" keyword in section 4.2 for more information
5 O1 }9 I9 K% X1 l, ]( H4 Mabout log facilities.
7 H( Q9 h! Q/ I: i  F
4 s' F: ?4 @' u
! z4 i" _1 d  {' e" T4 L8.2. Log formats6 ^$ m0 m. o, I: j* n' u/ [6 E$ ?: a! S
----------------
$ ^( ?  x/ w; m, r
( J* l9 y9 r5 D$ Y& H% BHAProxy supports 4 log formats. Several fields are common between these formats" `+ r- R: u, T, ^! U
and will be detailed in the following sections. A few of them may vary
" f" p& H# K, Q, b3 I4 ]+ D) gslightly with the configuration, due to indicators specific to certain+ f' H, \6 s8 i: I, a
options. The supported formats are as follows :
; C7 i" k1 X& G8 o+ g6 D/ s9 q6 h- A7 U
  - the default format, which is very basic and very rarely used. It only
& B6 T0 Y8 v- J, F; g    provides very basic information about the incoming connection at the moment
' C6 U9 I- }9 L1 R    it is accepted : source IP:port, destination IP:port, and frontend-name.
! J( ~- n1 O0 a1 z    This mode will eventually disappear so it will not be described to great0 s5 \  X, \% b( b- v* [
    extents.; }, f+ a  ~3 {$ U# D+ N' k
" @; J$ g8 l0 [+ w' c/ I' F
  - the TCP format, which is more advanced. This format is enabled when "option4 E6 f$ U9 A) L3 v; U( P2 h7 x. U
    tcplog" is set on the frontend. HAProxy will then usually wait for the
, k" ~$ h2 R0 w    connection to terminate before logging. This format provides much richer) U* @2 ^# }/ b+ W# d6 ^) S
    information, such as timers, connection counts, queue size, etc... This) ?/ D% L/ `) U! F! ?! m
    format is recommended for pure TCP proxies.
3 `+ \; D- l" V. G, W' s+ }9 T3 \0 x: [+ H1 l
  - the HTTP format, which is the most advanced for HTTP proxying. This format
* i/ D# |) l9 ?4 g" `, ^    is enabled when "option httplog" is set on the frontend. It provides the4 d( @: f9 }, [& o& c
    same information as the TCP format with some HTTP-specific fields such as
6 Q8 ]8 K: o6 o) b    the request, the status code, and captures of headers and cookies. This, N- X7 |2 |$ l5 I( T* v( ~
    format is recommended for HTTP proxies.
/ S/ s7 p9 c! n( d- r# {) r1 Z
7 p; b9 A, s0 C1 K5 R( B* u# b  - the CLF HTTP format, which is equivalent to the HTTP format, but with the. K; p  z0 U+ |2 b
    fields arranged in the same order as the CLF format. In this mode, all
; n( n) |' p( f+ h' n' W    timers, captures, flags, etc... appear one per field after the end of the1 b+ a5 I# G) d6 b! A! S+ u
    common fields, in the same order they appear in the standard HTTP format.( i  [1 u$ \0 A% V! u4 P) q2 R

- v* `+ j8 x5 o/ E8 f( h, t, ^6 LNext sections will go deeper into details for each of these formats. Format
  d$ H$ c  M  |+ nspecification will be performed on a "field" basis. Unless stated otherwise, a+ ?( i$ ]. e& r; D3 s6 h3 P0 @
field is a portion of text delimited by any number of spaces. Since syslog1 c9 \. }9 U. o
servers are susceptible of inserting fields at the beginning of a line, it is8 k; n6 ?) C. N$ I; b& R" O# n
always assumed that the first field is the one containing the process name and
5 t9 I+ W" A9 r; p* b$ iidentifier.
, Y. Z- u; @5 Y1 j4 u  v5 {4 I( h& K, I
Note : Since log lines may be quite long, the log examples in sections below
* E1 ^' Z. @' ^' `( {       might be broken into multiple lines. The example log lines will be8 f4 \) V, I9 F1 E+ h: g
       prefixed with 3 closing angle brackets ('>>>') and each time a log is6 r8 q, n" X5 P2 H
       broken into multiple lines, each non-final line will end with a' h5 {& `) B! P/ z  l. E0 X8 c$ d
       backslash ('\') and the next line will start indented by two characters.& r; P3 q) ?. ~. U, k( E

/ N9 u" f6 f, z# R$ L/ x' r  {$ V8 l( i
8.2.1. Default log format9 U1 I/ J' u( O% E7 v, v: V
-------------------------; `$ i0 j1 {1 _7 h& o* P. \, n8 f# S

/ l6 ~+ @. X$ N# K% fThis format is used when no specific option is set. The log is emitted as soon
$ T$ u) K/ t) W! x6 R/ Qas the connection is accepted. One should note that this currently is the only5 N$ n9 g( T2 a  y; d4 C2 Q5 c
format which logs the request's destination IP and ports.! v7 d" \  Z. \, i0 E+ }

, {7 o7 r1 i) y$ F( J) w) ]  Example :
, E/ ?  _; n# Z0 W0 A6 P        listen www
. E* i7 n; ^  }8 l            mode http
' ]- U1 x  t6 A+ }            log global# F! q4 Y& X1 P& P/ ?: G! k
            server srv1 127.0.0.1:8000
& X$ U: t* E( }) D3 J/ x6 S+ X% f9 Q$ c8 T. k! X* q8 ~
    >>> Feb  6 12:12:09 localhost \
4 u) v% `; d; L4 a2 R          haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \$ E& h4 q" B: n
          (www/HTTP)
+ s2 r; e( ]$ I% ^9 X% m0 h
4 U8 }7 c5 o; B0 `  ]  Field   Format                                Extract from the example above- f* s: J' E0 k/ v4 N
      1   process_name '[' pid ']:'                            haproxy[14385]:; @  \$ p0 X+ a( O+ B
      2   'Connect from'                                          Connect from& b" Q: ~$ M) j! u9 w
      3   source_ip ':' source_port                             10.0.1.2:333126 @# e6 q% m9 h2 n; b& l( n$ {
      4   'to'                                                              to
" B5 L2 T8 `6 V% ]& @      5   destination_ip ':' destination_port                   10.0.3.31:8012# W. C" @4 }1 b% t/ O2 W
      6   '(' frontend_name '/' mode ')'                            (www/HTTP)
/ H# @3 X$ D/ U% M
, D. F: l; S& m& J2 ?Detailed fields description :, Q6 s: n0 A- J$ y! k8 L
  - "source_ip" is the IP address of the client which initiated the connection.
. Y' j# d& h# K1 |, @, A: _  - "source_port" is the TCP port of the client which initiated the connection.$ I9 @+ G1 n% q8 s
  - "destination_ip" is the IP address the client connected to.
$ F6 F1 T7 m8 `# ]  - "destination_port" is the TCP port the client connected to.
8 M3 {# \3 v0 M9 E/ D  - "frontend_name" is the name of the frontend (or listener) which received
7 }# D& l- n8 E  a( K    and processed the connection.3 Q0 @4 S( O# M
  - "mode is the mode the frontend is operating (TCP or HTTP).+ X* x# T! m: \/ x. c& n& r4 d! w4 g
/ u1 T9 a0 K9 }7 x& q+ S; Z
It is advised not to use this deprecated format for newer installations as it7 X1 t7 S+ ?( {# Q
will eventually disappear.' O+ g9 m5 D: g: R. S1 S

( |& }  U& O8 @- O$ n. c
4 O0 ?7 }8 O7 [4 u0 O8.2.2. TCP log format
: U5 x+ N8 a) O( }) b- v( y. p; o---------------------; X3 v3 O( x, k; ~4 F# o9 l
' V; h- U* ^# e8 Y9 |6 |( L/ C5 |
The TCP format is used when "option tcplog" is specified in the frontend, and
/ i7 }+ f/ J& A7 K& ois the recommended format for pure TCP proxies. It provides a lot of precious
3 y. m% r, I; M0 Dinformation for troubleshooting. Since this format includes timers and byte3 \0 k! h8 w% M9 @- l
counts, the log is normally emitted at the end of the session. It can be
. K5 `' C+ k. N. u) }emitted earlier if "option logasap" is specified, which makes sense in most
$ w& N9 w0 y+ O! G& u3 c0 ^environments with long sessions such as remote terminals. Sessions which match
' X2 T* c; B) D* Ythe "monitor" rules are never logged. It is also possible not to emit logs for- X4 B3 y: X. A+ @2 [4 V0 F
sessions for which no data were exchanged between the client and the server, by+ W" d9 H" Q' u
specifying "option dontlognull" in the frontend. Successful connections will
6 H- E$ ^/ P+ ^" S! s" g8 E  Tnot be logged if "option dontlog-normal" is specified in the frontend. A few, g9 K* L7 x$ z5 T6 i
fields may slightly vary depending on some configuration options, those are
2 v) D$ S& R0 E1 H# f! nmarked with a star ('*') after the field name below.
0 s( R6 V1 S  o) N+ ?; i6 _; Z9 m0 A' @( n1 D
  Example :
. ~' v# X. N; I  p        frontend fnt
/ _" \# c6 e) X, r9 ]; u$ |3 r' {& w, y            mode tcp! w$ C9 U, W+ Z: S( [  j& U
            option tcplog1 h- P2 H6 Q: a, l+ J  K9 v
            log global6 L  h! n. ~5 L& {* `
            default_backend bck9 c0 N( {' J% a" i0 z+ K1 e
- q1 w' O6 g0 D8 j
        backend bck
8 [) B8 k5 Y- [6 k4 j            server srv1 127.0.0.1:8000( e# {, ]5 l) c  ~0 o5 _3 Z; x- T" p

; |" E0 H. b( ]& V9 T    >>> Feb  6 12:12:56 localhost \
- F3 @1 ]; l. _3 o# c7 |* x          haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \2 A8 c! H9 N- ?& Z; `
          bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0
4 j' o7 Q( z  k9 M# R. O3 }3 i7 D9 C( u! L7 I! W
  Field   Format                                Extract from the example above
; b5 K# T" K, U9 L3 {7 ~, p      1   process_name '[' pid ']:'                            haproxy[14387]:
, Z1 z2 v) |2 d) w; n      2   client_ip ':' client_port                             10.0.1.2:33313
; t$ B5 x) K" P      3   '[' accept_date ']'                       [06/Feb/2009:12:12:51.443]. ^4 C2 |$ f  r8 d
      4   frontend_name                                                    fnt3 N6 h+ e# p* J! ?; D
      5   backend_name '/' server_name                                bck/srv1
9 V7 F2 R: p5 c( M. W- ]5 t      6   Tw '/' Tc '/' Tt*                                           0/0/5007) K* S: j' u. t' ]( m
      7   bytes_read*                                                      2120 e: Q: U2 u  F
      8   termination_state                                                 --
8 \, x9 }7 [8 \' l1 m      9   actconn '/' feconn '/' beconn '/' srv_conn '/' retries*    0/0/0/0/3
, A) T% f; P1 ?+ S' f4 w6 y, B0 V2 v     10   srv_queue '/' backend_queue                                      0/0) B6 o( _! H6 b" W

( w, ]: a* z5 }% T/ a) uDetailed fields description :& _2 A# N8 P9 U% l7 h( C' o* F
  - "client_ip" is the IP address of the client which initiated the TCP, j2 _% p) J/ S  b9 _
    connection to haproxy.
+ {2 F3 F. w; l; o3 Y9 z$ n( n" q7 X
  - "client_port" is the TCP port of the client which initiated the connection.. e: G" v! g& m$ b6 B6 M
' f& U4 I, C7 T% o; k9 {
  - "accept_date" is the exact date when the connection was received by haproxy6 z" d# R+ @/ c3 A; x& U7 W2 o6 K+ r
    (which might be very slightly different from the date observed on the9 h' ]- r# h7 \. r! B1 y; l* c
    network if there was some queuing in the system's backlog). This is usually
+ w: H" v, n7 p& r! w    the same date which may appear in any upstream firewall's log.1 W1 K+ n9 h$ A" o- y  ?3 ^0 O
/ T) {% W8 ~& U* i6 ?% N  _
  - "frontend_name" is the name of the frontend (or listener) which received" e6 @! I, V# r) [0 H# Z
    and processed the connection.& h0 v/ `; q- V$ I: g
0 z1 e: n# e3 E3 J: x. o
  - "backend_name" is the name of the backend (or listener) which was selected
4 F$ d6 X" t1 n! a: D7 x/ ~' q    to manage the connection to the server. This will be the same as the0 p; V) q) L. j* O6 F9 ~
    frontend if no switching rule has been applied, which is common for TCP
0 M8 S! h% Q5 H7 k2 q1 N# e$ V! P    applications.; ~7 b! a1 A6 E
& G7 a# `  }' M6 j+ t( X, k$ L8 ~
  - "server_name" is the name of the last server to which the connection was
1 U1 f! i& `) ^: _) o) p  B    sent, which might differ from the first one if there were connection errors
& ?3 @4 c5 R6 ^3 }& {7 }    and a redispatch occurred. Note that this server belongs to the backend& v* M8 s7 F8 V. F* W6 J. I2 U
    which processed the request. If the connection was aborted before reaching
( |) w: H( \* F5 U    a server, "<NOSRV>" is indicated instead of a server name.
1 J; z' C& t% w; b% A( ^  ?
( E5 V3 ?2 y& I) a0 n  - "Tw" is the total time in milliseconds spent waiting in the various queues.
& g  r' D0 R$ f) q0 @% z; l! s    It can be "-1" if the connection was aborted before reaching the queue.4 @& J7 o/ f/ @
    See "Timers" below for more details.
' t" E' w6 p8 _* k" T6 ?( ^! q. i3 c  j9 M0 U; X4 M( X
  - "Tc" is the total time in milliseconds spent waiting for the connection to
7 U# A, x. N% ~2 n$ U1 `    establish to the final server, including retries. It can be "-1" if the2 q% W. g% n: Q" h: V8 S4 t" r
    connection was aborted before a connection could be established. See
' h, o3 d8 a; h* z+ @/ g    "Timers" below for more details.( U8 T) A5 \& j9 x
/ {# F/ |9 R' H! K: `0 h$ Z3 ?
  - "Tt" is the total time in milliseconds elapsed between the accept and the( s2 T! m: t! _
    last close. It covers all possible processings. There is one exception, if
5 g9 v- o: k4 q    "option logasap" was specified, then the time counting stops at the moment9 I: J* ?' f8 I3 {
    the log is emitted. In this case, a '+' sign is prepended before the value,
1 Z- t6 q# i% d    indicating that the final one will be larger. See "Timers" below for more% n/ C. }! U. X) n" y9 |: ^
    details.
3 Z+ f; n$ G8 G( t0 T
: a, g0 e; N0 }- M3 {; g2 I  - "bytes_read" is the total number of bytes transmitted from the server to
( |7 x: v( f  R: {/ G    the client when the log is emitted. If "option logasap" is specified, the
, F  L: y, V& w( [8 ~- v2 v    this value will be prefixed with a '+' sign indicating that the final one3 z# \, t& f! c  T/ f' U6 w! Y4 P
    may be larger. Please note that this value is a 64-bit counter, so log
2 L1 i! p) E( i5 Q    analysis tools must be able to handle it without overflowing.
! G, b) F% s$ Z6 G2 u  S% Q# O, H! f$ W" x+ l
  - "termination_state" is the condition the session was in when the session
+ K- f3 Z2 [' i    ended. This indicates the session state, which side caused the end of
) P" \) q$ p5 o9 c    session to happen, and for what reason (timeout, error, ...). The normal3 X6 O: _, _' w, X* `
    flags should be "--", indicating the session was closed by either end with, G6 ?$ [) @! H6 q; U0 M
    no data remaining in buffers. See below "Session state at disconnection"
" L, p5 t- u* s2 @) Y    for more details., n( Y/ d' h5 Z
5 ~+ `  o; Z1 J5 c" Q1 S
  - "actconn" is the total number of concurrent connections on the process when: R- q9 e( A" M% X2 d: U
    the session was logged. It it useful to detect when some per-process system
% q  a1 N1 l% z2 K( H( W1 E. [    limits have been reached. For instance, if actconn is close to 512 when% H+ l: p0 k/ D6 u2 x
    multiple connection errors occur, chances are high that the system limits
3 j8 J* t9 R4 f4 u& d) a    the process to use a maximum of 1024 file descriptors and that all of them, k* O: ^' Z" q; W5 e
    are used. See section 3 "Global parameters" to find how to tune the system.$ j- N: n& v6 k  n
5 w' c. ]! j  d& O
  - "feconn" is the total number of concurrent connections on the frontend when9 d6 x3 V! N0 E
    the session was logged. It is useful to estimate the amount of resource
  p9 \9 V5 W' c3 h8 y    required to sustain high loads, and to detect when the frontend's "maxconn"2 j1 F8 t6 N" k" b! D6 k
    has been reached. Most often when this value increases by huge jumps, it is2 p1 A- b* |9 H7 m
    because there is congestion on the backend servers, but sometimes it can be
6 x& M* |/ @/ M* K+ o: u9 v    caused by a denial of service attack.: ~$ U" x* q, B( W

7 j4 W$ X4 Y3 I4 s' \8 v  - "beconn" is the total number of concurrent connections handled by the
2 ?8 k1 b9 K" x' v. }. ^3 f* @    backend when the session was logged. It includes the total number of. `' W3 I# `; s& h' {
    concurrent connections active on servers as well as the number of
0 \0 J  l2 Z  I: K3 N7 z' f    connections pending in queues. It is useful to estimate the amount of
+ u( i: X/ S2 h; r& _# u    additional servers needed to support high loads for a given application.: u+ \. {1 l5 k9 V# Y$ ?
    Most often when this value increases by huge jumps, it is because there is: S2 }6 G7 \- b2 j
    congestion on the backend servers, but sometimes it can be caused by a
" w6 C- D3 i# S    denial of service attack.& D5 e1 j$ y- Y( T

* L* O+ h8 |" t  - "srv_conn" is the total number of concurrent connections still active on
. M, B- x8 S0 _3 ^) W    the server when the session was logged. It can never exceed the server's
  j) A+ k  Y0 q7 L5 W    configured "maxconn" parameter. If this value is very often close or equal
* c: `6 K, Y- }+ p5 u7 C# v# k3 S    to the server's "maxconn", it means that traffic regulation is involved a
2 J4 q- [( |5 Q% n8 V* Y! A  l    lot, meaning that either the server's maxconn value is too low, or that
% i# N. x6 i  N5 ]    there aren't enough servers to process the load with an optimal response
# ^0 M$ w2 [) \- j( z$ u    time. When only one of the server's "srv_conn" is high, it usually means
5 ]% {, X: A* l# v2 ]' ^    that this server has some trouble causing the connections to take longer to
- [: V2 d8 X' o% r2 j2 O    be processed than on other servers.; E) {! X- p5 v+ @5 ?

  H1 _9 H$ T8 x# ^" ?7 R) @  J  - "retries" is the number of connection retries experienced by this session' y5 J1 m# \/ m$ Y2 O4 ]
    when trying to connect to the server. It must normally be zero, unless a* ]0 ^6 D) Z. ^: @7 |+ ~  x
    server is being stopped at the same moment the connection was attempted./ }. h  i: ~  _, w' W4 j
    Frequent retries generally indicate either a network problem between
7 q9 V) x# n) s    haproxy and the server, or a misconfigured system backlog on the server9 E% r( w# R+ o9 K$ U
    preventing new connections from being queued. This field may optionally be
* n( h4 Q: }, B; D# N  @    prefixed with a '+' sign, indicating that the session has experienced a* \9 z) k  I/ A3 a; X% a1 |
    redispatch after the maximal retry count has been reached on the initial
% G( ^( W  ?7 M    server. In this case, the server name appearing in the log is the one the" j+ D6 R  ?7 s$ g' _
    connection was redispatched to, and not the first one, though both may
% h% h' ^; q$ a$ s    sometimes be the same in case of hashing for instance. So as a general rule
( y  j% m9 k  T    of thumb, when a '+' is present in front of the retry count, this count
1 a  A2 C) R/ C8 y    should not be attributed to the logged server.
& U4 d! O5 t* j/ y4 C8 R  E
3 n: n+ h& |. z8 z- e2 U  - "srv_queue" is the total number of requests which were processed before  |9 M2 J: T+ H& ]
    this one in the server queue. It is zero when the request has not gone: `. _- o( l* A
    through the server queue. It makes it possible to estimate the approximate
* x, z$ {$ P- ]5 }) G1 W9 R    server's response time by dividing the time spent in queue by the number of
  S: k" ^+ _2 b  Y/ P6 U    requests in the queue. It is worth noting that if a session experiences a
6 `" N1 G3 R! x3 Y/ g! H. t! E    redispatch and passes through two server queues, their positions will be0 _& Q8 B0 h! c8 }
    cumulated. A request should not pass through both the server queue and the
0 c8 J9 f3 `/ u9 a3 G' h    backend queue unless a redispatch occurs.
: J; [+ F2 P4 i- s# v' u1 b) H7 W$ @: I1 Y* x- d; |
  - "backend_queue" is the total number of requests which were processed before2 O1 `5 w7 T" m% s4 O; ]; W
    this one in the backend's global queue. It is zero when the request has not. x8 L: x( z! L/ B( a* d3 p
    gone through the global queue. It makes it possible to estimate the average1 R/ _- |2 F; |: E. u
    queue length, which easily translates into a number of missing servers when* E) w- u4 o! K& y0 t
    divided by a server's "maxconn" parameter. It is worth noting that if a9 h* f2 V+ E' u
    session experiences a redispatch, it may pass twice in the backend's queue,
- E9 ]& H1 M  i5 [- d, T+ J4 |! b$ w" i    and then both positions will be cumulated. A request should not pass, T4 b4 b4 {; V! E: C
    through both the server queue and the backend queue unless a redispatch" b2 z7 n4 {9 o8 C2 c( n8 y( ^1 ]0 G+ D
    occurs.+ {; H" X1 |2 ]2 q, F  u( `
, N9 b% y0 n  Q* v$ m
, w8 p" z& d) h2 y
8.2.3. HTTP log format
$ I/ [. G2 T1 a! _4 l8 k----------------------
& h" Q" ^: q$ D. @3 B* s9 _/ a4 P. B( r9 Q
The HTTP format is the most complete and the best suited for HTTP proxies. It
4 R1 c+ D9 g- X+ M8 n1 lis enabled by when "option httplog" is specified in the frontend. It provides1 V, ^1 h2 q' W1 s; J9 _9 Y1 S
the same level of information as the TCP format with additional features which; J& r' q/ o1 H2 l# L
are specific to the HTTP protocol. Just like the TCP format, the log is usually
: d0 u" I/ C, p& p* X( A4 F# qemitted at the end of the session, unless "option logasap" is specified, which' S# A4 L6 k5 I1 G& i4 F
generally only makes sense for download sites. A session which matches the
. H5 x* b# I$ j, F"monitor" rules will never logged. It is also possible not to log sessions for, n8 R* v9 q& S
which no data were sent by the client by specifying "option dontlognull" in the9 D7 ?3 U. a4 J+ D5 Q- B
frontend. Successful connections will not be logged if "option dontlog-normal"
0 P6 ]; G- n) c" f& Pis specified in the frontend.
% d6 g9 W/ F1 }& u* B. [1 m
7 ]; v# f; n9 @, \* N, ~, [! c; o6 ]' LMost fields are shared with the TCP log, some being different. A few fields may
0 {% r' q7 V. A" n' I1 \6 Nslightly vary depending on some configuration options. Those ones are marked( k7 w4 h5 S6 }
with a star ('*') after the field name below.- y2 I2 Z  f- r5 x+ j1 Y0 f* N( I
( @: Y+ Y: r8 M& O- A
  Example :! u- j9 {0 x2 j' u3 V2 O  Y
        frontend http-in
0 Q) `* f8 v( i( t4 h5 \* @            mode http. f3 u6 |  L' G% \
            option httplog
5 X* t/ r0 N) O& T: D$ b$ o* H            log global' Q/ _. h& ^5 }  ?' R* I  i7 X
            default_backend bck
9 C5 Z. k8 j: @* X* H, I. Z' J6 q! B% _, o7 r
        backend static& |* @- @7 O& b$ v. Z2 e
            server srv1 127.0.0.1:80008 ^9 c" \0 [+ }

  E* O4 {( |3 ~5 d* q% W$ S& ~    >>> Feb  6 12:14:14 localhost \/ X7 ]+ d$ A9 M- j0 C' b; A" {
          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
$ K- C; G' c9 b: S. Q- V          static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \9 S  F) W  t# Q2 T
          {} "GET /index.html HTTP/1.1"
4 m, @8 E# R+ j5 S. @
; U8 g. J/ R+ W  Field   Format                                Extract from the example above! B- b4 s8 E8 `* l; ?
      1   process_name '[' pid ']:'                            haproxy[14389]:
1 V0 U0 Y+ }$ T      2   client_ip ':' client_port                             10.0.1.2:33317
2 N- a: e( \6 `5 u7 B/ U      3   '[' accept_date ']'                       [06/Feb/2009:12:14:14.655], ]4 ^2 W5 ~2 P0 F  A/ N0 m
      4   frontend_name                                                http-in' J' m8 g' G. o0 o) b; b
      5   backend_name '/' server_name                             static/srv1  R' \# j" Z8 n
      6   Tq '/' Tw '/' Tc '/' Tr '/' Tt*                       10/0/30/69/1098 G1 ~- d& H7 m/ K
      7   status_code                                                      200& `( t/ o' Y; q' e6 P
      8   bytes_read*                                                     2750
7 U7 e% y8 }, R, i      9   captured_request_cookie                                            -6 K- ~: P. I8 z& W7 M# n6 C
     10   captured_response_cookie                                           -7 g$ C$ f, }5 v; H5 M
     11   termination_state                                               ----
3 v0 X5 X8 }& C# B1 {     12   actconn '/' feconn '/' beconn '/' srv_conn '/' retries*    1/1/1/1/0" ~/ d3 \! Z% P) N1 b% l! u! B
     13   srv_queue '/' backend_queue                                      0/0
+ p" O  m, l8 S; }: f     14   '{' captured_request_headers* '}'                   {haproxy.1wt.eu}$ A4 S, T5 u% x( F" w
     15   '{' captured_response_headers* '}'                                {}0 J5 [' m3 ^- M8 ^9 j: X
     16   '"' http_request '"'                      "GET /index.html HTTP/1.1"
8 d6 c) V6 \; f
4 A( u$ ~+ r( a8 m, r0 D
1 c' m, c/ e* d3 z  _4 `Detailed fields description :
- s5 \9 ~; Z- B# ]; w  - "client_ip" is the IP address of the client which initiated the TCP, ?. I* E! G" }* d! W
    connection to haproxy.
! e) n: F6 ]9 ]  Z9 }; X9 W0 m5 `& R! W; `/ V
  - "client_port" is the TCP port of the client which initiated the connection.$ P, D, ], ]3 c, z
! e4 E$ z* S' o2 K' W
  - "accept_date" is the exact date when the TCP connection was received by
+ A3 j2 p8 b/ Y9 ~    haproxy (which might be very slightly different from the date observed on
+ s' s5 j, q7 T1 ]: E' ^    the network if there was some queuing in the system's backlog). This is
) R+ s5 K7 ?, N- T8 z    usually the same date which may appear in any upstream firewall's log. This
6 r( ^% u: j. l9 z/ v! d    does not depend on the fact that the client has sent the request or not.
# e/ q( E, f6 D4 Z  ]5 p2 \) }9 ]# Q& S9 Q$ o
  - "frontend_name" is the name of the frontend (or listener) which received
+ j6 E+ K5 x/ r+ H    and processed the connection.
4 e' |( }& O4 A; v9 x# W; B- g8 Z0 `7 Q+ _' V' X# s; s
  - "backend_name" is the name of the backend (or listener) which was selected- a; z' N; Y+ m; h3 L/ ^% L
    to manage the connection to the server. This will be the same as the
  ?0 h3 o3 F1 a! J# Q1 p; c    frontend if no switching rule has been applied.
4 K4 O+ P- c. e$ _- K. q5 P
% o9 G( v, ^% T" Z1 C! S" I' o  - "server_name" is the name of the last server to which the connection was
# X) M' T# _5 q/ G3 q    sent, which might differ from the first one if there were connection errors
$ A5 r' t+ H7 l, ~, `, P    and a redispatch occurred. Note that this server belongs to the backend! |; D7 I1 T1 L; w/ B
    which processed the request. If the request was aborted before reaching a
: \) V" z* }1 l( F* h    server, "<NOSRV>" is indicated instead of a server name. If the request was7 l4 e% G4 ^, N7 c, V
    intercepted by the stats subsystem, "<STATS>" is indicated instead.8 Y" o8 V5 E" _3 ~" Q3 H: b

6 v! j+ w9 d& |; p4 }  - "Tq" is the total time in milliseconds spent waiting for the client to send% \5 P5 r: \$ m8 ?7 P* F& E
    a full HTTP request, not counting data. It can be "-1" if the connection
' B3 x; a$ I9 d  h) H7 d    was aborted before a complete request could be received. It should always
0 a: r8 C  |( N; n' q    be very small because a request generally fits in one single packet. Large
+ E/ Y0 ~% D5 m4 W1 o3 |    times here generally indicate network trouble between the client and
- {9 _! R. `0 r4 y& f# x    haproxy. See "Timers" below for more details.
' j9 H# c) j( C* [2 w' U* q: s/ n5 k7 _( y' x, y
  - "Tw" is the total time in milliseconds spent waiting in the various queues.
& t8 L5 D5 A' F7 c( p- y( H    It can be "-1" if the connection was aborted before reaching the queue.* H/ u+ Q8 q# E
    See "Timers" below for more details.
( M; z+ Z- w0 f# f: U' _
  g( \( {$ z. d+ M  - "Tc" is the total time in milliseconds spent waiting for the connection to7 @. m+ [  T, p% u) z4 q+ L
    establish to the final server, including retries. It can be "-1" if the& a4 O7 F/ z# K* \& J4 L2 F
    request was aborted before a connection could be established. See "Timers"" l1 ~! d5 M3 M) |# Y' r* F; b
    below for more details.
8 ^: V: r3 ~. t5 |1 t8 A
, x+ C, E9 X7 F, [7 C  - "Tr" is the total time in milliseconds spent waiting for the server to send7 r0 O, A0 u( e) P- I& u% B* b/ |0 Q
    a full HTTP response, not counting data. It can be "-1" if the request was, [0 a7 `7 h: R* z* O  p
    aborted before a complete response could be received. It generally matches
# x' c5 I0 i. S& p  ]; ?: S' l    the server's processing time for the request, though it may be altered by
# c& E6 J9 e6 z$ O9 H/ e    the amount of data sent by the client to the server. Large times here on
" o6 ]* z* J( M+ Z5 v* I7 Z* a8 W    "GET" requests generally indicate an overloaded server. See "Timers" below5 W: U, V% h. _  g* i' P1 M
    for more details.# v0 K$ A2 L) o
* o! X# @, U! m) I; {+ [- y
  - "Tt" is the total time in milliseconds elapsed between the accept and the! i  d! |; B) L0 c- j
    last close. It covers all possible processings. There is one exception, if$ ?6 A$ [9 y7 |- U  |3 ], I
    "option logasap" was specified, then the time counting stops at the moment
( I: d3 T7 z2 y! S! B" }- o    the log is emitted. In this case, a '+' sign is prepended before the value,+ U1 J: q* F0 |; [; }* r, T
    indicating that the final one will be larger. See "Timers" below for more# g4 g* f  P+ h  |5 K0 ?& C' X# p
    details.
3 a+ H+ }- i/ q/ h  `: x  u( n: S
: J4 i4 k& J0 R% ]. S  - "status_code" is the HTTP status code returned to the client. This status) d, W/ i* F0 b& S4 _$ d
    is generally set by the server, but it might also be set by haproxy when
0 S, V( X- y0 }) J& n+ N9 ?    the server cannot be reached or when its response is blocked by haproxy.& u7 O' e5 m" Z7 }% r
6 g- N! d3 V/ L# Y# s. p1 J; T7 i
  - "bytes_read" is the total number of bytes transmitted to the client when* q- G) W; d, Z/ Y6 ~
    the log is emitted. This does include HTTP headers. If "option logasap" is
% U0 R: s- y$ o  [3 E- \    specified, the this value will be prefixed with a '+' sign indicating that, }" B" Z! q) P3 @+ }! i$ C& O% o
    the final one may be larger. Please note that this value is a 64-bit
0 I6 T' {% `' D3 _7 B$ W2 c9 D7 c  P    counter, so log analysis tools must be able to handle it without6 N* B. M. x% h1 @
    overflowing.
9 ?% ~) u4 ^3 V: }: H0 P! ]& O: K& v: E( I# c( U( ~* L: C
  - "captured_request_cookie" is an optional "name=value" entry indicating that" {" N6 i6 J( y4 z( k7 ^! m
    the client had this cookie in the request. The cookie name and its maximum
6 r0 r9 M! E  j0 n2 N% `    length are defined by the "capture cookie" statement in the frontend; e' b5 F" K* ^* d- e+ O" k1 M
    configuration. The field is a single dash ('-') when the option is not
" m' L  ^+ l/ A! P$ @5 K; B    set. Only one cookie may be captured, it is generally used to track session6 `4 Z8 ^0 L; K+ O: @
    ID exchanges between a client and a server to detect session crossing2 M" ]/ x; ?7 Q
    between clients due to application bugs. For more details, please consult
7 ]8 f' I3 N3 K) L  |$ o: `; m; t    the section "Capturing HTTP headers and cookies" below.4 r+ x& U9 x1 L2 O! V  a* U

8 K' {- @! h+ Y! X1 J( F! f  - "captured_response_cookie" is an optional "name=value" entry indicating
4 H7 {- v9 Y1 K2 E    that the server has returned a cookie with its response. The cookie name: ]* k) K- x3 G% Z
    and its maximum length are defined by the "capture cookie" statement in the
2 G) l% c1 K2 `6 j$ R! T    frontend configuration. The field is a single dash ('-') when the option is6 u2 Z" h# Y0 t
    not set. Only one cookie may be captured, it is generally used to track4 Z2 [) G+ L$ C( i
    session ID exchanges between a client and a server to detect session$ E  b% T& S  z" [' h8 ^- E4 F7 q
    crossing between clients due to application bugs. For more details, please. U$ N; _% R7 d+ G
    consult the section "Capturing HTTP headers and cookies" below.
1 |6 v0 U1 @; J' `* u. P$ |7 d6 u4 C% Q* h
  - "termination_state" is the condition the session was in when the session
' j' `6 G& i% f3 [+ T    ended. This indicates the session state, which side caused the end of
0 P9 a4 S/ E6 V" z# F" s    session to happen, for what reason (timeout, error, ...), just like in TCP
* h: M: i0 ?9 r% Z6 B" d9 J3 J    logs, and information about persistence operations on cookies in the last
9 D0 ?! \+ k3 B) B  u    two characters. The normal flags should begin with "--", indicating the
  Q  {! ?9 V9 @+ C8 }! v5 B8 W    session was closed by either end with no data remaining in buffers. See3 A( Y! J) |8 x
    below "Session state at disconnection" for more details.
; e- h; k7 U8 o. W! X# b* A4 l
' [2 _0 S) Z$ G7 Q  - "actconn" is the total number of concurrent connections on the process when& ^/ a0 b4 l  _( `  q3 a: H% ^
    the session was logged. It it useful to detect when some per-process system
, \' E+ D' R6 e" a2 }% _6 s" z    limits have been reached. For instance, if actconn is close to 512 or 1024% n) k- b% y4 Q/ W0 D
    when multiple connection errors occur, chances are high that the system$ c, _) D& ~$ I: I) B: V
    limits the process to use a maximum of 1024 file descriptors and that all
9 K% E  P& b: e' u( u1 l$ h$ e    of them are used. See section 3 "Global parameters" to find how to tune the3 P- U( Y5 n0 v, i: H
    system.
& X4 C# J: Y/ n) G8 Q! y
8 Y1 k. q3 b. U- M9 G  - "feconn" is the total number of concurrent connections on the frontend when: O, v2 t8 [4 D2 f3 O4 g
    the session was logged. It is useful to estimate the amount of resource
/ @6 y7 r% I+ Z' s" ^" W    required to sustain high loads, and to detect when the frontend's "maxconn"6 H% G7 G/ c; }0 ~3 j5 p& K
    has been reached. Most often when this value increases by huge jumps, it is
1 r& |, V: e) B# t& h    because there is congestion on the backend servers, but sometimes it can be; P  ^% |6 V. s2 D7 V
    caused by a denial of service attack.% j8 T- P( K8 m

& G  j3 f$ j7 w  - "beconn" is the total number of concurrent connections handled by the1 o; y* ^8 e7 p8 O
    backend when the session was logged. It includes the total number of& v2 Z2 C, y2 Z# J
    concurrent connections active on servers as well as the number of! {. x. ~" w' Z8 }. R
    connections pending in queues. It is useful to estimate the amount of
4 X# `' ^. d7 Z. r    additional servers needed to support high loads for a given application." n$ y1 ~& i- Y5 i
    Most often when this value increases by huge jumps, it is because there is" ~2 m1 u' H4 f7 o4 x2 w2 ]9 d
    congestion on the backend servers, but sometimes it can be caused by a  L# k& W! f5 p* M. h# y3 w' m; i+ L; c
    denial of service attack.4 b. Q7 V5 o7 J1 Z  t" b

, z% N+ }$ g$ E1 J: V/ m7 P  - "srv_conn" is the total number of concurrent connections still active on* o* G" E6 G, f6 G1 f) X' o- a
    the server when the session was logged. It can never exceed the server's
/ P. @, y* {, _9 i    configured "maxconn" parameter. If this value is very often close or equal: U) J2 L4 R4 k
    to the server's "maxconn", it means that traffic regulation is involved a
! j) V& D( K+ \9 b5 A, C- x5 u    lot, meaning that either the server's maxconn value is too low, or that
% d0 J  q- h% b* I& ^    there aren't enough servers to process the load with an optimal response1 C: l% c+ h! j$ ?, w( W
    time. When only one of the server's "srv_conn" is high, it usually means
; Z7 x' o- ^) i7 k9 q9 a    that this server has some trouble causing the requests to take longer to be
( Z$ F" W' I; q    processed than on other servers.: H( v# R1 G5 Q* j' r; P  V
! n+ ~& W& n1 S
  - "retries" is the number of connection retries experienced by this session
+ D7 S* _$ H- ]0 n" J6 a8 }    when trying to connect to the server. It must normally be zero, unless a' `" |" n% R& f* F8 s# E! \* [
    server is being stopped at the same moment the connection was attempted.
; H" @/ a* J# d0 E+ ~    Frequent retries generally indicate either a network problem between+ Y9 o  p* Y3 u# o; E; ^0 t" u& w
    haproxy and the server, or a misconfigured system backlog on the server
9 r' g, E1 L/ v4 W. O1 f1 F    preventing new connections from being queued. This field may optionally be2 \8 z0 \" Y7 t5 M- g4 Q
    prefixed with a '+' sign, indicating that the session has experienced a) ^1 S& c( T# U
    redispatch after the maximal retry count has been reached on the initial
' w. s8 h/ s8 N- P: h% P    server. In this case, the server name appearing in the log is the one the. p/ T: u# k) ^6 x% H% L
    connection was redispatched to, and not the first one, though both may
, q/ b0 A1 q5 h9 k    sometimes be the same in case of hashing for instance. So as a general rule5 k7 W# h! s1 ]7 h( p
    of thumb, when a '+' is present in front of the retry count, this count
" M5 X5 ?0 E9 |# |3 H    should not be attributed to the logged server.
1 ~# e  V( f, l& D
) ~  M' J! _( h! S# q  - "srv_queue" is the total number of requests which were processed before* b' X5 O+ @  E3 o/ [+ ~
    this one in the server queue. It is zero when the request has not gone
" x- L, r, ~/ ]" }6 j& R, ]    through the server queue. It makes it possible to estimate the approximate/ h$ y8 n' p# h3 \( }
    server's response time by dividing the time spent in queue by the number of
. j, S% O, `% o/ t/ d    requests in the queue. It is worth noting that if a session experiences a
+ K6 b+ N. ]9 r. H! ?" B: ~( B    redispatch and passes through two server queues, their positions will be
% z0 j/ L  p( v# C9 X1 J) ^6 W    cumulated. A request should not pass through both the server queue and the
: G) C  f7 ]7 c4 s, B# _    backend queue unless a redispatch occurs.
; k' K' y, Y$ [* m' m6 B- e4 f% x: l9 z1 U- V! V
  - "backend_queue" is the total number of requests which were processed before% c5 R9 U6 j: K5 a. U; J0 Z
    this one in the backend's global queue. It is zero when the request has not/ V' y9 |% u- T" A, p
    gone through the global queue. It makes it possible to estimate the average
, @+ E  T5 n  H& v6 L  t    queue length, which easily translates into a number of missing servers when$ U( v$ ?; i% ?. B
    divided by a server's "maxconn" parameter. It is worth noting that if a
9 W4 l0 Y# ]5 f* T$ _% B    session experiences a redispatch, it may pass twice in the backend's queue,
- w' K  s) O8 X- x6 Y" s    and then both positions will be cumulated. A request should not pass. T8 m9 T8 m7 |- W. v+ G7 `' w
    through both the server queue and the backend queue unless a redispatch
) s* u  L  F6 M1 s1 G7 V$ D4 ^    occurs.
2 L/ r+ L$ G4 }& F9 M
5 B7 ]4 a% a0 Z1 l  - "captured_request_headers" is a list of headers captured in the request due* P/ b, r( c* x+ L$ i' g
    to the presence of the "capture request header" statement in the frontend.
# `" h% Y2 \5 F$ Q  K    Multiple headers can be captured, they will be delimited by a vertical bar2 [" `# L1 N! R- m7 t. ?$ d
    ('|'). When no capture is enabled, the braces do not appear, causing a- o5 z: i0 o, ]* N3 q* Y
    shift of remaining fields. It is important to note that this field may* ]6 i0 D& A2 ~( ?2 T+ L
    contain spaces, and that using it requires a smarter log parser than when3 g5 W7 Y8 [4 Z
    it's not used. Please consult the section "Capturing HTTP headers and
* g% A! b2 f0 t    cookies" below for more details.. v: u) f' c* r' V6 C
3 C' J. L, |8 c8 H: j9 U
  - "captured_response_headers" is a list of headers captured in the response
5 K  B! @/ ~9 l: h) h    due to the presence of the "capture response header" statement in the8 e2 M  D4 }" s1 a0 w2 g
    frontend. Multiple headers can be captured, they will be delimited by a3 Y! y# Y, c' R9 n6 S
    vertical bar ('|'). When no capture is enabled, the braces do not appear,  V3 |+ i. t4 G' A- r
    causing a shift of remaining fields. It is important to note that this
% `' H! W  V  j% T    field may contain spaces, and that using it requires a smarter log parser
* e2 f' v) X7 Q, f+ c6 ]    than when it's not used. Please consult the section "Capturing HTTP headers
% }8 I8 P" N0 y    and cookies" below for more details.2 R9 l  j, d  r
$ }) c9 X+ V7 l; ~  f0 }
  - "http_request" is the complete HTTP request line, including the method,
* H4 x. ?5 X- |  d+ Q0 Z    request and HTTP version string. Non-printable characters are encoded (see! s9 t6 j& o8 P0 [$ T
    below the section "Non-printable characters"). This is always the last
/ n* `2 i2 x* j- R) h6 L    field, and it is always delimited by quotes and is the only one which can9 O2 [4 v7 f' Q, J3 j9 i
    contain quotes. If new fields are added to the log format, they will be% ]  k2 v% G5 Y
    added before this field. This field might be truncated if the request is
8 [; t6 h& ~! W! A/ @    huge and does not fit in the standard syslog buffer (1024 characters). This+ P! T, g+ v* y, n1 B
    is the reason why this field must always remain the last one.+ T* r7 ]! x1 o! y; Z8 X

6 J; P6 o1 z$ }/ P5 K8 `6 b+ B+ Q: a3 j; p
8.3. Advanced logging options
5 w4 z- ~. I, Z# @5 d-----------------------------2 r( X# g  \1 h3 Z8 g  g

  B1 V% e8 C2 O$ nSome advanced logging options are often looked for but are not easy to find out
2 L6 e' C1 }# ^+ @% hjust by looking at the various options. Here is an entry point for the few) n7 Q1 H5 q3 g; A; O. W3 y+ b- v
options which can enable better logging. Please refer to the keywords reference( ^; |* F. k% m1 p: I6 j
for more information about their usage.
# Z* E/ }& C6 j! o6 j3 Y+ g% h& A7 V9 S

% O6 }1 A- u/ J8.3.1. Disabling logging of external tests2 }1 X1 V+ F& \% F, {! ^1 N# N4 d
------------------------------------------
6 h1 d$ L1 r/ A' e& F
8 a9 w- U1 }! [1 O5 k5 F9 x: pIt is quite common to have some monitoring tools perform health checks on  A2 U: G" H2 f. V' L
haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any
. y% h3 G! C( W* S% Zcommercial load-balancer, and sometimes it will simply be a more complete  d, s/ V; ?6 \1 }' [3 k4 l
monitoring system such as Nagios. When the tests are very frequent, users often
4 n7 m) M- m6 Y! M5 n: h: \ask how to disable logging for those checks. There are three possibilities :
  G. ^! g6 y3 p
9 q! I  ^9 w3 D! e  - if connections come from everywhere and are just TCP probes, it is often
: ]& [2 P; }; @, j  `( Q' s' H    desired to simply disable logging of connections without data exchange, by  n5 g6 ^) W  K
    setting "option dontlognull" in the frontend. It also disables logging of0 e( ~9 r; j' j: V0 ]$ R
    port scans, which may or may not be desired.
* N4 y$ }2 o: \# I, R6 ~
+ T$ Q6 j2 S5 q$ M6 H/ U; t7 l  - if the connection come from a known source network, use "monitor-net" to
# R% I) M$ T. h9 X" {    declare this network as monitoring only. Any host in this network will then7 N) b% d* T5 ~# |2 |/ F
    only be able to perform health checks, and their requests will not be
% A% d1 g' A; b! S    logged. This is generally appropriate to designate a list of equipments
0 j) [; a& r+ J4 r4 M* d    such as other load-balancers.1 S& E. Y) Y7 X9 O3 i

4 g. A9 J* R1 P4 c! L8 g7 v  L. G7 o  - if the tests are performed on a known URI, use "monitor-uri" to declare
5 N+ Y/ m. b2 K0 e/ M; h* y% t    this URI as dedicated to monitoring. Any host sending this request will
$ E% i* w, ~0 J6 M3 A- f: c    only get the result of a health-check, and the request will not be logged.- s- \/ G# l5 g! b7 \

% ^7 \/ L0 X/ g( G8 k# e6 g3 d; ]5 v) Y  J
8.3.2. Logging before waiting for the session to terminate2 j% q% `! b, p7 j
----------------------------------------------------------
$ r/ M* O9 l0 l1 z/ ~% t, Z4 R" F0 h7 K4 ?  d
The problem with logging at end of connection is that you have no clue about( W9 N! d* |- N% `1 B
what is happening during very long sessions, such as remote terminal sessions
# T' C3 z7 k3 f8 \or large file downloads. This problem can be worked around by specifying. R* Y* w3 P# N! m
"option logasap" in the frontend. Haproxy will then log as soon as possible,) o6 d9 [( ^" ^$ }, z  T
just before data transfer begins. This means that in case of TCP, it will still0 D1 \6 I. r0 @# K) D: M2 S
log the connection status to the server, and in case of HTTP, it will log just0 w, N8 _% j8 W+ G1 i2 o- i8 L) i
after processing the server headers. In this case, the number of bytes reported
8 ^" n1 T* f% M' his the number of header bytes sent to the client. In order to avoid confusion
& j8 g" z0 q, vwith normal logs, the total time field and the number of bytes are prefixed5 [# G+ a' D% |
with a '+' sign which means that real numbers are certainly larger.
( b  P& d. |- w  I6 `& a/ x
3 X5 ^0 l5 X2 ]( Y; I
( l, l, j, c" L) }8.3.3. Raising log level upon errors2 o8 W  a4 s- G) ?$ R* p
------------------------------------4 N3 x6 O0 v* [7 }7 I! f
! o  U1 m$ O: b$ J4 ]' ]
Sometimes it is more convenient to separate normal traffic from errors logs,
7 v7 M& U4 V/ u5 T  v& d7 E; ^for instance in order to ease error monitoring from log files. When the option
  v+ c/ }) K. t2 s+ u6 M3 _"log-separate-errors" is used, connections which experience errors, timeouts,$ H2 J' S0 [) ^2 e' I
retries, redispatches or HTTP status codes 5xx will see their syslog level0 G( Y2 g' v" t. ^
raised from "info" to "err". This will help a syslog daemon store the log in
! u( H# q. z8 T4 I) [a separate file. It is very important to keep the errors in the normal traffic
2 o0 E& L7 ^9 G( Lfile too, so that log ordering is not altered. You should also be careful if; m: S' d. Y2 e! M* z
you already have configured your syslog daemon to store all logs higher than0 i! `7 E5 `+ {2 E& }0 H
"notice" in an "admin" file, because the "err" level is higher than "notice".
( \$ q% U4 Y, b* D2 Q) ]3 q& b9 m; D4 m- B  @- U

$ H  x6 s( C; W8 M% M9 U4 C# d' G: V8.3.4. Disabling logging of successful connections
3 e/ H% b% W8 d. G( f9 q3 t6 Z--------------------------------------------------* w; L7 Z) V5 C

0 n- b; M2 R4 t, L% x6 \; V) v5 NAlthough this may sound strange at first, some large sites have to deal with
& x. ^' a' m0 d. m7 ~3 ^, emultiple thousands of logs per second and are experiencing difficulties keeping% Z5 b+ }2 s* w
them intact for a long time or detecting errors within them. If the option8 _* o8 E- j5 H( |& b/ x
"dontlog-normal" is set on the frontend, all normal connections will not be, H( h" t5 X1 G* ^; a
logged. In this regard, a normal connection is defined as one without any
. c8 k5 ]! g# t% ^' e2 T+ a. x' n+ rerror, timeout, retry nor redispatch. In HTTP, the status code is checked too,
% e! K# p6 m# R7 }7 u# zand a response with a status 5xx is not considered normal and will be logged
* ?% _3 x4 R- T  T. L1 c. `: r9 L# T) htoo. Of course, doing is is really discouraged as it will remove most of the) B6 f8 s  `, s8 @" _' K4 ?
useful information from the logs. Do this only if you have no other
; y7 m0 ?) J! P' |alternative.( M9 n* L% h& e+ d8 c
1 j6 }" ?: q! z% E$ G9 X9 Z
0 j$ J0 }' Q! e( Q
8.4. Timing events4 Q! s) c2 C: u* M
------------------
2 V) q) O1 x. {* x9 Z
: o# p6 ]1 v0 h2 D) u3 Y  W- }Timers provide a great help in troubleshooting network problems. All values are( i) ^, h# l+ O$ a" c9 L; }! S
reported in milliseconds (ms). These timers should be used in conjunction with* Y$ |1 N) C0 l1 d8 l
the session termination flags. In TCP mode with "option tcplog" set on the
- ^' u6 I# r. S4 p9 z5 l( N; vfrontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP6 u  `2 u4 A3 T$ Q4 n$ Z- X
mode, 5 control points are reported under the form "Tq/Tw/Tc/Tr/Tt" :
# t/ }; R" F: c) S: [) y2 g" ?$ T, R" r
  - Tq: total time to get the client request (HTTP mode only). It's the time0 ], H0 c1 Y4 n1 n2 o
    elapsed between the moment the client connection was accepted and the
( v& h  X. u7 \: c# z    moment the proxy received the last HTTP header. The value "-1" indicates
! z4 c$ N. Z) x4 c( H! Y1 ^    that the end of headers (empty line) has never been seen. This happens when
6 ]# X3 ^* o* I' I& T, a/ l; o# r    the client closes prematurely or times out.
& Z# E, m- w4 \& E7 G% v5 Y: a# o1 n5 ^, Y+ i+ h. f
  - Tw: total time spent in the queues waiting for a connection slot. It, x+ l- n+ ~- b  y# g
    accounts for backend queue as well as the server queues, and depends on the
" u9 j  `" Y; a3 l, T) ^    queue size, and the time needed for the server to complete previous
2 P/ W2 }. Q$ `0 a( V! f    requests. The value "-1" means that the request was killed before reaching
1 r+ m% X) L8 m. S& e" n    the queue, which is generally what happens with invalid or denied requests.. @1 p. s& d9 u

8 w! w* S, d" U& F* J  - Tc: total time to establish the TCP connection to the server. It's the time
  h3 p& @% j3 h; A" U    elapsed between the moment the proxy sent the connection request, and the
- b" [, V* d" Q0 G7 G  d$ P, Q$ }8 ?    moment it was acknowledged by the server, or between the TCP SYN packet and
' K6 j: I) B1 I+ x& P8 s    the matching SYN/ACK packet in return. The value "-1" means that the
" g8 e! s! @* i3 L  l  }6 v    connection never established.
3 @5 _9 }$ N: N( r9 r# f. A
( T: N1 j5 [4 i+ A& u  - Tr: server response time (HTTP mode only). It's the time elapsed between# Z4 m3 W/ L; i
    the moment the TCP connection was established to the server and the moment
2 t) X3 d! c4 X9 `    the server sent its complete response headers. It purely shows its request
2 w: W8 x. H9 n9 I7 R/ I    processing time, without the network overhead due to the data transmission.
2 I4 z3 k; g) S2 I* h    It is worth noting that when the client has data to send to the server, for* N5 g% g5 B, q% Z; u
    instance during a POST request, the time already runs, and this can distort( f0 l) ]9 v0 n9 [/ L, H
    apparent response time. For this reason, it's generally wise not to trust
( n2 V* ?& f' q7 D2 }  c    too much this field for POST requests initiated from clients behind an
. V1 _( {6 _" _. \2 @  y    untrusted network. A value of "-1" here means that the last the response( k6 S" F7 j' U" B6 L$ e! F6 ^  Q
    header (empty line) was never seen, most likely because the server timeout. i8 b" ]/ [5 ], z! F* J- o
    stroke before the server managed to process the request.
+ d. j3 i+ C2 V! N/ F1 L$ U4 |( K, ?6 U% x  D( _) s9 I
  - Tt: total session duration time, between the moment the proxy accepted it
( Z- [& |& p# l( l, O    and the moment both ends were closed. The exception is when the "logasap"- U% V4 |+ P% |# ~) \. [
    option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is
+ e; y2 L; g0 b2 M7 c% g( L    prefixed with a '+' sign. From this field, we can deduce "Td", the data0 ?* L5 Q3 S3 `: [; h6 J" a0 ^
    transmission time, by substracting other timers when valid :3 P/ M6 s0 ?, I. D* w
4 f5 W; g# j! h8 a; N  `( m
        Td = Tt - (Tq + Tw + Tc + Tr)
4 s! b  g8 Y7 L8 r+ W* a: C; G1 T# O5 N, W# J2 X3 s/ B
    Timers with "-1" values have to be excluded from this equation. In TCP8 E) s* P3 L3 O) g
    mode, "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be
& }3 p1 A  A) o8 f0 e1 M" K    negative.
8 n$ q: W5 M4 Y$ z4 P2 K- Y
9 p8 O( U1 G- L. N5 S9 zThese timers provide precious indications on trouble causes. Since the TCP
0 V/ z% F3 s' T+ z3 L* }, ~* Hprotocol defines retransmit delays of 3, 6, 12... seconds, we know for sure/ C6 L0 z# _. J2 u' e
that timers close to multiples of 3s are nearly always related to lost packets3 S- B0 N/ H0 i) U
due to network problems (wires, negotiation, congestion). Moreover, if "Tt" is
( p+ T6 C0 T5 T4 ?$ o' _) `close to a timeout value specified in the configuration, it often means that a
; Q, G2 n7 O& |7 O" |session has been aborted on timeout.
4 r4 Z. v( V; d/ @# k# h/ g3 k
6 t& y8 p$ N. M( X. Y0 O8 h- GMost common cases :
, w; i2 r# b9 _. }4 b/ w4 F: d. T2 k& S* `$ ~$ i4 C1 w, K. N
  - If "Tq" is close to 3000, a packet has probably been lost between the) y' w7 u) b  ?5 Y! }
    client and the proxy. This is very rare on local networks but might happen% Y* u/ `* D  E
    when clients are on far remote networks and send large requests. It may- R  U* h) N: `3 b
    happen that values larger than usual appear here without any network cause.
! V: h0 I# N  G( j' O1 P& r2 r    Sometimes, during an attack or just after a resource starvation has ended,
' V1 }3 N9 a+ A+ C    haproxy may accept thousands of connections in a few milliseconds. The time5 ]) J- [) s/ P9 m3 A
    spent accepting these connections will inevitably slightly delay processing- J' @0 i6 L; C
    of other connections, and it can happen that request times in the order of( Z% G  h( N: J7 `  k. _/ N$ g8 |
    a few tens of milliseconds are measured after a few thousands of new
* u3 o: h, w1 e    connections have been accepted at once. Setting "option http-server-close"6 m9 k% O) w# I9 d
    may display larger request times since "Tq" also measures the time spent
8 W0 ?. {% U0 m5 ?/ u  b    waiting for additional requests.
7 x& j) Q( L1 j3 f1 G' \4 C3 h$ C& ?5 c4 A$ a
  - If "Tc" is close to 3000, a packet has probably been lost between the5 o( A, a: W" H4 @
    server and the proxy during the server connection phase. This value should
1 \1 r  P% H. [) a, z/ c2 q    always be very low, such as 1 ms on local networks and less than a few tens. K$ a( ?$ z/ r. ?7 S* y
    of ms on remote networks.
9 N' Z, |7 I& R, X7 A6 d
- M7 J9 \7 h; y; M3 g1 r7 P0 g* I  - If "Tr" is nearly always lower than 3000 except some rare values which seem/ A5 L' W8 @' c' |3 S+ K
    to be the average majored by 3000, there are probably some packets lost! ~# b- R% T1 q0 E
    between the proxy and the server.9 T" d9 |- v! A. c) A5 \9 Y
( a9 ]" \" T  ~( o  \
  - If "Tt" is large even for small byte counts, it generally is because% Z/ [8 O8 R5 y' ^. S
    neither the client nor the server decides to close the connection, for
6 Y7 x, X' U- V9 M    instance because both have agreed on a keep-alive connection mode. In order
8 J5 b" b) I# s- n2 O- [$ z2 R    to solve this issue, it will be needed to specify "option httpclose" on
+ a/ g& r& C; [! a2 \* x    either the frontend or the backend. If the problem persists, it means that% {8 r, C6 j  }
    the server ignores the "close" connection mode and expects the client to! ^  z! q) u, W) ^, D
    close. Then it will be required to use "option forceclose". Having the% |" ?( q( s+ N9 a1 Q  o5 J$ A
    smallest possible 'Tt' is important when connection regulation is used with0 V9 e: P  C- x
    the "maxconn" option on the servers, since no new connection will be sent
: {2 B7 w) G  z* @5 b    to the server until another one is released.
# B7 Q0 {' n; x  N, y2 W
/ C7 }" n# z9 H+ OOther noticeable HTTP log cases ('xx' means any value to be ignored) :/ i+ e1 l+ F  f( z; ^2 E. m
  R/ L8 X% S) K* P' Y& `* `. b
  Tq/Tw/Tc/Tr/+Tt  The "option logasap" is present on the frontend and the log: ?/ v# i2 K" G6 ]
                   was emitted before the data phase. All the timers are valid& h& v; f- y4 M
                   except "Tt" which is shorter than reality.. l# M/ `* m& Z4 l5 E% r

( c/ \- O6 _# @5 y4 R  -1/xx/xx/xx/Tt   The client was not able to send a complete request in time( Z5 C& k% Y4 E5 @1 g# }+ @! s0 f
                   or it aborted too early. Check the session termination flags
8 A7 f6 B7 h' `0 L                   then "timeout http-request" and "timeout client" settings.
# k; J2 ?; K! U5 T2 U6 v) q% G; k8 x
7 B- ^  K0 H' \+ g4 \* p  Tq/-1/xx/xx/Tt   It was not possible to process the request, maybe because3 A( ~) q8 p& r  K* m& Z' Y6 E
                   servers were out of order, because the request was invalid
4 M; x& a  N9 i                   or forbidden by ACL rules. Check the session termination
) t0 C+ T/ k9 A7 E' R$ A! e- I0 d% g                   flags.
% q2 I2 L9 D0 p8 ?) x
7 D* Y9 x- J0 [$ F* w  Tq/Tw/-1/xx/Tt   The connection could not establish on the server. Either it
" a) R, d/ r5 `, _7 K7 o                   actively refused it or it timed out after Tt-(Tq+Tw) ms.
& \5 r% e8 O" X0 `  \3 I  K                   Check the session termination flags, then check the
& I. ]  E. d' A9 t                   "timeout connect" setting. Note that the tarpit action might
. I+ m6 s1 @6 W  ]' W3 S1 t                   return similar-looking patterns, with "Tw" equal to the time7 }9 z7 a0 Y- A3 d* r$ p
                   the client connection was maintained open.
9 M; Y3 }+ @+ v6 f1 n
4 o4 s) p: P  o2 v0 m: X, {  Tq/Tw/Tc/-1/Tt   The server has accepted the connection but did not return
+ [$ }1 o% E' z( ~; k1 k9 S9 O! V                   a complete response in time, or it closed its connexion7 I8 p) l0 h+ \- {0 q% J; \
                   unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session: j. T' s. c& V6 v% A7 M* R) B; W; A
                   termination flags, then check the "timeout server" setting.
' z! k, ?4 D7 g3 a2 A# l0 _) ^& E  N/ O* |: z% \. U$ v/ n% f/ w% |( C3 L
' k4 Z: t# ]7 l
8.5. Session state at disconnection" p5 g2 f& u7 M: d- X+ l1 J
-----------------------------------4 U+ m0 {9 M3 g  e
$ m& b- X  u2 m
TCP and HTTP logs provide a session termination indicator in the9 ]# f2 ?+ }; H+ l% @
"termination_state" field, just before the number of active connections. It is1 ~/ g+ n& @: ]( O* C
2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,- ^8 A5 T" ?; i/ ?+ P! B6 \
each of which has a special meaning :* Q5 u( e) `/ N2 `: b1 a& h
, G$ j6 U: Q$ r8 n0 p+ I$ G: Q# U, ?
  - On the first character, a code reporting the first event which caused the
  X( z6 g1 Z; U' z& o/ Q    session to terminate :0 r2 J  c  l/ Z4 R1 \/ X1 b- _+ M) d
# y* b6 M  e; q+ |% ]3 O) g2 a
        C : the TCP session was unexpectedly aborted by the client.# V" Z9 L# C$ _

( R! d) F9 T# T        S : the TCP session was unexpectedly aborted by the server, or the
( G  l7 ~% f& d5 Q( |9 J            server explicitly refused it.% B. v0 x; e0 @- M% p  h

3 p& R/ n# s4 f        P : the session was prematurely aborted by the proxy, because of a6 D; l" U- x2 V' ^" I) i3 X
            connection limit enforcement, because a DENY filter was matched,0 E  N* T. n6 j3 a) I
            because of a security check which detected and blocked a dangerous; N# y" V* p5 R
            error in server response which might have caused information leak, m3 u2 o6 z. t/ l; w2 K
            (eg: cacheable cookie), or because the response was processed by& d! c) ]5 x' m7 q7 v- M0 C
            the proxy (redirect, stats, etc...).
9 U5 c7 k1 |8 v! `9 B1 b7 A5 V1 [0 L- l, W/ ~# i4 j. _2 `
        R : a resource on the proxy has been exhausted (memory, sockets, source2 g2 u; }4 \. V5 ]9 a6 Z
            ports, ...). Usually, this appears during the connection phase, and! d0 r/ A" H2 |% \
            system logs should contain a copy of the precise error. If this
& f/ Q! r9 `' W$ `# p            happens, it must be considered as a very serious anomaly which) J0 X; S. U6 ?: t0 a
            should be fixed as soon as possible by any means.  k3 d1 U" z; p& C0 N
/ v. T" S  S: |$ n5 b
        I : an internal error was identified by the proxy during a self-check.
8 _' ~2 C0 @! I/ q% ^! M5 U            This should NEVER happen, and you are encouraged to report any log* Y4 ?! _( `3 p" S5 {
            containing this, because this would almost certainly be a bug. It5 }9 ?) i7 E2 B" N
            would be wise to preventively restart the process after such an
; k0 D* h" H+ l' n            event too, in case it would be caused by memory corruption.( ?# O0 d& N+ Q, s5 o) b

+ {' C. a& Y' Y        c : the client-side timeout expired while waiting for the client to  |9 I' u% i! N( ^
            send or receive data.) l# n8 X6 U1 c5 L% c) W1 [
6 b( q( }: j/ q) n# M
        s : the server-side timeout expired while waiting for the server to+ |2 ]; V0 v8 a+ p4 W
            send or receive data.% q; E" z' c5 `. \! z

' c* g& ^5 ^5 f2 L. C0 P3 r  z        - : normal session completion, both the client and the server closed. x5 m. `+ o6 N8 F0 W( G
            with nothing left in the buffers.; Q5 n5 y7 ^. J! L9 f
; g9 T0 a( }! j& ~& [
  - on the second character, the TCP or HTTP session state when it was closed :3 w! U+ L" H9 Y
6 ], T( j5 J8 J: K! `0 u0 ]
        R : the proxy was waiting for a complete, valid REQUEST from the client' Z0 o% v! Y% w
            (HTTP mode only). Nothing was sent to any server.3 S0 ?3 }4 S4 [+ m# r8 a
! s% R$ d$ [& s/ E" f& V8 {
        Q : the proxy was waiting in the QUEUE for a connection slot. This can6 }9 Q6 r, U; |3 E" Q
            only happen when servers have a 'maxconn' parameter set. It can
" A9 e( z2 c. B3 H) _" T* Z            also happen in the global queue after a redispatch consecutive to
& o4 c) x) O7 ~9 I) a, }& Y/ y            a failed attempt to connect to a dying server. If no redispatch is# J4 p* }0 q3 r# ~4 n6 v+ d, }
            reported, then no connection attempt was made to any server.# w, t, e4 c7 y9 }- U# L  C
% l# l9 W' B3 T( F' F
        C : the proxy was waiting for the CONNECTION to establish on the
' O4 p7 T2 j4 v5 n            server. The server might at most have noticed a connection attempt.# Z) R5 O1 l) e$ e6 z9 B$ ~

, D) s6 x" ~, l8 n, k* ^' \1 ?6 |; g$ F        H : the proxy was waiting for complete, valid response HEADERS from the% D  t! m9 V8 ?$ }" q7 ?
            server (HTTP only)., m/ H/ B5 \$ w! k0 V" ~
! J" M; e. _# M3 _1 |; T
        D : the session was in the DATA phase.4 ?4 w6 H' T9 M. L5 E

9 z# U( y2 P  a8 I* U% l) h        L : the proxy was still transmitting LAST data to the client while the" N4 Z1 ?8 ], f* w" K
            server had already finished. This one is very rare as it can only
% }! L' u# O' X            happen when the client dies while receiving the last packets.
+ j! i8 i& G1 P5 ~4 A$ c+ R
) }! b4 D8 x- _6 a5 R. R( h6 Z        T : the request was tarpitted. It has been held open with the client
7 }' l3 V4 U# i. x7 X            during the whole "timeout tarpit" duration or until the client& V$ w2 `5 l8 ~6 _, e( i
            closed, both of which will be reported in the "Tw" timer.
6 u% k3 v7 J3 y+ t5 V" ^# I
9 T. [$ A) C8 `, B9 d/ a        - : normal session completion after end of data transfer.5 k' o5 b$ P& F4 y# n! m
, i' s1 l2 k+ ?" k" J  ?
  - the third character tells whether the persistence cookie was provided by
  q# u/ l/ _# l  X- y& |  e" Y    the client (only in HTTP mode) :- v7 e9 S$ e: \' q

( r9 x$ r8 j& f6 d' V8 j3 {        N : the client provided NO cookie. This is usually the case for new
% L% t5 B; `! \            visitors, so counting the number of occurrences of this flag in the
1 c% I7 J5 w: e3 k1 t) k+ g6 i            logs generally indicate a valid trend for the site frequentation.' b4 @& p8 m" i; m

8 ~! g7 R! V, ~9 t" S* X        I : the client provided an INVALID cookie matching no known server.6 @0 ^7 s/ A' \. O  [& n6 X
            This might be caused by a recent configuration change, mixed
9 u5 B. d* o. b) v1 c; Y            cookies between HTTP/HTTPS sites, persistence conditionally# h4 v, ]4 s: T7 J9 ~
            ignored, or an attack.
* ?# V$ |" o& Z0 [  y% U' E) I
! V# _) \3 ], l; z* c        D : the client provided a cookie designating a server which was DOWN,
, W: i. d! @! t" n9 t' b2 F+ q            so either "option persist" was used and the client was sent to
0 N8 m" [# U8 C5 }1 K  C            this server, or it was not set and the client was redispatched to, h" {" M# n3 p4 @4 A8 c8 ]7 R
            another server.5 l; T! P: u2 S9 ^! z% v- Y4 O% G
/ M3 m3 c! R- k; \3 k4 u
        V : the client provided a VALID cookie, and was sent to the associated1 j+ f2 H. B& M  p! T- R. y
            server.' w4 L' t0 a7 W+ o7 @5 s: w
" i; t# F6 K4 \% h! r( r3 O
        E : the client provided a valid cookie, but with a last date which was
1 ~- T/ c' e2 [9 S# d            older than what is allowed by the "maxidle" cookie parameter, so
5 J& s5 ^! m* M. @* Z            the cookie is consider EXPIRED and is ignored. The request will be
7 U. }" _; X4 W& S$ F" M% `1 d6 u            redispatched just as if there was no cookie.
0 ^; v. z2 k4 T2 w6 E# G; x
8 A/ T6 e) Z  z+ ~" G4 {        O : the client provided a valid cookie, but with a first date which was
) P# M+ D! g$ A            older than what is allowed by the "maxlife" cookie parameter, so
- M. O! V2 _- b            the cookie is consider too OLD and is ignored. The request will be
7 O; y  F- B, @5 [7 n  }3 n4 i* t            redispatched just as if there was no cookie.4 i& t/ G( f4 u7 ^+ {. V
1 \8 z  `7 @5 Z+ M
        - : does not apply (no cookie set in configuration)./ M) H* G  V5 a6 J" n8 @- p

" [; g8 N/ y1 E0 N  o: _  - the last character reports what operations were performed on the persistence: y; {% G% w% g# f
    cookie returned by the server (only in HTTP mode) :
  F8 O& z" h! n% J3 S  Y0 O8 {$ G1 ^9 I3 R1 e. p% k( s; c
        N : NO cookie was provided by the server, and none was inserted either.8 H0 b8 A* e6 L4 D

7 ~9 z! F- `. A& b        I : no cookie was provided by the server, and the proxy INSERTED one.
' P7 a( a: E3 X            Note that in "cookie insert" mode, if the server provides a cookie,
" L) X0 u7 K+ f, s            it will still be overwritten and reported as "I" here.
/ k' H, ]5 H7 J' j
4 c( n/ V- z! L: {        U : the proxy UPDATED the last date in the cookie that was presented by2 }' D! Z3 I& `* U! P8 J
            the client. This can only happen in insert mode with "maxidle". It
) D4 L0 G6 |9 r            happens everytime there is activity at a different date than the
1 p8 H# A7 \0 S- \- z, w* W5 Y            date indicated in the cookie. If any other change happens, such as
* j) [5 b5 n3 @! X. j            a redispatch, then the cookie will be marked as inserted instead.
' K3 h: V$ Z: b4 f, o3 g% A3 B$ y5 O3 x
        P : a cookie was PROVIDED by the server and transmitted as-is.
4 z8 Y% Q' Z& Y1 a: @. `# U# ^9 R' t' H
        R : the cookie provided by the server was REWRITTEN by the proxy, which
2 V" T+ p  h3 O& Q+ q            happens in "cookie rewrite" or "cookie prefix" modes.
  U- C) o) D8 m& X" W+ f$ a3 `# Y$ s) u$ j) @5 j- X, j2 Y: j
        D : the cookie provided by the server was DELETED by the proxy.
) ^8 w; }  s7 M. ?7 T% P  u, f# d1 ^) m% g3 a" z' O% n# u  v
        - : does not apply (no cookie set in configuration).+ B7 {$ Y2 @6 p& {; `" m" v& s2 H
2 f& ?' k. ^; L. [. T
The combination of the two first flags gives a lot of information about what( s0 `& g4 a) m  U8 z1 b4 ?9 ?
was happening when the session terminated, and why it did terminate. It can be9 s- ]  _+ ?: l( D  e2 S; X+ K2 e
helpful to detect server saturation, network troubles, local system resource
, V! w- ^& v  n$ t# b5 w$ M" a- x2 Istarvation, attacks, etc...
4 O3 `5 `) ?! j& y8 v
! M8 F9 K5 e! l( JThe most common termination flags combinations are indicated below. They are
1 r' W4 ?- o$ ]& `5 Lalphabetically sorted, with the lowercase set just after the upper case for" j: ]& b0 L! R
easier finding and understanding.0 N8 u; J7 c8 H/ a

6 {* ^9 ]# P, s0 k0 R( B1 `  Flags   Reason2 G+ L$ }! p1 N' @/ `' |! Y
% Y' L- K  j7 W/ x: S! d9 K& v
     --   Normal termination.1 S1 S  B3 Y1 y: |" w

& e% u$ G' w' N     CC   The client aborted before the connection could be established to the' m, x# _: @% d; ]# F) G9 E8 }: O5 Y
          server. This can happen when haproxy tries to connect to a recently
8 w1 I+ G8 }* p8 g, ^          dead (or unchecked) server, and the client aborts while haproxy is
6 [( e& [. c( H; }          waiting for the server to respond or for "timeout connect" to expire.
( {3 r* t( y* n9 i5 G* h/ G8 q
' ]* [' |5 C0 |9 ]  B* o# I     CD   The client unexpectedly aborted during data transfer. This can be! }3 w# T" E3 B1 k! K( G
          caused by a browser crash, by an intermediate equipment between the* J5 f2 \6 P, b- w0 A  d
          client and haproxy which decided to actively break the connection,
& Q' T3 _/ {. f          by network routing issues between the client and haproxy, or by a, h$ ~" {. t8 J$ y- D6 }" X
          keep-alive session between the server and the client terminated first- O8 S# {( I9 w7 k  {
          by the client.# O0 D: G# ?" D- Q6 E8 d
9 c* k5 I% q! x7 ?+ [2 s
     cD   The client did not send nor acknowledge any data for as long as the& x1 r% I, r  j( j7 k# k6 `- Y
          "timeout client" delay. This is often caused by network failures on
; S& N. Y& Z. q          the client side, or the client simply leaving the net uncleanly.  B- z: w4 O1 R0 p

+ d; X; H4 f/ I9 P     CH   The client aborted while waiting for the server to start responding.
, \9 U; \& G6 U3 i4 j, ?' g          It might be the server taking too long to respond or the client" r, }2 n) n8 w
          clicking the 'Stop' button too fast.+ ?0 b+ L: a' ]' z( J: Y' F/ _7 U
+ ?2 L4 e2 {$ \: {2 J
     cH   The "timeout client" stroke while waiting for client data during a# G& Q5 F: [9 A/ I  x
          POST request. This is sometimes caused by too large TCP MSS values
& {% S, J  X6 B/ m5 n          for PPPoE networks which cannot transport full-sized packets. It can
7 ]# H: y) W: o5 s: Q* }          also happen when client timeout is smaller than server timeout and) q3 d6 ?) Q. G4 x/ }9 |
          the server takes too long to respond.' E% N2 m' N' c
9 F6 c6 G% k# l
     CQ   The client aborted while its session was queued, waiting for a server& P  I- S* ?5 V
          with enough empty slots to accept it. It might be that either all the( [7 u% m9 X* u' Y
          servers were saturated or that the assigned server was taking too  b! c. W8 Q0 l& L6 i; H) T8 e% ^
          long a time to respond.- u% D2 ], }, c; I' C

7 H" _0 A% `3 R0 O8 F     CR   The client aborted before sending a full HTTP request. Most likely
, A- A% m+ V2 f: S  r0 X          the request was typed by hand using a telnet client, and aborted
" A" B0 w# l; b3 l# |6 M8 D9 ~0 e          too early. The HTTP status code is likely a 400 here. Sometimes this
& k3 h# Q4 p$ c& |          might also be caused by an IDS killing the connection between haproxy
/ `7 \& a2 u5 u  F" K( w          and the client.
  _7 C/ S) \: b$ r( ?  d, K
( d' ]6 F# j7 ]     cR   The "timeout http-request" stroke before the client sent a full HTTP% i$ Z( P3 Q2 k; }, q- T7 L7 F6 N
          request. This is sometimes caused by too large TCP MSS values on the) J  y9 p! K7 P# b
          client side for PPPoE networks which cannot transport full-sized/ j9 e1 V8 u) R1 G2 k6 j+ u
          packets, or by clients sending requests by hand and not typing fast" I( L8 y& U, m: a! D" Q( I
          enough, or forgetting to enter the empty line at the end of the0 @% [1 T7 Z6 m, {1 Z& W
          request. The HTTP status code is likely a 408 here.
2 E3 q8 ~. p/ V  A- i- \9 j# @  l3 I" _
     CT   The client aborted while its session was tarpitted. It is important to
" T, i8 d. I' l& p          check if this happens on valid requests, in order to be sure that no
9 `! s+ }; N$ L2 c; e" N          wrong tarpit rules have been written. If a lot of them happen, it+ p1 B5 p# y+ x+ a& ^$ _! P5 W: N
          might make sense to lower the "timeout tarpit" value to something* M$ e% q7 P$ I3 ^) _. d
          closer to the average reported "Tw" timer, in order not to consume
- s, K& i, U: j. k6 H          resources for just a few attackers.
2 N2 e0 E: C& Y5 s, d  Q3 V  P, l6 K$ r+ n; X6 X. k- B  x
     SC   The server or an equipment between it and haproxy explicitly refused2 J7 p7 @" C$ v
          the TCP connection (the proxy received a TCP RST or an ICMP message
1 A3 t3 k, M. b. J8 q5 A5 [/ s9 W          in return). Under some circumstances, it can also be the network
0 V/ e/ v2 S7 i. W- A5 M$ L. T( w          stack telling the proxy that the server is unreachable (eg: no route,
2 f; g: G; f, N          or no ARP response on local network). When this happens in HTTP mode,- K" T1 O8 c5 @1 P
          the status code is likely a 502 or 503 here.) L" e0 ~8 v6 e) l- M8 W

. |1 ?- N. ~& n0 T8 N; X     sC   The "timeout connect" stroke before a connection to the server could" J7 B% \; W8 F# [0 {6 p
          complete. When this happens in HTTP mode, the status code is likely a
4 p7 w4 M2 S7 w  }. t! s          503 or 504 here.! {( Z8 s0 v9 ~: n+ F  v

* k4 {1 R. T" o' v. q" A$ Q     SD   The connection to the server died with an error during the data
  `5 E6 i9 S- [. x. M, |$ l" }/ }* L          transfer. This usually means that haproxy has received an RST from
" x; a9 c; G2 q- ?7 Z, @' y          the server or an ICMP message from an intermediate equipment while
# v4 x3 d2 a" T  b  c          exchanging data with the server. This can be caused by a server crash# d* @/ O4 S# ]
          or by a network issue on an intermediate equipment., k& r* E7 g! Y" q

. E3 |: q; S1 e* k7 X  G     sD   The server did not send nor acknowledge any data for as long as the
4 ^& l+ k, Z4 U& ~9 K: y          "timeout server" setting during the data phase. This is often caused
/ e  l3 H' e& i          by too short timeouts on L4 equipments before the server (firewalls,
3 v8 Q" L& {7 A+ v- f0 }' N          load-balancers, ...), as well as keep-alive sessions maintained
9 E' P1 z& y* Y          between the client and the server expiring first on haproxy.& @# u; Q2 F8 S

2 L! b+ p# Y% f- d/ S2 q- n" |  g2 X     SH   The server aborted before sending its full HTTP response headers, or
4 X# ^9 K2 B# b/ Y* U# ^          it crashed while processing the request. Since a server aborting at; o: l6 `7 \+ m: \, l
          this moment is very rare, it would be wise to inspect its logs to* f3 B. F* E. b% c
          control whether it crashed and why. The logged request may indicate a0 H: h- F0 I  B
          small set of faulty requests, demonstrating bugs in the application.
$ h( s9 Z: l' Q# G% D# H  }  w- H4 E          Sometimes this might also be caused by an IDS killing the connection
, g* W/ M' v! L( D5 \          between haproxy and the server.
3 e6 d! S9 |+ W) K( ]; b0 B" N+ \9 C" b
     sH   The "timeout server" stroke before the server could return its% i, L- V) m% B# [4 u6 k
          response headers. This is the most common anomaly, indicating too; @% F5 q- @- ]* \* ]7 q
          long transactions, probably caused by server or database saturation.
& W" g0 Z. K/ P0 R& P- ^3 n          The immediate workaround consists in increasing the "timeout server"
; w! r/ f5 Y, L$ B9 g          setting, but it is important to keep in mind that the user experience
: [+ h' v# m  P0 d          will suffer from these long response times. The only long term
9 W2 G. S' ?: N" B          solution is to fix the application.
+ [" q/ B7 A- I3 m! ]8 e- e: Q; x) K0 w2 t. X
     sQ   The session spent too much time in queue and has been expired. See
# X0 S: A; ~- D$ b& R          the "timeout queue" and "timeout connect" settings to find out how to5 s, k! z/ n# N# Z! u' _$ v
          fix this if it happens too often. If it often happens massively in$ ^: V5 X* `7 H3 X, t7 Z0 G3 P! L
          short periods, it may indicate general problems on the affected
( t1 J) U4 j4 g1 s/ Z9 s# v, i          servers due to I/O or database congestion, or saturation caused by5 `- y0 d5 ^' P4 T+ ^- x
          external attacks.
; `0 m6 c( }" r% \; q& ^& c3 `8 t8 R) E. l9 b. G. C
     PC   The proxy refused to establish a connection to the server because the
. I5 k" |0 x) s          process' socket limit has been reached while attempting to connect.- m/ Q0 H2 d) Y8 f0 a: ~
          The global "maxconn" parameter may be increased in the configuration2 c$ [2 f+ {, C1 [2 d" s' x
          so that it does not happen anymore. This status is very rare and
9 ?! w* }% c7 n& a8 @! O          might happen when the global "ulimit-n" parameter is forced by hand.
5 q2 z1 Y; U% @9 t, Y, A$ S5 I$ Y) V6 f
     PD   The proxy blocked an incorrectly formatted chunked encoded message in7 E7 x' `# [7 z# ~
          a request or a response, after the server has emitted its headers. In
8 {6 o: \5 v) d5 Q. Q* ?          most cases, this will indicate an invalid message from the server to' s% d2 z) ~4 S
          the client. Haproxy supports chunk sizes of up to 2GB - 1 (2147483647
& h- R: v" o, o5 y& Y% x% Q4 S          bytes). Any larger size will be considered as an error.
! u1 X% P. T2 h  x
$ w% I( ^& u6 M$ {# m# A     PH   The proxy blocked the server's response, because it was invalid,% {6 V  l9 L9 s+ u$ D$ @3 d9 U
          incomplete, dangerous (cache control), or matched a security filter.
  {+ O5 S* D, S          In any case, an HTTP 502 error is sent to the client. One possible
" }' U, V4 P( x9 U3 f" W          cause for this error is an invalid syntax in an HTTP header name4 t) N0 B, g% I! A) k
          containing unauthorized characters. It is also possible but quite9 H* Q. ~- f) G% I
          rare, that the proxy blocked a chunked-encoding request from the
! J( ~5 ~, |" c! O% e' W0 u          client due to an invalid syntax, before the server responded. In this
% ^3 f8 c0 N0 H- H6 a          case, an HTTP 400 error is sent to the client and reported in the( u; Z% w, L% H' O) v% F& t
          logs.. J% _6 g1 d; F6 J; s, ]1 m3 G

; J; d3 {* M- l7 `' ]0 I     PR   The proxy blocked the client's HTTP request, either because of an$ }+ a. Z7 r& S$ M' O/ j$ x
          invalid HTTP syntax, in which case it returned an HTTP 400 error to
1 R1 l7 w+ N0 V. D) y          the client, or because a deny filter matched, in which case it
! p! ?. P3 j# c$ {+ B          returned an HTTP 403 error.; T' ?% i2 H6 ]) J+ T2 q* Z

+ \. A6 F! K+ F3 t     PT   The proxy blocked the client's request and has tarpitted its8 `' W/ ?7 l4 L5 s
          connection before returning it a 500 server error. Nothing was sent$ @# A& e% }) u) o4 ]; W- l7 J
          to the server. The connection was maintained open for as long as
7 a; ]- S1 w( g7 X          reported by the "Tw" timer field.
8 P9 ~$ j" M) L  M4 s5 t+ m+ ?) S8 Z
/ \$ d1 o  ]1 N, Y/ v+ a     RC   A local resource has been exhausted (memory, sockets, source ports)( M! p, C' M1 u, a0 P' H
          preventing the connection to the server from establishing. The error6 U0 V* {+ p& m
          logs will tell precisely what was missing. This is very rare and can+ y0 r; f/ J' H  h0 w; _( [
          only be solved by proper system tuning.& A: y/ E) _( J, d$ \

9 P' E9 w, W. U7 j% q( LThe combination of the two last flags gives a lot of information about how9 }' s# l  t0 I2 i( D% X
persistence was handled by the client, the server and by haproxy. This is very
, _. _( s' {' E! p5 k! T2 simportant to troubleshoot disconnections, when users complain they have to
; s3 f- U. g. |re-authenticate. The commonly encountered flags are :7 g% y/ {# `5 ]! R
! \( n1 ^( h7 }- U- O0 `
     --   Persistence cookie is not enabled.. s7 n+ [; A/ v4 B9 b  O
$ ?3 ]( e2 f+ }9 w: T: Z6 v
     NN   No cookie was provided by the client, none was inserted in the, Y  a- Q( B. w0 y. t' @
          response. For instance, this can be in insert mode with "postonly"
3 U: d* B) f" i1 s          set on a GET request.
8 k6 o, j0 v) [1 c. X& X% r
" }* B6 L0 x9 s& R  R1 x8 y8 L6 y     II   A cookie designating an invalid server was provided by the client,
9 d% k& q! m: _$ g( b; o          a valid one was inserted in the response. This typically happens when
& n. |3 Q" r/ Y! E8 c" k3 d          a "server" entry is removed from the configuraton, since its cookie
/ C; @5 j+ G0 @- }/ p# F1 I          value can be presented by a client when no other server knows it., x; H5 M" k5 }/ l3 a
, i6 k  T7 s+ B7 }) x6 Y
     NI   No cookie was provided by the client, one was inserted in the9 [/ u. F% q$ `0 P( e! R# q
          response. This typically happens for first requests from every user" P7 C6 a1 ?7 X4 i9 y
          in "insert" mode, which makes it an easy way to count real users.
1 z0 Q3 T+ _, V+ @3 R, S% ]+ C
4 d  z+ b! k+ h/ \; e3 R     VN   A cookie was provided by the client, none was inserted in the3 }4 s2 U3 Q  A4 `  K4 k7 c/ z
          response. This happens for most responses for which the client has) {- J9 l7 u8 Y0 Q6 w9 l) d
          already got a cookie.
% U2 J4 i! p6 k# j( }% _7 ?% [  t# p( F0 ?5 T; v  ~2 f; A+ G! C
     VU   A cookie was provided by the client, with a last visit date which is, }4 l6 y3 p4 P. H. v' d  ?
          not completely up-to-date, so an updated cookie was provided in
) q7 Q$ U# s% ?/ U          response. This can also happen if there was no date at all, or if
/ m4 k  w5 l1 l/ n          there was a date but the "maxidle" parameter was not set, so that the. P7 g5 Y: I0 H  D' i
          cookie can be switched to unlimited time., r0 P( ^" s0 w# S  }

4 f$ f6 P5 m2 z+ r% t! t, A, N     EI   A cookie was provided by the client, with a last visit date which is3 \3 P) O" n8 ^, I3 k
          too old for the "maxidle" parameter, so the cookie was ignored and a0 ~( N, z% W) h! e# ?( Q6 L
          new cookie was inserted in the response.0 u+ y* g5 @" Y) K# `' ?
- G& j, I! E5 ]; ^) E
     OI   A cookie was provided by the client, with a first visit date which is
4 p0 B/ }  D& w: i2 r5 X- O          too old for the "maxlife" parameter, so the cookie was ignored and a
. G8 n" i" P, X9 ~7 K+ L6 \" e          new cookie was inserted in the response.
1 l) c: w0 r3 m6 \6 J3 R; N* L  A  b3 Y  t
     DI   The server designated by the cookie was down, a new server was. _$ l( F0 ~. j- v, j& @) o7 }4 c" S
          selected and a new cookie was emitted in the response.: R/ k  k$ m: {8 C0 F

" P( q! O9 x# e     VI   The server designated by the cookie was not marked dead but could not
" b2 F9 Z3 u3 S% F" m/ b+ M  `          be reached. A redispatch happened and selected another one, which was
& O3 ?" n0 ?$ {" m! T+ a          then advertised in the response.: j' Q) T" j4 l, P

- e5 t) W! y. M: \( W9 W  J2 h; h9 h/ s2 n3 P$ y+ a6 v" T
8.6. Non-printable characters
; l1 l4 K! ]% C; M) ~-----------------------------
& X$ F* w+ u5 Y( J0 q* [, `, s; g6 r
* `9 t- N  n' x) wIn order not to cause trouble to log analysis tools or terminals during log4 w( }% R' j/ A1 X1 J
consulting, non-printable characters are not sent as-is into log files, but are
) y3 {0 Z; \, d' C; i- M3 Kconverted to the two-digits hexadecimal representation of their ASCII code,' w4 ~; h7 \$ q
prefixed by the character '#'. The only characters that can be logged without& w! l, e! ~" q9 H' j
being escaped are comprised between 32 and 126 (inclusive). Obviously, the
) B0 D$ k1 b5 ^% B$ x, y( Y6 qescape character '#' itself is also encoded to avoid any ambiguity ("#23"). It! g/ t" q6 \  A: |, j
is the same for the character '"' which becomes "#22", as well as '{', '|' and
, ?2 O! T. f  G/ s- |'}' when logging headers.
; w7 A" Z8 O! E8 ?% h  F
+ o1 R; |% K. x1 GNote that the space character (' ') is not encoded in headers, which can cause% L( [1 K* B) h0 v7 [) q
issues for tools relying on space count to locate fields. A typical header$ |0 J; v5 x4 G0 P0 @5 ^6 j( O
containing spaces is "User-Agent".4 x/ \6 F6 I0 v, g

5 S9 P) N; Y7 ]. l( J, tLast, it has been observed that some syslog daemons such as syslog-ng escape
) ~3 G4 P) m4 G; Q) f# Q- uthe quote ('"') with a backslash ('\'). The reverse operation can safely be' B6 ~4 p( k- h( s# W' p
performed since no quote may appear anywhere else in the logs.6 y, V0 x0 j2 b1 m
4 }5 E, F4 n) J" X3 z* S, s
$ f/ F% a( C+ Y  o
8.7. Capturing HTTP cookies0 u7 }, b$ K) T" z
---------------------------
1 R, [) M3 t" L$ [2 T
0 H: b- ?+ k& ]6 M3 k' U3 jCookie capture simplifies the tracking a complete user session. This can be2 b/ T" Y+ g! e3 g
achieved using the "capture cookie" statement in the frontend. Please refer to- O% R; Q7 m7 ~' y/ C2 @& a
section 4.2 for more details. Only one cookie can be captured, and the same
2 O' a, g0 y  P' b9 Wcookie will simultaneously be checked in the request ("Cookie:" header) and in
8 Q: T9 o0 D7 Sthe response ("Set-Cookie:" header). The respective values will be reported in7 H# o" }/ i, ?! T! q
the HTTP logs at the "captured_request_cookie" and "captured_response_cookie"2 l$ M' S& Z" G5 X
locations (see section 8.2.3 about HTTP log format). When either cookie is8 I( ?% F2 {; o+ @
not seen, a dash ('-') replaces the value. This way, it's easy to detect when a( J/ S6 q# v/ i( J5 M7 B3 {" _! y/ Y5 h
user switches to a new session for example, because the server will reassign it
6 B$ _+ j7 s1 R1 R5 l. `: m  ma new cookie. It is also possible to detect if a server unexpectedly sets a
- X- ^# K1 x  f( @" U( I# g3 cwrong cookie to a client, leading to session crossing.& d% [! L7 u! B7 P% S

5 j: \) X, X2 a: `: ^  Examples :& n( m  |, Q1 Y7 `7 Q
        # capture the first cookie whose name starts with "ASPSESSION"# [! [. O0 ^4 i; M
        capture cookie ASPSESSION len 32
; B7 b  P' t9 g+ }6 w" B. U0 F% t# ?% w' {( n
        # capture the first cookie whose name is exactly "vgnvisitor"1 Z2 Q; R" O6 \0 n9 v9 ~
        capture cookie vgnvisitor= len 32, ~% N: @- z) d- L# {* G

3 e* U. R/ B: H/ \- P& `( D- `" K7 Z
8.8. Capturing HTTP headers
* N' j# l5 j6 h$ V( h( U---------------------------! I* E" `( ?( k# K( M. d3 w

0 X' G$ I$ V8 U, F: F, oHeader captures are useful to track unique request identifiers set by an upper
+ d; O4 j- T: A0 z0 `# Wproxy, virtual host names, user-agents, POST content-length, referrers, etc. In/ b5 Z4 y! t: r, F, A9 D
the response, one can search for information about the response length, how the# O/ @1 b+ H( o; _6 H  S/ L/ I! m
server asked the cache to behave, or an object location during a redirection., a: j# T; D: v7 I( |$ ^/ B

- p) X) c3 C& j/ U! f( RHeader captures are performed using the "capture request header" and "capture' ]' c7 ]" R: t- g' L( g
response header" statements in the frontend. Please consult their definition in5 P% G: F8 }9 r- l; Z
section 4.2 for more details.
8 F. _, l9 o" X1 ], M1 ~
$ \6 G7 @$ r* j$ {' |It is possible to include both request headers and response headers at the same
$ ?) e& j- H% `- Wtime. Non-existent headers are logged as empty strings, and if one header' |5 Z7 b  ~: }
appears more than once, only its last occurrence will be logged. Request headers) G; k& ^4 {) |2 ^, X  y  n, b8 ~
are grouped within braces '{' and '}' in the same order as they were declared,$ y5 u8 c% T8 [7 l$ l* D5 l6 {
and delimited with a vertical bar '|' without any space. Response headers
5 Y( k6 j  C0 l2 B4 Mfollow the same representation, but are displayed after a space following the1 T0 F: ?2 x4 N8 H. [/ x) G4 P  D$ ^
request headers block. These blocks are displayed just before the HTTP request- ?0 x: Y% w5 m8 {3 {% ], A
in the logs.: ^2 }9 Z7 H+ B8 x3 z% G

" m8 q6 _  h3 O  r$ ]  Example :
. Q$ z5 C; k9 `# K2 \! I  Y, N        # This instance chains to the outgoing proxy4 O# D) H4 `* J8 K- i
        listen proxy-out
) }0 a+ u! l. j" ^, J3 ]2 |* H            mode http* K# [) c: a3 E9 t: i3 Z
            option httplog
% o5 `4 n9 E% l6 X2 v            option logasap
& T1 Y7 k9 b  Q7 y; }( `            log global0 o* e2 i0 y! [, I
            server cache1 192.168.1.1:3128
0 G7 n1 X& A. P# N/ O! [+ w! T* O4 u4 {6 I( m, ]
            # log the name of the virtual server
: v& s! ^! P6 D  K% v% O            capture request  header Host len 208 N4 C' c  k" ]7 E

3 K/ e0 _( H3 c2 {9 ~8 Q: F; k            # log the amount of data uploaded during a POST  D) x8 F0 V) q
            capture request  header Content-Length len 10
/ }6 a1 ~# _& L. J
( o  x: p0 \1 c! t- y            # log the beginning of the referrer3 t+ I. I. `/ d/ s
            capture request  header Referer len 20
& w. x  _3 k& o0 {( v- J  |. s6 T# b- X
            # server name (useful for outgoing proxies only)
' c6 X$ j% _& g  U6 k+ ~' I" c! h7 ~            capture response header Server len 20# d  R3 I( [* W1 O; f! N

$ L+ c4 H' n- D: N& K0 `            # logging the content-length is useful with "option logasap"
& Y% W; [* @2 \. G" C  g! k5 w0 g7 U/ {            capture response header Content-Length len 10$ X9 f( p. T. V; d0 b4 m4 f  w

6 O  ~- ~! X: o5 ~" G$ [            # log the expected cache behaviour on the response
# [" t. @+ p* I$ i" s# ]6 B+ M: t            capture response header Cache-Control len 8
2 t# g! W. r2 P6 S9 b* b( M* g7 k9 v0 O
            # the Via header will report the next proxy's name+ S+ p( k1 A( E5 f: Z( g& w
            capture response header Via len 201 L1 a$ Y2 ?. D- i7 d

, Y. M: e. i/ u3 Z/ G; F$ y            # log the URL location during a redirection
5 R) f1 m9 L$ \- L7 `            capture response header Location len 20
9 \% [' h: a! D8 z5 s2 i. X( P& c3 i" N$ W7 D7 n
    >>> Aug  9 20:26:09 localhost \
0 ^7 A, U! U- @9 A8 T0 v* D; ^# m          haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \& s# B: l0 y1 E3 k& d) l
          proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \( s- d+ o- A+ {* d! i% {3 B; B
          {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \& u& d7 \- b6 f4 T  u2 P
          "GET http://fr.adserver.yahoo.com/"
# S) P! e# r: w) \$ N% F4 m# H' W, M) E
    >>> Aug  9 20:30:46 localhost \
; \, Y) c3 M0 s% C( O          haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \, `' ~, \& R9 u: v! o
          proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \5 w/ V* B4 O# c$ |
          {w.ods.org||} {Formilux/0.1.8|3495|||} \
9 w% _. M* b% ]9 J          "GET http://trafic.1wt.eu/ HTTP/1.1"
1 C& ~# [* W5 n) j0 D% U
5 `2 t/ e* V( k& T  P    >>> Aug  9 20:30:46 localhost \" ^) W7 S" H& n4 b+ {
          haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \$ R5 a# p" l; b, f; @
          proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \( _/ x' e- Z/ t
          {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \& `( F/ _- ?# B% T2 B( y/ [% {
          {Apache|230|||http://www.sytadin.} \5 [& |' g4 O2 h( e- k+ z8 A
          "GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"
1 P- U9 O8 Z- b. v. ^$ X3 F( e; d' m" D+ |" q* `* G8 a! C
6 X3 _, C! D, }5 x+ ~
8.9. Examples of logs! I6 D0 h- j9 c3 b) u# X, s
---------------------
6 f+ O/ n0 P! R7 u
/ k- Z: V- W' y* S6 t* ]  yThese are real-world examples of logs accompanied with an explanation. Some of+ J' I% V* o6 @# G; L
them have been made up by hand. The syslog part has been removed for better
. L! C' O; R) }4 J+ v$ @9 H3 Areading. Their sole purpose is to explain how to decipher them.0 e+ U) k5 ?$ [0 e: a* `# \; W# V

/ E% O, n* h! @7 n1 `    >>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \" L: E' N6 z2 W2 v
          px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \- b8 U/ I1 B! F) A, V7 d3 X
          "HEAD / HTTP/1.0"
" E3 N8 n& c# [/ z# ~
" Y  e5 _7 h* ?    => long request (6.5s) entered by hand through 'telnet'. The server replied
% x7 J# F0 z8 I2 q; X       in 147 ms, and the session ended normally ('----')- d8 v+ a4 l$ S$ [# I& T# C

1 B* Z; R% [3 g3 Y9 X' N, D4 l    >>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \& ^8 D* ?) c6 {0 E5 `4 S* D
          px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \
" Q8 `0 F; H; Q" n4 T3 _% ~7 f          0/9 "HEAD / HTTP/1.0"
( \8 n& c' H5 J- i6 y! @- O
0 L, j  Y5 S0 @& k1 v    => Idem, but the request was queued in the global queue behind 9 other
7 i3 `! j& o5 R. V6 T# Z* T       requests, and waited there for 1230 ms.! j! B( D7 ~2 f/ a" E  H; I

) j4 M9 s$ I* ]3 t    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \6 ~$ j$ u; Q" o7 D8 h- F4 F
          px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \
# [0 Y- ]1 t. H          "GET /image.iso HTTP/1.0"
" i* H8 Y: s$ I5 `* u4 V- d1 f3 V  D7 b" N
    => request for a long data transfer. The "logasap" option was specified, so: R" e& K4 E. n9 K% q( C
       the log was produced just before transferring data. The server replied in7 f7 `) O: ?0 \. S
       14 ms, 243 bytes of headers were sent to the client, and total time from8 l- _7 s/ L# C& w1 e4 s" w& M
       accept to first data byte is 30 ms.9 Y8 a- T% p# R& }

& {2 A  K, ^. v$ o5 }- v1 H    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
7 u# t) P8 d- n+ c: u          px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \# z) ^6 \! l# a1 W4 s% F5 p( u
          "GET /cgi-bin/bug.cgi? HTTP/1.0". S9 j' {! w$ f# W% t

6 C. ?# z  Q* F1 Y" O/ w' C    => the proxy blocked a server response either because of an "rspdeny" or: a9 ?& ]; A8 r  B2 y, u# D& c
       "rspideny" filter, or because the response was improperly formatted and! z  ?# K' q: f% `/ v
       not HTTP-compliant, or because it blocked sensitive information which' s  u% w' r2 Q
       risked being cached. In this case, the response is replaced with a "502
+ i1 E' [/ k. c       bad gateway". The flags ("PH--") tell us that it was haproxy who decided
( t/ g$ L  |9 R+ a; ?' a       to return the 502 and not the server.% {$ H' Z1 O9 \) ~& o( ^
1 D, K9 l+ d! m0 [1 h$ {
    >>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \/ w  e- |4 M6 _6 j7 G
          px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""
7 o5 z' Q8 e9 |4 L& j) F( I8 P) W
: P7 j# p' n1 Z( u% x    => the client never completed its request and aborted itself ("C---") after
+ @# Z% h* p( w( w  w       8.5s, while the proxy was waiting for the request headers ("-R--").) L! J3 `" v! H6 }' J& D" C/ o0 j
       Nothing was sent to any server.5 G: r8 `9 L* P

0 m% ^, y  b( h, x    >>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \. s! Z, m1 X- n# U: Y+ B7 {
         px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""
- P/ ~5 A( f& A$ f9 J0 k, b4 i: P* Z# ^/ z" M
    => The client never completed its request, which was aborted by the
/ y% ]7 u+ o. V7 Y" @1 b! _& f! x       time-out ("c---") after 50s, while the proxy was waiting for the request- W# t, e; D( l6 b; a% }0 Q
       headers ("-R--").  Nothing was sent to any server, but the proxy could! W& `* M/ ]# n2 e, w! O! Y
       send a 408 return code to the client.7 a  l& [% L5 I2 Y
1 o3 j- X  H( [- W5 I& u0 S) h
    >>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \' R/ B# |$ ?% e$ i
          px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
2 O- n, m: A! w5 t" N' i' O0 _; O2 g3 @  r7 D
    => This log was produced with "option tcplog". The client timed out after. V) B  U3 W8 t! U4 w
       5 seconds ("c----").( X+ d# o: U( r, p3 ^9 _
0 g6 [0 B" ~/ _
    >>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \
0 n9 W  ^9 g1 c/ ]2 p          px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \: `( j* K. B0 `3 G+ `. {
          0/0 "HEAD / HTTP/1.0"
9 k$ Z$ r( v2 q  b# f0 \# F8 E) a8 ^
    => The request took 3s to complete (probably a network problem), and the
& ^8 K  m! l+ A9 c: i       connection to the server failed ('SC--') after 4 attempts of 2 seconds
5 }9 Q: u: I7 a       (config says 'retries 3'), and no redispatch (otherwise we would have# e7 M. G, l" d$ ~7 x
       seen "/+3"). Status code 503 was returned to the client. There were 115
' v+ V; }4 A2 q) N- U7 \" }( H       connections on this server, 202 connections on this proxy, and 205 on
( X) w: P# Q6 \7 e       the global process. It is possible that the server refused the
' R7 N% z3 S1 f( o2 ~       connection because of too many already established.
! I* v: L* g& s/ T
+ t* f" P" s( A8 t' ], U6 a; j9 v6 z5 d) z
9. Statistics and monitoring$ P9 m- p0 @$ {$ |) \0 s
----------------------------
- I  r; s% O3 j2 Z$ d/ R
4 ^% f1 g5 x5 l& G: x( QIt is possible to query HAProxy about its status. The most commonly used
' d3 A1 I: ]7 g  w# emechanism is the HTTP statistics page. This page also exposes an alternative7 @3 K; A% v; R* N- b
CSV output format for monitoring tools. The same format is provided on the
9 ]9 k& ]2 \, ~2 a3 h2 p' ~Unix socket.. _9 x0 q+ Z6 ~
5 d  a7 v6 g  l  B+ l
; C! [, _( u$ P* q
9.1. CSV format
* T( g# Y; w, w+ O. m+ s  R  V, ~---------------
' m1 O/ H; x9 Q4 Q" z
  V) @. r( _& l" I; u! U  x9 [The statistics may be consulted either from the unix socket or from the HTTP. G9 e. l. @# H: Y2 A- Z
page. Both means provide a CSV format whose fields follow.
* p  |% ?5 G" g
% l! b/ [7 n$ c  0. pxname: proxy name: }' M  \1 ~8 M3 s
  1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name3 |* n" A; S: d
    for server)
" D- t/ d  _, q# p! d  2. qcur: current queued requests
# A- E7 l1 ?2 r$ o  3. qmax: max queued requests
( |5 Q( E4 b+ \9 `6 Y) D( o  4. scur: current sessions$ [* e8 C  W9 a% k
  5. smax: max sessions9 W1 R( y& x( `# c% `. v0 ?9 @1 R
  6. slim: sessions limit; K2 m2 u1 H5 K
  7. stot: total sessions& n) M. p/ j0 a3 K2 J
  8. bin: bytes in
; R6 `) }- f5 l* r) i* F3 ^  9. bout: bytes out
# P. W" D! u* C3 F. S$ z1 y 10. dreq: denied requests4 j1 x# D& {7 w' U" Y
11. dresp: denied responses6 F5 n% C6 h' [0 w1 [" j
12. ereq: request errors" q+ w/ M* K' Y. {
13. econ: connection errors
+ A2 @: v4 j1 `* \& Y! u 14. eresp: response errors (among which srv_abrt)
& a, k* i$ T5 E! _ 15. wretr: retries (warning)
) W/ n# }- I" H' r3 \ 16. wredis: redispatches (warning)& R; w. ]( v% F  {
17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)# |# o8 b. F$ H8 {% X9 i4 O
18. weight: server weight (server), total weight (backend)
8 z+ @) g+ a+ F6 i 19. act: server is active (server), number of active servers (backend)8 H: A6 Z: N$ [1 ~; Q# |
20. bck: server is backup (server), number of backup servers (backend)
3 a' n. k+ o! x0 ^8 j' z1 R 21. chkfail: number of failed checks
; L; U- V' I) P* D0 h 22. chkdown: number of UP->DOWN transitions6 o$ r+ K* y; _3 I
23. lastchg: last status change (in seconds)
6 h3 K$ l: x4 F9 T: m+ d 24. downtime: total downtime (in seconds)7 R& O& `7 q. e. P( @1 z
25. qlimit: queue limit, ^! }  j4 H1 Z9 o, K
26. pid: process id (0 for first instance, 1 for second, ...)
+ i9 K6 g3 \# `& g& s# E! P8 ]" C 27. iid: unique proxy id0 ]3 P) F9 m$ N8 F
28. sid: service id (unique inside a proxy)
6 u4 Y( n) d' ?' O' O5 J0 J# R 29. throttle: warm up status/ v; M5 l( L" ~$ z1 S
30. lbtot: total number of times a server was selected* Q, Z4 G8 k0 Q0 K# S1 c9 K' t; d
31. tracked: id of proxy/server if tracking is enabled
7 \: j& x5 w( B# @: ~ 32. type (0=frontend, 1=backend, 2=server, 3=socket)
0 i) ~& i6 l0 N4 z2 i" p. O. ~ 33. rate: number of sessions per second over last elapsed second/ B5 q4 j" j! l6 f$ E
34. rate_lim: limit on new sessions per second) D7 i' K' e9 o7 P3 f
35. rate_max: max number of new sessions per second
" C6 A( M2 V( `- ]7 s7 e9 V 36. check_status: status of last health check, one of:
; G9 Z/ p! M1 {2 i8 s        UNK     -> unknown
3 ~% B1 d$ i3 k" i7 K        INI     -> initializing
+ k, k, E6 b. k        SOCKERR -> socket error
0 E3 a* T7 P- I2 \% @7 X        L4OK    -> check passed on layer 4, no upper layers testing enabled
/ W! X: P3 S+ C  Y) e9 Y) y        L4TOUT  -> layer 1-4 timeout6 S; G: H  Y$ k$ q. T5 O( s; K) {+ x
        L4CON   -> layer 1-4 connection problem, for example
# ]+ F+ r: O6 z6 j& b                   "Connection refused" (tcp rst) or "No route to host" (icmp)
- f& P' |$ @3 {. p        L6OK    -> check passed on layer 6
  O6 I" s, p( h- c" K! c7 m        L6TOUT  -> layer 6 (SSL) timeout
; [: `2 i4 u7 |0 f4 s/ \        L6RSP   -> layer 6 invalid response - protocol error' J  B, j9 E/ u0 V
        L7OK    -> check passed on layer 79 b) W# q7 D7 _' d% G/ o
        L7OKC   -> check conditionally passed on layer 7, for example 404 with& D7 y$ X! f) F3 q2 p& S7 T
                   disable-on-404
( r8 Y8 r$ Y) [        L7TOUT  -> layer 7 (HTTP/SMTP) timeout
) ]5 ]. E; H2 B0 b" Y, B' b        L7RSP   -> layer 7 invalid response - protocol error/ k+ `- k8 z5 L0 x, A" n/ ]
        L7STS   -> layer 7 response error, for example HTTP 5xx& U  w$ N: Y) m. y& [. K5 ]: w
37. check_code: layer5-7 code, if available
. b  s# b& H/ [/ P  e. @8 y3 L 38. check_duration: time in ms took to finish last health check
2 ~2 P5 z: b1 p2 u- B1 d7 R 39. hrsp_1xx: http responses with 1xx code
/ U$ B+ S6 D) \. ~2 G7 z 40. hrsp_2xx: http responses with 2xx code7 J/ ^; L7 b3 i; Q8 M3 ]0 x- ^1 V3 W( q
41. hrsp_3xx: http responses with 3xx code
6 t5 H0 {& w: B 42. hrsp_4xx: http responses with 4xx code
' K! h# D. d$ E2 X' Y8 ^% \ 43. hrsp_5xx: http responses with 5xx code: x' b, a3 Z: Q3 x% e- f. \6 I
44. hrsp_other: http responses with other codes (protocol error)
$ C" d" f. N- G& q4 p) R6 e 45. hanafail: failed health checks details
" l/ ]& H9 i$ X" ~0 U 46. req_rate: HTTP requests per second over last elapsed second- g2 ]# g2 v5 U& k$ F
47. req_rate_max: max number of HTTP requests per second observed5 j- [7 y# H) k/ r
48. req_tot: total number of HTTP requests received$ e. V; O( I7 G$ B' H4 L; d
49. cli_abrt: number of data transfers aborted by the client
# Q) I, e# _  ]: W- N: D( x! X: @7 ` 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)& K1 U3 a8 N) J% h' i/ ]$ z; D
' t( H" L* C/ K4 A

- R0 X9 [$ ~+ q' _8 b9.2. Unix Socket commands
  n  w0 l& m% G' E/ Y-------------------------
9 `3 A$ k3 F3 @2 R% W- H
7 a0 W7 x; \3 cThe following commands are supported on the UNIX stats socket ; all of them& k7 ?9 M, Z8 `: }: p2 P6 F
must be terminated by a line feed. The socket supports pipelining, so that it. M; T* i! Q  q5 D; F, x7 |7 J* P
is possible to chain multiple commands at once provided they are delimited by5 P( e2 E; ^. y: Y3 c; t
a semi-colon or a line feed, although the former is more reliable as it has no
( @. u6 B2 z; {: h% H, O* i, Frisk of being truncated over the network. The responses themselves will each be
% i8 n, e% U( k. J& N8 ~  |% Wfollowed by an empty line, so it will be easy for an external script to match a
% n: ^$ u* j$ E, d. O! rgiven response with a given request. By default one command line is processed' i; [- m' l- b' a+ |
then the connection closes, but there is an interactive allowing multiple lines
; q. u/ I. ]' T2 H7 z" Uto be issued one at a time.6 Q: b9 u# I) D9 X7 L
* g* ?9 F$ m4 p3 h. Q# z8 q
It is important to understand that when multiple haproxy processes are started
4 @6 \# C4 ~  n9 V  o( x5 eon the same sockets, any process may pick up the request and will output its6 R3 Y$ L+ V6 Y2 c7 ?
own stats.1 i. r0 ~! F9 \' `2 a
1 F, c6 T; X' `% R+ I1 Q# T* u
clear counters) S6 F$ O: o' w+ Z$ O9 l8 W
  Clear the max values of the statistics counters in each proxy (frontend &/ b6 H% o' @  `- j( f: _* e
  backend) and in each server. The cumulated counters are not affected. This% k* s& I+ p# O0 [6 \& \
  can be used to get clean counters after an incident, without having to
3 f. ?7 f$ ^& R9 {% P: f8 }. Y) V2 f  restart nor to clear traffic counters. This command is restricted and can* b! j! s$ z4 i# w: o% e4 b
  only be issued on sockets configured for levels "operator" or "admin".
& |0 V3 r9 c0 b6 O: U
1 w* C& J& f+ Pclear counters all. S/ Z$ |6 c9 {, |+ Z0 u/ N
  Clear all statistics counters in each proxy (frontend & backend) and in each
" w' i% E; R  a$ J  server. This has the same effect as restarting. This command is restricted- [( m, u% @( z
  and can only be issued on sockets configured for level "admin".& l3 o+ a1 O' L  q/ }4 e$ p: ~

# e5 Q: D* ^0 a% e3 A) n# z) j9 Tdisable server <backend>/<server>, |- f0 T( ~; \2 L! n: E) b! i
  Mark the server DOWN for maintenance. In this mode, no more checks will be3 ]' _4 [  y/ k$ h7 V. s9 g
  performed on the server until it leaves maintenance.
# |$ D6 }( K# r0 @  If the server is tracked by other servers, those servers will be set to DOWN
( ~% [+ T- v9 R" Z  N  during the maintenance.6 A) X5 R, ?3 }

  v7 l2 n* s2 k$ d  In the statistics page, a server DOWN for maintenance will appear with a
2 M5 n- S- |2 {* W& V  "MAINT" status, its tracking servers with the "MAINT(via)" one.& ~) t: O( v5 [0 B6 h. F9 K
/ n# ]3 Y$ P2 J: B
  Both the backend and the server may be specified either by their name or by- h7 |- ^# a# o& h7 K- @3 \6 Z
  their numeric ID, prefixed with a sharp ('#').) i. ]3 X' s5 ?* w2 Z' V% O8 |0 w

4 E; n6 ]5 D+ w: M3 Y3 E: p' q  This command is restricted and can only be issued on sockets configured for) t( ^3 \' k/ U7 q
  level "admin".
8 p- A" U: t0 K8 T- z
) @+ t, y# O  ?5 D  ?0 N5 G- m# Venable server <backend>/<server>' n& O  s: m$ {! [
  If the server was previously marked as DOWN for maintenance, this marks the
& f7 p3 Z* @; R7 D6 ~9 J% W  server UP and checks are re-enabled.# ^3 S; D  _9 t9 E' W8 v% @4 f
) z9 O$ X' P; O  H  g) i
  Both the backend and the server may be specified either by their name or by
* C# H, F" J6 H9 K/ C, m  their numeric ID, prefixed with a sharp ('#').
0 G. X1 w8 y. y9 D( X/ T) C* \2 I8 {4 r3 j
  This command is restricted and can only be issued on sockets configured for+ n5 n9 g$ _# t- q& \2 W6 V1 ]) v
  level "admin".6 c, `4 W% k( E1 y

# G& `9 W1 d! u( H- ^get weight <backend>/<server>2 }$ x9 {* U  {& j* s6 A( F. \
  Report the current weight and the initial weight of server <server> in
; E6 v/ k8 g9 @  backend <backend> or an error if either doesn't exist. The initial weight is
* Y- S" N" p' N+ c/ H) n1 M  the one that appears in the configuration file. Both are normally equal% E( L/ z% T7 h
  unless the current weight has been changed. Both the backend and the server
, E9 s5 F2 G' K' x! f  may be specified either by their name or by their numeric ID, prefixed with a& s! }4 Y, M7 |: D  L- l
  sharp ('#').
2 I5 C1 _" k' i% W- A
6 R7 s+ x* v$ j; |help8 f: p: P% R3 ^% \. z% h% ?* t
  Print the list of known keywords and their basic usage. The same help screen# j: j0 ^: [2 h: K4 Z6 W
  is also displayed for unknown commands.
+ Y7 M, D7 |+ z- v
; H: w5 _& G! jprompt* d  [! H. H: j; a2 x
  Toggle the prompt at the beginning of the line and enter or leave interactive  Z  C3 w- R" i/ K+ |
  mode. In interactive mode, the connection is not closed after a command" f$ f& l* w0 {( s% C* Y
  completes. Instead, the prompt will appear again, indicating the user that5 Y( y' h7 s' ^$ O' ]: G- n
  the interpreter is waiting for a new command. The prompt consists in a right9 \1 G- u: s) S
  angle bracket followed by a space "> ". This mode is particularly convenient
3 j, i% U$ `3 K4 J, S  when one wants to periodically check information such as stats or errors.# e, U+ n8 c- o5 p; V/ [3 y
  It is also a good idea to enter interactive mode before issuing a "help"& e5 j) K3 D6 e% b* l8 A* Z
  command.* r7 b2 z: N+ w+ _# ^5 Y

; k6 Q0 U$ T; c- E( K6 dquit2 V& G) G0 q! M" z$ b$ X- j, F
  Close the connection when in interactive mode.8 U. ]' o& i/ l# f0 O% I6 i

8 y3 B! b( a  I: e' ~5 Z  Fset timeout cli <delay>/ i' F7 O0 w/ v& T- v1 X) L
  Change the CLI interface timeout for current connection. This can be useful
: _- y; h+ f% ~* F9 x, x( g  during long debugging sessions where the user needs to constantly inspect
; q0 W: ?+ r& f1 M1 A  some indicators without being disconnected. The delay is passed in seconds.! o0 s: u+ K& c* W
( }2 V$ ~7 o7 V& d4 [
set weight <backend>/<server> <weight>[%]
. z$ E9 t! Y; Z1 i9 e# J! E  Change a server's weight to the value passed in argument. If the value ends+ j3 v. t: i# D( m. Z
  with the '%' sign, then the new weight will be relative to the initially1 L) |. S. P$ T4 _( t5 O
  configured weight. Relative weights are only permitted between 0 and 100%,$ a/ v% f9 f( `; a. l+ M8 G' U
  and absolute weights are permitted between 0 and 256. Servers which are part
. M; t& Z3 ~( P: t  of a farm running a static load-balancing algorithm have stricter limitations
2 J, ?5 t0 c) X) f  u+ V  because the weight cannot change once set. Thus for these servers, the only
" J2 _, _3 L- q. p  T8 j. F7 C6 z) o  accepted values are 0 and 100% (or 0 and the initial weight). Changes take
1 I6 ?) F: A2 i4 Q" x; [6 s5 a2 p  effect immediately, though certain LB algorithms require a certain amount of
; {5 h, ~0 z; V0 a  requests to consider changes. A typical usage of this command is to disable
; p5 W/ D  B' }- D& _$ {- `) c) }7 }  a server during an update by setting its weight to zero, then to enable it
: R3 e4 x4 {6 f  i  again after the update by setting it back to 100%. This command is restricted" z0 \3 T5 }% k$ {8 X
  and can only be issued on sockets configured for level "admin". Both the
7 G, y; t: n9 j; Y+ ^  backend and the server may be specified either by their name or by their" O  m8 Y7 _$ h# b
  numeric ID, prefixed with a sharp ('#').. Z; x" B( A' R- F3 h

/ _4 O, h  Z6 c5 @% m% \/ cshow errors [<iid>]
- B0 o/ ^4 F7 A3 |/ \  Dump last known request and response errors collected by frontends and/ b$ d+ z, B: L# B, O8 q4 x; z
  backends. If <iid> is specified, the limit the dump to errors concerning
- Q) n0 v: ]0 n  either frontend or backend whose ID is <iid>. This command is restricted
; n2 q) g, o: o2 x* h' ?  and can only be issued on sockets configured for levels "operator" or4 o' c+ ]- u4 [7 b
  "admin".& X4 Y# B1 k- R" X  k0 \  a$ j

0 }/ ~8 P! O% E! @  The errors which may be collected are the last request and response errors
7 u5 R  Q* m7 Z1 D7 E  caused by protocol violations, often due to invalid characters in header
: n4 K7 h: a# E  names. The report precisely indicates what exact character violated the
! s) T9 w; E3 w9 ^2 m/ T  Y  protocol. Other important information such as the exact date the error was* T. k+ }. P: s7 }2 V& S8 Q  P
  detected, frontend and backend names, the server name (when known), the, F. r6 H& G& a' F8 Z% W. c+ ]* K
  internal session ID and the source address which has initiated the session3 n6 |* a+ E% U: x2 p+ g
  are reported too.7 \$ q2 G( A! n2 w# G0 f

0 {! E. u8 {! L3 ]  All characters are returned, and non-printable characters are encoded. The. H" y: c9 }: P; c
  most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one
: s. i$ L$ z( P9 K2 W5 _  letter following a backslash. The backslash itself is encoded as '\\' to
. K9 u* e% D6 i6 x  i! S  avoid confusion. Other non-printable characters are encoded '\xNN' where* s$ h% u4 T0 v( G+ [( w
  NN is the two-digits hexadecimal representation of the character's ASCII. U# G/ M( M$ x, I& ^6 B
  code.
* R9 B( n, s( U7 D, w$ M' V6 i2 H; z. [
  Lines are prefixed with the position of their first character, starting at 0; G$ H4 a( }' N+ H% L8 C2 [. u
  for the beginning of the buffer. At most one input line is printed per line,
! |' `# J7 I5 A  and large lines will be broken into multiple consecutive output lines so that% W8 Z1 w$ V0 A; J* l2 n% A+ |/ v
  the output never goes beyond 79 characters wide. It is easy to detect if a
: @- d/ c6 M2 U. A! d' ]  line was broken, because it will not end with '\n' and the next line's offset
* v( C" T* p" Y# W/ N  will be followed by a '+' sign, indicating it is a continuation of previous
2 l! s4 C+ {. ^2 ]9 K  line.
- Z2 I" |$ H: O0 U$ A3 J) I  w) w1 ?: r  h) O6 B9 q# P7 v
  Example :3 f. V' J  r* o8 A' I
    >>> $ echo "show errors" | socat stdio /tmp/sock1$ ]. E; ]8 F& S3 a# n, c' d0 v4 d1 c8 `
        [04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response; g: n2 e' w) N/ z* [3 L4 Q
          src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)4 z0 A2 h, A& B4 L2 h8 d
          response length 213 bytes, error at position 23:4 q9 N9 P+ g& W; S5 G, O! ?0 z$ j
% C+ R8 Z9 e  |; V' ]9 b7 q
          00000  HTTP/1.0 200 OK\r\n
4 N/ s+ c5 A! E          00017  header/bizarre:blah\r\n
: s' |5 p$ s1 \" U0 l          00038  Location: blah\r\n% T: a; V* N# g  R7 b9 w0 T+ y
          00054  Long-line: this is a very long line which should b" X* w  A; Z! w7 [) [
          00104+ e broken into multiple lines on the output buffer,# b: G+ S: z: I( [  _
          00154+  otherwise it would be too large to print in a ter
2 M$ Z+ M" O, x) X          00204+ minal\r\n/ L5 g, t9 z9 G* p+ P
          00211  \r\n/ Y: N6 ~9 h9 e7 m' Y1 `
7 u/ U( D& C' G1 s& W( u
    In the example above, we see that the backend "http-in" which has internal
9 p, Q3 C# L& E* f6 f    ID 2 has blocked an invalid response from its server s2 which has internal" }9 b( _3 Z6 ^5 \+ ?' m$ f0 q4 [
    ID 1. The request was on session 54 initiated by source 127.0.0.1 and
9 J0 [1 q# N3 @* m6 F# _# W    received by frontend fe-eth0 whose ID is 1. The total response length was; o2 H( s) K( N+ h2 A  T
    213 bytes when the error was detected, and the error was at byte 23. This6 @8 d" Y% R& C
    is the slash ('/') in header name "header/bizarre", which is not a valid
4 a& N3 Y9 t5 V$ g( V$ ]* C    HTTP character for a header name.% L( z+ B6 h$ g

. A9 k4 T7 I3 v. a8 gshow info: g2 G' [. r- `- d  S" J3 u: P5 B
  Dump info about haproxy status on current process.2 n' g8 Z2 [8 T& g2 ]

: ~9 k1 k6 c: t1 u* z1 h$ Zshow sess/ B" z1 J7 G' G9 [$ o. j% z
  Dump all known sessions. Avoid doing this on slow connections as this can
9 M; y# V, R% g8 _+ J# ~1 P+ x( q  be huge. This command is restricted and can only be issued on sockets
: A3 S) s# S( M$ e$ R  J  configured for levels "operator" or "admin".
+ O. n2 \- e+ l& ?2 p8 C9 D- ]: W4 {1 H$ Q+ P9 b
show sess <id>' @7 @* \% g4 \- g( c5 Q7 I* g
  Display a lot of internal information about the specified session identifier.
  s2 }- L$ v+ p3 X6 f2 H7 }  This identifier is the first field at the beginning of the lines in the dumps# G. l3 b% u8 a5 K# j
  of "show sess" (it corresponds to the session pointer). Those information are' m( k+ b* ]; p. |
  useless to most users but may be used by haproxy developers to troubleshoot a
( W# n' D9 [( F6 [8 Z3 r: M" ?  complex bug. The output format is intentionally not documented so that it can
$ e5 _/ U3 K+ B: C  freely evolve depending on demands.
3 ~8 F9 C' K% o4 U$ m, z) m
! f" m+ k; j- U3 y6 Rshow stat [<iid> <type> <sid>]
0 Z: T# J9 F# Q! C' v+ `0 o5 R* S  Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
2 u. U  X: @. b" ?6 T7 J9 z  possible to dump only selected items :) k' @& `0 T8 c4 {# h
    - <iid> is a proxy ID, -1 to dump everything
% m2 X+ b# s2 M  F# ~5 U. c  A    - <type> selects the type of dumpable objects : 1 for frontends, 2 for
; X6 v; g1 p$ N: j9 C1 ]       backends, 4 for servers, -1 for everything. These values can be ORed,
$ ?0 N- I0 H1 k$ V9 p; t       for example:; N) U  s$ p& L7 s
          1 + 2     = 3   -> frontend + backend.
3 h* m7 n2 u" W3 [# a  `2 j- k          1 + 2 + 4 = 7   -> frontend + backend + server.# b- p# h( t2 V4 k( J
    - <sid> is a server ID, -1 to dump everything from the selected proxy.0 Y1 c& `/ o6 @/ I8 G  a* k

& |8 `) g  t$ q9 {# a8 {1 [5 S  Example :% w4 b" ]0 Q3 r# M- a# X+ s/ _
    >>> $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock15 @4 l$ E- l5 Y6 V  [
        Name: HAProxy
0 L+ B2 n- ^+ ?        Version: 1.4-dev2-49
: R! Z) d$ [- ]* Y        Release_date: 2009/09/233 K+ k, e# q. e, t7 y
        Nbproc: 1- X4 E- a" z8 a* g
        Process_num: 1  L; C' g; {9 `
        (...)3 a, q) |0 @, F# ]/ i
. h* e  Z, S% ]% {, A
        # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,  (...)
; ^+ e4 H. x4 I& {  O3 @/ o        stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
  }/ ~  [0 a- }* U        stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...). r: }  b% d9 q( }4 y8 m
        (...)9 [; x- A- G8 `9 t. V+ H4 T" m
        www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)
9 w& A4 r8 A! \3 x; f/ }; K" \! z! d1 T+ c; A
        $
# ?( S# t8 B, c2 Q$ ~8 c. U7 g: S
7 D  p) ~5 q5 s/ S$ Z/ y    Here, two commands have been issued at once. That way it's easy to find
  Z! _4 C' j# e7 _    which process the stats apply to in multi-process mode. Notice the empty. D, `# p* w+ x9 S8 x  Q3 K! N7 t
    line after the information output which marks the end of the first block.1 M9 |7 y5 _# e! F
    A similar empty line appears at the end of the second block (stats) so that
0 d( k6 ]3 X$ P# e# h  G% k    the reader knows the output has not been truncated.$ ?- O$ R2 s3 J, [" T+ w
: p, ~; @0 V; L$ C6 n7 T0 ~
4 b0 ~" |8 z" Q) @
/*+ w8 u" S7 J+ l9 ~" e. U
* Local variables:5 U3 D/ c6 _& b" w/ F% x
*  fill-column: 79$ T- f! }8 q# b# _0 d( t# F$ a
* End:
9 K' {% A$ v5 V, W */
$ Q: |$ v/ }% e+ p2 C0 S/ Q. f" U5 W$ _6 H/ O9 B
8 V9 T7 T. n2 t
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 00:46 , Processed in 0.051200 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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