]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
15 years ago[MINOR] http: make the conditional redirect support keep-alive
Willy Tarreau [Sun, 3 Jan 2010 16:32:57 +0000 (17:32 +0100)] 
[MINOR] http: make the conditional redirect support keep-alive

It makes sense to permit a client to keep its connection when
performing a redirect to the same host. We only detect the fact
that the redirect location begins with a slash to use the keep-alive
(if the client supports it).

15 years ago[MINOR] http: don't wait for sending requests to the server
Willy Tarreau [Sun, 3 Jan 2010 16:24:51 +0000 (17:24 +0100)] 
[MINOR] http: don't wait for sending requests to the server

By default we automatically wait for enough data to fill large
packets if buf->to_forward is not null. This causes a problem
with POST/Expect requests which have a data size but no data
immediately available. Instead of causing noticeable delays on
such requests, simply add a flag to disable waiting when sending
requests.

15 years ago[BUG] http: take care of errors, timeouts and aborts during the data phase
Willy Tarreau [Sun, 3 Jan 2010 16:07:49 +0000 (17:07 +0100)] 
[BUG] http: take care of errors, timeouts and aborts during the data phase

In server-close mode particularly, the response buffer is marked for
no-auto-close after a response passed through. This prevented a POST
request from being aborted on errors, timeouts or anything if the
response was received before the request was complete.

15 years ago[MINOR] http: move redirect messages to HTTP/1.1 with a content-length
Willy Tarreau [Sun, 3 Jan 2010 14:09:36 +0000 (15:09 +0100)] 
[MINOR] http: move redirect messages to HTTP/1.1 with a content-length

This is cleaner and this tells clients we support 1.1.

15 years ago[OPTIM] http: don't immediately enable reading on request
Willy Tarreau [Sun, 3 Jan 2010 13:38:03 +0000 (14:38 +0100)] 
[OPTIM] http: don't immediately enable reading on request

If we enable reading of a request immediately after completing
another one, we end up performing small reads until the request
buffer is complete. This takes time and makes it harder to realign
the buffer when needed. Just enable reading when we need to.

15 years ago[BUG] http: the request URI pointer is relative to the buffer
Willy Tarreau [Sun, 3 Jan 2010 12:04:35 +0000 (13:04 +0100)] 
[BUG] http: the request URI pointer is relative to the buffer

The rq.u field is relative to buf->data, not to msg->sol. We have
to subtract msg->som everywhere this error was made. Maybe it will
be simpler to have a pointer to the buffer in the message and find
appropriate data there.

15 years ago[BUG] http: redirects were broken by chunk changes
Willy Tarreau [Sun, 3 Jan 2010 11:24:37 +0000 (12:24 +0100)] 
[BUG] http: redirects were broken by chunk changes

Redirects used to initialize a chunk whose size was not set (0).
Also, the return code of chunk_strcpy() is 1 in case of success.

15 years ago[OPTIM] http: set MSG_MORE on response when a pipelined request is pending
Willy Tarreau [Sun, 3 Jan 2010 10:37:54 +0000 (11:37 +0100)] 
[OPTIM] http: set MSG_MORE on response when a pipelined request is pending

Many times we see a lot of short responses in HTTP (typically 304 on a
reload). It is a waste of network bandwidth to send that many small packets
when we know we can merge them. When we know that another HTTP request is
following a response, we set BF_EXPECT_MORE on the response buffer, which
will turn MSG_MORE on exactly once. That way, multiple short responses can
leave pipelined if their corresponding requests were also pipelined.

15 years ago[MINOR] stream_sock: enable MSG_MORE when forwarding finite amount of data
Willy Tarreau [Sun, 3 Jan 2010 10:18:34 +0000 (11:18 +0100)] 
[MINOR] stream_sock: enable MSG_MORE when forwarding finite amount of data

While it could be dangerous to enable MSG_MORE on infinite data (eg:
interactive sessions), it makes sense to enable it when we know the
chunk to be sent is just a part of a larger one.

15 years ago[BUG] http: fix erroneous trailers size computation
Willy Tarreau [Sun, 3 Jan 2010 06:42:04 +0000 (07:42 +0100)] 
[BUG] http: fix erroneous trailers size computation

We used to forward more trailers than required, causing a
desynchronization of the output. Now we schedule all for forwarding
as soon as we encounter them.

15 years ago[BUG] last fix was overzealous and disabled server-close
Willy Tarreau [Sat, 2 Jan 2010 23:19:31 +0000 (00:19 +0100)] 
[BUG] last fix was overzealous and disabled server-close

we must not close on remote shutdown but on remote error only.

15 years ago[BUG] http: ensure we abort data transfer on write error
Willy Tarreau [Sat, 2 Jan 2010 22:58:04 +0000 (23:58 +0100)] 
[BUG] http: ensure we abort data transfer on write error

When a write error is encountered during a data phase, we must
absolutely abort the pending data transfer, otherwise it will
never complete.

15 years ago[MAJOR] http: add support for option http-server-close
Willy Tarreau [Sat, 2 Jan 2010 21:47:18 +0000 (22:47 +0100)] 
[MAJOR] http: add support for option http-server-close

This option enables HTTP keep-alive on the client side and close mode
on the server side. This offers the best latency on the slow client
side, and still saves as many resources as possible on the server side
by actively closing connections. Pipelining is supported on both requests
and responses, though there is currently no reason to get pipelined
responses.

15 years ago[MEDIUM] http: make the parsers able to wait for a buffer flush
Willy Tarreau [Sat, 2 Jan 2010 21:04:45 +0000 (22:04 +0100)] 
[MEDIUM] http: make the parsers able to wait for a buffer flush

When too large a message lies in a buffer before parsing a new
request/response, we can now wait for previous outgoing data to
leave the buffer before attempting to parse again. After that
we can consider the opportunity to realign the buffer if needed.

15 years ago[MEDIUM] http: make the analyser not rely on msg being initialized anymore
Willy Tarreau [Sat, 2 Jan 2010 20:59:16 +0000 (21:59 +0100)] 
[MEDIUM] http: make the analyser not rely on msg being initialized anymore

The HTTP parser needed the msg structure to hold pre-initialized pointers.
This causes a trouble with keep-alive because if some data is still in the
buffer, the pointers can be anywhere after the data and later become invalid
when the buffer gets realigned.

It was not needed to rely on that since we have two valid information
in the buffer itself :

  - buf->lr : last visited place
  - buf->w + buf->send_max : beginning of next message

So by doing the maths only on those values, we can avoid doing tricks
on msg->som.

15 years ago[BUILD] halog: insufficient include path in makefile
Willy Tarreau [Sat, 2 Jan 2010 11:23:30 +0000 (12:23 +0100)] 
[BUILD] halog: insufficient include path in makefile

15 years ago[MINOR] config: option forceclose is valid in frontends too
Willy Tarreau [Wed, 30 Dec 2009 00:10:35 +0000 (01:10 +0100)] 
[MINOR] config: option forceclose is valid in frontends too

This option was disabled for frontends in the configuration because
it was useless in its initial implementation, though it was still
checked in the code. Let's officially enable it now.

15 years ago[MEDIUM] http: add some SI_FL_NOLINGER around server errors
Willy Tarreau [Tue, 29 Dec 2009 13:56:36 +0000 (14:56 +0100)] 
[MEDIUM] http: add some SI_FL_NOLINGER around server errors

When we catch an error from the server, speed up the connection
abort since we don't want to remain long with pending data in the
socket, and we want to be able to reuse our source port ASAP.

15 years ago[MEDIUM] session: set SI_FL_NOLINGER when aborting on write timeouts
Willy Tarreau [Tue, 29 Dec 2009 13:49:56 +0000 (14:49 +0100)] 
[MEDIUM] session: set SI_FL_NOLINGER when aborting on write timeouts

Doing this helps us flush the system buffers from all unread data. This
avoids having orphans when clients suddenly get off the net without
reading their entire response.

15 years ago[MEDIUM] http: make forceclose use SI_FL_NOLINGER
Willy Tarreau [Tue, 29 Dec 2009 13:39:48 +0000 (14:39 +0100)] 
[MEDIUM] http: make forceclose use SI_FL_NOLINGER

Option forceclose is not limited to the shortage of source ports
anymore thanks to this flag.

15 years ago[MINOR] stream_sock: add SI_FL_NOLINGER for faster close
Willy Tarreau [Tue, 29 Dec 2009 13:36:34 +0000 (14:36 +0100)] 
[MINOR] stream_sock: add SI_FL_NOLINGER for faster close

This new flag may be set by any user on a stream interface to tell
the underlying protocol that there is no need for lingering on the
socket since we know the other side either received everything or
does not care about what we sent.

This will typically be used with forced server close in HTTP mode,
where we want to quickly close a server connection after receiving
its response. Otherwise the system would prevent us from reusing
the same port for some time.

15 years ago[MEDIUM] http: properly handle "option forceclose"
Willy Tarreau [Tue, 29 Dec 2009 11:09:05 +0000 (12:09 +0100)] 
[MEDIUM] http: properly handle "option forceclose"

The "forceclose" option used to close the output channel to the
server once it started to respond. While this happened to work with
most servers, some of them considered this as a connection abort and
immediately stopped responding.

Now that we're aware of the end of a request and response, we're able
to trivially handle this option and properly close both sides when the
server's response is complete.

During this change it appeared that forwarding could be allowed when
the BF_SHUTW_NOW flag was set on a buffer, which obviously is not
acceptable and was causing some trouble. This has been fixed too and
is the reason for the MEDIUM status on this patch.

15 years ago[MEDIUM] http: add two more states for the closing period
Willy Tarreau [Tue, 29 Dec 2009 11:05:52 +0000 (12:05 +0100)] 
[MEDIUM] http: add two more states for the closing period

HTTP_MSG_CLOSING and HTTP_MSG_CLOSED are needed to know when it
is safe to close a connection without risking to destroy pending
data.

15 years ago[MINOR] stream_sock: prepare for closing when all pending data are sent
Willy Tarreau [Tue, 29 Dec 2009 07:02:56 +0000 (08:02 +0100)] 
[MINOR] stream_sock: prepare for closing when all pending data are sent

Since we'll soon be able to close a connection with remaining data in a
buffer, it becomes obvious that we can prepare to close when we're about
to send the last chunk of data and not the whole buffer.

15 years ago[BUG] buffers: wrong size calculation for displaced data
Willy Tarreau [Mon, 28 Dec 2009 17:37:54 +0000 (18:37 +0100)] 
[BUG] buffers: wrong size calculation for displaced data

This error was triggered by requests not starting at the beginning
of the buffer. It cannot happen with earlier versions though it might
be a good idea to fix it anyway.

15 years ago[MEDIUM] http: rework the buffer alignment logic
Willy Tarreau [Mon, 28 Dec 2009 16:39:57 +0000 (17:39 +0100)] 
[MEDIUM] http: rework the buffer alignment logic

There were still issues with the buffer alignment. Now we ensure
that we always align it before a request or response is completely
parsed if there is less than maxrewrite bytes free at the end. In
practice, it's not called that often and ensures we can always work
as expected.

15 years ago[BUG] stream_sock: wrong max computation on recv
Willy Tarreau [Mon, 28 Dec 2009 16:36:37 +0000 (17:36 +0100)] 
[BUG] stream_sock: wrong max computation on recv

Since the introduction of the automatic sizing of buffers during reads,
a bug appeared where the max size could be negative, causing large
chunks of memory to be overwritten during recv() calls if a read pointer
was already past the buffer's limit.

15 years ago[BUG] http: typos on several unlikely() around header insertion
Willy Tarreau [Mon, 28 Dec 2009 05:57:33 +0000 (06:57 +0100)] 
[BUG] http: typos on several unlikely() around header insertion

In many places where we perform header insertion, an error control
is performed but due to a mistake, it cannot match any error :

   if (unlikely(error) < 0)
instead of
   if (unlikely(error < 0))

This prevents error 400 responses from being sent when the buffer is
full due to many header additions. This must be backported to 1.3.

15 years ago[MAJOR] http: implement body parser
Willy Tarreau [Sun, 27 Dec 2009 21:54:55 +0000 (22:54 +0100)] 
[MAJOR] http: implement body parser

The body parser will be used in close and keep-alive modes. It follows
the stream to keep in sync with both the request and the response message.
Both chunked transfer-coding and content-length are supported according to
RFC2616.

The multipart/byterange encoding has not yet been implemented and if not
seconded by any of the two other ones, will be forwarded till the close,
as requested by the specification.

Both the request and the response analysers converge into an HTTP_MSG_DONE
state where it will be possible to force a close (option forceclose) or to
restart with a fresh new transaction and maintain keep-alive.

This change is important. All tests are OK but any possible behaviour
change with "option httpclose" might find its root here.

15 years ago[MINOR] new function stream_int_cond_close()
Willy Tarreau [Sun, 27 Dec 2009 21:51:06 +0000 (22:51 +0100)] 
[MINOR] new function stream_int_cond_close()

This one will be used to conditionally send a message upon a
close on a stream interface. It will not overwrite any existing
data.

15 years ago[BUG] http: body parsing must consider the start of message
Willy Tarreau [Sun, 27 Dec 2009 21:47:25 +0000 (22:47 +0100)] 
[BUG] http: body parsing must consider the start of message

When parsing body for URL parameters, we must not consider that
data are available from buf->data but from buf->data + msg->som.
This is not a problem right now but may become with keep-alive.

15 years ago[MEDIUM] http: automatically re-aling request buffer
Willy Tarreau [Sun, 27 Dec 2009 16:18:11 +0000 (17:18 +0100)] 
[MEDIUM] http: automatically re-aling request buffer

When parsing a request that does not start at the beginning of the
buffer, we may experience a buffer full issue. In order to avoid
this, we try to realign the buffer if it is not really full. That
will be required when we have to deal with pipelined requests.

15 years ago[BUG] http: offsets are relative to the buffer, not to ->som
Willy Tarreau [Sun, 27 Dec 2009 14:50:06 +0000 (15:50 +0100)] 
[BUG] http: offsets are relative to the buffer, not to ->som

Some wrong operations were performed on buffers, assuming the
offsets were relative to the beginning of the request while they
are relative to the beginning of the buffer. In practice this is
not yet an issue since both are the same... until we add support
for keep-alive.

15 years ago[MINOR] buffers: add buffer_ignore() to skip some bytes
Willy Tarreau [Sun, 27 Dec 2009 14:45:38 +0000 (15:45 +0100)] 
[MINOR] buffers: add buffer_ignore() to skip some bytes

This simple function will be used to skip blanks at the beginning of a
request or response.

15 years ago[MEDIUM] http: add a new transaction flags indicating if we know the transfer length
Willy Tarreau [Sat, 26 Dec 2009 14:34:26 +0000 (15:34 +0100)] 
[MEDIUM] http: add a new transaction flags indicating if we know the transfer length

It's not enough to know if the connection will be in CLOSE or TUNNEL mode,
we still need to know whether we want to read a full message to a known
length or read it till the end just as in TUNNEL mode. Some updates to the
RFC clarify slightly better the corner cases, in particular for the case
where a non-chunked encoding is used last.

Now we also take care of adding a proper "connection: close" to messages
whose size could not be determined.

15 years ago[MEDIUM] http: rework chunk-size parser
Willy Tarreau [Sat, 26 Dec 2009 12:56:06 +0000 (13:56 +0100)] 
[MEDIUM] http: rework chunk-size parser

Chunked encoding can be slightly more complex than what was implemented.
Specifically, it supports some optional extensions that were not parsed
till now if present, and would have caused an error to be returned.

Also, now we enforce check for too large values in chunk sizes in order
to ensure we never overflow.

Last, we're now able to return a request error if we can't read the
chunk size because the buffer is already full.

15 years ago[MINOR] http: introduce a new synchronisation state : HTTP_MSG_DONE
Willy Tarreau [Tue, 22 Dec 2009 15:50:27 +0000 (16:50 +0100)] 
[MINOR] http: introduce a new synchronisation state : HTTP_MSG_DONE

This state indicates that an HTTP message (request or response) is
complete. This will be used to know when we can re-initialize a
new transaction. Right now we only switch to it after the end of
headers if there is no data. When other analysers are implemented,
we can switch to this state too.

The condition to reuse a connection is when the response finishes
after the request. This will have to be checked when setting the
state.

15 years ago[MINOR] http: move 1xx handling earlier to eliminate a lot of ifs
Willy Tarreau [Tue, 22 Dec 2009 15:01:27 +0000 (16:01 +0100)] 
[MINOR] http: move 1xx handling earlier to eliminate a lot of ifs

The response 1xx was set too low and required a lot of tests along
the code in order to avoid some processing. We still left the test
after the response rewrite rules so that we can eliminate unwanted
headers if required.

15 years ago[MINOR] http: move the http transaction init/cleanup code to proto_http
Willy Tarreau [Tue, 22 Dec 2009 14:03:09 +0000 (15:03 +0100)] 
[MINOR] http: move the http transaction init/cleanup code to proto_http

This code really belongs to the http part since it's transaction-specific.
This will also make it easier to later reinitialize a transaction in order
to support keepalive.

15 years ago[MAJOR] buffers: automatically compute the maximum buffer length
Willy Tarreau [Sun, 13 Dec 2009 14:53:05 +0000 (15:53 +0100)] 
[MAJOR] buffers: automatically compute the maximum buffer length

We used to apply a limit to each buffer's size in order to leave
some room to rewrite headers, then we used to remove this limit
once the session switched to a data state.

Proceeding that way becomes a problem with keepalive because we
have to know when to stop reading too much data into the buffer
so that we can leave some room again to process next requests.

The principle we adopt here consists in only relying on to_forward+send_max.
Indeed, both of those data define how many bytes will leave the buffer.
So as long as their sum is larger than maxrewrite, we can safely
fill the buffers. If they are smaller, then we refrain from filling
the buffer. This means that we won't risk to fill buffers when
reading last data chunk followed by a POST request and its contents.

The only impact identified so far is that we must ensure that the
BF_FULL flag is correctly dropped when starting to forward. Right
now this is OK because nobody inflates to_forward without using
buffer_forward().

15 years ago[MINOR] http: only consider chunk encoding with HTTP/1.1
Willy Tarreau [Tue, 22 Dec 2009 08:59:58 +0000 (09:59 +0100)] 
[MINOR] http: only consider chunk encoding with HTTP/1.1

This must be ignored in case of HTTP/1.0.

15 years ago[MAJOR] http: completely process the "connection" header
Willy Tarreau [Mon, 21 Dec 2009 19:11:07 +0000 (20:11 +0100)] 
[MAJOR] http: completely process the "connection" header

Up to now, we only had a flag in the session indicating if it had to
work in "connection: close" mode. This is not at all compatible with
keep-alive.

Now we ensure that both sides of a connection act independantly and
only relative to the transaction. The HTTP version of the request
and response is also correctly considered. The connection already
knows several modes :
  - tunnel (CONNECT or no option in the config)
  - keep-alive (when permitted by configuration)
  - server-close (close the server side, not the client)
  - close (close both sides)

This change carefully detects all situations to find whether a request
can be fully processed in its mode according to the configuration. Then
the response is also checked and tested to fix corner cases which can
happen with different HTTP versions on both sides (eg: a 1.0 client
asks for explicit keep-alive, and the server responds with 1.1 without
a header).

The mode is selected by a capability elimination algorithm which
automatically focuses on the least capable agent between the client,
the frontend, the backend and the server. This ensures we won't get
undesired situtations where one of the 4 "agents" is not able to
process a transaction.

No "Connection: close" header will be added anymore to HTTP/1.0 requests
or responses since they're already in close mode.

The server-close mode is still not completely implemented. The response
needs to be rewritten as keep-alive before being sent to the client if
the connection was already in server-close (which implies the request
was in keep-alive) and if the response has a content-length or a
transfer-encoding (but only if client supports 1.1).

A later improvement in server-close mode would probably be to detect
some situations where it's interesting to close the response (eg:
redirections with remote locations). But even then, the client might
close by itself.

It's also worth noting that in tunnel mode, no connection header is
affected in either direction. A tunnelled connection should theorically
be notified at the session level, but this is useless since by definition
there will not be any more requests on it. Thus, we don't need to add a
flag into the session right now.

15 years ago[MEDIUM] backend: remove HTTP POST parsing from get_server_ph_post()
Willy Tarreau [Sun, 6 Dec 2009 18:18:09 +0000 (19:18 +0100)] 
[MEDIUM] backend: remove HTTP POST parsing from get_server_ph_post()

Now that the HTTP analyser will already have parsed the beginning
of the request body, we don't have to check for transfer-encoding
anymore since we have the current chunk size in hdr_content_len.

15 years ago[MEDIUM] http: process request body in a specific analyser
Willy Tarreau [Sun, 6 Dec 2009 17:49:18 +0000 (18:49 +0100)] 
[MEDIUM] http: process request body in a specific analyser

The POST body analysis was split between two analysers for historical
reasons. Now we only have one analyser which checks content length
and waits for enough data to come.

Right now this analyser waits for <url_param_post_limit> bytes of
body to reach the buffer, or the first chunk. But this could be
improved to wait for any other amount of data or any specific
contents.

15 years ago[BUG] check_post: limit analysis to the buffer length
Willy Tarreau [Sun, 6 Dec 2009 17:16:59 +0000 (18:16 +0100)] 
[BUG] check_post: limit analysis to the buffer length

If "balance url_param XXX check_post" is used, we must bound the
number of bytes analysed to the buffer's length.

15 years ago[BUG] config: fix erroneous check on cookie domain names, again
Krzysztof Piotr Oledzki [Tue, 15 Dec 2009 22:40:47 +0000 (23:40 +0100)] 
[BUG] config: fix erroneous check on cookie domain names, again

The previous check was correct: the RFC states that it is required
to have a domain-name which contained a dot AND began with a dot.
However, currently some (all?) browsers do not obey this specification,
so such configuration might work.

This patch reverts 3d8fbb6658d4414dac20892bbd9e79e14e99e67f but
changes the check from FATAL to WARNING and extends the message.

15 years ago[BUG] second fix for the printf format warning
Willy Tarreau [Thu, 17 Dec 2009 20:12:16 +0000 (21:12 +0100)] 
[BUG] second fix for the printf format warning

Fix 500b8f0349fb52678f5143c49f5a8be5c033a988 fixed the patch for the 64 bit
case but caused the opposite type issue to appear on 32 bit platforms. Cast
the difference and be done with it since gcc does not agree on type carrying
the difference between two pointers on 32 and 64 bit platforms.

15 years ago[BUG] format '%d' expects type 'int', but argument 5 has type 'long int'
Krzysztof Piotr Oledzki [Tue, 15 Dec 2009 21:34:51 +0000 (22:34 +0100)] 
[BUG] format '%d' expects type 'int', but argument 5 has type 'long int'

src/cfgparse.c: In function 'readcfgfile':
src/cfgparse.c:4087: warning: format '%d' expects type 'int', but argument 5 has type 'long int'

15 years ago[MEDIUM] Decrease server health based on http responses / events, version 3
Krzysztof Piotr Oledzki [Tue, 15 Dec 2009 21:31:24 +0000 (22:31 +0100)] 
[MEDIUM] Decrease server health based on http responses / events, version 3

Implement decreasing health based on observing communication between
HAProxy and servers.

Changes in this version 2:
 - documentation
 - close race between a started check and health analysis event
 - don't force fastinter if it is not set
 - better names for options
 - layer4 support

Changes in this version 3:
 - add stats
 - port to the current 1.4 tree

15 years ago[DOC] some small spell fixes and unifications
Krzysztof Piotr Oledzki [Sun, 13 Dec 2009 20:55:50 +0000 (21:55 +0100)] 
[DOC] some small spell fixes and unifications

Traditionnally -> Traditionally
preceeded -> preceded
statictics -> statistics
(...)

15 years ago[MINOR] config: don't report error on all subsequent files on failure
Willy Tarreau [Tue, 15 Dec 2009 20:46:25 +0000 (21:46 +0100)] 
[MINOR] config: don't report error on all subsequent files on failure

Cyril Bonté found that when an error is detected in one config file, it
is also reported in all other ones, which is wrong. The fix obviously
consists in checking the return code from readcfgfile() and not the
accumulator.

15 years ago[MINOR] ebtree: add functions to lookup non-null terminated strings
Willy Tarreau [Mon, 14 Dec 2009 11:40:27 +0000 (12:40 +0100)] 
[MINOR] ebtree: add functions to lookup non-null terminated strings

Sometimes it's useful to lookup a string without terminating it with a
zero. We can do that relying on ebmb_lookup() since the string in the
tree contains a zero.

15 years ago[BUG] Configuration parser bug when escaping characters
Cyril Bonté [Sun, 6 Dec 2009 12:43:42 +0000 (13:43 +0100)] 
[BUG] Configuration parser bug when escaping characters

Today I was testing headers manipulation but I met a bug with my first test.
To reproduce it, add for example this line :

    rspadd Cache-Control:\ max-age=1500

Check the response header, it will provide :

Cache-Control: max-age=15000 <= the last character is duplicated

This only happens when we use backslashes on the last line of the
configuration file, without returning to the line.

Also if the last line is like :
  rspadd Cache-Control:\ max-age=1500\

the last backslash causes a segfault.

This is not due to rspadd but to a more general bug in cfgparse.c :
...
if (skip) {
        memmove(line + 1, line + 1 + skip, end - (line + skip + 1));
        end -= skip;
}
...

should be :
...
if (skip) {
        memmove(line + 1, line + 1 + skip, end - (line + skip));
        end -= skip;
}
...

I've reproduced it with haproxy 1.3.22 and the last 1.4 snapshot.

15 years ago[MINOR] config: support passing multiple "domain" statements to cookies
Willy Tarreau [Thu, 3 Dec 2009 22:28:34 +0000 (23:28 +0100)] 
[MINOR] config: support passing multiple "domain" statements to cookies

In some environments it is not possible to rely on any wildcard for a
domain name (eg: .com, .net, .fr...) so it is required to send multiple
domain extensions. (Un)fortunately the syntax check on the domain name
prevented that from being done the dirty way. So let's just build a
domain list when multiple domains are passed on the same line.
(cherry picked from commit 950245ca2b772fd6b99b8152c48c694ed0212857)

15 years ago[BUG] config: cookie domain was ignored in defaults sections
Willy Tarreau [Thu, 3 Dec 2009 22:13:06 +0000 (23:13 +0100)] 
[BUG] config: cookie domain was ignored in defaults sections

Since cookie can appear in a defaults section, the domain extension
must be supported there as well.

(cherry picked from commit baf78c8e03db8c2255aefb6e11b38b48d1ec5d34)

15 years ago[BUG] config: fix erroneous check on cookie domain names
Willy Tarreau [Thu, 3 Dec 2009 22:10:56 +0000 (23:10 +0100)] 
[BUG] config: fix erroneous check on cookie domain names

It was a OR instead of a AND, so it was required to have a cookie
name which contained a dot AND began with a dot.
(cherry picked from commit a1e107fc13e5d8886bf900f302322bfa6ed35d37)

15 years ago[BUG] config: disable 'option httplog' on TCP proxies
Willy Tarreau [Mon, 9 Nov 2009 20:27:51 +0000 (21:27 +0100)] 
[BUG] config: disable 'option httplog' on TCP proxies

Gabriel Sosa reported that logs were appearing with BADREQ when
'option httplog' was used with a TCP proxy (eg: inherited via a
default instance). This patch detects it and falls back to tcplog
after emitting a warning.
(cherry picked from commit 5f0bd6537f8b56b643ef485d7a3c96d996d9b01a)

15 years ago[BUG] config: fix wrong handling of too large argument count
Willy Tarreau [Mon, 9 Nov 2009 20:16:53 +0000 (21:16 +0100)] 
[BUG] config: fix wrong handling of too large argument count

Holger Just reported that running ACLs with too many args caused
a segfault during config parsing. This is caused by a wrong test
on argument count. In case of too many arguments on a config line,
the last one was not correctly zeroed. This is now done and we
report the error indicating what part had been truncated.
(cherry picked from commit 3b39c1446b9bd842324e87782a836948a07c25a2)

15 years ago[BUG] config: fix error message when config file is not found
Willy Tarreau [Sun, 6 Dec 2009 12:10:44 +0000 (13:10 +0100)] 
[BUG] config: fix error message when config file is not found

Cameron Simpson reported an annoying case where haproxy simply reports
"Error(s) found in configuration file" when the file is not found or
not readable.

Fortunately the parsing function still returns -1 in case of open
error, so we're able to detect the issue from the caller and report
the corresponding errno message.

15 years ago[MINOR] http: detect tunnel mode and set it in the session
Willy Tarreau [Mon, 30 Nov 2009 11:19:56 +0000 (12:19 +0100)] 
[MINOR] http: detect tunnel mode and set it in the session

In order to support keepalive, we'll have to differentiate
normal sessions from tunnel sessions, which are the ones we
don't want to analyse further.

Those are typically the CONNECT requests where we don't care
about any form of content-length, as well as the requests
which are forwarded on non-close and non-keepalive proxies.

15 years ago[BUG] x-original-to: name was not set in default instance
Willy Tarreau [Mon, 30 Nov 2009 10:50:16 +0000 (11:50 +0100)] 
[BUG] x-original-to: name was not set in default instance

This resulted in an empty header name when option originalto
was declared in a default sections.

15 years ago[MEDIUM] appsession: add "len", "prefix" and "mode" options
Cyril Bonté [Sun, 29 Nov 2009 19:04:48 +0000 (20:04 +0100)] 
[MEDIUM] appsession: add "len", "prefix" and "mode" options

To sum up :
- len : it's now the max number of characters for the value, preventing
  garbaged results.
- a new option "prefix" is added, this allows to use dynamic cookie
  names (e.g. ASPSESSIONIDXXX).

Previously in the thread, I wanted to use the value found with
"capture cookie" but when i started to update the documentation, I
found this solution quite weird. I've made a small rework to not
depend on "capture cookie".

- There's the posssiblity to define the URL parser mode (path parameters
  or query string).

15 years ago[MINOR] http: keep pointer to beginning of data
Willy Tarreau [Sun, 29 Nov 2009 17:12:29 +0000 (18:12 +0100)] 
[MINOR] http: keep pointer to beginning of data

We now set msg->col and msg->sov to the first byte of non-header.
They will be used later when parsing chunks. A new macro was added
to perform size additions on an http_msg in order to limit the risks
of copy-paste in the long term.

During this operation, it appeared that the http_msg struct was not
optimal on 64-bit, so it was re-ordered to fill the holes.

15 years ago[DOC] option is "defer-accept", not "defer_accept"
Willy Tarreau [Sat, 28 Nov 2009 07:21:29 +0000 (08:21 +0100)] 
[DOC] option is "defer-accept", not "defer_accept"

15 years ago[BUG] stream_sock: BUF_INFINITE_FORWARD broke splice on 64-bit platforms
Willy Tarreau [Sat, 28 Nov 2009 06:47:10 +0000 (07:47 +0100)] 
[BUG] stream_sock: BUF_INFINITE_FORWARD broke splice on 64-bit platforms

Yohan Tordjman at Dstorage found that upgrading haproxy to 1.4-dev4
caused truncated objects to be returned. An strace quickly exhibited
the issue which was 100% reproducible :

4297  epoll_wait(0, {}, 10, 0)          = 0
4297  epoll_wait(0, {{EPOLLIN, {u32=7, u64=7}}}, 10, 1000) = 1
4297  splice(0x7, 0, 0x5, 0, 0xffffffffffffffff, 0x3) = -1 EINVAL (Invalid argument)
4297  shutdown(7, 1 /* send */)         = 0
4297  close(7)                          = 0
4297  shutdown(2, 1 /* send */)         = 0
4297  close(2)                          = 0

This is caused by the fact that the forward length is taken from
BUF_INFINITE_FORWARD, which is -1. The problem does not appear
in 32-bit mode because this value is first cast to an unsigned
long, truncating it to 32-bit (4 GB). Setting an upper bound
fixes the issue.

Also, a second error check has been added for splice. If EINVAL
is returned, we fall back to recv().

15 years ago[MINOR] http: create new MSG_BODY sub-states
Willy Tarreau [Sun, 8 Nov 2009 12:10:58 +0000 (13:10 +0100)] 
[MINOR] http: create new MSG_BODY sub-states

An HTTP message can be decomposed into several sub-states depending
on the transfer-encoding. We'll have to keep these state information
while parsing chunks, so we must extend the values. In order not to
change everything, we'll now consider that anything >= MSG_BODY is
the body, and that the value indicates the precise state. The
MSG_ERROR status which was greater than MSG_BODY was moved for this.

15 years ago[MINOR] tools: add hex2i() function to convert hex char to int
Willy Tarreau [Mon, 2 Nov 2009 19:12:52 +0000 (20:12 +0100)] 
[MINOR] tools: add hex2i() function to convert hex char to int

15 years ago[BUILD] missing #ifndef in ebsttree.h
Willy Tarreau [Mon, 2 Nov 2009 13:43:39 +0000 (14:43 +0100)] 
[BUILD] missing #ifndef in ebsttree.h

15 years ago[BUILD] missing #ifndef in ebmbtree.h
Willy Tarreau [Mon, 2 Nov 2009 13:41:23 +0000 (14:41 +0100)] 
[BUILD] missing #ifndef in ebmbtree.h

15 years ago[MINOR] server tracking: don't care about the tracked server's mode
Alex Williams [Mon, 2 Nov 2009 02:27:13 +0000 (21:27 -0500)] 
[MINOR] server tracking: don't care about the tracked server's mode

Right now, an HTTP server cannot track a TCP server and vice-versa.
This patch enables proxy tracking without relying on the proxy's mode
(tcp/http/health). It only requires a matching proxy name to exist. The
original function was renamed to findproxy_mode().

15 years ago[CLEANUP] ebtree: cast to char * to get rid of gcc warning
Willy Tarreau [Thu, 29 Oct 2009 11:00:11 +0000 (12:00 +0100)] 
[CLEANUP] ebtree: cast to char * to get rid of gcc warning

Gcc warns about potential signedness issues when using strcmp().

15 years ago[MINOR] Collect & provide http response codes for frontends, fix backends
Krzysztof Piotr Oledzki [Sat, 24 Oct 2009 13:36:15 +0000 (15:36 +0200)] 
[MINOR] Collect & provide http response codes for frontends, fix backends

This patch extends and corrects the functionality introduced by
"Collect & provide http response codes received from servers":
 - responses are now also accounted for frontends
 - backend's and frontend's counters are incremented based
   on responses sent to client, not received from servers

15 years ago[MINOR] add additional "a href"s to stats page
Krzysztof Piotr Oledzki [Sat, 24 Oct 2009 12:24:30 +0000 (14:24 +0200)] 
[MINOR] add additional "a href"s to stats page

This patch adds <a href> html links for proxies, frontends, servers
and backends. Once located, can be clicked. Users no longer have to
manually add #anchor to stat's url.

15 years ago[BUG] definitely fix regparm issues between haproxy core and ebtree
Willy Tarreau [Tue, 27 Oct 2009 20:40:18 +0000 (21:40 +0100)] 
[BUG] definitely fix regparm issues between haproxy core and ebtree

It's a pain to enable regparm because ebtree is built in its corner
and does not depend on the rest of the config. This causes no problem
except that if the regparm settings are not exactly similar, then we
can get inconsistent function interfaces and crashes.

One solution realized in this patch consists in externalizing all
compiler settings and changing CONFIG_XXX_REGPARM into CONFIG_REGPARM
so that we ensure that any sub-component uses the same setting. Since
ebtree used a value here and not a boolean, haproxy's config has been
set to use a number too. Both haproxy's core and ebtree currently use
the same copy of the compiler.h file. That way we don't have any issue
anymore when one setting changes somewhere.

15 years ago[CLEANUP] ebtree: remove old unused files
Willy Tarreau [Mon, 26 Oct 2009 20:15:10 +0000 (21:15 +0100)] 
[CLEANUP] ebtree: remove old unused files

15 years ago[MEDIUM] build: switch ebtree users to use new ebtree version
Willy Tarreau [Mon, 26 Oct 2009 20:10:04 +0000 (21:10 +0100)] 
[MEDIUM] build: switch ebtree users to use new ebtree version

All files referencing the previous ebtree code were changed to point
to the new one in the ebtree directory. A makefile variable (EBTREE_DIR)
is also available to use files from another directory.

The ability to build the libebtree library temporarily remains disabled
because it can have an impact on some existing toolchains and does not
appear worth it in the medium term if we add support for multi-criteria
stickiness for instance.

15 years ago[IMPORT] import ebtree v5.0 into directory ebtree/
Willy Tarreau [Mon, 26 Oct 2009 18:48:54 +0000 (19:48 +0100)] 
[IMPORT] import ebtree v5.0 into directory ebtree/

We needed to upgrade ebtree to v5.0 to support string indexing,
and it was getting very painful to have it split across 2 dirs
and to have to patch it. Now we just have to copy the .c and .h
files to the right place.

15 years ago[MINOR] Add "a name" to stats page
Krzysztof Piotr Oledzki [Thu, 22 Oct 2009 20:48:09 +0000 (22:48 +0200)] 
[MINOR] Add "a name" to stats page

If you have a lot of proxies/servers in your stats page it is
not easy to locate the one you are interested in. You can
of couse use search function from you favorite web browser
but browsers often lost their focus when reloading stats.

This patch adds <a name> html tags for proxies, frontends, servers
and backends. You can use it to access a specific place, for example:

http://(stats_url)#proxy
http://(stats_url)#proxy/Frontend
http://(stats_url)#proxy/server1
http://(stats_url)#proxy/server2
http://(stats_url)#proxy/Backend

15 years ago[MINOR] http: remove the last call to stream_int_return
Willy Tarreau [Sun, 18 Oct 2009 21:56:35 +0000 (23:56 +0200)] 
[MINOR] http: remove the last call to stream_int_return

And remove the now unused function itself too.

15 years ago[MINOR] http response: update the TX_CLI_CONN_KA flag on rewrite
Willy Tarreau [Sun, 18 Oct 2009 21:52:50 +0000 (23:52 +0200)] 
[MINOR] http response: update the TX_CLI_CONN_KA flag on rewrite

If we modify the "connection" header we send to the client,
update the TX_CLI_CONN_KA flag.

15 years ago[MEDIUM] http response: check body length and set transaction flags
Willy Tarreau [Sun, 18 Oct 2009 21:45:12 +0000 (23:45 +0200)] 
[MEDIUM] http response: check body length and set transaction flags

We also check the close status and terminate the server persistent
connection if appropriate. Note that since this change, we'll not
get any "Connection: close" headers added to HTTP/1.0 responses
anymore, which is good.

15 years ago[MINOR] http: pre-set the persistent flags in the transaction
Willy Tarreau [Sun, 18 Oct 2009 21:43:57 +0000 (23:43 +0200)] 
[MINOR] http: pre-set the persistent flags in the transaction

We should pre-set the persistent flags then try to clear them
instead of the opposite.

15 years ago[MAJOR] http: create the analyser which waits for a response
Willy Tarreau [Sun, 18 Oct 2009 20:53:08 +0000 (22:53 +0200)] 
[MAJOR] http: create the analyser which waits for a response

The code part which waits for an HTTP response has been extracted
from the old function. We now have two analysers and the second one
may re-enable the first one when an 1xx response is encountered.
This has been tested and works.

The calls to stream_int_return() that were remaining in the wait
analyser have been converted to stream_int_retnclose().

15 years ago[MEDIUM] http request: make use of pre-parsed transfer-encoding header
Willy Tarreau [Sun, 18 Oct 2009 19:36:47 +0000 (21:36 +0200)] 
[MEDIUM] http request: make use of pre-parsed transfer-encoding header

This change should go a bit further. We should have a dedicated analyser
to find and skip chunks.

15 years ago[MEDIUM] http request: simplify POST length detection
Willy Tarreau [Sun, 18 Oct 2009 19:28:29 +0000 (21:28 +0200)] 
[MEDIUM] http request: simplify POST length detection

We can now rely on the pre-parsed content-length and transfer-encoding
to find what the supposed body length will be.

15 years ago[MINOR] http request: simplify the test of no-data
Willy Tarreau [Sun, 18 Oct 2009 19:17:42 +0000 (21:17 +0200)] 
[MINOR] http request: simplify the test of no-data

Now we can rely on (chunked && !hdr_content_len) to stop forwarding
data. We only do that for known methods that are not CONNECT though.

15 years ago[MINOR] http request: update the TX_SRV_CONN_KA flag on rewrite
Willy Tarreau [Sun, 18 Oct 2009 19:04:35 +0000 (21:04 +0200)] 
[MINOR] http request: update the TX_SRV_CONN_KA flag on rewrite

If we modify the "connection" header we send to the server,
update the TX_SRV_CONN_KA flag.

15 years ago[MEDIUM] http request: parse connection, content-length and transfer-encoding
Willy Tarreau [Sun, 18 Oct 2009 18:55:02 +0000 (20:55 +0200)] 
[MEDIUM] http request: parse connection, content-length and transfer-encoding

Store those elements in the transaction. RFC2616 is strictly followed.
Note that requests containing two different content-length fields are
discarded as invalid.

15 years ago[MINOR] http: add new transaction flags for keep-alive and content-length
Willy Tarreau [Sun, 18 Oct 2009 17:50:43 +0000 (19:50 +0200)] 
[MINOR] http: add new transaction flags for keep-alive and content-length

We'll need to store the keep-alive status as well as content-length
and/or transfer-encoding status.

15 years ago[MEDIUM] appsession: add the "request-learn" option
Cyril Bonté [Wed, 14 Oct 2009 22:15:40 +0000 (00:15 +0200)] 
[MEDIUM] appsession: add the "request-learn" option

This patch has 2 goals :

1. I wanted to test the appsession feature with a small PHP code,
using PHPSESSID. The problem is that when PHP gets an unknown session
id, it creates a new one with this ID. So, when sending an unknown
session to PHP, persistance is broken : haproxy won't see any new
cookie in the response and will never attach this session to a
specific server.

This also happens when you restart haproxy : the internal hash becomes
empty and all sessions loose their persistance (load balancing the
requests on all backend servers, creating a new session on each one).
For a user, it's like the service is unusable.

The patch modifies the code to make haproxy also learn the persistance
from the client : if no session is sent from the server, then the
session id found in the client part (using the URI or the client cookie)
is used to associated the server that gave the response.

As it's probably not a feature usable in all cases, I added an option
to enable it (by default it's disabled). The syntax of appsession becomes :

  appsession <cookie> len <length> timeout <holdtime> [request-learn]

This helps haproxy repair the persistance (with the risk of losing its
session at the next request, as the user will probably not be load
balanced to the same server the first time).

2. This patch also tries to reduce the memory usage.
Here is a little example to explain the current behaviour :
- Take a Tomcat server where /session.jsp is valid.
- Send a request using a cookie with an unknown value AND a path
  parameter with another unknown value :

  curl -b "JSESSIONID=12345678901234567890123456789012" http://<haproxy>/session.jsp;jsessionid=00000000000000000000000000000001

(I know, it's unexpected to have a request like that on a live service)
Here, haproxy finds the URI session ID and stores it in its internal
hash (with no server associated). But it also finds the cookie session
ID and stores it again.

- As a result, session.jsp sends a new session ID also stored in the
  internal hash, with a server associated.

=> For 1 request, haproxy has stored 3 entries, with only 1 which will be usable

The patch modifies the behaviour to store only 1 entry (maximum).

15 years ago[MAJOR] buffer: flag BF_DONT_READ to disable reads when not required
Willy Tarreau [Sat, 17 Oct 2009 12:37:52 +0000 (14:37 +0200)] 
[MAJOR] buffer: flag BF_DONT_READ to disable reads when not required

When processing a GET or HEAD request in close mode, we know we don't
need to read anything anymore on the socket, so we can disable it.
Doing this can save up to 40% of the recv calls, and half of the
epoll_ctl calls.

For this we need a buffer flag indicating that we're not interesting in
reading anymore. Right now, this flag also disables both polled reads.
We might benefit from disabling only speculative reads, but we will need
at least this flag when we want to support keepalive anyway.

Currently we don't disable the flag on completion, but it does not
matter as we close ASAP when performing the shutw().

15 years ago[MEDIUM] fd: merge fd_list into fdtab
Willy Tarreau [Sat, 17 Oct 2009 20:54:17 +0000 (22:54 +0200)] 
[MEDIUM] fd: merge fd_list into fdtab

The fd_list[] used by sepoll was indexed on the fd number and was only
used to store the equivalent of an integer. Changing it to be merged
with fdtab reduces the number of pointer computations, the code size
and some initialization steps. It does not harm other pollers much
either, as only one integer was added to the fdtab array.

15 years ago[OPTIM] move some rarely used fields out of fdtab
Willy Tarreau [Sun, 18 Oct 2009 05:25:52 +0000 (07:25 +0200)] 
[OPTIM] move some rarely used fields out of fdtab

Some rarely information are stored in fdtab, making it larger for no
reason (source port ranges, remote address, ...). Such information
lie there because the checks can't find them anywhere else. The goal
will be to move these information to the stream interface once the
checks make use of it.

For now, we move them to an fdinfo array. This simple change might
have improved the cache hit ratio a little bit because a 0.5% of
performance increase has measured.

15 years ago[CLEANUP] sepoll: clean up the fd_clr/fd_set functions
Willy Tarreau [Sat, 17 Oct 2009 19:43:03 +0000 (21:43 +0200)] 
[CLEANUP] sepoll: clean up the fd_clr/fd_set functions

This cleanup also slightly reduces code size due to a better
construct and the use of an inlined version of alloc_spec_entry().

15 years ago[MINOR] http: detect connection: close earlier
Willy Tarreau [Sat, 17 Oct 2009 18:12:21 +0000 (20:12 +0200)] 
[MINOR] http: detect connection: close earlier

Till now we would only set SN_CONN_CLOSED after rewriting it. Now we
set it just after checking the Connection header so that we can use
the result later if required.

15 years ago[DOC] option tcp-smart-connect was missing from index
Willy Tarreau [Sat, 17 Oct 2009 14:04:09 +0000 (16:04 +0200)] 
[DOC] option tcp-smart-connect was missing from index

15 years ago[BUG] Fix silly typo: hspr_other -> hrsp_other
Krzysztof Piotr Oledzki [Wed, 14 Oct 2009 20:26:01 +0000 (22:26 +0200)] 
[BUG] Fix silly typo: hspr_other -> hrsp_other

s/hspr_other/hrsp_other/

15 years ago[DOC] point to 1.4 doc, not 1.3
Willy Tarreau [Wed, 14 Oct 2009 20:22:03 +0000 (22:22 +0200)] 
[DOC] point to 1.4 doc, not 1.3

The links were wrong.

15 years ago[MINOR] Collect & provide http response codes received from servers
Krzysztof Piotr Oledzki [Tue, 13 Oct 2009 19:14:09 +0000 (21:14 +0200)] 
[MINOR] Collect & provide http response codes received from servers

Additional data is provided on both html & csv stats:
 - html: when passing a mouse over Sessions -> Total (servers, backends)
 - cvs: by 6 additional fields (hrsp_1xx, hrsp_2xx, hrsp_3xx, hrsp_4xx, hrsp_5xx, hspr_other)

Patch inspired by:
 http://www.formilux.org/archives/haproxy/0910/2528.html
 http://www.formilux.org/archives/haproxy/0910/2529.html

15 years ago[DOC] trivial fix for man page
Michael Shuler [Wed, 14 Oct 2009 15:23:03 +0000 (10:23 -0500)] 
[DOC] trivial fix for man page

I'm working on helping Arnaud update haproxy in Debian, and one of the
package build warnings I received was about "hyphen where a minus sign
was intended" in the man page - details:
http://lintian.debian.org/tags/hyphen-used-as-minus-sign.html

Patch included in my 1.3.20 Debian package is attached.