1145 Commits

Author SHA1 Message Date
Willy Tarreau
fb0afa77c9 MEDIUM: stream: move the listener's pointer to the session
The listener is session-specific, move it there.
2015-04-06 11:23:57 +02:00
Willy Tarreau
e7dff02dd4 REORG/MEDIUM: stream: rename stream flags from SN_* to SF_*
This is in order to keep things consistent.
2015-04-06 11:23:57 +02:00
Willy Tarreau
87b09668be REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.

In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.

The files stream.{c,h} were added and session.{c,h} removed.

The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.

Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.

Once all changes are completed, we should see approximately this :

   L7 - http_txn
   L6 - stream
   L5 - session
   L4 - connection | applet

There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.

Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-06 11:23:56 +02:00
Willy Tarreau
cb703b0352 BUG/MAJOR: http: null-terminate the http actions keywords list
Commit a0dc23f ("MEDIUM: http: implement http-request set-{method,path,query,uri}")
forgot to null-terminate the list, resulting in crashes when these actions
are used if the platform doesn't pad the struct with nulls.

Thanks to Gunay Arslan for reporting a detailed trace showing the
origin of this bug.

No backport to 1.5 is needed.
2015-04-03 09:58:02 +02:00
Willy Tarreau
601a4d1741 BUG/MEDIUM: http: hdr_cnt would not count any header when called without name
It's documented that these sample fetch functions should count all headers
and/or all values when called with no name but in practice it's not what is
being done as a missing name causes an immediate return and an absence of
result.

This bug is present in 1.5 as well and must be backported.
2015-04-01 19:16:09 +02:00
Willy Tarreau
615105e7e8 MEDIUM: compression: add a distinction between UA- and config- algorithms
Thanks to MSIE/IIS, the "deflate" name is ambigous. According to the RFC
it's a zlib-wrapped deflate stream, but IIS used to send only a raw deflate
stream, which is the only format MSIE understands for "deflate". The other
widely used browsers do support both formats. For this reason some people
prefer to emit a raw deflate stream on "deflate" to serve more users even
it that means violating the standards. Haproxy only follows the standard,
so they cannot do this.

This patch makes it possible to have one algorithm name in the configuration
and another one in the protocol. This will make it possible to have a new
configuration token to add a different algorithm so that users can decide if
they want a raw deflate or the standard one.
2015-03-28 16:46:38 +01:00
Willy Tarreau
e7e49a8d0b MINOR: http: check the algo name "identity" instead of the function pointer
Next patch will statity all compression functions, so let's stop relying
on a function pointer comparison and use the algo name instead.
2015-03-28 15:43:17 +01:00
Thierry FOURNIER
7fe75e0dab MINOR: http: export function inet_set_tos()
This is used by Lua.
2015-03-18 11:34:06 +01:00
Thierry FOURNIER
5531f87ace MINOR: http: split http_transform_header() function in two parts.
This function is a callback for HTTP actions. This function
creates the replacement string from a build_logline() format
and transform the header.

This patch split this function in two part. With this modification,
the header transformation and the replacement string are separed.

We can now transform the header with another replacement string
source than a build_logline() format.
2015-03-18 11:34:06 +01:00
Thierry FOURNIER
b77aece24a MINOR: http: split the function http_action_set_req_line() in two parts
The first part is the replacement engine. It take a replacement action
number and a replacement string and process the action.

The second part is the function which is called by the 'http-request
action' to replace a request line part. This function makes the
string used as replacement.

This split permits to use the replacement engine in other parts of the
code than the request action. The Lua use it for his own http action.
2015-03-18 11:34:06 +01:00
Thierry FOURNIER
63d692c037 MEDIUM: http: allows 'R' and 'S' in the protocol alphabet
This patch allow the 'R' and the 'S' in the protocol/version
alphabet. It permits to process RTSP requests like HTTP.
2015-03-17 16:19:52 +01:00
Thierry FOURNIER
5a33ac78ad MEDIUM/CLEANUP: http: rewrite and lighten http_transform_header() prototype
The http_transform_header() function prototype uses some parameter
which can be guessed from other parameer. This patch removes
theses parameters.
2015-03-17 11:42:43 +01:00
Thierry FOURNIER
191f9efdc5 BUG/MEDIUM: http: the function "(req|res)-replace-value" doesn't respect the HTTP syntax
These function used an invalid header parser.
 - The trailing white-spaces were embedded in the replacement regex,
 - The double-quote (") containing comma (,) were not respected.

This patch replace this parser by the "official" parser http_find_header2().
2015-03-17 11:42:43 +01:00
Thierry FOURNIER
534101658d BUG/MAJOR: http: don't read past buffer's end in http_replace_value
The function http_replace_value use bad variable to detect the end
of the input string.

Regression introduced by the patch "MEDIUM: regex: Remove null
terminated strings." (c9c2daf2)

We need to backport this patch int the 1.5 stable branch.

WT: there is no possibility to overwrite existing data as we only read
    past the end of the request buffer, to copy into the trash. The copy
    is bounded by buffer_replace2(), just like the replacement performed
    by exp_replace(). However if a buffer happens to contain non-zero data
    up to the next unmapped page boundary, there's a theorical risk of
    crashing the process despite this not being reproducible in tests.
    The risk is low because "http-request replace-value" did not work due
    to this bug so that probably means it's not used yet.
2015-03-16 14:20:07 +01:00
Thierry FOURNIER
01c30124ae BUG/MEDIUM: http: the action set-{method|path|query|uri} doesn't run.
This bug is introduced by the commit "MEDIUM: http/tcp: permit to
resume http and tcp custom actions" ( bc4c1ac6ad3dfd5bb ).

Before this patch, the return code of the function was ignored.
After this path, if the function returns 0, it wats a YIELD.

The function http_action_set_req_line() retunrs 0, in succes case.

This patch changes the return code of this function.
2015-03-14 15:53:31 +01:00
Jesse Hathaway
2468d4e4f7 MEDIUM: http: Compress HTTP responses with status codes 201,202,203 in addition to 200
It is common for rest applications to return status codes other than
200, so compress the other common 200 level responses which might
contain content.
2015-03-11 23:23:41 +01:00
Willy Tarreau
350f487300 CLEANUP: session: simplify references to chn_{prod,cons}(&s->{req,res})
These 4 combinations are needlessly complicated since the session already
has direct access to the associated stream interfaces without having to
check an indirect pointer.
2015-03-11 20:41:47 +01:00
Willy Tarreau
73796535a9 REORG/MEDIUM: channel: only use chn_prod / chn_cons to find stream-interfaces
The purpose of these two macros will be to pass via the session to
find the relevant stream interfaces so that we don't need to store
the ->cons nor ->prod pointers anymore. Currently they're only defined
so that all references could be removed.

Note that many places need a second pass of clean up so that we don't
have any chn_prod(&s->req) anymore and only &s->si[0] instead, and
conversely for the 3 other cases.
2015-03-11 20:41:47 +01:00
Willy Tarreau
a5f5d8dc69 MEDIUM: stream-int: add a flag indicating which side the SI is on
This new flag "SI_FL_ISBACK" is set only on the back SI and is cleared
on the front SI. That way it's possible only by looking at the SI to
know what side it is.
2015-03-11 20:41:46 +01:00
Willy Tarreau
2bb4a96f8f REORG/MEDIUM: stream-int: introduce si_ic/si_oc to access channels
We'll soon remove direct references to the channels from the stream
interface since everything belongs to the same session, so let's
first not dereference si->ib / si->ob anymore and use macros instead.
2015-03-11 20:41:46 +01:00
Willy Tarreau
22ec1eadd0 REORG/MAJOR: move session's req and resp channels back into the session
The channels were pointers to outside structs and this is not needed
anymore since the buffers have moved, but this complicates operations.
Move them back into the session so that both channels and stream interfaces
are always allocated for a session. Some places (some early sample fetch
functions) used to validate that a channel was NULL prior to dereferencing
it. Now instead we check if chn->buf is NULL and we force it to remain NULL
until the channel is initialized.
2015-03-11 20:41:46 +01:00
Willy Tarreau
612adb8459 BUG/MAJOR: http: fix stats regression consecutive to HTTP_RULE_RES_YIELD
Commit bc4c1ac ("MEDIUM: http/tcp: permit to resume http and tcp custom actions")
unfortunately broke the stats applet by moving the clearing of the analyser bit
after processing the applet headers. It used to work only in HTTP/1.1 and not
in HTTP/1.0. This is 1.6-specific, no backport is needed.
2015-03-10 15:33:55 +01:00
Thierry FOURNIER
bc4c1ac6ad MEDIUM: http/tcp: permit to resume http and tcp custom actions
Later, the processing of some actions needs to be interrupted and resumed
later. This patch permit to resume the actions. The actions that needs
to run with the resume mode are not yet avalaible. It will be soon with
Lua patches. So the code added by this patch is untestable for the moment.

The list of "tcp_exec_req_rules" cannot resme because is called by the
unresumable function "accept_session".
2015-02-28 23:12:33 +01:00
Thierry FOURNIER
9e2ef999a9 MEDIUM: http: change the code returned by the response processing rule functions
Actually, this function returns a pointer on the rule that stop
the evaluation of the rule list. Later we integrate the possibility
of interrupt and resue the processsing of some actions. The current
response mode is not sufficient to returns the "interrupt" information.

The pointer returned is never used, so I change the return type of
this function by an enum. With this enum, the function is ready to
return the "interupt" value.
2015-02-28 23:12:33 +01:00
Thierry FOURNIER
49f45af9aa MINOR: global: export many symbols.
The functions "val_payload_lv" and "val_hdr" are useful with
lua. The lua automatic binding for sample fetchs needs to
compare check functions.

The "arg_type_names" permit to display error messages.
2015-02-28 23:12:32 +01:00
Thierry FOURNIER
f41a809dc9 MINOR: sample: add private argument to the struct sample_fetch
The add of this private argument is to prepare the integration
of the lua fetchs.
2015-02-28 23:12:31 +01:00
Thierry FOURNIER
68a556e282 MINOR: converters: give the session pointer as converter argument
Some usages of the converters need to know the attached session. The Lua
needs the session for retrieving his running context. This patch adds
the "session" as an argument of the converters prototype.
2015-02-28 23:12:31 +01:00
Thierry FOURNIER
1edc971919 MINOR: converters: add a "void *private" argument to converters
This permits to store specific configuration pointer. It is useful
with future Lua integration.
2015-02-28 23:12:31 +01:00
Willy Tarreau
eb27ec7569 MINOR: http: add the new sample fetches req.hdr_names and res.hdr_names
These new sample fetches retrieve the list of header names as they appear
in the request or response. This can be used for debugging, for statistics
as well as an aid to better detect the presence of proxies or plugins on
some browsers, which alter the request compared to a regular browser by
adding or reordering headers.
2015-02-20 14:00:44 +01:00
Willy Tarreau
c90dc23e99 MINOR: http: add a new function to iterate over each header line
New function http_find_next_header() will be used to scan all the input
headers for various processing and for http/1 to http/2 header mapping.
2015-02-20 14:00:44 +01:00
Willy Tarreau
34d4c3c13f BUG/MINOR: http: abort request processing on filter failure
Commit c600204 ("BUG/MEDIUM: regex: fix risk of buffer overrun in
exp_replace()") added a control of failure on the response headers,
but forgot to check for the error during request processing. So if
the filters fail to apply, we could keep the request. It might
cause some headers to silently fail to be added for example. Note
that it's tagged MINOR because a standard configuration cannot make
this case happen.

The fix should be backported to 1.5 and 1.4 though.
2015-01-30 20:58:58 +01:00
Willy Tarreau
aa435e7d7e BUG/MINOR: http: fix incorrect header value offset in replace-hdr/replace-value
The two http-req/http-resp actions "replace-hdr" and "replace-value" were
expecting exactly one space after the colon, which is wrong. It was causing
the first char not to be seen/modified when no space was present, and empty
headers not to be modified either. Instead of using name->len+2, we must use
ctx->val which points to the first character of the value even if there is
no value.

This fix must be backported into 1.5.
2015-01-29 14:01:34 +01:00
Willy Tarreau
a0dc23f093 MEDIUM: http: implement http-request set-{method,path,query,uri}
This commit implements the following new actions :

- "set-method" rewrites the request method with the result of the
  evaluation of format string <fmt>. There should be very few valid reasons
  for having to do so as this is more likely to break something than to fix
  it.

- "set-path" rewrites the request path with the result of the evaluation of
  format string <fmt>. The query string, if any, is left intact. If a
  scheme and authority is found before the path, they are left intact as
  well. If the request doesn't have a path ("*"), this one is replaced with
  the format. This can be used to prepend a directory component in front of
  a path for example. See also "set-query" and "set-uri".

  Example :
      # prepend the host name before the path
      http-request set-path /%[hdr(host)]%[path]

- "set-query" rewrites the request's query string which appears after the
  first question mark ("?") with the result of the evaluation of format
  string <fmt>. The part prior to the question mark is left intact. If the
  request doesn't contain a question mark and the new value is not empty,
  then one is added at the end of the URI, followed by the new value. If
  a question mark was present, it will never be removed even if the value
  is empty. This can be used to add or remove parameters from the query
  string. See also "set-query" and "set-uri".

  Example :
      # replace "%3D" with "=" in the query string
      http-request set-query %[query,regsub(%3D,=,g)]

- "set-uri" rewrites the request URI with the result of the evaluation of
  format string <fmt>. The scheme, authority, path and query string are all
  replaced at once. This can be used to rewrite hosts in front of proxies,
  or to perform complex modifications to the URI such as moving parts
  between the path and the query string. See also "set-path" and
  "set-query".

All of them are handled by the same parser and the same exec function,
which is why they're merged all together. For once, instead of adding
even more entries to the huge switch/case, we used the new facility to
register action keywords. A number of the existing ones should probably
move there as well.
2015-01-23 20:27:41 +01:00
Willy Tarreau
15a53a4384 MEDIUM: regex: add support for passing regex flags to regex_exec_match()
This function (and its sister regex_exec_match2()) abstract the regex
execution but make it impossible to pass flags to the regex engine.
Currently we don't use them but we'll need to support REG_NOTBOL soon
(to indicate that we're not at the beginning of a line). So let's add
support for this flag and update the API accordingly.
2015-01-22 14:24:53 +01:00
Willy Tarreau
8560328211 BUG/MEDIUM: http: make http-request set-header compute the string before removal
The way http-request/response set-header works is stupid. For a naive
reuse of the del-header code, it removes all occurrences of the header
to be set before computing the new format string. This makes it almost
unusable because it is not possible to append values to an existing
header without first copying them to a dummy header, performing the
copy back and removing the dummy header.

Instead, let's share the same code as add-header and perform the optional
removal after the string is computed. That way it becomes possible to
write things like :

   http-request set-header X-Forwarded-For %[hdr(X-Forwarded-For)],%[src]

Note that this change is not expected to have any undesirable impact on
existing configs since if they rely on the bogus behaviour, they don't
work as they always retrieve an empty string.

This fix must be backported to 1.5 to stop the spreadth of ugly configs.
2015-01-21 20:45:00 +01:00
Willy Tarreau
49ad95cc8e MINOR: http: add a new fetch "query" to extract the request's query string
This fetch extracts the request's query string, which starts after the first
question mark. If no question mark is present, this fetch returns nothing. If
a question mark is present but nothing follows, it returns an empty string.
This means it's possible to easily know whether a query string is present
using the "found" matching method. This fetch is the completemnt of "path"
which stops before the question mark.
2015-01-20 19:47:47 +01:00
Willy Tarreau
319f745ba0 MINOR: channel: rename bi_erase() to channel_truncate()
It applies to the channel and it doesn't erase outgoing data, only
pending unread data, which is strictly equivalent to what recv()
does with MSG_TRUNC, so that new name is more accurate and intuitive.
2015-01-14 20:32:59 +01:00
Willy Tarreau
ba0902ede4 CLEANUP: channel: rename channel_reserved -> channel_is_rewritable
channel_reserved is confusingly named. It is used to know whether or
not the rewrite area is left intact for situations where we want to
ensure we can use it before proceeding. Let's rename it to fix this
confusion.
2015-01-14 18:41:33 +01:00
Willy Tarreau
7c1c217426 BUG/MEDIUM: http: fix header removal when previous header ends with pure LF
In 1.4-dev7, a header removal mechanism was introduced with commit 68085d8
("[MINOR] http: add http_remove_header2() to remove a header value."). Due
to a typo in the function, the beginning of the headers gets desynchronized
if the header preceeding the deleted one ends with an LF/CRLF combination
different form the one of the removed header. The reason is that while
rewinding the pointer, we go back by a number of bytes taking into account
the LF/CRLF status of the removed header instead of the previous one. The
case where it fails is in http-request del-header/set-header where the
multiple occurrences of a header are present and their LF/CRLF ending
differs from the preceeding header. The loop then stops because no more
headers are found given that the names and length do not match.

Another point to take into consideration is that removing headers using
a loop of http_find_header2() and this function is inefficient since we
remove values one at a time while it could be simpler and faster to
remove full header lines. This is something that should be addressed
separately.

This fix must be backported to 1.5 and 1.4. Note that http-send-name-header
relies on this function as well so it could be possible that some of the
issues encountered with it in 1.4 come from this bug.
2015-01-07 17:23:50 +01:00
Willy Tarreau
f2f7d6b27b MEDIUM: buffer: add a new buf_wanted dummy buffer to report failed allocations
Doing so ensures that even when no memory is available, we leave the
channel in a sane condition. There's a special case in proto_http.c
regarding the compression, we simply pre-allocate the tmpbuf to point
to the dummy buffer. Not reusing &buf_empty for this allows the rest
of the code to differenciate an empty buffer that's not used from an
empty buffer that results from a failed allocation which has the same
semantics as a buffer full.
2014-12-24 23:47:32 +01:00
Willy Tarreau
e583ea583a MEDIUM: buffer: use b_alloc() to allocate and initialize a buffer
b_alloc() now allocates a buffer and initializes it to the size specified
in the pool minus the size of the struct buffer itself. This ensures that
callers do not need to care about buffer details anymore. Also this never
applies memory poisonning, which is slow and useless on buffers.
2014-12-24 23:47:32 +01:00
Godbach
d972203fbc BUG/MINOR: parse: refer curproxy instead of proxy
Since during parsing stage, curproxy always represents a proxy to be operated,
it should be a mistake by referring proxy.

Signed-off-by: Godbach <nylzhaowei@gmail.com>
2014-12-18 11:01:51 +01:00
Godbach
1f1fae6202 BUG/MINOR: http: fix typo: "401 Unauthorized" => "407 Unauthorized"
401 Unauthorized => 407 Unauthorized

Signed-off-by: Godbach <nylzhaowei@gmail.com>
2014-12-17 17:05:49 +01:00
Willy Tarreau
5506e3f8b6 BUG/MINOR: stats: correctly set the request/response analysers
When enabling stats, response analysers were set on the request
analyser list, which 1) has no effect, and 2) means we don't have
the response analysers properly set.

In practice these response analysers are set when the connection
to the server or applet is established so we don't need/must not
set them here.

Fortunately this bug had no impact since the flags are distinct,
but it definitely is confusing.

It should be backported to 1.5.
2014-11-21 17:53:08 +01:00
Cyril Bonté
a83a50bd7d BUG/MINOR: log: fix request flags when keep-alive is enabled
Colin Ingarfield reported some unexplainable flags in the logs.
For example, a "LR" termination state was set on a request which was forwarded
to a server, where "LR" means that the request should have been handled
internally by haproxy.

This case happens when at least client side keep-alive is enabled. Next
requests in the connection will inherit the flags from the previous request.

2 fields are impacted : "termination_state" and "Tt" in the timing events,
where a "+" can be added, when a previous request was redispatched.

This is not critical for the service itself but can confuse troubleshooting.

The fix must be backported to 1.5 and 1.4.
2014-10-22 22:37:30 +02:00
Willy Tarreau
7d59e90473 BUG/MEDIUM: http: don't dump debug headers on MSG_ERROR
When the HTTP parser is in state HTTP_MSG_ERROR, we don't know if it was
already initialized or not. If the error happens before HTTP_MSG_RQBEFORE,
random offsets might be present and we don't want to display such random
strings in debug mode.

While it's theorically possible to randomly crash the process when running
in debug mode here, this bug was not tagged MAJOR because it would not
make sense to run in debug mode in production.

This fix must be backported to 1.5 and 1.4.
2014-10-22 19:25:09 +02:00
Willy Tarreau
e1cfc1f2b4 BUG/MINOR: config: do not accept more track-sc than configured
MAX_SESS_STKCTR allows one to define the number of stick counters that can
be used in parallel in track-sc* rules. The naming of this macro creates
some confusion because the value there is sometimes used as a max instead
of a count, and the config parser accepts values from 0 to MAX_SESS_STKCTR
and the processing ignores anything tracked on the last one. This means
that by default, track-sc3 is allowed and ignored.

This fix must be backported to 1.5 where the problem there only affects
TCP rules.
2014-10-17 11:53:05 +02:00
Willy Tarreau
4e21ff9244 BUG/MEDIUM: http: adjust close mode when switching to backend
Commit 179085c ("MEDIUM: http: move Connection header processing earlier")
introduced a regression : the backend's HTTP mode is not considered anymore
when setting the session's HTTP mode, because wait_for_request() is only
called once, when the frontend receives the request (or when the frontend
is in TCP mode, when the backend receives the request).

The net effect is that in some situations when the frontend and the backend
do not work in the same mode (eg: keep-alive vs close), the backend's mode
is ignored.

This patch moves all that processing to a dedicated function, which is
called from the original place, as well as from session_set_backend()
when switching from an HTTP frontend to an HTTP backend in different
modes.

This fix must be backported to 1.5.
2014-09-30 18:44:22 +02:00
Willy Tarreau
ce730de867 MEDIUM: http: enable header manipulation for 101 responses
Ryan Brock reported that server stickiness did not work for WebSocket
because the cookies and headers are not modified on 1xx responses. He
found that his browser correctly presents the cookies learned on 101
responses, which was not specifically defined in the WebSocket spec,
nor in the cookie spec. 101 is a very special case. Being part of 1xx,
it's an interim response. But within 1xx, it's special because it's
the last HTTP/1 response that transits on the wire, which is different
from 100 or 102 which may appear multiple times. So in that sense, we
can consider it as a final response regarding HTTP/1, and it makes
sense to allow header processing there. Note that we still ensure not
to mangle the Connection header, which is critical for HTTP upgrade to
continue to work smoothly with agents that are a bit picky about what
tokens are found there.

The rspadd rules are now processed for 101 responses as well, but the
cache-control checks are not performed (since no body is delivered).

Ryan confirmed that this patch works for him.

It would make sense to backport it to 1.5 given that it improves end
user experience on WebSocket servers.
2014-09-16 10:40:38 +02:00
Willy Tarreau
9dc1c61c43 BUG/CRITICAL: http: don't update msg->sov once data start to leave the buffer
Commit bb2e669 ("BUG/MAJOR: http: correctly rewind the request body
after start of forwarding") was incorrect/incomplete. It used to rely on
CF_READ_ATTACHED to stop updating msg->sov once data start to leave the
buffer, but this is unreliable because since commit a6eebb3 ("[BUG]
session: clear BF_READ_ATTACHED before next I/O") merged in 1.5-dev1,
this flag is only ephemeral and is cleared once all analysers have
seen it. So we can start updating msg->sov again each time we pass
through this place with new data. With a sufficiently large amount of
data, it is possible to make msg->sov wrap and validate the if()
condition at the top, causing the buffer to advance by about 2GB and
crash the process.

Note that the offset cannot be controlled by the attacker because it is
a sum of millions of small random sizes depending on how many bytes were
read by the server and how many were left in the buffer, only because
of the speed difference between reading and writing. Also, nothing is
written, the invalid pointer resulting from this operation is only read.

Many thanks to James Dempsey for reporting this bug and to Chris Forbes for
narrowing down the faulty area enough to make its root cause analysable.

This fix must be backported to haproxy 1.5.
2014-09-02 16:48:54 +02:00