Commit Graph

1685 Commits

Author SHA1 Message Date
Willy Tarreau
7c96f678fa [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.
2009-12-27 22:47:25 +01:00
Willy Tarreau
aec571c2bb [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.
2009-12-27 17:18:11 +01:00
Willy Tarreau
1d3bcce4dd [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.
2009-12-27 15:50:06 +01:00
Willy Tarreau
d21e01c63f [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.
2009-12-27 15:45:38 +01:00
Willy Tarreau
e8e785bb85 [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.
2009-12-26 16:29:04 +01:00
Willy Tarreau
115acb9755 [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.
2009-12-26 13:56:06 +01:00
Willy Tarreau
0394594b06 [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.
2009-12-22 16:50:27 +01:00
Willy Tarreau
63c9e5ffa6 [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.
2009-12-22 16:01:27 +01:00
Willy Tarreau
0937bc43cf [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.
2009-12-22 15:03:09 +01:00
Willy Tarreau
7c3c54177a [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().
2009-12-22 10:06:34 +01:00
Willy Tarreau
9e13c3c630 [MINOR] http: only consider chunk encoding with HTTP/1.1
This must be ignored in case of HTTP/1.0.
2009-12-22 09:59:58 +01:00
Willy Tarreau
5b15447672 [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.
2009-12-22 09:52:43 +01:00
Willy Tarreau
157dd638e9 [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.
2009-12-22 09:52:42 +01:00
Willy Tarreau
522d6c048f [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.
2009-12-22 09:52:42 +01:00
Willy Tarreau
dc8017ced6 [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.
2009-12-22 09:52:42 +01:00
Krzysztof Piotr Oledzki
1a8bea9390 [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 3d8fbb6658 but
changes the check from FATAL to WARNING and extends the message.
2009-12-17 21:14:21 +01:00
Willy Tarreau
3ccf94efd9 [BUG] second fix for the printf format warning
Fix 500b8f0349 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.
2009-12-17 21:14:20 +01:00
Krzysztof Piotr Oledzki
500b8f0349 [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'
2009-12-16 00:29:41 +01:00
Krzysztof Piotr Oledzki
97f07b832f [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
2009-12-16 00:29:27 +01:00
Krzysztof Piotr Oledzki
f864533c05 [DOC] some small spell fixes and unifications
Traditionnally -> Traditionally
preceeded -> preceded
statictics -> statistics
(...)
2009-12-16 00:20:05 +01:00
Willy Tarreau
25a67fae3e [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.
2009-12-15 21:46:25 +01:00
Willy Tarreau
c9a31da73f [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.
2009-12-14 12:43:37 +01:00
Cyril Bont
dd1b01d027 [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.
2009-12-06 13:46:14 +01:00
Willy Tarreau
68a897b2be [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 950245ca2b)
2009-12-06 13:25:23 +01:00
Willy Tarreau
4d187ac350 [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 baf78c8e03)
2009-12-06 13:25:05 +01:00
Willy Tarreau
3d8fbb6658 [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 a1e107fc13)
2009-12-06 13:24:20 +01:00
Willy Tarreau
1780416e33 [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 5f0bd6537f)
2009-12-06 13:24:11 +01:00
Willy Tarreau
7bb651ec1d [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 3b39c1446b)
2009-12-06 13:23:43 +01:00
Willy Tarreau
c438242878 [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.
2009-12-06 13:10:44 +01:00
Willy Tarreau
d0f06fc4b2 [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.
2009-11-30 12:19:56 +01:00
Willy Tarreau
b86db34fe0 [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.
2009-11-30 11:50:16 +01:00
Cyril Bonté
b21570ae0f [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).
2009-11-30 11:31:53 +01:00
Willy Tarreau
fa355d4a51 [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.
2009-11-29 18:12:29 +01:00
Willy Tarreau
53319c91ef [DOC] option is "defer-accept", not "defer_accept" 2009-11-28 08:21:29 +01:00
Willy Tarreau
a9de333aa5 [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().
2009-11-28 07:47:10 +01:00
Willy Tarreau
655dce90d4 [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.
2009-11-08 13:10:58 +01:00
Willy Tarreau
da3b7c31f7 [MINOR] tools: add hex2i() function to convert hex char to int 2009-11-02 20:12:52 +01:00
Willy Tarreau
9e2e39e117 [BUILD] missing #ifndef in ebsttree.h 2009-11-02 14:43:39 +01:00
Willy Tarreau
ead63a034a [BUILD] missing #ifndef in ebmbtree.h 2009-11-02 14:41:23 +01:00
Alex Williams
96532db923 [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().
2009-11-02 11:08:00 +01:00
Willy Tarreau
4c84822d97 [CLEANUP] ebtree: cast to char * to get rid of gcc warning
Gcc warns about potential signedness issues when using strcmp().
2009-10-29 12:00:11 +01:00
Krzysztof Piotr Oledzki
de71d16ec0 [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
2009-10-27 21:56:47 +01:00
Krzysztof Piotr Oledzki
1f67285541 [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.
2009-10-27 21:56:47 +01:00
Willy Tarreau
cc05fba613 [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.
2009-10-27 21:53:58 +01:00
Willy Tarreau
3e79479348 [CLEANUP] ebtree: remove old unused files 2009-10-26 21:15:10 +01:00
Willy Tarreau
45cb4fb640 [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.
2009-10-26 21:10:04 +01:00
Willy Tarreau
c218602b1d [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.
2009-10-26 19:48:54 +01:00
Krzysztof Piotr Oledzki
516ed49964 [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
2009-10-24 09:54:31 +02:00
Willy Tarreau
8e89b84848 [MINOR] http: remove the last call to stream_int_return
And remove the now unused function itself too.
2009-10-18 23:56:35 +02:00
Willy Tarreau
b50943e717 [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.
2009-10-18 23:53:19 +02:00