1309 Commits

Author SHA1 Message Date
Willy Tarreau
ed2fd2daea [BUG] http: fix incorrect error reporting during data transfers
We've had several issues related to data transfers. First, if a
client aborted an upload before the server started to respond, it
would get a 502 followed by a 400. The same was true (in the other
way around) if the server suddenly aborted while the client was
uploading the data.

The flags reported in the logs were misleading. Request errors could
be reported while the transfer was stopped during the data phase. The
status codes could also be overwritten by a 400 eventhough the start
of the response was transferred to the client.

The stats were also wrong in case of data aborts. The server or the
client could sometimes be miscredited for being the author of the
abort depending on where the abort was detected. Some client aborts
could also be accounted as request errors and some server aborts as
response errors.

Now it seems like all such issues are fixed. Since we don't have a
specific state for data flowing from the client to the server
before the server responds, we're still counting the client aborted
transfers as "CH", and they become "CD" when the server starts to
respond. Ideally a "P" state would be desired.

This patch should be backported to 1.4.
2010-12-29 13:55:32 +01:00
Willy Tarreau
0499e3575c [BUG] http: analyser optimizations broke pipelining
HTTP pipelining currently needs to monitor the response buffer to wait
for some free space to be able to send a response. It was not possible
for the HTTP analyser to be called based on response buffer activity.
Now we introduce a new buffer flag BF_WAKE_ONCE which is set when the
HTTP request analyser is set on the response buffer and some activity
is detected. This is not clean at all but once of the only ways to fix
the issue before we make it possible to register events for analysers.

Also it appeared that one realign condition did not cover all cases.
2010-12-17 07:15:57 +01:00
Willy Tarreau
10479e4bac [MINOR] stats: add global event ID and count
This counter will help quickly spot whether there are new errors or not.
It is also assigned to each capture so that a script can keep trace of
which capture was taken when.
2010-12-12 14:00:34 +01:00
Willy Tarreau
e1582eb7f6 [MINOR] http: capture incorrectly chunked message bodies
It is possible to block on incorrectly chunked requests or responses,
but this becomes very hard to debug when it happens once in a while.
This patch adds the ability to also capture incorrectly chunked requests
and responses. The chunk will appear in the error buffer and will be
verifiable with the usual "show errors". The incorrect byte will match
the error location.
2010-12-12 13:10:11 +01:00
Willy Tarreau
81f2fb97fe [MINOR] http: support wrapping messages in error captures
Error captures did only support contiguous messages. This is annoying
for capturing chunking errors, so let's ensure the function is able to
copy wrapped messages.
2010-12-12 13:09:08 +01:00
Willy Tarreau
3fe693b4d6 [BUG] http chunking: don't report a parsing error on connection errors
When haproxy parses chunk-encoded data that are scheduled to be sent, it is
possible that the other end is closed (mainly due to a client abort returning
as an error). The message state thus changes to HTTP_MSG_ERROR and the error
is reported as a chunk parsing error ("PD--") while it is not. Detect this
case before setting the flags and set the appropriate flag in this case.
2010-12-12 12:50:05 +01:00
Willy Tarreau
078272e115 [MINOR] stats: report HTTP message state and buffer flags in error dumps
Debugging parsing errors can be greatly improved if we know what the parser
state was and what the buffer flags were (especially for closed inputs/outputs
and full buffers). Let's add that to the error snapshots.
2010-12-12 12:46:33 +01:00
Willy Tarreau
57f5c12c04 [OPTIM] http: don't send each chunk in a separate packet
When forwarding chunk-encoded data, each chunk gets a TCP PUSH flag when
going onto the wire simply because the send() function does not know that
some data remain after it (next chunk). Now we set the BF_EXPECT_MORE flag
on the buffer if the chunk size is not null. That way we can reduce the
number of packets sent, which is particularly noticeable when forwarding
compressed data, especially as it requires less ACKs from the client.
2010-12-02 00:39:33 +01:00
Willy Tarreau
342b11c4d4 [BUG] http: do not re-enable the PROXY analyser on keep-alive
The PROXY analyser is connection-oriented and must only be set once. When
an HTTP transaction is done, we must not re-enable it.
2010-11-29 07:32:02 +01:00
Willy Tarreau
26db59ea6b [BUG] http: correctly update the header list when removing two consecutive headers
When a header is removed, the previous header's next pointer is updated
to reflect the next of the current header. However, when cycling through
the loop, we update the prev pointer to point to the deleted header, which
means that if we delete another header, it's the deleted header's next
pointer that will be updated, leaving the deleted header in the list with
a null length, which is forbidden.

We must just not update the prev pointer after a removal.

This bug was present when either "reqdel" and "rspdel" removed two consecutive
headers. It could also occur when removing cookies in either requests or
responses, but since headers were the last header processing, the issue
remained unnoticed.

Issue reported by Hank A. Paulson.

This fix must be ported to 1.4 and possibly 1.3.
2010-11-28 07:06:23 +01:00
Willy Tarreau
b810554f8f [CRITICAL] cookies: mixing cookies in indirect mode and appsession can crash the process
Cookies in indirect mode are removed from the cookie header. Three pointers
ought to be updated when appsession cookies are processed next, but were not.
The result is that a memcpy() can be called with a negative value causing the
process to crash. It is not sure whether this can be remotely exploited or not.
(cherry picked from commit c5f3749aa3ccfdebc4992854ea79823d26f66213)
2010-11-28 07:06:22 +01:00
Willy Tarreau
77eb9b8a2d [BUG] appsession: fix possible double free in case of out of memory
In out of memory conditions, the ->destroy function would free all
possibly allocated pools from the current appsession, including those
that were not yet allocated nor assigned, which used to point to a
previous allocation, obviously resulting in a segfault.
(cherry picked from commit 75eae485921d3a6ce197915c769673834ecbfa5c)
2010-11-19 13:25:11 +01:00
Willy Tarreau
f70fc75296 [BUG] capture: do not capture a cookie if there is no memory left
In case of out of memory, it was possible to write to a null pointer
when capturing response cookies due to a missing "else" block. The
request handling was fine though.
(cherry picked from commit 62e3604d7dd27741c0b4c9e27d9e7c73495dfc32)
2010-11-19 13:25:11 +01:00
Emeric Brun
485479d8e9 [MEDIUM] Create new protected pattern types CONSTSTRING and CONSTDATA to force memcpy if data from protected areas need to be manipulated.
Enhance pattern convs and fetch argument parsing, now fetchs and convs callbacks used typed args.
Add more details on error messages on parsing pattern expression function.
Update existing pattern convs and fetchs to new proto.
Create stick table key type "binary".
Manage Truncation and padding if pattern's fetch-converted result don't match table key size.
2010-11-11 09:29:07 +01:00
Cyril Bont
acd7d63ff9 [CLEANUP] Remove unneeded chars allocation
Some arrays used to log addresses add some more bytes for ports but this space
is never used.
2010-11-11 09:26:28 +01:00
Emeric Brun
5bd86a8ff5 [MINOR] Support listener's sockets unix on http logs.
Enhance controls of sockets family on X-Forwarded-For and X-Original-To insert
2010-11-09 15:59:42 +01:00
Willy Tarreau
ba4c5be880 [MINOR] cookie: add support for the "preserve" option
This option makes haproxy preserve any persistence cookie emitted by
the server, which allows the server to change it or to unset it, for
instance, after a logout request.
(cherry picked from commit 52e6d75374c7900c1fe691c5633b4ae029cae8d5)
2010-10-30 19:04:36 +02:00
Willy Tarreau
7f18e52b13 [MINOR] acl: add the http_req_first match
This match returns true when the request calling it is the first one of
a connection.
(cherry picked from commit 922ca979c50653c415852531f36fe409190ad76b)
2010-10-30 19:04:35 +02:00
Willy Tarreau
70461308fe [MEDIUM] checks: set server state to one state from failure when leaving maintenance
When we're enabling a server again (unix CLI or stats interface), we must not mark
it completely up because it can take a while before a failure is detected. So we
mark it one step above failure, which means it's up but will be marked down upon
first failure.
(cherry picked from commit 83c3e06452457ed5660fc814cbda5bf878bf19a2)
2010-10-30 19:04:34 +02:00
Cyril Bont
474be415af [MEDIUM] stats: add an admin level
The stats web interface must be read-only by default to prevent security
holes. As it is now allowed to enable/disable servers, a new keyword
"stats admin" is introduced to activate this admin level, conditioned by ACLs.
(cherry picked from commit 5334bab92ca7debe36df69983c19c21b6dc63f78)
2010-10-30 19:04:34 +02:00
Cyril Bont
70be45dbdf [MEDIUM] enable/disable servers from the stats web interface
Based on a patch provided by Judd Montgomery, it is now possible to
enable/disable servers from the stats web interface. This allows to select
several servers in a backend and apply the action to them at the same time.

Currently, there are 2 known limitations :
- The POST data are limited to one packet
  (don't alter too many servers at a time).
- Expect: 100-continue is not supported.
(cherry picked from commit 7693948766cb5647ac03b48e782cfee2b1f14491)
2010-10-30 19:04:34 +02:00
Willy Tarreau
ef4f391cc4 [MEDIUM] cookie: set the date in the cookie if needed
If a maxidle or maxlife parameter is set on the persistence cookie in
insert mode and the client did not provide a recent enough cookie,
then we emit a new cookie with a new last_seen date and the same
first_seen (if maxlife is set). Recent enough here designates a
cookie that would be rounded to the same date. That way, we can
refresh a cookie when required without doing it in all responses.

If the request did not contain such parameters, they are set anyway.
This means that a monitoring request that is forced to a server will
get an expiration date anyway, but this should not be a problem given
that the client is able to set its cookie in this case. This also
permits to force an expiration date on visitors who previously did
not have one.

If a request comes with a dated cookie while no date check is performed,
then a new cookie is emitted with no date, so that we don't risk dropping
the user too fast due to a very old date when we re-enable the date check.

All requests that were targetting the correct server and which had their
expiration date added/updated/removed in the response cookie are logged
with the 'U' ("updated") flag instead of the 'I' ("inserted"). So very
often we'll see "VU" instead of "VN".
(cherry picked from commit 8b3c6ecab6d37be5f3655bc3a2d2c0f9f37325eb)
2010-10-30 19:04:33 +02:00
Willy Tarreau
f64d1410fc [MEDIUM] cookie: check for maxidle and maxlife for incoming dated cookies
If a cookie comes in with a first or last date, and they are configured on
the backend, they're checked. If a date is expired or too far in the future,
then the cookie is ignored and the specific reason appears in the cookie
field of the logs.
(cherry picked from commit faa3019107eabe6b3ab76ffec9754f2f31aa24c6)
2010-10-30 19:04:33 +02:00
Willy Tarreau
f1348310e8 [MEDIUM] cookie: reassign set-cookie status flags to store more states
The set-cookie status flags were not very handy and limited. Reorder
them to save some room for additional values and add the "U" flags
(for Updated expiration date) that will be used with expirable cookies
in insert mode.
(cherry picked from commit 5bab52f821bb0fa99fc48ad1b400769e66196ece)
2010-10-30 19:04:33 +02:00
Willy Tarreau
b761ec4c94 [MINOR] cookie: add the expired (E) and old (O) flags for request cookies
These flags will indicate the cookie status when an expiration date is
set.
(cherry picked from commit 3f0f0e4583a432d34b75bc7b9dd2c756b4e181a7)
2010-10-30 19:04:33 +02:00
Willy Tarreau
bca9969daf [MEDIUM] cookie: support client cookies with some contents appended to their value
In all cookie persistence modes but prefix, we now support cookies whose
value is suffixed with some contents after a vertical bar ('|'). This will
be used to pass an optional expiration date. So as of now we only consider
the part of the cookie value which is used before the vertical bar.
(cherry picked from commit a4486bf4e5b03b5a980d03fef799f6407b2c992d)
2010-10-30 19:04:32 +02:00
Willy Tarreau
22a9534213 [MEDIUM] make it possible to combine http-pretend-keepalived with httpclose
Some configs may involve httpclose in a frontend and http-pretend-keepalive
in a backend. httpclose used to take priority over keepalive, thus voiding
its effect. This change ensures that when both are combined, keepalive is
still announced to the server while close is announced to the client.
(cherry picked from commit 2be7ec90fa9caf66294f446423bbab2d00db9004)
2010-10-30 19:04:31 +02:00
Willy Tarreau
e3f284aa7b [BUILD] proto_http: eliminate some build warnings with gcc-2.95
gcc-2.95 does not like labels before the first case in a switch
statement.
(cherry picked from commit e1c51a861ba0c389d31dfb010e8b188f5f43313a)
2010-10-30 19:04:31 +02:00
Willy Tarreau
58bd8fd46d [BUG] stream_sock: try to flush any extra pending request data after a POST
Some broken browsers still happen to send a CRLF after a POST. Those which
send a CRLF in a second packet have it queued into the system's buffers,
which causes an RST to be emitted by some systems upon close of the response
(eg: Linux). The client may then receive the RST without the last response
segments, resulting in a truncated response.

This change leaves request polling enabled on a POST so that we can flush
any late data from the request buffers.

A more complete workaround would consist in reading from the request for a
long time, until we get confirmation that the close has been ACKed. This
is much more complex and should only be studied for newer versions.
(cherry picked from commit 12e316af4f0245fde12dbc224ebe33c8fea806b2)
2010-10-30 19:04:30 +02:00
Willy Tarreau
24581bae02 [MEDIUM] http: fix space handling in the response cookie parser
This patch addresses exactly the same issues as the previous one, but
for responses this time. It also introduces implicit support for the
Set-Cookie2 header, for which there's almost nothing specific to do
since it is a clean header. This one allows multiple cookies in a
same header, by respecting the HTTP messaging semantics.

The new parser has been tested with insertion, rewrite, passive,
removal, prefixing and captures, and it looks OK. It's still able
to rewrite (or delete) multiple cookies at once. Just as with the
request parser, it tries hard to fix formating of the cookies it
displaces.

This patch too should be backported to 1.4 and possibly to 1.3.
2010-09-01 00:02:44 +02:00
Willy Tarreau
eb7b0a2b56 [MEDIUM] http: fix space handling in the request cookie parser
The request cookie parser did not allow spaces to appear in cookie
values nor around the equal sign. The various RFCs on the subject
say different things, some suggesting that a space is allowed after
the equal sign and being worded in a way that lets one believe it
is allowed before too. Some spaces may appear inside values and be
part of the values. The quotes allow delimiters to be embedded in
values. The spaces before and after attributes should be trimmed.

The new parser addresses all those points and has been carefully tested.
It fixes misplaced spaces around equal signs before processing the cookies
or forwarding them. It also tries its best to perform clean removals by
always keeping the delimiter after the value being removed and leaving one
space after it.

The variable inside the parser have been renamed to make the code a lot
more understandable, and one multi-function pointer has been eliminated.

Since this patch fixes real possible issues, it should be backported to 1.4
and possibly 1.3, since one (single) case of wrong spaces has been reported
in 1.3.

The code handling the Set-Cookie has not been touched yet.
2010-09-01 00:02:21 +02:00
Willy Tarreau
0f7f51fbe0 [BUG] http: don't consider commas as a header delimitor within quotes
The header parser has a bug which causes commas to be matched within
quotes while it was not expected. The way the code was written could
make one think it was OK. The resulting effect is that the following
config would use the second IP address instead of the third when facing
this request :

   source 0.0.0.0 usesrc hdr_ip(X-Forwarded-For,2)

   GET / HTTP/1.0
   X-Forwarded-for: "127.0.0.1, 127.0.0.2", 127.0.0.3

This fix must be backported to 1.4 and 1.3.
2010-08-30 11:06:34 +02:00
Willy Tarreau
92aa1fac0a [BUG] http: don't set auto_close if more data are expected
Fix 4fe41902789d188ee4c23b14a7cdbf075463b158 was a bit too strong. It
has caused some chunked-encoded responses to be truncated when a recv()
call could return multiple chunks followed by a close. The reason is
that when a chunk is parsed, only its contents are scheduled to be
forwarded. Thus, the reader sees auto_close+shutr and sets shutw_now.
The sender in turn sends the last scheduled data and does shutw().

Another nasty effect is that it has reduced the keep-alive rate. If
a response did not completely fit into the buffer, then the auto_close
bit was left on and the sender would close upon completion.

The fix consists in not making use of auto_close when chunked encoding
is used nor when keep-alive is used, which makes sense. However it is
maintained on error processing.

Thanks to Cyril Bont for reporting the issue early.
2010-08-28 19:06:28 +02:00
Willy Tarreau
5c54c71463 [MEDIUM] http: forward client's close when abortonclose is set
While it's usually desired to wait for a server response even
when the client closes its request channel, it can be problematic
with long polling requests. In order to let the server decide what
to do in such a case, if option abortonclose is set, we simply
forward the shutdown to the server. That way, it can decide to
take the appropriate action. Most servers will still process the
request, while some will probably want to abort.

Obviously, this only works as long as the client has not sent
another pipelined request over the same connection.

(was commit 0e25d86da49827ff6aa3c94132c01292b5ba4854 in 1.4)
2010-08-17 21:37:51 +02:00
Willy Tarreau
f059a0f63a [MAJOR] session-counters: split FE and BE track counters
Having a single tracking pointer for both frontend and backend counters
does not work. Instead let's have one for each. The keyword has changed
to "track-be-counters" and "track-fe-counters", and the ACL "trk_*"
changed to "trkfe_*" and "trkbe_*".
2010-08-10 18:04:15 +02:00
Willy Tarreau
da7ff64aa9 [MEDIUM] session-counters: add HTTP req/err tracking
This patch adds support for the following session counters :
  - http_req_cnt : HTTP request count
  - http_req_rate: HTTP request rate
  - http_err_cnt : HTTP request error count
  - http_err_rate: HTTP request error rate

The equivalent ACLs have been added to check the tracked counters
for the current session or the counters of the current source.
2010-08-10 18:04:14 +02:00
Willy Tarreau
6df7a0e7d3 [MINOR] http: reset analysers to listener's, not frontend's
When resetting a session's request analysers, we must take them from the
listener, not from the frontend. At the moment there is no difference
but this might change.
2010-08-10 14:04:42 +02:00
Willy Tarreau
bb695393da [BUG] http: denied requests must not be counted as denied resps in listeners
Socket stats had a wrong counter. This harmless bugfix must be backported
to 1.4.
2010-08-10 14:02:54 +02:00
Willy Tarreau
ee55dc024b [MINOR] frontend: rely on the frontend and not the backend for INDEPSTR
Till now, the frontend relied on the backend's options for INDEPSTR,
while at the time of accept, the frontend and backend are the same.
So we now use the frontend's pointer instead of the backend and we
don't have any dependency on the backend anymore in the frontend's
accept code.
2010-06-14 10:53:17 +02:00
Willy Tarreau
070ceb6cfb [MEDIUM] session: don't assign conn_retries upon accept() anymore
The conn_retries attribute is now assigned when switching from SI_ST_INI
to SI_ST_REQ. This eliminates one of the last dependencies on the backend
in the frontend's accept() function.
2010-06-14 10:53:16 +02:00
Willy Tarreau
ee28de0a12 [MEDIUM] session: move the conn_retries attribute to the stream interface
The conn_retries still lies in the session and its initialization depends
on the backend when it may not yet be known. Let's first move it to the
stream interface.
2010-06-14 10:53:16 +02:00
Willy Tarreau
d04e858db0 [MEDIUM] session: initialize server-side timeouts after connect()
It was particularly embarrassing that the server timeout was assigned
to buffers during an accept() just to be potentially changed later in
case of a use_backend rule. The frontend side has nothing to do with
server timeouts.

Now we initialize them right after the connect() succeeds. Later this
should change for a unique stream-interface timeout setting only.
2010-06-14 10:53:14 +02:00
Willy Tarreau
ace495e468 [CLEANUP] buffer->cto is not used anymore
The connection timeout stored in the buffer has not been used since the
stream interface were introduced. Let's get rid of it as it's one of the
things that complicate factoring of the accept() functions.
2010-06-14 10:53:14 +02:00
Willy Tarreau
03fa5df64a [CLEANUP] rename client -> frontend
The 'client.c' file now only contained frontend-specific functions,
so it has naturally be renamed 'frontend.c'. Same for client.h. This
has also been an opportunity to remove some cross references from
files that should not have depended on it.

In the end, this file should contain a protocol-agnostic accept()
code, which would initialize a session, task, etc... based on an
accept() from a lower layer. Right now there are still references
to TCP.
2010-06-14 10:53:10 +02:00
Willy Tarreau
663308bea1 [BUG] debug: correctly report truncated messages
By using msg->sol as the beginning of a message, wrong messages were
displayed in debug mode when they were truncated on the last line,
because msg->sol points to the beginning of the last line. Use
data+msg->som instead.
2010-06-07 22:43:55 +02:00
Willy Tarreau
1ba0e5f451 [BUG] debug: wrong pointer was used to report a status line
This would only be wrong when the server has not completely responded yet.
Fix two other occurrences of wrong rsp<->sl associations which were harmless
but wrong anyway.
2010-06-07 22:43:55 +02:00
Willy Tarreau
79ebac602d [BUG] http: report correct flags in case of client aborts during body
Some client abort/timeouts during body transfer were reported as "PR--"
instead of "CD--" or "cD--". This fix has to be ported to 1.5.
2010-06-07 22:43:54 +02:00
Willy Tarreau
4fe4190278 [BUG] http: automatically close response if req is aborted
Latest BF_READ_ATTACHED fix has unveiled a nice issue with the way
HTTP requests and responses are forwarded. The case where the request
aborts after the response has responded (POST with early response)
forgot to re-enable auto-close on the response. In fact it still
worked thanks to a side effect as long as BF_READ_ATTACHED was there
to force the states to be resynced (and the flags). Since last fix,
the missing auto-close causes CLOSE_WAIT connections when the client
aborts too late during a data transfer.

The right fix consists in considering the situation where the client
experiences an error and to explicitly abort the transfer. There is
no need to wake the response analysers up for that since they'd have
no added value and the analysers flags are cleared. However for a
future usage, that might help (eg: stickiness, ...).

This fix should be backported to 1.4 if the previous one is backported
too. After all the non-reg tests, the risks to see a problem arise
without both patches seems low, and both patches touch sensible areas
of the code. So there's no hurry.
2010-06-07 22:42:44 +02:00
Willy Tarreau
d45b3d5aff [BUG] http: dispatch and http_proxy modes were broken for a long time
Both dispatch and http_proxy modes were broken since 1.4-dev5 when
the adjustment of server health based on response codes was introduced.
In fact, in these modes, s->srv == NULL. The result is a plain segfault.
It should have been noted critical, but the fact that it remained 6
months without being noticed indicates that almost nobody uses these
modes anymore. Also, the crash is immediate upon first request.

Further versions should not be affected anymore since it's planned to
have a dummy server instead of these annoying NULL pointers.
2010-05-23 08:56:02 +02:00
Willy Tarreau
4a568976c5 [MINOR] stick-tables: add support for "stick on hdr"
It is now possible to stick on an IP address found in a HTTP header. Right
now only the last occurrence of the header can be used, which is generally
enough for most uses. Also, the header extraction rule only knows how to
convert the header to IP. Later it will be usable as a plain string with
an implicit conversion, and the syntax will not change.
2010-05-13 22:10:02 +02:00