Commit Graph

1231 Commits

Author SHA1 Message Date
Willy Tarreau
197e10aaae MEDIUM: acl: get rid of the SET_RES flags
We now simply rely on a boolean result from a fetch to declare a match.
Booleans are not compared against patterns, they fix the result.
2012-05-08 20:57:15 +02:00
Willy Tarreau
f853c46bc3 MEDIUM: pattern/acl: get rid of temp_pattern in ACLs
This one is not needed anymore as we can return the data and its type in the
sample provided by the caller. ACLs now always return the proper type. BOOL
is already returned when the result is expected to be processed as a boolean.

temp_pattern has been unexported now.
2012-05-08 20:57:14 +02:00
Willy Tarreau
3740635b88 MAJOR: acl: make use of the new sample struct and get rid of acl_test
This change is invasive in lines of code but not much in terms of
functionalities as it's mainly a replacement of struct acl_test
with struct sample.
2012-05-08 20:57:14 +02:00
Willy Tarreau
422aa0792d MEDIUM: pattern: add new sample types to replace pattern types
The new sample types are necessary for the acl-pattern convergence.
These types are boolean and signed int. Some types were renamed for
less ambiguity (ip->ipv4, integer->uint).
2012-05-08 20:57:14 +02:00
Willy Tarreau
8f7406e9b4 MEDIUM: acl: remove the ACL_TEST_F_NULL_MATCH flag
This flag was used to force a boolean match even if there was no pattern
to match. It was used only by http_auth() and designed only for this one.
It's easier and cleaner to make the fetch function perform the test and
report the boolean result as a few other functions already do. It simplifies
the acl_exec_cond() logic and will help merging ACLs and patterns.
2012-05-08 20:57:13 +02:00
Willy Tarreau
21d68a6895 MEDIUM: pattern: add an argument validation callback to pattern descriptors
This is used to validate that arguments are coherent. For instance,
payload_lv expects that the last arg (if any) is not more negative
than the sum of the first two. The error is reported if any.
2012-05-08 20:57:13 +02:00
Willy Tarreau
9fcb984b17 MEDIUM: pattern: use the standard arg parser
We don't need the pattern-specific args parsers anymore, make use of the
common parser instead. We still need to improve this by adding a validation
function to report abnormal argument values or combinations. We don't report
precise parsing errors yet but this was not previously done either.
2012-05-08 20:57:13 +02:00
Willy Tarreau
f995410355 MEDIUM: pattern: get rid of arg_i in all functions making use of arguments
arg_i was almost unused, and since we migrated to use struct arg everywhere,
the rare cases where arg_i was needed could be replaced by switching to
arg->type = ARGT_STOP.
2012-05-08 20:57:12 +02:00
Willy Tarreau
ecfb8e8ff9 MEDIUM: pattern: replace type pattern_arg with type arg
arg is more complete than pattern_arg since it also covers ACL args,
so let's use this one instead.
2012-05-08 20:57:12 +02:00
Willy Tarreau
61612d49a7 MAJOR: acl: store the ACL argument types in the ACL keyword declaration
The types and minimal number of ACL keyword arguments are now stored in
their declaration. This will allow many more fantasies if some ACL use
several arguments or types.

Doing so required to rework all ACL keyword declarations to add two
parameters. So this was a good opportunity for a general cleanup and
to sort all entries in alphabetical order.

We still have two pending issues :
  - parse_acl_expr() checks for errors but has no way to report them to
    the user ;
  - the types of some arguments are still not resolved and kept as strings
    (eg: ARGT_FE/BE/TAB) for compatibility reasons, which must be resolved
    in acl_find_targets()
2012-05-08 20:57:11 +02:00
Willy Tarreau
34db108423 MAJOR: acl: make use of the new argument parsing framework
The ACL parser now uses the argument parser to build a typed argument list.
Right now arguments are all strings and only one argument is supported since
this is what ACLs currently support.
2012-05-08 20:57:11 +02:00
Willy Tarreau
d53e2428d1 MEDIUM: http/acl: make acl_fetch_hdr_{ip,val} rely on acl_fetch_hdr()
These two functions will now exploit the return of acl_fetch_hdr() instead
of doing the same work again and again.
2012-05-08 20:57:10 +02:00
Willy Tarreau
e333ec9f24 MEDIUM: http/acl: merge all request and response ACL fetches of headers and cookies
Latest changes have made it possible to remove all differences between
request and response processing, making it worth merging request and
response ACL fetch functions to reduce code size.

Most likely with minor adaptation it will be possible to use the same hdr_*
functions to match in the response path, and cook_* for the response cookie
too.
2012-05-08 20:57:10 +02:00
Willy Tarreau
7744e0cf43 BUG/MINOR: http_auth: ACLs are volatile, not permanent
ACLs are volatile since they require a fetch of request buffer data which is
then copied to a temporary shared place. The issue is minor though since auth
is generally checked very early.
2012-05-08 20:57:10 +02:00
Willy Tarreau
c0239e0425 MEDIUM: http: make all ACL fetch function use acl_prefetch_http()
All ACLs which need to process HTTP contents first call this function which
performs all the preliminary tests and also triggers the request parsing if
needed. A macro was written to simplify the code.

As a side effect, it's not required anymore to check for the HTTP ACL before
checking for HTTP contents.
2012-05-08 20:57:10 +02:00
Willy Tarreau
14174bc4c0 MEDIUM: http: add a prefetch function for ACL pattern fetch
This function will be called by all ACL fetch functions. Right now all ACL
fetch functions have to perform the exact same tests to check whether data
are available. Also, only one of them is able to actually parse an HTTP
request.

Using the prefetch function, it will be possible to try to parse a request
on the fly and to avoid the fetch if some data are missing. This will
significantly reduce the amount of tests in all ACL fetch functions.
2012-05-08 20:57:09 +02:00
Willy Tarreau
9dab5fc4d4 MEDIUM: buffers: rename a number of buffer management functions
The following renaming took place :
1) buffer input functions
  buffer_put_block => bi_putblk
  buffer_put_char => bi_putchr
  buffer_put_string => bi_putstr
  buffer_put_chunk => bi_putchk
  buffer_feed => bi_putstr
  buffer_feed_chunk => bi_putchk
  buffer_cut_tail => bi_erase
  buffer_ignore => bi_fast_delete

2) buffer output functions
  buffer_get_char => bo_getchr
  buffer_get_line => bo_getline
  buffer_get_block => bo_getblk
  buffer_skip => bo_skip
  buffer_write => bo_inject

3) buffer input avail/full functions were introduced :
  bi_avail
  bi_full
2012-05-08 20:56:56 +02:00
Willy Tarreau
cc5cfcbcce MEDIUM: buffers: add new pointer wrappers and get rid of almost all buffer_wrap_add calls
buffer_wrap_add was convenient for the migration but is not handy at all.
Let's have new wrappers that report input begin/end and output begin/end
instead.

It looks like we'll also need a b_adv(ofs) to advance a buffer's pointer.
2012-05-08 12:28:14 +02:00
Willy Tarreau
ec1bc82a1d MEDIUM: buffers: fix unsafe use of buffer_ignore at some places
buffer_ignore may only be used when the output of a buffer is empty,
but it's not granted it is always the case when sending HTTP error
responses. Better use buffer_cut_tail() instead, and use buffer_ignore
only on non-wrapping data.
2012-05-08 12:28:14 +02:00
Willy Tarreau
8b1323e4cb MINOR: http: remove useless wrapping checks in http_msg_analyzer
The message cannot wrap here.
2012-05-08 12:28:14 +02:00
Willy Tarreau
4baf44ba67 MEDIUM: http: remove buffer arg in chunk parsing functions
The buffer pointer is now taken from the http_msg in the following
functions :

	http_parse_chunk_size
	http_forward_trailers
	http_skip_chunk_crlf

Most internal pointers were converted to const as the result of the
operation.
2012-05-08 12:28:14 +02:00
Willy Tarreau
21710ffa35 MEDIUM: http: remove buffer arg in http_buffer_heavy_realign
The buffer pointer is now taken from the http_msg. The function has also
been renamed "http_message_realign".
2012-05-08 12:28:13 +02:00
Willy Tarreau
418bfcc794 MEDIUM: http: remove buffer arg in http_upgrade_v09_to_v10
The buffer and http_msg pointers are now taken from the transaction.
2012-05-08 12:28:13 +02:00
Willy Tarreau
a560c21f54 MEDIUM: http: remove buffer arg in http_msg_analyzer
The buffer pointer is now taken from the http_msg.
2012-05-08 12:28:13 +02:00
Willy Tarreau
8a0cef2dad MEDIUM: http: remove buffer arg in http_capture_bad_message
The buffer pointer is now taken from the http_msg.
2012-05-08 12:28:13 +02:00
Willy Tarreau
6acf7c9179 MEDIUM: http: remove buffer arg in a few header manipulation functions
The buffer pointer is now taken from the http_msg in the following functions :

 - http_remove_header2
 - http_header_add_tail
 - http_header_add_tail2
 - http_parse_connection_header
 - http_change_connection_header
2012-05-08 12:28:12 +02:00
Willy Tarreau
45c0d98769 MEDIUM: http: http_send_name_header: remove references to msg and buffer
They can be deduced from txn.
2012-05-08 12:28:12 +02:00
Willy Tarreau
3a215bedba MAJOR: http: make http_msg->sol relative to buffer's origin
msg->sol is now a relative pointer just like all other ones. There is no
more absolute references to the buffer outside the struct buffer itself.

Next two cleanups should include removing buffer references to functions
which already have an msg, and removal of wrapping detection in request
and response parsing which cannot wrap by definition.
2012-05-08 12:28:12 +02:00
Willy Tarreau
62f791ea6f MEDIUM: http: add a pointer to the buffer in http_msg
ACLs and patterns only rely on a struct http_msg and don't know the pointer
to the actual data. struct http_msg will soon only hold relative references
so that's not possible. We need http_msg to hold a reference to the struct
buffer before having relative pointers everywhere.

It is likely that doing so will also result in opportunities to simplify
a number of functions arguments. The following functions are already
candidate :

	http_buffer_heavy_realign
	http_capture_bad_message
	http_change_connection_header
	http_forward_trailers
	http_header_add_tail
	http_header_add_tail2
	http_msg_analyzer
	http_parse_chunk_size
	http_parse_connection_header
	http_remove_header2
	http_send_name_header
	http_skip_chunk_crlf
	http_upgrade_v09_to_v10
2012-05-08 12:28:12 +02:00
Willy Tarreau
12e48b36dd MAJOR: http: turn http_msg->eol to a buffer-relative offset
It was an absolute pointer to the buffer's data, now it's a pointer relative
to the buffer's origin.
2012-05-08 12:28:12 +02:00
Willy Tarreau
fa4a03ca08 CLEANUP: http: remove unused http_msg->col
The <col> element of the struct http_msg has not been used for a long
time now, remove it.
2012-05-08 12:28:11 +02:00
Willy Tarreau
ea1175a687 MAJOR: http: change msg->{som,col,sov,eoh} to be relative to buffer origin
These offsets were relative to the buffer itself. Now they're relative to
the buffer's origin (buf->p) which normally corresponds to the start of
current message.

This saves a big dependency between the HTTP message struct and the buffers.
It appeared during this change that ->col is not used anymore (it will have
to be removed). Next step is to turn ->eol and ->sol from absolute to relative.
2012-05-08 12:28:11 +02:00
Willy Tarreau
a458b67965 MAJOR: http: move buffer->lr to http_msg->next
The buffer's pointer <lr> was only used by HTTP parsers which also use a
struct http_msg to keep track of the parser's state. We've reached a point
where it makes no sense to keep ->lr in the buffer, as the split between
buffer and msg is only arbitrary for historical reasons.

This change ensures that touching buffers will not impact HTTP messages
anymore, making the buffers more content-agnostic. However, it becomes
very important not to forget to update msg->next when some data get
forwarded or moved (and in general each time buf->p is updated).

The new pointer in http_msg becomes relative to buffer->p so that
parsing multiple messages becomes easier. It is possible that at one
point ->som and ->next will be merged.

Note: http_parse_reqline() and http_parse_stsline() have been temporarily
modified to know the message starting point in the buffer (->p).
2012-05-08 12:28:11 +02:00
Willy Tarreau
363a5bb152 MAJOR: buffers: replace buf->r with buf->p + buf->i
This change gets rid of buf->r which is always equal to buf->p + buf->i.
It removed some wrapping detection at a number of places, but required addition
of new relative offset computations at other locations. A large number of places
can be simplified now with extreme care, since most of the time, either the
pointer has to be computed once or we need a difference between the old ->w and
old ->r to compute free space. The cleanup will probably happen with the rewrite
of the buffer_input_* and buffer_output_* functions anyway.

buf->lr still has to move to the struct http_msg and be relative to buf->p
for the rework to be complete.
2012-05-08 12:28:11 +02:00
Willy Tarreau
89fa706d39 MAJOR: buffers: replace buf->w with buf->p - buf->o
This change introduces the buffer's base pointer, which is the limit between
incoming and outgoing data. It's the point where the parsing should start
from. A number of computations have already been greatly simplified, but
more simplifications are expected to come from the removal of buf->r.

The changes appear good and have revealed occasional improper use of some
pointers. It is possible that this patch has introduced bugs or revealed
some, although preliminary testings tend to indicate that everything still
works as it should.
2012-05-08 12:28:10 +02:00
Willy Tarreau
02d6cfc1d7 MAJOR: buffer: replace buf->l with buf->{o+i}
We don't have buf->l anymore. We have buf->i for pending data and
the total length is retrieved by adding buf->o. Some computation
already become simpler.

Despite extreme care, bugs are not excluded.

It's worth noting that msg->err_pos as set by HTTP request/response
analysers becomes relative to pending data and not to the beginning
of the buffer. This has not been completed yet so differences might
occur when outgoing data are left in the buffer.
2012-05-08 12:28:10 +02:00
Willy Tarreau
2e046c6017 MAJOR: buffer rework: replace ->send_max with ->o
This is the first minor step of the buffer rework. It's only renaming,
it should have no impact.
2012-04-30 11:57:00 +02:00
Willy Tarreau
a36fc4d7ed MEDIUM: move message-related flags from transaction to message
Too many flags are stored in the transaction structure. Some flags are
clearly message-specific and exist in two versions (request and response).
Move them to a new "flags" field in the http_message struct instead.
2012-04-30 11:57:00 +02:00
Willy Tarreau
21337825c0 CLEANUP: remove a few warning about unchecked return values in debug code
There were a few unchecked write() calls in the debug code that cause
gcc 4.x to emit warnings on recent libc. We don't want to check them
as we can't make anything from the result, let's simply surround them
with an empty if statement.

Note that one of the warnings was for chdir("/") which normally cannot
fail since it follows a successful chroot (which means the perms are
necessarily there). Anyway let's move the call uppe to protect it too.
2012-04-30 11:56:30 +02:00
Willy Tarreau
b56928a74c CLEANUP: http: message parser must ignore HTTP_MSG_ERROR
The issue only happens when DEBUG_FULL is enabled, which causes
http_msg_analyzer() to complain if it's called twice with an invalid
message, for instance because of two consecutive ACLs using req_proto_http.

The code is commented out when DEBUG_FULL is disabled, so this is not a bug,
just an annoyance for the developer.
2012-04-30 11:51:59 +02:00
Willy Tarreau
46787ed700 BUILD: http: stop gcc-4.1.2 from complaining about possibly uninitialized values
The three warnings below are totally wrong since the variables depend on another
one which is only turned on when the variables are initialized. Still this gcc-4.1.2
isn't able to see this and prefers to complain wrongly. So let's initialize the
variables to shut it up since we're not in the fast path.

src/proto_http.c: In function 'acl_fetch_any_cookie_cnt':
src/proto_http.c:8393: warning: 'val_end' may be used uninitialized in this function

src/proto_http.c: In function 'http_process_req_stat_post':
src/proto_http.c:2577: warning: 'st_next_param' may be used uninitialized in this function
src/proto_http.c:2577: warning: 'st_cur_param' may be used uninitialized in this function
2012-04-30 00:19:31 +02:00
Willy Tarreau
3fb818c014 BUILD: http: make extract_cookie_value() return an int not size_t
It's very annoying that we have to deal with the crappy size_t and with ints
at some places because these ones don't mix well. Patch 6f61b2 changed the
chunk len to int but its size remains size_t and some functions are having
trouble being used by several callers depending on the type of their arguments.

Let's turn extract_cookie_value() to int for now on, and plan a massive cleanup
later to remove all size_t.
2012-04-30 00:19:28 +02:00
Willy Tarreau
9b061e3320 MEDIUM: stream_sock: add a get_src and get_dst callback and remove SN_FRT_ADDR_SET
These callbacks are used to retrieve the source and destination address
of a socket. The address flags are not hold on the stream interface and
not on the session anymore. The addresses are collected when needed.

This still needs to be improved to store the IP and port separately so
that it is not needed to perform a getsockname() when only the IP address
is desired for outgoing traffic.
2012-04-07 18:03:52 +02:00
William Lallemand
a73203e3dc MEDIUM: log: Unique ID
The Unique ID, is an ID generated with several informations. You can use
a log-format string to customize it, with the "unique-id-format" keyword,
and insert it in the request header, with the "unique-id-header" keyword.
2012-04-07 16:25:26 +02:00
William Lallemand
5f2324019d MEDIUM: log: New format-log flags: %Fi %Fp %Si %Sp %Ts %rt %H %pid
%Fi: Frontend IP
%Fp: Frontend Port
%Si: Server IP
%Sp: Server Port
%Ts: Timestamp
%rt: HTTP request counter
%H: hostname
%pid: PID

+X: Hexadecimal represenation

The +X mode in logformat displays hexadecimal for the following flags
%Ci %Cp %Fi %Fp %Bi %Bp %Si %Sp %Ts %ct %pid

rename logformat_write_string() to lf_text()

Optimize size computation
2012-04-07 16:05:39 +02:00
Willy Tarreau
04aa6a9ce8 MEDIUM: http: add cookie and scookie ACLs
The ACL matches rely on the extract_cookie_value() function as used for
for patterns. This permits ACLs to match cookie values based on the cookie
name instead of having to perform substring matching on the cookie header.
2012-04-07 08:47:26 +02:00
Willy Tarreau
4573af939c MEDIUM: http: make extract_cookie_value() iterate over cookie values
This will make the function usable for ACLs.
2012-04-06 18:20:06 +02:00
Willy Tarreau
c89ccb6221 MEDIUM: log: add a new cookie flag 'U' to report situations where cookie is not used
This happens when a "use-server" rule sets the server instead.
2012-04-05 21:18:22 +02:00
Willy Tarreau
4a5cadea40 MEDIUM: session: implement the "use-server" directive
Sometimes it is desirable to forward a particular request to a specific
server without having to declare a dedicated backend for this server. This
can be achieved using the "use-server" rules. These rules are evaluated after
the "redirect" rules and before evaluating cookies, and they have precedence
on them. There may be as many "use-server" rules as desired. All of these
rules are evaluated in their declaration order, and the first one which
matches will assign the server.
2012-04-05 21:14:10 +02:00
Cyril Bonté
19979e176e MINOR: stats admin: reduce memcmp()/strcmp() calls on status codes
memcmp()/strcmp() calls were needed in different parts of code to determine
the status code. Each new status code introduces new calls, which can become
inefficient and source of bugs.
This patch reorganizes the code to rely on a numeric status code internally
and to be hopefully more generic.
2012-04-05 09:58:27 +02:00
Cyril Bonté
cf8d9ae3cd MINOR: stats admin: allow unordered parameters in POST requests
Previously, the stats admin page required POST parameters to be provided
exactly in the same order as the HTML form.
This patch allows to handle those parameters in any orders.

Also, note that haproxy won't alter server states anymore if backend or server
names are ambiguous (duplicated names in the configuration) to prevent
unexpected results (the same should probably be applied to the stats socket).
2012-04-05 09:58:25 +02:00
Willy Tarreau
42f7d89156 BUG/MAJOR: possible crash when using capture headers on TCP frontends
Olufemi Omojola provided a config and a core showing a possible crash
when captures are configured on a TCP-mode frontend which branches to
an HTTP backend. The reason is that being in TCP mode, the frontend
does not allocate capture pools for the request, but the HTTP backend
tries to use them and dies on the NULL.

While such a config has long been unlikely to happen, it looks like
people using websocket tend to do this more often now.

Change the control to use the pointer instead of the number of captures
to know when to log.

This bug was reported in 1.4.20, so it must be backported there.
2012-03-24 08:35:36 +01:00
William Lallemand
bddd4fd93b MEDIUM: log: use log_format for mode tcplog
Merge http_sess_log() and tcp_sess_log() to sess_log() and move it to
log.c

A new field in logformat_type define if you can use a logformat
variable in TCP or HTTP mode.

doc: log-format in tcp mode

Note that due to the way log buffer allocation currently works, trying to
log an HTTP request without "option httplog" is still not possible. This
will change in the near future.
2012-03-12 15:47:13 +01:00
Willy Tarreau
869fc1edc2 BUG: http: disable TCP delayed ACKs when forwarding content-length data
Commits 5c6209 and 072930 were aimed at avoiding undesirable PUSH flags
when forwarding chunked data, but had the undesired effect of causing
data advertised by content-length to be affected by the delayed ACK too.
This can happen when the data to be forwarded are small enough to fit into
a single send() call, otherwise the BF_EXPECT_MORE flag would be removed.

Content-length data don't need the BF_EXPECT_MORE flag since the low-level
forwarder already knows it can safely rely on bf->to_forward to set the
appropriate TCP flags.

Note that the issue is only observed in requests at the moment, though the
later introduction of server-side keep-alive could trigger the issue on the
response path too.

Special thanks to Randy Shults for reporting this issue with a lot of
details helping to reproduce it.

The fix must be backported to 1.4.
2012-03-05 08:46:34 +01:00
Willy Tarreau
2d5cd479bc BUG: queue: fix dequeueing sequence on HTTP keep-alive sessions
When a request completes on a server and the server connection is closed
while the client connection stays open, the HTTP engine releases all server
connection slots and scans the queues to offer the connection slot to
another pending request.

An issue happens when the released connection allows other requests to be
dequeued : may_dequeue_tasks() relies on srv->served which is only decremented
by sess_change_server() which itself is only called after may_dequeue_tasks().
This results in no connection being woken up until another connection terminates
so that may_dequeue_tasks() is called again.

This fix is minimalist and only moves sess_change_server() earlier (which is
safe). It should be reworked and the code factored out so that the same occurrence
in session.c shares the same code.

This bug has been there since the introduction of option-http-server-close and
the fix must be backported to 1.4.
2012-03-01 23:49:20 +01:00
Willy Tarreau
431946e961 MEDIUM: increase chunk-size limit to 2GB-1
Since commit 115acb97, chunk size was limited to 256MB. There is no reason for
such a limit and the comment on the code suggests a missing zero. However,
increasing the limit past 2 GB causes trouble due to some 32-bit subtracts
in various computations becoming negative (eg: buffer_max_len). So let's limit
the chunk size to 2 GB - 1 max.
2012-02-27 09:51:52 +01:00
Willy Tarreau
53bf6af3f9 BUG: fix httplog trailing LF
commit a1cc3811 introduced an undesirable \0\n ending on HTTP log messages. This
is because of an extra character count passed to __send_log() which causes the LF
to be appended past the \0. Some syslog daemons thus log an extra empty line. The
fix is obvious. Fix the function comments to remind what they expect on their input.

This is past 1.5-dev7 regression so there's no backport needed.
2012-02-24 11:48:42 +01:00
William Lallemand
a1cc381151 MEDIUM: log: make http_sess_log use log_format
http_sess_log now use the logformat linked list to make the log
string, snprintf is not used for speed issue.

CLF mode also uses logformat.

NOTE: as of now, empty fields in CLF now are "" not "-" anymore.
2012-02-09 17:03:28 +01:00
William Lallemand
d9e9066e71 BUILD: fix declaration inside a scope block 2012-02-06 09:46:16 +01:00
Willy Tarreau
b05405a3a8 BUILD: fix build error on FreeBSD
Marcello Gorlani reported that commit 5e205524ad
(BUG: http: re-enable TCP quick-ack upon incomplete HTTP requests) broke build
on FreeBSD.

Moving the include lower fixes the issue. This must be backported to 1.4 too.
2012-01-23 15:35:52 +01:00
Willy Tarreau
422246eb26 MEDIUM: http: block non-ASCII characters in URIs by default
These ones are invalid and blocked unless "option accept-invalid-http-request"
is specified in the frontend. In any case, the faulty request is logged.

Note that some of the remaining invalid chars are still not checked against,
those are the invalid ones between 32 and 127 :

    34 ('"'), 60 ('<'), 62 ('>'), 92 ('\'), 94 ('^'),
    96 ('`'), 123 ('{'), 124 ('|'), 125 ('}')

Using a lookup table might be better at some point.
2012-01-07 23:55:20 +01:00
Willy Tarreau
2e9506d771 BUG: http: tighten the list of allowed characters in a URI
The HTTP request parser was considering that any non-LWS char was
par of the URI. Unfortunately, this allows control chars to be sent
in the URI, sometimes resulting in backend servers misbehaving, for
instance when they interprete \0 as an end of string and respond
with plain HTTP/0.9 without headers, that haproxy blocks as invalid
responses.

RFC3986 clearly states the list of allowed characters in a URI. Even
non-ASCII chars are not allowed. Unfortunately, after having run 10
years with these chars allowed, we can't block them right now without
an optional workaround. So the first step consists in only blocking
control chars. A later patch will allow non-ASCII only when an appropriate
option is enabled in the frontend.

Control chars are 0..31 and 127, with the exception of 9, 10 and 13
(\t, \n, \r).
2012-01-07 23:22:31 +01:00
Mark Lamourine
c2247f0b8d MEDIUM: http: add support for sending the server's name in the outgoing request
New option "http-send-name-header" specifies the name of a header which
will hold the server name in outgoing requests. This is the name of the
server the connection is really sent to, which means that upon redispatches,
the header's value is updated so that it always matches the server's name.
2012-01-05 15:17:31 +01:00
Willy Tarreau
e428fb7b4e MEDIUM: patterns: the hdr() pattern is now of type string
This pattern previously was limited to type IP. With the new header
extraction function, it becomes possible to extract strings, so that
the header can be returned as a string. This will not change anything
to existing configs, as string will automatically be converted to IP
when needed. However, new configs will be able to use IPv6 addresses
from headers in stick-tables, as well as stick on any non-IP header
(eg: host, user-agent, ...).
2011-12-30 17:33:27 +01:00
Willy Tarreau
294c473756 MEDIUM: http: replace get_ip_from_hdr2() with http_get_hdr()
The new function does not return IP addresses but header values instead,
so that the caller is free to make what it want of them. The conversion
is not quite clean yet, as the previous test which considered that address
0.0.0.0 meant "no address" is still used. A different IP parsing function
should be used to take this into account.
2011-12-30 17:33:26 +01:00
Willy Tarreau
664092ccc1 MEDIUM: acl: use temp_pattern to store any string-type information
Now strings and data blocks are stored in the temp_pattern's chunk
and matched against this one.

The rdp_cookie currently makes extensive use of acl_fetch_rdp_cookie()
and will be a good candidate for the initial rework so that ACLs use
the patterns framework and not the other way around.
2011-12-30 17:33:26 +01:00
Willy Tarreau
f4362b3e3b MEDIUM: acl: use temp_pattern to store any address-type information
IPv4 and IPv6 addresses are now stored into temp_pattern instead of
the dirty hack consisting into storing them into the consumer's target
address.

Some refactoring should now be possible since the methods used to fetch
source and destination addresses are similar between patterns and ACLs.
2011-12-30 17:33:26 +01:00
Willy Tarreau
a5e375646c MEDIUM: acl: use temp_pattern to store any integer-type information
All ACL fetches which return integer value now store the result into
the temporary pattern struct. All ACL matches which rely on integer
also get their value there.

Note: the pattern data types are not set right now.
2011-12-30 17:33:26 +01:00
Willy Tarreau
8e5e955c50 MEDIUM: acl: use temp_pattern to store fetched information in the "method" match
This match was using both the int and ptr part of the acl_test struct. Let's
change this to be able to store it into a chunk with a special encoding.
2011-12-30 17:33:25 +01:00
Willy Tarreau
5e205524ad BUG: http: re-enable TCP quick-ack upon incomplete HTTP requests
By default we disable TCP quick-acking on HTTP requests so that we
avoid sending a pure ACK immediately followed by the HTTP response.
However, if the client sends an incomplete request in a short packet,
its TCP stack might wait for this packet to be ACKed before sending
the rest of the request, delaying incoming requests by up to 40-200ms.

We can detect this undesirable situation when parsing the request :
  - if an incomplete request is received
  - if a full request is received and uses chunked encoding or advertises
    a content-length larger than the data available in the buffer

In these situations, we re-enable TCP quick-ack if we had previously
disabled it.
2011-12-17 16:45:29 +01:00
William Lallemand
0f99e34978 MEDIUM: log: Use linked lists for loggers
This patch settles the 2 loggers limitation.
Loggers are now stored in linked lists.

Using "global log", the global loggers list content is added at the end
of the current proxy list. Each "log" entries are added at the end of
the proxy list.

"no log" flush a logger list.
2011-10-31 14:09:19 +01:00
Sagi Bashari
1611e2d4a1 BUG/MINOR: fix options forwardfor if-none when an alternative header name is specified 2011-10-09 08:10:30 +02:00
Willy Tarreau
6471afb43d MINOR: remove the client/server side distinction in SI addresses
Stream interfaces used to distinguish between client and server addresses
because they were previously of different types (sockaddr_storage for the
client, sockaddr_in for the server). This is not the case anymore, and this
distinction is confusing at best and has caused a number of regressions to
be introduced in the process of converting everything to full-ipv6. We can
now remove this and have a much cleaner code.
2011-09-23 10:54:59 +02:00
Willy Tarreau
0e69854ed4 MINOR: acl: add new matches for header/path/url length
This patch introduces hdr_len, path_len and url_len for matching these
respective parts lengths against integers. This can be used to detect
abuse or empty headers.
2011-09-16 08:32:32 +02:00
Willy Tarreau
275600b6c7 BUG/MEDIUM: don't trim last spaces from headers consisting only of spaces
Commit 588bd4 fixed header parsing so that trailing spaces were not part
of the returned string. Unfortunately, if a header only had spaces, the
last spaces were trimmed past the beginning of the value, causing a negative
length to be returned.

A quick code review shows that there should be no impact since the only
places where the vlen is used are either compared to a specific value or
with explicit contents (eg: digits).

This must be backported to 1.4.
2011-09-16 08:11:26 +02:00
Willy Tarreau
eabea0763b [MINOR] stats: report the number of requests intercepted by the frontend
These requests are mainly monitor requests, as well as stats requests when
the stats are processed by the frontend. Having this counter helps explain
the difference in number of sessions that is sometimes observed between a
frontend and a backend.
2011-09-10 23:32:41 +02:00
Willy Tarreau
ad14f753ea [MINOR] http: take a capture of bad content-lengths.
Sometimes a bad content-length header is encountered and this causes
an abort. It's hard to debug without a trace, so let's take a capture
of the contents when this happens.
2011-09-05 00:54:57 +02:00
Willy Tarreau
3b8c08a174 [MINOR] http: take a capture of truncated responses
If a server starts to respond but stops before the body, then we
capture the truncated response. We don't do this on the request
because it would happen too often upon stupid attacks.
2011-09-05 00:54:56 +02:00
Willy Tarreau
fec4d89b24 [MINOR] http: take a capture of too large requests and responses
It's hard to prove a request or response is too large if there is no
capture, so let's take a snapshot of those too.
2011-09-05 00:54:56 +02:00
Willy Tarreau
588bd4f813 [BUG] http: trailing white spaces must also be trimmed after headers
Trailing spaces after headers were not trimmed, only the leading ones
were. An issue was detected today with a content-length value which
was padded with spaces and which was rejected. Recent updates to the
http-bis draft made it a lot more clear that such spaces must be ignored,
so this is what this patch does.

It should be backported to 1.4.
2011-09-05 00:54:56 +02:00
Willy Tarreau
631f01c2f1 [MINOR] make use of addr_to_str() and get_host_port() to replace many inet_ntop()
Many inet_ntop calls were partially right, which was hard to detect given
the complex combinations. Some of them were relying on the listener's proto
instead of the address itself, which could have been different when dealing
with an accept-proxy connection.

The new addr_to_str() function does the dirty job and returns the family, which
makes it particularly suited to calls from switch/case statements. A large number
of if/else statements were removed and the stats output could even be cleaned up
in the case of session dump.

As a side effect of doing this, the resulting code is smaller by almost 1kB.
All changed parts have been tested and provided expected output.
2011-09-05 00:54:36 +02:00
Willy Tarreau
86ad42c5b7 [MINOR] make use of set_host_port() and get_host_port() to get rid of family mismatches
This also simplifies the code and makes it more auditable.
2011-09-05 00:54:35 +02:00
Willy Tarreau
87cf51406c [MEDIUM] http: make x-forwarded-for addition conditional
If "option forwardfor" has the "if-none" argument, then the header is
only added when the request did not already have one. This option has
security implications, and should not be set blindly.
2011-08-19 22:57:24 +02:00
Willy Tarreau
b3eb221e78 [MEDIUM] http: add support for 'cookie' and 'set-cookie' patterns
This is used to perform cookie-based stickiness with table replication
between multiple masters and across restarts. This partially overrides
some of the appsession capabilities.
2011-07-01 16:16:17 +02:00
Simon Horman
af51495397 [MINOR] Add active connection list to server
The motivation for this is to allow iteration of all the connections
of a server without the expense of iterating over the global list
of connections.

The first use of this will be to implement an option to close connections
associated with a server when is is marked as being down or in maintenance
mode.
2011-06-21 22:00:12 +02:00
Simon Horman
70735c98f7 [CLEANUP] Remove assigned but unused variables
gcc (Debian 4.6.0-2) 4.6.1 20110329 (prerelease)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

...
src/proto_http.c:3029:14: warning: variable ‘del_cl’ set but not used [-Wunused-but-set-variable]
In file included from ebtree/eb64tree.c:23:0:
ebtree/eb64tree.h: In function ‘__eb64_lookup’:
ebtree/eb64tree.h:128:6: warning: variable ‘node_bit’ set but not used [-Wunused-but-set-variable]
ebtree/eb64tree.h: In function ‘__eb64i_lookup’:
ebtree/eb64tree.h:180:6: warning: variable ‘node_bit’ set but not used [-Wunused-but-set-variable]
In file included from ebtree/ebpttree.h:26:0,
                 from ebtree/ebimtree.c:23:
ebtree/eb64tree.h: In function ‘__eb64_lookup’:
ebtree/eb64tree.h:128:6: warning: variable ‘node_bit’ set but not used [-Wunused-but-set-variable]
ebtree/eb64tree.h: In function ‘__eb64i_lookup’:
ebtree/eb64tree.h:180:6: warning: variable ‘node_bit’ set but not used [-Wunused-but-set-variable]
In file included from ebtree/ebpttree.h:26:0,
                 from ebtree/ebistree.h:25,
                 from ebtree/ebistree.c:23:
ebtree/eb64tree.h: In function ‘__eb64_lookup’:
ebtree/eb64tree.h:128:6: warning: variable ‘node_bit’ set but not used [-Wunused-but-set-variable]
ebtree/eb64tree.h: In function ‘__eb64i_lookup’:
ebtree/eb64tree.h:180:6: warning: variable ‘node_bit’ set but not used [-Wunused-but-set-variable]
2011-06-18 20:21:33 +02:00
Willy Tarreau
bf9c2fcd93 [BUG] stats: support url-encoded forms
Bashkim Kasa reported that the stats admin page did not work when colons
were used in server or backend names. This was caused by url-encoding
resulting in ':' being sent as '%3A'. Now we systematically decode the
field names and values to fix this issue.
2011-05-31 22:44:28 +02:00
Willy Tarreau
0729303fb0 [OPTIM] http: optimize chunking again in non-interactive mode
Now that we support the http-no-delay mode, we can optimize HTTP
chunking again by always waiting for more data to come until the
last chunk is met.

This patch may or may not be backported to 1.4, it's not a big deal,
it will mainly help for chunks which are aligned with the buffer size.
2011-05-30 18:42:41 +02:00
Willy Tarreau
96e312139a [MEDIUM] http: add support for "http-no-delay"
There are some very rare server-to-server applications that abuse the HTTP
protocol and expect the payload phase to be highly interactive, with many
interleaved data chunks in both directions within a single request. This is
absolutely not supported by the HTTP specification and will not work across
most proxies or servers. When such applications attempt to do this through
haproxy, it works but they will experience high delays due to the network
optimizations which favor performance by instructing the system to wait for
enough data to be available in order to only send full packets. Typical
delays are around 200 ms per round trip. Note that this only happens with
abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
affected.

When "option http-no-delay" is present in either the frontend or the backend
used by a connection, all such optimizations will be disabled in order to
make the exchanges as fast as possible. Of course this offers no guarantee on
the functionality, as it may break at any other place. But if it works via
HAProxy, it will work as fast as possible. This option should never be used
by default, and should never be used at all unless such a buggy application
is discovered. The impact of using this option is an increase of bandwidth
usage and CPU usage, which may significantly lower performance in high
latency environments.

This change should be backported to 1.4 since the first report of such a
misuse was in 1.4. Next patch will also be needed.
2011-05-30 18:42:41 +02:00
Willy Tarreau
5c62092ca1 [MINOR] http: partially revert the chunking optimization for now
Commit 57f5c1 used to provide a nice improvement on chunked encoding since
it ensured that we did not set a PUSH flag for every chunk or buffer data
part of a chunked transfer.

Some applications appear to erroneously abuse HTTP chunking in order to
get interactive exchanges between a user agent and an origin server with
very small chunks. While it happens to work through haproxy, it's terribly
slow due to the latency added after passing each chunk to the system, who
could wait up to 200ms before pushing them onto the wire.

So we need an interactive mode for such usages. In the mean time, step back
on the optim, but not completely, so that we still keep the flag as long as
we know we're not finished with the current chunk.

This change should be backported to 1.4 too as the issue was discovered
with it.
2011-05-11 20:17:42 +02:00
Willy Tarreau
ae94d4df8f [MINOR] http: make the "HTTP 200" status code configurable.
This status code is used in response to requests matching "monitor-uri".
Some users need to adjust it to fit their needs (eg: make some strings
appear there). As it's already defined as a chunked string and used
exactly like other status codes, it makes sense to make it configurable
with the usual "errorfile", "errorloc", ...
2011-05-11 16:31:43 +02:00
Willy Tarreau
027a85bb03 [MINOR] http: don't report the "haproxy" word on the monitoring response
Some people like to make the monitoring URL testable from unsafe locations.
Reporting haproxy's existence there can sometimes be problematic. This patch
should not be backported to 1.4 because it is possible, eventhough unlikely,
that some scripts rely on this word to appear there.
2011-05-11 16:31:43 +02:00
Willy Tarreau
1fc1f45618 [CRITICAL] fix risk of crash when dealing with space in response cookies
When doing fix 24581bae02 to correctly handle
response cookies, an unfortunate typo was inserted in the less likely code
path, resulting in a risk of crash when cookie-based persistence is enabled
and the server emits a cookie with several spaces around the equal sign.

This bug was noticed during a code backport. Its effects were never reported
because this situation is very unlikely to appear, but it can be provoked on
purpose by the server.

This patch must be backported to 1.4 versions which contain the fix above
(anything > 1.4.8), and to similar 1.3 versions > 1.3.25. 1.5-dev versions
after 1.5-dev2 are affected too.
2011-04-08 00:50:36 +02:00
Willy Tarreau
d8ee85a0a3 [BUG] http: fix content-length handling on 32-bit platforms
Despite much care around handling the content-length as a 64-bit integer,
forwarding was broken on 32-bit platforms due to the 32-bit nature of
the ->to_forward member of the "buffer" struct. The issue is that this
member is declared as a long, so while it works OK on 64-bit platforms,
32-bit truncate the content-length to the lower 32-bits.

One solution could consist in turning to_forward to a long long, but it
is used a lot in the critical path, so it's not acceptable to perform
all buffer size computations on 64-bit there.

The fix consists in changing the to_forward member to a strict 32-bit
integer and ensure in buffer_forward() that only the amount of bytes
that can fit into it is considered. Callers of buffer_forward() are
responsible for checking that their data were taken into account. We
arbitrarily ensure we never consider more than 2G at once.

That's the way it was intended to work on 32-bit platforms except that
it did not.

This issue was tracked down hard at Exosec with Bertrand Jacquin,
Thierry Fournier and Julien Thomas. It remained undetected for a long
time because files larger than 4G are almost always transferred in
chunked-encoded format, and most platforms dealing with huge contents
these days run on 64-bit.

The bug affects all 1.5 and 1.4 versions, and must be backported.
2011-03-28 16:25:16 +02:00
Willy Tarreau
26f0f17200 [BUG] http: fix possible incorrect forwarded wrapping chunk size (take 2)
Fix acd20f80 was incomplete, the computed "bytes" value was not used.

This fix must be backported to 1.4.
2011-03-27 20:00:03 +02:00
Willy Tarreau
7b7a8e9d83 [BUG] log: retrieve the target from the session, not the SI
Since we now have the copy of the target in the session, use it instead
of relying on the SI for it. The SI drops the target upon unregister()
so applets such as stats were logged as "NOSRV".
2011-03-27 19:53:06 +02:00
Willy Tarreau
0b3a411543 [BUG] session: conn_retries was not always initialized
Johannes Smith reported some wrong retries count in logs associated with bad
requests. The cause was that the conn_retries field in the stream interface
was only initialized when attempting to connect, but is used when logging,
possibly with an uninitialized value holding last connection's conn_retries.
This could have been avoided by making use of a stream interface initializer.

This bug is 1.5-specific.
2011-03-27 19:16:56 +02:00
Willy Tarreau
6da0f6d6dd [BUG] http: stats were not incremented on http-request deny
A counter increase was missing here.
This should be backported to 1.4 with care, as the code has changed a bit.
2011-03-13 22:00:24 +01:00
Willy Tarreau
ff011f26e9 [REORG] http: move the http-request rules to proto_http
And also rename "req_acl_rule" "http_req_rule". At the beginning that
was a bit confusing to me, especially the "req_acl" list which in fact
holds what we call rules. After some digging, it appeared that some
part of the code is 100% HTTP and not just related to authentication
anymore, so let's move that part to HTTP and keep the auth-only code
in auth.c.
2011-03-13 22:00:24 +01:00
Willy Tarreau
f68a15a951 [MEDIUM] http: always evaluate http-request rules before stats http-request
Right now, http-request rules are not evaluated if the URL matches the
stats request. This is quite unexpected. For instance, in the config
below, an abuser present in the abusers list will not be prevented access
to the stats.

   listen pub
        bind :8181
	acl abuser src -f abusers.lst
        http-request deny if abuser
        stats uri /stats

It is not a big deal but it's not documented as such either. For 1.5, let's
have both lists be evaluated in turn, until one blocks. For 1.4 we'll simply
update the doc to indicate that.

Also instead of duplicating the code, the patch factors out the list walking
code. The HTTP auth has been moved slightly earlier, because it was set after
the header addition code, but we don't need to add headers to a request we're
dropping.
2011-03-13 22:00:24 +01:00
Willy Tarreau
7d0aaf39d1 [MEDIUM] stats: split frontend and backend stats
It's very annoying that frontend and backend stats are merged because we
don't know what we're observing. For instance, if a "listen" instance
makes use of a distinct backend, it's impossible to know what the bytes_out
means.

Some points take care of not updating counters twice if the backend points
to the frontend, indicating a "listen" instance. The thing becomes more
complex when we try to add support for server side keep-alive, because we
have to maintain a pointer to the backend used for last request, and to
update its stats. But we can't perform such comparisons anymore because
the counters will not match anymore.

So in order to get rid of this situation, let's have both frontend AND
backend stats in the "struct proxy". We simply update the relevant ones
during activity. Some of them are only accounted for in the backend,
while others are just for frontend. Maybe we can improve a bit on that
later, but the essential part is that those counters now reflect what
they really mean.
2011-03-13 22:00:23 +01:00
David du Colombier
6f5ccb1589 [MEDIUM] add internal support for IPv6 server addresses
This patch turns internal server addresses to sockaddr_storage to
store IPv6 addresses, and makes the connect() function use it. This
code already works but some caveats with getaddrinfo/gethostbyname
still need to be sorted out while the changes had to be merged at
this stage of internal architecture changes. So for now the config
parser will not emit an IPv6 address yet so that user experience
remains unchanged.

This change should have absolutely zero user-visible effect, otherwise
it's a bug introduced during the merge, that should be reported ASAP.
2011-03-13 22:00:12 +01:00
Willy Tarreau
827aee913f [MAJOR] session: remove the ->srv pointer from struct session
This one has been removed and is now totally superseded by ->target.
To get the server, one must use target_srv(&s->target) instead of
s->srv now.

The function ensures that non-server targets still return NULL.
2011-03-10 23:32:17 +01:00
Willy Tarreau
9e000c6ec8 [CLEANUP] stream_interface: use inline functions to manipulate targets
The connection target involves a type and a union of pointers, let's
make the code cleaner using simple wrappers.
2011-03-10 23:32:17 +01:00
Willy Tarreau
3d80d911aa [MEDIUM] session: remove s->prev_srv which is not needed anymore
s->prev_srv is used by assign_server() only, but all code paths leading
to it now take s->prev_srv from the existing s->srv. So assign_server()
can do that copy into its own stack.

If at one point a different srv is needed, we still have a copy of the
last server on which we failed a connection attempt in s->target.
2011-03-10 23:32:16 +01:00
Willy Tarreau
664beb8610 [MINOR] session: add a pointer to the new target into the session
When dealing with HTTP keep-alive, we'll have to know if we can reuse
an existing connection. For that, we'll have to check if the current
connection was made on the exact same target (referenced in the stream
interface).

Thus, we need to first assign the next target to the session, then
copy it to the stream interface upon connect(). Later we'll check for
equivalence between those two operations.
2011-03-10 23:32:16 +01:00
Willy Tarreau
295a837726 [REORG] session: move the data_ctx struct to the stream interface's applet
This is in fact where those parts belong to. The old data_state was replaced
by applet.state and is now initialized when the applet is registered. It's
worth noting that the applet does not need to know the session nor the
buffer anymore since everything is brought by the stream interface.

It is possible that having a separate applet struct would simplify the
code but that's not a big deal.
2011-03-10 23:32:16 +01:00
Willy Tarreau
75581aebb0 [CLEANUP] session: remove data_source from struct session
This one was only used for logging purposes, it's not needed
anymore.
2011-03-10 23:32:15 +01:00
Willy Tarreau
71904a4ee8 [MEDIUM] log: take the logged server name from the stream interface
With HTTP keep-alive, logging the right server name will be quite
complex because the assigned server will possibly change before we log.
Also, when we want to log accesses to an applet, it's not easy because
the applet becomes NULL again before logging.

The logged server's name is now taken from the target stored in the
stream interface. That way we can log an applet, a server name, or we
could even log a proxy or anything else if we wanted to. Ideally the
session should contain a desired target which is the one which should
be logged.
2011-03-10 23:32:15 +01:00
Willy Tarreau
957c0a5845 [REORG] session: move client and server address to the stream interface
This will be needed very soon for the keep-alive.
2011-03-10 23:32:14 +01:00
Willy Tarreau
bc4af0573c [REORG] stream_interface: move the st0, st1 and private members to the applet
Those fields are only used by the applets, so let's move them to the
struct.
2011-03-10 23:32:14 +01:00
Willy Tarreau
b24281b0ff [MINOR] stream_interface: make use of an applet descriptor for IO handlers
I/O handlers are still delicate to manipulate. They have no type, they're
just raw functions which have no knowledge of themselves. Let's have them
declared as applets once for all. That way we can have multiple applets
share the same handler functions and we can store their names there. When
we later need to add more parameters (eg: usage stats), we'll be able to
do so in the applets themselves.

The CLI functions has been prefixed with "cli" instead of "stats" as it's
clearly what is going on there.

The applet descriptor in the stream interface should get all the applet
specific data (st0, ...) but this will be done in the next patch so that
we don't pollute this one too much.
2011-03-10 23:32:14 +01:00
Cyril Bonté
1e2a170cf8 [BUG] stats: admin web interface must check the proxy state
Similar to the stats socket bug, we must check that the proxy is not disabled
before trying to enable/disable a server.

Even if a disabled proxy is not displayed, someone can inject a faulty proxy
name in the POST parameters. So, we must ensure that no disabled proxy can be
used.
2011-03-04 10:01:40 +01:00
Willy Tarreau
61a21a34da [BUG] http: balance url_param did not work with first parameters on POST
Bryan Talbot reported that POST requests with a query string were not
correctly processed if the hash parameter was the first one, because
the delimiter that was looked for to trigger the parsing was '&' instead
of '?'.

Also, while checking the code, it became apparent that it was enough for
a query string to be present in the request for POST parameters to be
ignored, even if the url_param was in the body and not in the URL.

The code has then been fixed like this :
   1) look for URL param. If found, return it.
   2) if no URL param was found and method is POST, then look it up into
      the body

The code now seems to pass all request combinations.

This patch must be backported to 1.4 since 1.4 is equally broken right now.
2011-03-01 20:42:20 +01:00
Willy Tarreau
124d99181c [BUG] http: fix computation of message body length after forwarding has started
Till now, the forwarding code was making use of the hdr_content_len member
to hold the size of the last chunk parsed. As such, it was reset after being
scheduled for forwarding. The issue is that this entry was reset before the
data could be viewed by backend.c in order to parse a POST body, so the
"balance url_param check_post" did not work anymore.

In order to fix this, we need two things :
  - the chunk size (reset upon every forward)
  - the total body size (not reset)

hdr_content_len was thus replaced by the former (hence the size of the patch)
as it makes more sense to have it stored that way than the way around.

This patch should be backported to 1.4 with care, considering that it affects
the forwarding code.
2011-03-01 20:30:48 +01:00
Willy Tarreau
acd20f80c1 [BUG] http: fix possible incorrect forwarded wrapping chunk size
It seems like if a response message is chunked and the chunk size wraps
at the end of the buffer and the crlf sequence is incomplete, then we
can forward a wrong chunk size due to incorrect handling of the wrapped
size. It seems extremely unlikely to occur on real traffic (no reason to
have half of the CRLF after a chunk) but nothing prevents it from being
possible.

This fix must be backported to 1.4.
2011-03-01 20:04:36 +01:00
Willy Tarreau
910ef306bc [BUG] http: use correct ACL pointer when evaluating authentication
req_acl was used instead of req_acl_final. As a matter of luck, both
happen to be the same at this point, but this is not granted in the
future.

This fix should be backported to 1.4.
2011-02-13 12:18:22 +01:00
Cyril Bont
23b39d9859 [MINOR] stats: add support for several packets in stats admin
Some browsers send POST requests in several packets, which was not supported
by the "stats admin" function.

This patch allows to wait for more data when they are not fully received
(we are still limited to a certain size defined by the buffer size minus its
reserved space).
It also adds support for the "Expect: 100-Continue" header.
2011-02-12 13:10:18 +01:00
Willy Tarreau
5c4784f4b8 [BUG] http: update the header list's tail when removing the last header
Stefan Behte reported a strange case where depending on the position of
the Connection header in the header list, some headers added after it
were or were not usable in "balance hdr()". The reason is that when the
last header is removed, the list's tail was not updated, so any header
added after that one was not visible from the list.

This fix must be backported to 1.4 and possibly 1.3.
2011-02-12 13:07:35 +01:00
Willy Tarreau
0013433b09 [MINOR] http: improve url_param pattern extraction to ignore empty values
It's better to avoid sticking on empty parameter values, as this almost
always indicates a missing parameter. Otherwise it's easy to enter a
situation where all new visitors stick to the same server.
2011-01-04 14:57:34 +01:00
David Cournapeau
16023eef0b [MINOR] http: add pattern extraction method to stick on query string parameter
This is an updated version of my patch for url parameter extraction on
stick table. It adds "url_param(name)" as a possible stick method.
2011-01-03 13:26:02 +01:00
Cyril Bonté
9ea2b9ac75 [BUG] http: fix http-pretend-keepalive and httpclose/tunnel mode
Since haproxy 1.4.9, combining option httpclose and option
http-pretend-keepalive can leave the connections opened until the backend
keep-alive timeout is reached, providing bad performances.
The same can occur when the proxy is in tunnel mode.

This patch ensures that the server side connection is closed after the
response and ignore http-pretend-keepalive in tunnel mode.
2010-12-29 15:24:48 +01:00
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 4fe4190278 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
Willy Tarreau
b337b532de [MEDIUM] acl: add tree-based lookups of networks
Networks patterns loaded from files for longest match ACL testing
will now be arranged into a prefix tree. This is possible thanks to
the new prefix features in ebtree v6.0. Longest match testing is
slightly slower than exact data maching. However, the measured impact
of running at 42000 requests per second and testing whether the IP
address found in a header belongs to a list of 52000 networks or
not is 3% CPU (increase from 66% to 69%). This is low enough to
permit true geolocation based on huge tables.
2010-05-13 21:37:50 +02:00
Willy Tarreau
c4262961f8 [MEDIUM] acl: add tree-based lookups of exact strings
Now if some ACL patterns are loaded from a file and the operation is
an exact string match, the data will be arranged in a tree, yielding
a significant performance boost on large data sets. Note that this
only works when case is sensitive.

A new dedicated function, acl_lookup_str(), has been created for this
matching. It is called for every possible input data to test and it
looks the tree up for the data. Since the keywords are loosely typed,
we would have had to add a new columns to all keywords to adjust the
function depending on the type. Instead, we just compare on the match
function. We call acl_lookup_str() when we could use acl_match_str().
The tree lookup is performed first, then the remaining patterns are
attempted if the tree returned nothing.

A quick test shows that when matching a header against a list of 52000
network names, haproxy uses 68% of one core on a core2-duo 3.2 GHz at
42000 requests per second, versus 66% without any rule, which means
only a 2% CPU increase for 52000 rules. Doing the same test without
the tree leads to 100% CPU at 6900 requests/s. Also it was possible
to run the same test at full speed with about 50 sets of 52000 rules
without any measurable performance drop.
2010-05-13 21:37:45 +02:00
Willy Tarreau
c3bfeebdb4 [MINOR] fix possible crash in debug mode with invalid responses
When trying to display an invalid request or response we received,
we must at least check that we have identified something looking
like a start of message, otherwise we can dereference a NULL pointer.
2010-04-29 07:09:25 +02:00
Cyril Bont
47fdd8e993 [MINOR] add the "ignore-persist" option to conditionally ignore persistence
This is used to disable persistence depending on some conditions (for
example using an ACL matching static files or a specific User-Agent).
You can see it as a complement to "force-persist".

In the configuration file, the force-persist/ignore-persist declaration
order define the rules priority.

Used with the "appsesion" keyword, it can also help reducing memory usage,
as the session won't be hashed the persistence is ignored.
2010-04-25 22:37:14 +02:00
Cyril Bont
17530c34e4 [BUG] appsession should match the whole cookie name
I met a strange behaviour with appsession.

I firstly thought this was a regression due to one of my previous patch
but after testing with a 1.3.15.12 version, I also could reproduce it.

To illustrate, the configuration contains :
  appsession PHPSESSID len 32 timeout 1h

Then I call a short PHP script containing :
  setcookie("P", "should not match")

When calling this script thru haproxy, the cookie "P" matches the appsession rule :
Dumping hashtable 0x11f05c8
        table[1572]:    should+not+match

Shouldn't it be ignored ?
If you confirm, I'll send a patch for 1.3 and 1.4 branches to check that the
cookie length is equal to the appsession name length.

This is due to the comparison length, where the cookie length is took into
account instead of the appsession name length. Using the appsession name
length would allow ASPSESSIONIDXXX (+ check that memcmp won't go after the
buffer size).

Also, while testing, I noticed that HEAD requests where not available for
URIs containing the appsession parameter. 1.4.3 patch fixes an horrible
segfault I missed in a previous patch when appsession is not in the
configuration and HAProxy is compiled with DEBUG_HASH.
2010-04-07 21:56:10 +02:00
Willy Tarreau
8a8e1d99cb [MINOR] http: make it possible to pretend keep-alive when doing close
Some servers do not completely conform with RFC2616 requirements for
keep-alive when they receive a request with "Connection: close". More
specifically, they don't bother using chunked encoding, so the client
never knows whether the response is complete or not. One immediately
visible effect is that haproxy cannot maintain client connections alive.
The second issue is that truncated responses may be cached on clients
in case of network error or timeout.

scar Fras Barranco reported this issue on Tomcat 6.0.20, and
Patrik Nilsson with Jetty 6.1.21.

Cyril Bont proposed this smart idea of pretending we run keep-alive
with the server and closing it at the last moment as is already done
with option forceclose. The advantage is that we only change one
emitted header but not the overall behaviour.

Since some servers such as nginx are able to close the connection
very quickly and save network packets when they're aware of the
close negociation in advance, we don't enable this behaviour by
default.

"option http-pretend-keepalive" will have to be used for that, in
conjunction with "option http-server-close".
2010-04-05 16:26:34 +02:00
Willy Tarreau
bce7088275 [MEDIUM] add ability to connect to a server from an IP found in a header
Using get_ip_from_hdr2() we can look for occurrence #X or #-X and
extract the IP it contains. This is typically designed for use with
the X-Forwarded-For header.

Using "usesrc hdr_ip(name,occ)", it becomes possible to use the IP address
found in <name>, and possibly specify occurrence number <occ>, as the
source to connect to a server. This is possible both in a server and in
a backend's source statement. This is typically used to use the source
IP previously set by a upstream proxy.
2010-03-30 10:39:43 +02:00
Willy Tarreau
bf3f1de5b5 [BUG] http: fix truncated responses on chunk encoding when size divides buffer size
Bernhard Krieger reported truncated HTTP responses in presence of some
specific chunk-encoded data, and kindly offered complete traces of the
issue which made it easy to reproduce it.

Those traces showed that the chunks were of exactly 8192 bytes, chunk
size and CRLF included, which was exactly half the size of the buffer.
In this situation, the function http_chunk_skip_crlf() could erroneously
try to parse a CRLF after the chunk believing there were more data
pending, because the number of bytes present in the buffer was considered
instead of the number of remaining bytes to be parsed.
2010-03-17 15:54:24 +01:00
Willy Tarreau
3965040898 [MINOR] http: don't mark a server as failed when it returns 501/505
Those two codes can be triggered on demand by client requests.
We must not fail a server on them.

Ideally we should ignore a certain amount of status codes which do
not indicate life nor death.
2010-03-15 19:44:39 +01:00
Cyril Bont
7f2c53938c [BUG] clf logs segfault when capturing a non existant header
Hi Willy,

Please find a small patch to prevent haproxy segfaulting when logging captured headers in CLF format.

Example config to reproduce the bug :
listen test :10080
	log 127.0.0.1 local7 debug err
	mode	http
	option	httplog clf
	capture request header NonExistantHeader len 16

--
Cyril Bont
2010-03-14 20:02:10 +01:00
Willy Tarreau
6464841769 [BUG] http: don't wait for response data to leave buffer is client has left
In case of pipelined requests, if the client aborts before reading response
N-1, haproxy waits forever for the data to leave the buffer before parsing
the next response.
2010-03-05 10:57:48 +01:00
Willy Tarreau
3e1b6d1ed0 [STATS] frontend requests were not accounted for failed requests
But failed requests were accounted for, resulting in more failures
than requests.
2010-03-04 23:02:38 +01:00
Willy Tarreau
ae52678444 [STATS] count transfer aborts caused by client and by server
Often we need to understand why some transfers were aborted or what
constitutes server response errors. With those two counters, it is
now possible to detect an unexpected transfer abort during a data
phase (eg: too short HTTP response), and to know what part of the
server response errors may in fact be assigned to aborted transfers.
2010-03-04 20:34:23 +01:00
Willy Tarreau
40dba09343 [BUG] logs: don't report "proxy request" when server closes early
A copy-paste typo and a missing check were causing the logs to
report "PR" instead of "SD" when a server closes before sending
full data. Also, the log would erroneously report 502 while in
fact the correct response will already have been transmitted.
2010-03-04 18:45:47 +01:00
Willy Tarreau
8096de9a99 [MEDIUM] http: revert to use a swap buffer for realignment
The bounce realign function was algorithmically good but as expected
it was not cache-friendly. Using it with large requests caused so many
cache thrashing that the function itself could drain 70% of the total
CPU time for only 0.5% of the calls !

Revert back to a standard memcpy() using a specially allocated swap
buffer. We're now back to 2M req/s on pipelined requests.
2010-02-26 11:12:27 +01:00
Willy Tarreau
2465779459 [STATS] separate frontend and backend HTTP stats
It is wrong to merge FE and BE stats for a proxy because when we consult a
BE's stats, it reflects the FE's stats eventhough the BE has received no
traffic. The most common example happens with listen instances, where the
backend gets credited for all the trafic even when a use_backend rule makes
use of another backend.
2010-02-26 10:30:28 +01:00
Willy Tarreau
d9b587f260 [STATS] report HTTP requests (total and rate) in frontends
Now that we support keep-alive, it's important to report a separate
counter for requests. Right now it just appears in the CSV output.
2010-02-26 10:05:55 +01:00
Willy Tarreau
b97f199d4b [MEDIUM] http: don't use trash to realign large buffers
The trash buffer may now be smaller than a buffer because we can tune
it at run time. This causes a risk when we're trying to use it as a
temporary buffer to realign unaligned requests, because we may have to
put up to a full buffer into it.

Instead of doing a double copy, we're now relying on an open-coded
bouncing copy algorithm. The principle is that we move one byte at
a time to its final place, and if that place also holds a byte, then
we move it too, and so on. We finish when we've moved all the buffer.
It limits the number of memory accesses, but since it proceeds one
byte at a time and with random walk, it's not cache friendly and
should be slower than a double copy. However, it's only used in
extreme situations and the difference will not be noticeable.

It has been extensively tested and works reliably.
2010-02-25 23:54:31 +01:00
Willy Tarreau
0b89fbb076 [BUG] fix error response in case of server error
The fix below was incomplete :
    commit d5fd51c75b

    [BUG] http_server_error() must not purge a previous pending response

    This can cause parts of responses to be truncated in case of
    pipelined requests if the second request generates an error
    before the first request is completely flushed.

Pending response data being rejected was still sent, causing inappropriate
error responses in case of error while parsing a response header. We must
purge pending data from the response buffer that were not scheduled to be
sent (l - send_max).
2010-02-02 10:04:19 +01:00
Willy Tarreau
dc008c57a4 [MEDIUM] http: stricter processing of the CONNECT method
Now we establish the tunnel only once the status 200 reponse is
received. That way we can still support an authentication request
in response to a CONNECT, then a client's authentication response.
2010-02-01 16:20:08 +01:00
Willy Tarreau
5843d1a894 [MEDIUM] http: switch to tunnel mode after status 101 responses
A 101 response is accompanied with an Upgrade header indicating
a new protocol that is spoken on the connection after the exchange
completes. At least we should switch to tunnel mode after such a
response.
2010-02-01 15:13:32 +01:00
Krzysztof Olędzki
711ad9eb27 [MINOR] http-auth: last fix was wrong
I'm not sure if the fix is correct:

- if (req_acl->cond)
-         ret = acl_exec_cond(req_acl->cond, px, s, txn, ACL_DIR_REQ);
+ if (!req_acl->cond)
+         continue;

Doesn't it ignore rules with no condition attached? I think that the
proper solution would be the following.
2010-02-01 12:54:32 +01:00
Willy Tarreau
5142594dea [MINOR] http-auth: make the 'unless' keyword work as expected
One check was missing for the 'polarity' of the test. Now 'unless'
works. BTW, 'unless' provides a nice way to perform one-line auth :

    acl valid-user http_auth(user-list)
    http-request auth unless valid-user
2010-02-01 10:40:19 +01:00
Willy Tarreau
844a7e76d2 [MEDIUM] http: add support for proxy authentication
We're already able to know if a request is a proxy request or a
normal one, and we have an option "http-use-proxy-header" which states
that proxy headers must be checked. So let's switch to use the proxy
authentication headers and responses when this option is set and we're
facing a proxy request. That allows haproxy to enforce auth in front
of a proxy.
2010-01-31 21:46:18 +01:00
Krzysztof Piotr Oledzki
8c8bd4593c [MAJOR] use the new auth framework for http stats
Support the new syntax (http-request allow/deny/auth) in
http stats.

Now it is possible to use the same syntax is the same like in
the frontend/backend http-request access control:
 acl src_nagios src 192.168.66.66
 acl stats_auth_ok http_auth(L1)

 stats http-request allow if src_nagios
 stats http-request allow if stats_auth_ok
 stats http-request auth realm LB

The old syntax is still supported, but now it is emulated
via private acls and an aditional userlist.
2010-01-31 19:14:09 +01:00
Krzysztof Piotr Oledzki
f9423ae43a [MINOR] acl: add http_auth and http_auth_group
Add two acls to match http auth data:
 acl <name> http_auth(userlist)
 acl <name> http_auth_hroup(userlist) group1 group2 (...)
2010-01-31 19:14:09 +01:00
Krzysztof Piotr Oledzki
59bb218b86 [MINOR] http-request: allow/deny/auth support for frontend/backend/listen
Use the generic auth framework to control access to frontends/backends/listens
2010-01-31 19:14:08 +01:00
Willy Tarreau
fdb563c06f [MEDIUM] http: add support for conditional response header rewriting
Just as for the req* rules, we can now condition rsp* rules with ACLs.
ACLs match on response, so volatile request information cannot be used.
A warning is emitted if a configuration contains such an anomaly.
2010-01-31 15:43:27 +01:00
Willy Tarreau
8abd4cd526 [MEDIUM] http: add support for conditional request header addition
Now the reqadd rules also support ACLs. All req* rules are converted
now.
2010-01-31 15:12:45 +01:00
Willy Tarreau
6c123b15cb [MEDIUM] http: make the request filter loop check for optional conditions
From now on, if request filters have ACLs defined, these ACLs will be
evaluated to condition the filter. This will be used to conditionally
remove/rewrite headers based on ACLs.
2010-01-28 20:22:06 +01:00
Willy Tarreau
f4f04125d4 [MINOR] prepare req_*/rsp_* to receive a condition
It will be very handy to be able to pass conditions to req_* and rsp_*.
For now, we just add the pointer to the condition in the affected
structs.
2010-01-28 18:10:50 +01:00
Willy Tarreau
c3e8b25c79 [MINOR] http: disable keep-alive when process is going down
Krzysztof Oledzki suggested to disable keep-alive when a process
is going down due to a reload, in order to avoid ever-lasting
sessions. This is a simple and very efficient solution as it
ensures that at most one more request will be handled on a
keep-alive connection after the process has received a SIGUSR1
signal.
2010-01-28 15:01:20 +01:00
Willy Tarreau
739cfbab6a [BUG] http: trim any excess buffer data when recycling a connection
We must trim any excess data from the response buffer when recycling
a keep-alive connection, because we may have blocked an invalid response
from a server that we don't want to accidentely forward once we disable
the analysers, nor do we want those data to come along with next response.
A typical example of such data would be from a buggy server responding to
a HEAD with some data, or sending more than the advertised content-length.
2010-01-25 23:11:14 +01:00
Willy Tarreau
d08f82ebe2 [MINOR] http: remove a copy-paste typo in transaction cleaning
For deciding to set the BF_EXPECT_MORE, we reused the same code as in
http_wait_for_request(), but here we must ignore buf->lr which is not
yet set and useless. This might only have caused random sub-optimal
behaviours.
2010-01-25 22:46:30 +01:00
Willy Tarreau
88d349d25d [MEDIUM] http: add support for Proxy-Connection header
Despite what is explicitly stated in HTTP specifications,
browsers still use the undocumented Proxy-Connection header
instead of the Connection header when they connect through
a proxy. As such, proxies generally implement support for
this stupid header name, breaking the standards and making
it harder to support keep-alive between clients and proxies.

Thus, we add a new "option http-use-proxy-header" to tell
haproxy that if it sees requests which look like proxy
requests, it should use the Proxy-Connection header instead
of the Connection header.
2010-01-25 12:48:26 +01:00
Willy Tarreau
2a6d88dafe [MINOR] http: logs must report persistent connections to down servers
When using "option persist" or "force-persist", we want to know from the
logs if the cookie referenced a valid server or a down server. Till here
the flag reported a valid server even if the server was down, which is
misleading. Now we correctly report that the requested server was down.
We can typically see "--DI" when using "option persist" with redispatch,
ad "SCDN" when using force-persist on a down server.
2010-01-24 13:10:43 +01:00
Willy Tarreau
4de9149f87 [MINOR] add the "force-persist" statement to force persistence on down servers
This is used to force access to down servers for some requests. This
is useful when validating that a change on a server correctly works
before enabling the server again.
2010-01-22 19:10:05 +01:00
Willy Tarreau
ff7b5883c0 [OPTIM] http: don't delay response if next request is incomplete
We use to delay the response if there is a new request in the buffer.
However, if the pending request is incomplete, we should not delay the
pending responses.
2010-01-22 14:43:47 +01:00
Willy Tarreau
d5fd51c75b [BUG] http_server_error() must not purge a previous pending response
This can cause parts of responses to be truncated in case of
pipelined requests if the second request generates an error
before the first request is completely flushed.
2010-01-22 14:20:17 +01:00
Willy Tarreau
6046652253 [MAJOR] http: rework response Connection header handling
This one is the next step of previous patch. It correctly computes
the response mode and the Connection flag transformations depending
on the request mode and version, and the response version and headers.

We're now also able to add "Connection: keep-alive", and to convert
server's close during a keep-alive connection to a server-close
connection.
2010-01-22 11:49:41 +01:00
Willy Tarreau
bbf0b37f6c [MAJOR] http: rework request Connection header handling
We need to improve Connection header handling in the request for it
to support the upcoming keep-alive mode. Now we have two flags which
keep in the session the information about the presence of a
Connection: close and a Connection: keep-alive headers in the initial
request, as well as two others which keep the current state of those
headers so that we don't have to parse them again. Knowing the initial
value is essential to know when the client asked for keep-alive while
we're forcing a close (eg in server-close mode). Also the Connection
request parser is now able to automatically remove single header values
at the same time they are parsed. This provides greater flexibility and
reliability.

All combinations of listen/front/back in all modes and with both
1.0 and 1.1 have been tested.
2010-01-22 11:49:35 +01:00
Willy Tarreau
68085d8cfb [MINOR] http: add http_remove_header2() to remove a header value.
Calling this function after http_find_header2() automatically deletes
the current value of the header, and removes the header itself if the
value is the only one. The context is automatically adjusted for a
next call to http_find_header2() to return the next header. No other
change nor test should be made on the transient context though.
2010-01-18 19:51:33 +01:00
Willy Tarreau
cce7fa4c81 [MEDIUM] http: don't switch to tunnel mode upon close
The close mode of a transaction would be switched to tunnel mode
at the end of the processing, letting a lot of pending data pass
in the other direction if any. Let's fix that by checking for the
close mode during state resync too.
2010-01-17 11:38:34 +01:00
Willy Tarreau
d3c343f8aa [BUG] http: don't count req errors on client resets or t/o during keep-alive
We must set the error flags when detecting that a client has reset
a connection or timed out while waiting for a new request on a keep-alive
connection, otherwise process_session() sets it itself and counts one
request error.

That explains why some sites were showing an increase in request errors
with the keep-alive.
2010-01-16 10:26:19 +01:00
Emeric Brun
b982a3d23a [MEDIUM] Add stick table configuration and init. 2010-01-12 16:01:24 +01:00
Willy Tarreau
b16a5746b7 [MINOR] http: add a separate "http-keep-alive" timeout
This one is used to wait for next request after a response was sent
to the client.
2010-01-10 14:46:16 +01:00
Willy Tarreau
fcffa6911c [MINOR] http: differentiate waiting for new request and waiting for a complete requst
While waiting in a keep-alive state for a request, we want to silently
close if we don't get anything. However if we get a partial request it's
different because that means the client has started to send something.
This requires a new transaction flag. It will be used to implement a
distinct timeout for keep-alive and requests.
2010-01-10 14:24:53 +01:00
Willy Tarreau
a3377eeeff [MINOR] http: move appsession 'sessid' from session to http_txn
This change, suggested by Cyril Bont, makes a lot of sense and
would have made it obvious that sessid was not properly initialized
while switching to keep-alive. The code is now cleaner.
2010-01-10 10:49:11 +01:00
Willy Tarreau
75661457f7 [MINOR] http redirect: don't explicitly state keep-alive on 1.1
Do not set the "connection: keep-alive" header when the request is in
HTTP 1.1, it's implicit.
2010-01-10 10:35:01 +01:00
Willy Tarreau
148d099406 [BUG] stream_interface: fix retnclose and remove cond_close
The stream_int_cond_close() function was added to preserve the
contents of the response buffer because stream_int_retnclose()
was buggy. It flushed the response instead of flushing the
request. This caused issues with pipelined redirects followed
by error messages which ate the previous response.

This might even have caused object truncation on pipelined
requests followed by an error or by a server redirection.

Now that this is fixed, simply get rid of the now useless
function.
2010-01-10 10:21:21 +01:00
Cyril Bont
41689c22da [BUG] appsession: possible memory leak in case of out of memory condition
I've tried to follow all the pool_alloc2/pool_free2 calls in the code
to track memory leaks. I've found one which only happens when there's
already no more memory when allocating a new appsession cookie.
2010-01-10 00:50:14 +01:00
Willy Tarreau
81e3b4f48d [MINOR] http redirect: add the ability to append a '/' to the URL
Sometimes it can be desired to return a location which is the same
as the request with a slash appended when there was not one in the
request. A typical use of this is for sending a 301 so that people
don't reference links without the trailing slash. The name of the
new option is "append-slash" and it can be used on "redirect"
statements in prefix mode.
2010-01-10 00:42:19 +01:00
Willy Tarreau
dcb75c4a83 [MINOR] http: fix double slash prefix with server redirect
When using server redirection, it is possible to specify a path
consisting of only one slash. While this is discouraged (risk of
loop) it may sometimes be useful combined with content switching.
The prefixing of a '/' then causes two slashes to be returned in
the response. So we now do as with the other redirects, don't
prepend a slash if it's alone.
2010-01-10 00:24:22 +01:00
Willy Tarreau
962c3f4aab [MEDIUM] http: fix handling of message pointers
Some message pointers were not usable once the message reached the
HTTP_MSG_DONE state. This is the case for ->som which points to the
body because it is needed to parse chunks. There is one case where
we need the beginning of the message : server redirect. We have to
call http_get_path() after the request has been parsed. So we rely
on ->sol without counting on ->som. In order to achieve this, we're
making ->rq.{u,v} relative to the beginning of the message instead
of the buffer. That simplifies the code and makes it cleaner.

Preliminary tests show this is OK.
2010-01-10 00:15:35 +01:00
Willy Tarreau
59e0b0f972 [BUG] server redirection used an uninitialized string.
This might have been introduced with chunk extensions. Note that
the server redirect still does not work because http_get_path()
cannot get the correct path once the request message is in the
HTTP_MSG_DONE state (->som does not point to the start of message
anymore).
2010-01-09 21:29:23 +01:00
Willy Tarreau
1fac75385a [BUILD] appsession did not build anymore under gcc-2.95 2010-01-09 19:23:06 +01:00
Willy Tarreau
762a23618e [BUG] appsession's sessid must be reset at end of transaction
If we don't do that, we may corrupt the pools in keep-alive sessions.
2010-01-09 13:57:26 +01:00
Willy Tarreau
065e8338e8 [MEDIUM] http: wait for some flush of the response buffer before a new request
If we accept a new request and that request produces an immediate
response (error, redirect, ...), then we may fail to send it in
case of pipelined requests if the response buffer is full. To avoid
this, we check the availability of at least maxrewrite bytes in the
response buffer before accepting a new pipelined request.
2010-01-08 00:36:57 +01:00
Willy Tarreau
ea65e68cc8 [MINOR] http redirect: use proper call to return last response
During a redirect, we used to send the last chunk of response with
stream_int_cond_close(). But this is wrong in case of pipeline,
because if the response already contains something, this function
will refrain from touching the buffer. Use a concatenation function
instead.

Also, this call might still fail when the buffer is full, we need
a second fix to refrain from parsing an HTTP request as long as the
response buffer is full, otherwise we may not even be able to return
a pending redirect or an error code.
2010-01-08 00:36:57 +01:00
Willy Tarreau
4602363f6a [BUG] http: fix for capture memory leak was incorrect
That patch was incorrect because under some circumstances, the
capture memory could be freed by session_free() and then again
by http_end_txn(), causing a double free and an eventual segfault.
The pool use count was also reported wrong due to this bug.

The cleanup code was removed from session_free() to remain only
in http_end_txn().
2010-01-07 22:51:47 +01:00
Willy Tarreau
6fe60182aa [BUG] http: memory leak with captures when using keep-alive
Hank A. Paulson reported a massive memory leak when using keep-alive
mode. The information he provided made it easy to find that captured
request and response headers were erased but not released when renewing
a request.
2010-01-07 13:35:21 +01:00
Willy Tarreau
90deb18916 [MEDIUM] http: make safer use of the DONT_READ and AUTO_CLOSE flags
Several HTTP analysers used to set those flags to values that
were useful but without considering the possibility that they
were not called again to clean what they did. First, replace
direct flag manipulation with more explicit macros. Second,
enforce a rule stating that any buffer which changes one of
these flags from the default must restore it after completion,
so that other analysers see correct flags.

With both this fix and the previous one about analyser bits,
we should not see any more stuck sessions.
2010-01-07 00:20:41 +01:00
Willy Tarreau
8db1c17634 [BUG] http: check options before the connection header
Commit 0dfdf19b64 introduced a
regression because the connection header is now parsed and checked
depending on the configured options, but the options are set after
calling it instead of being set before.
2010-01-05 23:12:12 +01:00
Willy Tarreau
0dfdf19b64 [MEDIUM] http: restore the original behaviour of option httpclose
Historically, "option httpclose" has always worked the same way. It
only mangles the "Connection" header in the request and the response
if needed, but does not affect the connection by itself, and ignores
any further data. It is dangerous to change this behaviour without
leaving any other alternative. If an active close is desired, it's
better to make use of "option forceclose" which does exactly what
it intends to do.

So as of now, "option httpclose" will only mangle the headers as
before, and will only affect the connection by itself when combined
with another connection-related option (eg: keepalive or server-close).
2010-01-05 11:33:11 +01:00
Willy Tarreau
2832d63874 [BUG] http: don't set no-linger on response in case of forced close
This is a copy-paste error, it must only apply to the request.
2010-01-05 11:06:20 +01:00
Willy Tarreau
9300fb2c01 [BUG] http: redirect needed to be updated after recent changes
The data forwarding fixes broke http redirection which relied on
tricks.
2010-01-05 00:58:24 +01:00
Willy Tarreau
2fa144c66a [BUG] http: some possible missed close remain in the forward chain
We basically have to mimmic the code of process_session() here, so
when the remote output is closed, we must abort otherwise we'll end
up with data which cannot leave the buffer.
2010-01-04 23:16:01 +01:00
Willy Tarreau
e3fa6e5bd7 [BUG] http_process_res_common() must not skip the forward analyser
By default this function returned 0 indicating an end of analysis.
This was not a problem as long as it was the last analyser in the
chain but becomes quite a big one now since it skips the forwarder
with auto_close enabled, causing some data to pass under the nose
of the last one undetected.
2010-01-04 22:57:43 +01:00
Willy Tarreau
610ecceef9 [MAJOR] http: fix again the forward analysers
There were still several situations leading to CLOSE_WAIT sockets
remaining there forever because some complex transitions were
obviously not caught due to the impossibility to resync changes
between the request and response FSMs.

This patch now centralizes the global transaction state and feeds
it from both request and response transitions. That way, whoever
finishes first, there will be no issue for converging to the correct
state.

Some heavy use of the new debugging function has helped a lot. Maybe
those calls could be removed after some time. First tests are very
positive.
2010-01-04 21:15:02 +01:00
Willy Tarreau
e988a79c74 [DEBUG] add an http_silent_debug function to debug HTTP states
This function outputs to fd #-1 the status of request and response
buffers, the transaction states, the stream interface states, etc...
That way, it's easy to find that output in an strace report, correctly
placed WRT the other syscalls.
2010-01-04 21:13:14 +01:00
Willy Tarreau
f5c8bd6a99 [BUG] http: fix hopefully last closing issue on data forwarding
The data forwarders are analysers. As such, the have to check for
various situations on which they have to abort, one of them being
the lack of data with closed input. Now we don't leave the functions
anymore without performing these checks. This has solved the new
CLOSE_WAIT issue that became more noticeable since last patch.
2010-01-04 07:10:34 +01:00
Willy Tarreau
d3347ee227 [BUG] http: disable auto-closing during chunk analysis
It may happen that we forward a close just after we sent the last
chunk, because we forgot to clear the AUTO_CLOSE flag.

This issue caused some pages to be truncated depending on some
timing races. Issue initially reported by Cyril Bont.
2010-01-04 02:10:45 +01:00
Willy Tarreau
caabe41a15 [OPTIM] http: optimize a bit the construct of the forward loops
By adjusting a few states and direct branches, we can save a few
percents of CPU, increasing by as much the resulting data rate.
2010-01-03 23:08:28 +01:00
Willy Tarreau
bddaa4a2f7 [CLEANUP] http: remove a remaining impossible condition
This test was there before we had the CLOSING and CLOSED states.
It makes no sense now.
2010-01-03 22:13:35 +01:00
Willy Tarreau
deb9ed8f60 [MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements
Now we use a linked list, there is no limit anymore.
2010-01-03 21:22:14 +01:00
Willy Tarreau
f285f54311 [MINOR] redirect: add support for unconditional rules
Sometimes it's useful to be able to specify an unconditional redirect
rule without adding "if TRUE".
2010-01-03 21:22:08 +01:00
Willy Tarreau
305ae85957 [BUG] http: fix cookie parser to support spaces and commas in values
The cookie parser could be fooled by spaces or commas in cookie names
and values, causing the persistence cookie not to be matched if located
just after such a cookie. Now spaces found in values are considered as
part of the value, and spaces, commas and semi-colons found in values
or names, are skipped till next cookie name.

This fix must be backported to 1.3.
2010-01-03 19:45:54 +01:00
Willy Tarreau
a9679ac94b [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).
2010-01-03 17:32:57 +01:00
Willy Tarreau
2be3939416 [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.
2010-01-03 17:24:51 +01:00
Willy Tarreau
6c2cbe14e4 [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.
2010-01-03 17:07:49 +01:00
Willy Tarreau
bc5aa19e97 [MINOR] http: move redirect messages to HTTP/1.1 with a content-length
This is cleaner and this tells clients we support 1.1.
2010-01-03 15:12:05 +01:00
Willy Tarreau
5e8949cf84 [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.
2010-01-03 14:54:32 +01:00
Willy Tarreau
a95a1f4614 [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.
2010-01-03 13:04:35 +01:00
Willy Tarreau
3bb9c23bd6 [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.
2010-01-03 12:24:37 +01:00
Willy Tarreau
face839296 [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.
2010-01-03 11:37:54 +01:00
Willy Tarreau
638cd02e9d [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.
2010-01-03 07:42:04 +01:00
Willy Tarreau
21c5e4d85b [BUG] last fix was overzealous and disabled server-close
we must not close on remote shutdown but on remote error only.
2010-01-03 00:19:31 +01:00
Willy Tarreau
082b01c541 [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.
2010-01-03 00:00:45 +01:00
Willy Tarreau
b608feb82a [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.
2010-01-02 22:47:18 +01:00
Willy Tarreau
2ab6eb1e24 [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.
2010-01-02 22:04:45 +01:00
Willy Tarreau
15de77e16e [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.
2010-01-02 21:59:16 +01:00
Willy Tarreau
c88ea68ef1 [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.
2009-12-29 14:56:36 +01:00
Willy Tarreau
9438c718ce [MEDIUM] http: make forceclose use SI_FL_NOLINGER
Option forceclose is not limited to the shortage of source ports
anymore thanks to this flag.
2009-12-29 14:39:48 +01:00
Willy Tarreau
82eeaf2fae [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.
2009-12-29 14:26:42 +01:00
Willy Tarreau
5523b32cc6 [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.
2009-12-29 12:05:52 +01:00
Willy Tarreau
83e3af0c86 [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.
2009-12-28 17:39:57 +01:00
Willy Tarreau
58cc872848 [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.
2009-12-28 06:57:33 +01:00
Willy Tarreau
d98cf93395 [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.
2009-12-27 22:54:55 +01:00
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
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
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
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
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
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
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
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
Willy Tarreau
b8c82c295b [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.
2009-10-18 23:45:12 +02:00
Willy Tarreau
75a5fef4d2 [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.
2009-10-18 23:43:57 +02:00
Willy Tarreau
b37c27e28f [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().
2009-10-18 23:15:41 +02:00
Willy Tarreau
2225dd4421 [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.
2009-10-18 21:36:47 +02:00
Willy Tarreau
03a5633299 [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.
2009-10-18 21:28:29 +02:00
Willy Tarreau
349a0f62b5 [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.
2009-10-18 21:19:33 +02:00
Willy Tarreau
4273664a1b [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.
2009-10-18 21:10:21 +02:00
Willy Tarreau
32b47f42a0 [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.
2009-10-18 20:59:20 +02:00
Cyril Bont
bf47aeb946 [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).
2009-10-18 11:56:26 +02:00
Willy Tarreau
f1ba4b3de5 [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().
2009-10-18 08:52:24 +02:00
Willy Tarreau
7859991dd7 [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.
2009-10-17 20:15:29 +02:00
Krzysztof Piotr Oledzki
5fb1882514 [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
2009-10-14 21:49:53 +02:00
Krzysztof Piotr Oledzki
6f61b21524 [BUG] Fix NULL pointer dereference in stats_check_uri_auth(), v2
Recent "struct chunk rework" introduced a NULL pointer dereference
and now haproxy segfaults if auth is required for stats but not found.

The reason is that size_t cannot store negative values, but current
code assumes that "len < 0" == uninitialized.

This patch fixes it.
2009-10-04 23:44:45 +02:00
Krzysztof Piotr Oledzki
aeebf9ba65 [MEDIUM] Collect & provide separate statistics for sockets, v2
This patch allows to collect & provide separate statistics for each socket.
It can be very useful if you would like to distinguish between traffic
generate by local and remote users or between different types of remote
clients (peerings, domestic, foreign).

Currently no "Session rate" is supported, but adding it should be possible
if we found it useful.
2009-10-04 18:56:02 +02:00
Krzysztof Piotr Oledzki
052d4fd07d [CLEANUP] Move counters to dedicated structures
Move counters from "struct proxy" and "struct server"
to "struct pxcounters" and "struct svcounters".

This patch should make no functional change.
2009-10-04 18:32:39 +02:00
Willy Tarreau
b0c9bc4f95 [MEDIUM] stats: make HTTP stats use an I/O handler
Doing this, we can remove the last BF_HIJACK user and remove
produce_content(). s->data_source could also be removed but
it is currently used to detect if the stats or a server was
used.
2009-10-04 15:56:38 +02:00
Krzysztof Piotr Oledzki
78abe618a8 [MAJOR] struct chunk rework
Add size to struct chunk and simplify the code as there is
no longer required to pass sizeof in chunk_printf().
2009-10-01 10:17:37 +02:00
Willy Tarreau
2f9cc8ab52 [BUG] http stats: large outputs sometimes got some parts chopped off
Due to a misplaced call to stream_int_retnclose(), the stats output
buffer was erased before each call to produce_content(), resulting
in missing pieces in the stats output if the connection was not
fast enough between haproxy and the client.
2009-09-24 22:22:18 +02:00
Willy Tarreau
56a560aef4 [MEDIUM] stats: prepare the connection for closing before dumping
We will need to modify the stats dump functions so that they can
be used in interactive mode. For this, we want their caller to
prepare the connection for a close, not themselves to do it.
Let's simply move the stream_int_retnclose() out.
2009-09-23 23:52:16 +02:00
Willy Tarreau
520d95e42b [MAJOR] buffers: split BF_WRITE_ENA into BF_AUTO_CONNECT and BF_AUTO_CLOSE
The BF_WRITE_ENA buffer flag became very complex to deal with, because
it was used to :
  - enable automatic connection
  - enable close forwarding
  - enable data forwarding

The last point was not very true anymore since we introduced ->send_max,
but still the test remained everywhere. This was causing issues such as
impossibility to connect without forwarding data, impossibility to prevent
closing when data was forwarded, etc...

This patch clarifies the situation by getting rid of this multi-purpose
flag and replacing it with :
  - data forwarding based only on ->send_max || ->pipe ;
  - a new BF_AUTO_CONNECT flag to allow automatic connection and only
    that ;
  - ability to perform an automatic connection when ->send_max or ->pipe
    indicate that data is waiting to leave the buffer ;
  - a new BF_AUTO_CLOSE flag to let the producer automatically set the
    BF_SHUTW_NOW flag when it gets a BF_SHUTR.

During this cleanup, it was discovered that some tests were performed
twice, or that the BF_HIJACK flag was still tested, which is not needed
anymore since ->send_max replcaed it. These places have been fixed too.

These cleanups have also revealed a few areas where the other flags
such as BF_EMPTY are not cleanly used. This will be an opportunity for
a second patch.
2009-09-19 21:14:54 +02:00
Willy Tarreau
816b979977 [MAJOR] http: add support for HTTP 1xx informational responses
HTTP supports status codes 100 and 101 to report protocol indications,
which are followed by the requests's response. Till now, haproxy would
only see those responses without parsing subsequent ones. That means
that cookie additions were only performed on 1xx messages for instance,
which does not work since headers must be ignored with 1xx messages.
Also, logs were not terribly useful with the common 100 status code
in response to "Expect: 100-continue" during POST some requests.

This change adds support for such messages. Now haproxy sees them,
forwards them and skips them until it finds a correct response, which
it logs and processes. As an exception, header removal/rewriting still
work on 1xx responses in order to be able to strip out sensible
information that may have accidentely been left by another equipment
(possibly an older haproxy itself). But headers addition are disabled
however.

This change brings the ability to loop on response without data, which
is a starting point to support keepalive. The change is marked as major
as a few fixes had to be performed in the HTTP message parser.
2009-09-19 14:53:47 +02:00
Willy Tarreau
106f979bbd [MINOR] acl: add support for hdr_ip to match IP addresses in headers
For x-forwarded-for and such headers, it's sometimes needed to match
based on network addresses. Let's use hdr_ip() for that.
2009-09-19 14:47:49 +02:00
Willy Tarreau
c465fd7836 [BUG] tarpit did not work anymore
Tarpit was broken by recent splitting of analysers. It would still
let the connection go to the server due to a missing buffer_write_dis().
Also, it was performed too late (after content switching rules).
2009-08-31 00:17:18 +02:00
Willy Tarreau
a07a34eb24 [MEDIUM] replace BUFSIZE with buf->size in computations
The first step towards dynamic buffer size consists in removing
all static definitions of the buffer size. Instead, we store a
buffer's size in itself. Right now they're all preinitialized
to BUFSIZE, but we will change that.
2009-08-16 23:27:46 +02:00
Willy Tarreau
52a0c60845 [MINOR] set s->srv_error according to the analysers
s->srv_error was set depending on the frontend's protocol. Now it is
set by the HTTP analyser, so that even when switching from a TCP
frontend to an HTTP backend, we can have HTTP error messages.
2009-08-16 22:45:38 +02:00
Willy Tarreau
b55932ddaf [MEDIUM] remove old experimental tcpsplice option
This Linux-specific option was never really used in production and
has since been superseded by new splicing options brought by recent
Linux kernels.

It caused several particular cases in the code because the kernel
would take care of the session without haproxy being able to do
anything on it, which became hard to handle in the new architecture.

Let's simply get rid of it now that there is a replacement available.
2009-08-16 13:20:32 +02:00
Emeric Brun
3a058f3091 [MINOR] add a new CLF log format
Appending the "clf" word after "option httplog" turns the HTTP log
format into a CLF format, more suited for certain tools.
2009-07-14 12:50:40 +02:00
Willy Tarreau
cd7afc0a13 [MINOR] http: take http request timeout from the backend
Since we can now switch from TCP to HTTP, we need to be able to apply
the HTTP request timeout after switching. That means we need to take
it from the backend and not from the frontend. Since the backend points
to the frontend before switching, that changes nothing for the normal
case.
2009-07-12 10:03:17 +02:00
Willy Tarreau
51aecc76f8 [MEDIUM] allow a TCP frontend to switch to an HTTP backend
This patch allows a TCP frontend to switch to an HTTP backend.
During the switch, missing structures are automatically allocated.
The HTTP parser is enabled so that the backend first waits for a
full HTTP request.
2009-07-12 09:47:04 +02:00
Willy Tarreau
2492d5b4d6 [MINOR] acl: add HTTP protocol detection (req_proto_http)
Now that we can perform TCP-based content switching, it makes sense
to be able to detect HTTP traffic and act accordingly. We already
have an HTTP decoder, we just have to call it in order to detect HTTP
protocol. Note that since the decoder will automatically fill in the
interesting fields of the HTTP transaction, it would make sense to
use this parsing to extend HTTP matching to TCP.
2009-07-12 08:06:20 +02:00
Willy Tarreau
1d0dfb155d [MAJOR] http: complete splitting of the remaining stages
The HTTP processing has been splitted into 7 steps, one of which
is not anymore HTTP-specific (content-switching). That way, it
becomes possible to use "use_backend" rules in TCP mode. A new
"use_server" directive should follow soon.
2009-07-07 15:10:31 +02:00
Willy Tarreau
3a816293e9 [MEDIUM] session: tell analysers what bit they were called for
Some stream analysers might become generic enough to be called
for several bits. So we cannot have the analyser bit hard coded
into the analyser itself. Let's make the caller inform the callee.
2009-07-07 10:55:49 +02:00
Willy Tarreau
d787e6648c [MEDIUM] http: split request waiter from request processor
We want to split several steps in HTTP processing so that
we can call individual analysers depending on what processing
we want to perform. The first step consists in splitting the
part that waits for a request from the rest.
2009-07-07 10:14:51 +02:00
Willy Tarreau
571ec98baa [CLEANUP] remove unused DEBUG_PARSE_NO_SPEEDUP define
This one has become useless with the new HTTP parser.
2009-07-07 08:56:15 +02:00
Willy Tarreau
06b917c7ab [BUG] http: redirect rules were processed too early
redirect rules are documented as being processed last before
use_backend but were mistakenly processed before block rules.
Fortunately very few people use a mix of block and redirect
rules, so this bug has never been reported yet.
2009-07-06 16:34:52 +02:00
Willy Tarreau
c9bd0cc224 [MINOR] add options dontlog-normal and log-separate-errors
Some big traffic sites have trouble dealing with logs and tend to
disable them. Here are two new options to help cope with massive
logs.

  - dontlog-normal only disables logging for 100% successful
    connections, other ones will still be logged

  - log-separate-errors will cause non-100% successful connections
    to be logged at level "err" instead of level "info" so that a
    properly configured syslog daemon can send them to a different
    file for longer conservation.
2009-05-10 11:57:02 +02:00
Maik Broemme
2850cb42b6 [MINOR] add X-Original-To: header
I have attached a patch which will add on every http request a new
header 'X-Original-To'. If you have HAProxy running in transparent mode
with a big number of SQUID servers behind it, it is very nice to have
the original destination ip as a common header to make decisions based
on it.

The whole thing is configurable with a new option 'originalto'. I have
updated the sourcecode as well as the documentation. The 'haproxy-en.txt'
and 'haproxy-fr.txt' files are untouched, due to lack of my french
language knowledge. ;)

Also the patch adds this header for IPv4 only. I haven't any IPv6 test
environment running here and don't know if getsockopt() with SO_ORIGINAL_DST
will work on IPv6. If someone knows it and wants to test it I can modify
the diff. Feel free to ask me questions or things which should be changed. :)

--Maik
2009-05-01 16:22:33 +02:00
Willy Tarreau
2df8d713b3 [BUG] fix wrong pointer arithmetics in HTTP message captures
The pointer arithmetics was wrong in http_capture_bad_message().
This has no impact right now because the error only msg->som was
affected and right now it's always 0. But this was a bug waiting
for keepalive support to strike.
2009-05-01 11:33:17 +02:00
Willy Tarreau
1772ece025 [MINOR] fix several printf formats and missing arguments
Last patch revealed a number of mistakes in printf-like calls, mostly int/long
mismatches, and a few missing arguments.
2009-04-03 14:49:12 +02:00
Willy Tarreau
4076a15255 [MEDIUM] http: capture invalid requests/responses even if accepted
It's useful to be able to accept an invalid header name in a request
or response but still be able to monitor further such errors. Now,
when an invalid request/response is received and accepted due to
an "accept-invalid-http-{request|response}" option, the invalid
request will be captured for later analysis with "show errors" on
the stats socket.
2009-04-02 21:36:37 +02:00
Willy Tarreau
32a4ec0ed7 [MEDIUM] http: add options to ignore invalid header names
Sometimes it is required to let invalid requests pass because
applications sometimes take time to be fixed and other servers
do not care. Thus we provide two new options :

     option accept-invalid-http-request  (for the frontend)
     option accept-invalid-http-response (for the backend)

When those options are set, invalid requests or responses do
not cause a 403/502 error to be generated.
2009-04-02 21:36:34 +02:00
Willy Tarreau
2ab85e6fee [BUG] don't set an expiration date directly from now_ms
now_ms can be zero, don't set ->analyse_exp directly from it, we
must use tick_add() instead.
2009-03-29 10:24:15 +02:00
Willy Tarreau
1b194fe03e [OPTIM] buffer: new BF_READ_DONTWAIT flag reduces EAGAIN rates
When the reader does not expect to read lots of data, it can
set BF_READ_DONTWAIT on the request buffer. When it is set,
the stream_sock_read callback will not try to perform multiple
reads, it will return after only one, and clear the flag.
That way, we can immediately return when waiting for an HTTP
request without trying to read again.

On pure request/responses schemes such as monitor-uri or
redirects, this has completely eliminated the EAGAIN occurrences
and the epoll_ctl() calls, resulting in a performance increase of
about 10%. Similar effects should be observed once we support
HTTP keep-alive since we'll immediately disable reads once we
get a full request.
2009-03-21 21:57:30 +01:00
Willy Tarreau
8365f9335d [CLEANUP] http: remove some commented out obsolete code in process_response 2009-03-15 23:11:49 +01:00
Willy Tarreau
6bf1736fb1 [BUILD] proto_http did not build on gcc-2.95 (again)
move the DPRINTF below the local variable declarations.
(cherry picked from commit 7b92db4cd5)

The patch accidently got reverted.
2009-03-08 23:10:34 +01:00
Willy Tarreau
6f0aa476bd [CLEANUP] buffer_flush() was misleading, rename it as buffer_erase 2009-03-08 20:33:29 +01:00
Willy Tarreau
ec22b2c27a [CLEANUP] remove last references to term_trace
term_trace was very useful while reworking the lower layers but has almost
completely been removed from every place it was referenced. Even the few
remaining ones were not accurate, so it's better to completely remove those
references and re-add them from scratch later if needed.
2009-03-06 13:07:40 +01:00
Willy Tarreau
7f062c4193 [MEDIUM] measure and report session rate on frontend, backends and servers
With this change, all frontends, backends, and servers maintain a session
counter and a timer to compute a session rate over the last second. This
value will be very useful because it varies instantly and can be used to
check thresholds. This value is also reported in the stats in a new "rate"
column.
2009-03-05 18:43:00 +01:00
Willy Tarreau
defc52da95 [MINOR] errors dump must use user-visible date, not internal date. 2009-03-04 20:53:44 +01:00
Willy Tarreau
f073a83b1d [MEDIUM] store a complete dump of request and response errors in proxies
Each proxy instance, either frontend or backend, now has some room
dedicated to storing a complete dated request or response in case
of parsing error. This will make it possible to consult errors in
order to find the exact cause, which is particularly important for
troubleshooting faulty applications.
2009-03-04 10:26:38 +01:00
Willy Tarreau
7552c031c0 [MINOR] ensure that http_msg_analyzer updates pointer to invalid char
If an invalid character is encountered while parsing an HTTP message, we
want to get buf->lr updated to reflect it.

Along this change, a few useless __label__ declarations have been removed
because they caused gcc to consume stack space without putting anything
there.
2009-03-01 11:10:40 +01:00
Willy Tarreau
7b92db4cd5 [BUILD] proto_http did not build on gcc-2.95
move the DPRINTF below the local variable declarations.
2009-02-24 10:48:35 +01:00
Willy Tarreau
fe651a50d6 [MINOR] redirect: in prefix mode a "/" means not to change the URI
If the prefix is set to "/", it means the user does not want to alter
the original URI, so we don't want to insert a new slash before the
original URI.

(cherry-picked from commit 02a35c74942c1bce762e996698add1270e6a5030)
2008-12-07 23:48:39 +01:00
Willy Tarreau
0140f2553c [MINOR] redirect: add support for "set-cookie" and "clear-cookie"
It is now possible to set or clear a cookie during a redirection. This
is useful for logout pages, or for protecting against some DoSes. Check
the documentation for the options supported by the "redirect" keyword.

(cherry-picked from commit 4af993822e880d8c932f4ad6920db4c9242b0981)
2008-12-07 23:46:38 +01:00
Willy Tarreau
79da4697ca [MINOR] redirect: add support for the "drop-query" option
If "drop-query" is present on a "redirect" line using the "prefix" mode,
then the returned Location header will be the request URI without the
query-string. This may be used on some login/logout pages, or when it
must be decided to redirect the user to a non-secure server.

(cherry-picked from commit f2d361ccd73aa16538ce767c766362dd8f0a88fd)
2008-12-07 23:42:01 +01:00
Willy Tarreau
fd39ddaa3d [BUG] cookie capture is declared in the frontend but checked on the backend
Cookie capture would only work by pure luck on the request but did
never work on responses since only the backend was checked. The fix
consists in always checking frontend for cookie captures.
(cherry picked from commit a83c5ba9315a7c47cda2698280b7e49a9d3eb374)
2008-12-07 23:36:52 +01:00
Willy Tarreau
0a46489228 [MINOR] slightly rebalance stats_dump_{raw,http}
Both should process the response buffer equally. They now both
clear the hijack bit once done, and both receive a pointer to
the response buffer in their arguments.
2008-12-07 18:30:00 +01:00
Willy Tarreau
01bf8675ed [MEDIUM] reference the current hijack function in the buffer itself
Instead of calling a hard-coded function to produce data, let's
reference this function into the buffer and call it from there
when BF_HIJACK is set. This goes in the direction of more generic
session management code.
2008-12-07 18:03:29 +01:00
Willy Tarreau
59234e91c2 [MEDIUM] rename process_request to http_process_request
Now the function only does HTTP request and nothing else. Also pass
the request buffer to it.
2008-11-30 23:51:27 +01:00
Willy Tarreau
d34af78a34 [MEDIUM] move the HTTP request body analyser out of process_request().
A new function http_process_request_body() has been created to process
the request body. Next step is now to clean up process_request().
2008-11-30 23:36:37 +01:00
Willy Tarreau
60b85b0694 [MEDIUM] extract the HTTP tarpit code from process_request().
The tarpit is now an autonomous independant analyser.
2008-11-30 23:28:40 +01:00
Willy Tarreau
edcf6687d6 [MEDIUM] extract TCP request processing from HTTP
The TCP analyser has moved to proto_tcp.c. Breaking the function
has required finer use of the return value and adding some tests
to process_session().
2008-11-30 23:15:34 +01:00
Willy Tarreau
0cac36f415 [MEDIUM] make the http server error function a pointer in the session
It was a bit awkward to have session.c call return_srv_error() for
HTTP error messages related to servers. The function has been adapted
to be passed a pointer to the faulty stream interface, and is now a
pointer in the session. It is possible that in the future, it will
become a callback in the stream interface itself.
2008-11-30 20:44:17 +01:00
Willy Tarreau
2d3d94cf23 [MINOR] replace srv_close_with_err() with http_server_error()
The new function looks like the previous one except that it operates
at the stream interface level and assumes an already closed SI.

Also remove some old unused occurrences of srv_close_with_err().
2008-11-30 20:28:57 +01:00
Willy Tarreau
dded32defa [MINOR] replace client_retnclose() with stream_int_retnclose()
This makes more sense to return a message to a stream interface
than to a session.

senddata.{c,h} have been removed.
2008-11-30 19:48:07 +01:00
Willy Tarreau
81acfab4fd [MINOR] replace the ambiguous client_return function by stream_int_return
This one applies to a stream interface, which makes more sense.
2008-11-30 19:22:53 +01:00
Willy Tarreau
a5555ec68a [MINOR] call session->do_log() for logging
In order to avoid having to call per-protocol logging function directly
from session.c, it's better to assign the logging function when the session
is created. This also eliminates a test when the function is needed, and
opens the way to more complete logging functions.
2008-11-30 19:02:32 +01:00
Willy Tarreau
55a8d0e1bb [CLEANUP] move the session-related functions to session.c
proto_http.c was not suitable for session-related processing, it was
just convenient for the tranformation.

Some more splitting must occur: process_request/response in proto_http.c
must be split again per protocol, and the caller must run a list.

Some functions should be directly attached to the session or the buffer
(eg: perform_http_redirect, return_srv_error, http_sess_log).
2008-11-30 18:47:21 +01:00
Willy Tarreau
fe3718ab79 [MAJOR] complete layer4/7 separation
All the processing has now completely been split in layers. As of
now, everything is still in process_session() which is not the right
place, but the code sequence works. Timeouts, retries, errors, all
work.

The shutdown sequence has been strictly applied: BF_SHUTR/BF_SHUTW
are only assigned by lower layers. Upper layers can only indicate
their wish to close using BF_SHUTR_NOW and BF_SHUTW_NOW.

When a shutdown is performed on a stream interface, the buffer flags
are updated accordingly and re-checked by upper layers. A lot of care
has been taken to ensure that aborts during intermediate connection
setups are correctly handled and shutdowns correctly propagated to
both buffers.

A future evolution would consist in ensuring that BF_SHUT?_NOW may
be set at any time, and applies only when the buffer is empty. This
might help with error messages, but might complicate the processing
of data remaining in buffers.

Some useless buffer flag combinations have been removed.

Stat counters are still broken (eg: per-server total number of sessions).

Error messages should be delayed to the close instant and be produced by
protocol.

Many functions must now move to proper locations.
2008-11-30 18:14:12 +01:00
Willy Tarreau
99126c35c1 [MEDIUM] make the stream interface control the SHUT{R,W} bits
It's better that the stream interface controls the BF_SHUT* bits so
that they always reflect the real state of the interface.
2008-11-27 22:32:14 +01:00
Willy Tarreau
8bfa426cad [MEDIUM] process shutw during connection attempt
It sometimes happens that a connection is aborted at the exact same moment
it establishes. We have to close the socket and not only to shut it down
for writes.

Some corner cases remain. We have to handle the shutr/shutw at the stream
interface and only report the status to the buffer, not the opposite.
2008-11-27 09:25:45 +01:00
Willy Tarreau
0a5d5ddeb9 [MEDIUM] remove stream_sock_update_data()
Two new functions are used instead : buffer_check_{shutr,shutw}.
It is indeed more adequate to check for new closures only when the
buffer reports them.

Several remaining unclosed connections were detected after a test,
even before this patch, so a bug remains. To reproduce, try the
following during 30 seconds :

  inject30l4 -n 20000 -l -t 1000 -P 10 -o 4 -u 100 -s 100 -G 127.0.0.1:8000/
2008-11-23 19:31:35 +01:00
Willy Tarreau
74ab2ac7b0 [MEDIUM] stream_interface: added a DISconnected state between CON/EST and CLO
There were rare situations where it was not easy to detect that a failed
session attempt had occurred and needed some server cleanup. In particular,
client aborts sometimes lead to session leaks on the server side.

A new state "SI_ST_DIS" (disconnected) has been introduced for this. When
a session has been closed at a stream interface but the server cleanup has
not occurred, this state is entered instead of CLO. The cleanup is then
performed there and the state goes to CLO.

A new diagram has been added to show possible stream_interface state
transitions that can occur in a stream-sock. It makes debugging easier.
2008-11-23 17:23:07 +01:00
Willy Tarreau
4351b3a4ca [MEDIUM] continue layering cleanups.
The server sessions are now only decremented when entering SI_ST_CER
and SI_ST_CLO states. A state is clearly missing between EST and CLO,
or after CLO (eg: END), because many cleanups are performed upon CLO
and must rely on tricks to ensure being done only once.

The goal of next changes will be to improve what has been started.
Ideally, the FD should only notify the SI about the change, which
should itself only notify the session when it has some news or when
it needs help (eg: redispatch). The buffer's error processing should
not change the FD's status immediately, otherwise we risk race conds
between a pending connect and a shutw (for instance). Also, the new
connect attempt should only be made after layer 7 and all the crap
above buffers.
2008-11-12 01:51:41 +01:00
Willy Tarreau
1e62de615b [MEDIUM] add the SN_CURR_SESS flag to the session to track open sessions
It is quite hard to track when the current session has already been counted
or discounted from the server's total number of established sessions. For
this reason, we introduce a new session flag, SN_CURR_SESS, which indicates
if the current session is one of those reported by the server or not. It
simplifies session accounting and makes it far more robust. It also makes
it possible to perform a last-minute cleanup during session_free().

Right now, with this fix and a few more buffer transitions fixes, no session
were found to remain after a test.
2008-11-11 20:26:58 +01:00
Willy Tarreau
cff6411f9a [MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.

The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.

Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.

Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.

Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.

This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.

The following debugging line was useful to track state changes :

  fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
          s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 06:26:53 +01:00
Willy Tarreau
efb453c259 [MAJOR] migrate the connection logic to stream interface
The connection setup code has been refactored in order to
make it run only on low level (stream interface). Several
complicated functions have been removed from backend.c,
and we now have sess_update_stream_int() to manage
an assigned connection, sess_prepare_conn_req() to assign a
server to a connection request, perform_http_redirect() to
redirect instead of connecting to server, and return_srv_error()
to return connection error status messages.

The stream_interface status changes are checked before adjusting
buffer flags, so that the buffers can be informed about this lower
level update.

A new connection is initiated by changing si->state from SI_ST_INI
to SI_ST_REQ.

The code seems to work but is awfully dirty. Some functions need
to be moved, and the layering is not yet quite clear.

A lot of dead old code has simply been removed.
2008-11-02 10:19:10 +01:00
Willy Tarreau
d7704b5343 [MINOR] add an expiration flag to the stream_sock_interface
This expiration flag is used to indicate that the timer has
expired without having to check it everywhere.
2008-11-02 10:19:10 +01:00
Willy Tarreau
3c6ab2e28d [MEDIUM] use buffer_check_timeouts instead of stream_sock_check_timeouts()
It's more appropriate to use buffer_check_timeouts() to check for buffer
timeouts and si->shutw/shutr to shutdown the stream interfaces.
2008-11-02 10:19:10 +01:00
Willy Tarreau
3537467679 [MEDIUM] move QUEUE and TAR timers to stream interfaces
It was not practical to have QUEUE and TAR timers in buffers, as they caused
triggering of the timeout flags. Move them to the stream interface where they
belong.
2008-11-02 10:19:09 +01:00
Willy Tarreau
a37095b96f [CLEANUP] process_session: move debug outputs out of the critical loop
The if(debug&closed) printfs have moved outside of the loop. It also
permitted to merge several of them.
2008-11-02 10:19:09 +01:00
Willy Tarreau
4ffd51a848 [MEDIUM] process_session: make use of the new buffer flags
Now we have almost two distinct parts between tcp and http.
Only the connection establishment code still requires some
resynchronization, the rest does not.
2008-11-02 10:19:09 +01:00
Willy Tarreau
9a2d15429d [MEDIUM] buffers: add BF_READ_ATTACHED and BF_ANA_TIMEOUT
Those two flags will be used to wake up analysers only when
needed.
2008-11-02 10:19:09 +01:00
Willy Tarreau
48adac5db9 [MEDIUM] stream interface: add the ->shutw method as well as in and out buffers
Those entries were really needed for cleaner and better code. Using them
has permitted to automatically close a file descriptor during a shut write,
reducing by 20% the number of calls to process_session() and derived
functions.

Process_session() does not need to know the file descriptor anymore, though
it still remains very complicated due to the special case for the connect
mode.
2008-11-02 10:19:08 +01:00
Willy Tarreau
e5ed406715 [MAJOR] make stream sockets aware of the stream interface
As of now, a stream socket does not directly wake up the task
but it does contact the stream interface which itself knows the
task. This allows us to perform a few cleanups upon errors and
shutdowns, which reduces the number of calls to data_update()
from 8 per session to 2 per session, and make all the functions
called in the process_session() loop completely swappable.

Some improvements are required. We need to provide a shutw()
function on stream interfaces so that one side which closes
its read part on an empty buffer can propagate the close to
the remote side.
2008-11-02 10:19:08 +01:00
Willy Tarreau
cb651251f9 [OPTIM] ev_sepoll: detect newly created FDs and check them once
When an accept() creates a new FD, it is already marked as set for
reads. But the task will be woken up without first checking if the
socket could be read.

The speculative I/O gives us a chance to either read the FD if there
are data pending on it, or immediately mark it for poll mode if
nothing is pending.

Simply doing this reduces the number of calls to process_session
from 6 to 5 per session, 2 to 1 calls to process_request, 10% less
calls to epoll_ctl, fd_clr, fd_set, stream_sock_data_update, 20%
less eb32_insert/eb_delete, etc... General performance increase
seems to be around 3%.
2008-11-02 10:19:07 +01:00
Willy Tarreau
3da77c5abd [MINOR] re-arrange buffer flags and rename some of them
The buffer flags became a big bazaar. Re-arrange them
so that their names are more explicit and so that they
are more easily readable in hex form. Some aggregates
have also been adjusted.
2008-11-02 10:19:07 +01:00
Willy Tarreau
72b179a53c [MEDIUM] reintroduce BF_HIJACK with produce_content
The stats dump are back. Even very large config files with
5000 servers work fast and well. The SN_SELF_GEN flag has
completely been removed.
2008-11-02 10:19:06 +01:00
Willy Tarreau
36e6a41bc8 [MINOR] only call flow analysers when their read side is connected.
It's useless to call flow analysers when their read side has not
seen a connection yet.
2008-11-02 10:19:06 +01:00
Willy Tarreau
3a16b2c9cd [MEDIUM] split stream_sock_process_data
It was a waste to constantly update the file descriptor's status
and timeouts during a flags update. So stream_sock_process_data
has been slit in two parts :
  stream_sock_data_update()  => computes updated flags
  stream_sock_data_finish()  => computes timeouts

Only the first one is called during flag updates. The second one
is only called upon completion. The number of calls to fd_set/fd_clr
has now significantly dropped.

Also, it's useless to check for errors and timeouts in the
process_session() loop, it's enough to check for them at the
beginning.
2008-11-02 10:19:06 +01:00
Willy Tarreau
f9839bdffe [MAJOR] make the client side use stream_sock_process_data()
The client side now relies on stream_sock_process_data(). One
part has not yet been re-implemented, it concerns the calls
to produce_content().

process_session() has been adjusted to correctly check for
changing bits in order not to call useless functions too many
times.

It already appears that stream_sock_process_data() should be
split so that the timeout computations are only performed at
the exit of process_session().
2008-11-02 10:19:06 +01:00
Willy Tarreau
2d2127989c [MEDIUM] stream_sock_process_data moved to stream_sock.c
The old temporary process_srv_data function moved to stream_sock.c.
2008-11-02 10:19:05 +01:00
Willy Tarreau
8a8188301b [MEDIUM] process_srv_data: ensure that we always correctly re-arm timeouts
We really want to ensure that we don't miss a timeout update and do not
update them for nothing. So the code takes care of updating the timeout
in the two following circumstances :
  - it was not set
  - some I/O has been performed

Maybe we'll be able to remove that from stream_sock_{read|write}, or
we'll find a way to ensure that we never have to re-enable this.
2008-11-02 10:19:05 +01:00
Willy Tarreau
2ac679d9aa [MEDIUM] third cleanup and optimization of process_srv_data()
Some repeated tests were factored out.
Now the code makes sense and is fully understandable.
2008-11-02 10:19:05 +01:00
Willy Tarreau
8fbd3b4ce7 [MEDIUM] second level of code cleanup for process_srv_data
Now the function is 100% server-independant. Next step will
consist in using the same function for the client side too.
2008-11-02 10:19:05 +01:00
Willy Tarreau
376580a873 [MEDIUM] massive cleanup of process_srv()
Server-specific calls were extracted and moved to the caller.
The function is now nearly server-agnostic.
2008-11-02 10:19:05 +01:00
Willy Tarreau
8b46aa01ac [OPTIM] remove useless fd_set(read) upon shutdown(write)
Those old tricks are no longer needed and are overwritten
anyway. Remove them.
2008-11-02 10:19:05 +01:00
Willy Tarreau
fa7e10251d [MAJOR] rework of the server FSM
srv_state has been removed from HTTP state machines, and states
have been split in either TCP states or analyzers. For instance,
the TARPIT state has just become a simple analyzer.

New flags have been added to the struct buffer to compensate this.
The high-level stream processors sometimes need to force a disconnection
without touching a file-descriptor (eg: report an error). But if
they touched BF_SHUTW or BF_SHUTR, the file descriptor would not
be closed. Thus, the two SHUT?_NOW flags have been added so that
an application can request a forced close which the stream interface
will be forced to obey.

During this change, a new BF_HIJACK flag was added. It will
be used for data generation, eg during a stats dump. It
prevents the producer on a buffer from sending data into it.

  BF_SHUTR_NOW  /* the producer must shut down for reads ASAP  */
  BF_SHUTW_NOW  /* the consumer must shut down for writes ASAP */
  BF_HIJACK     /* the producer is temporarily replaced        */

BF_SHUTW_NOW has precedence over BF_HIJACK. BF_HIJACK has
precedence over BF_MAY_FORWARD (so that it does not need it).

New functions buffer_shutr_now(), buffer_shutw_now(), buffer_abort()
are provided to manipulate BF_SHUT* flags.

A new type "stream_interface" has been added to describe both
sides of a buffer. A stream interface has states and error
reporting. The session now has two stream interfaces (one per
side). Each buffer has stream_interface pointers to both
consumer and producer sides.

The server-side file descriptor has moved to its stream interface,
so that even the buffer has access to it.

process_srv() has been split into three parts :
  - tcp_get_connection() obtains a connection to the server
  - tcp_connection_failed() tests if a previously attempted
    connection has succeeded or not.
  - process_srv_data() only manages the data phase, and in
    this sense should be roughly equivalent to process_cli.

Little code has been removed, and a lot of old code has been
left in comments for now.
2008-11-02 10:19:04 +01:00
Willy Tarreau
41f40ede3b [MEDIUM] make it possible for analysers to follow the whole session
Some analysers will need to remain present after connection is
established. Change the way BF_MAY_FORWARD is set to allow this.
2008-11-02 10:19:04 +01:00
Willy Tarreau
c52164a1a8 [BUG] process_request: HTTP body analysis must return zero if missing data
This missing return and timeout check caused an infinite loop too.
2008-08-17 19:27:11 +02:00
Willy Tarreau
2500981dc1 [BUG] process_cli/process_srv: don't call shutdown when already done
A few missing checks of BF_SHUTR and BF_SHUTW caused busy loops upon
some error paths.
2008-08-17 18:16:38 +02:00
Willy Tarreau
ffab5b4ab0 [MEDIUM] merge inspect_exp and txn->exp into request buffer
Since we may have several analysers on a buffer, it's more
convenient to have the analyser timeout attached to the
buffer itself.
2008-08-17 18:03:28 +02:00
Willy Tarreau
6d2889ba3d [OPTIM] process_cli/process_srv: reduce the number of tests
We can skip a number of tests by simply checking a few flags,
it saves a few CPU cycles in the fast path.
2008-08-17 16:25:06 +02:00
Willy Tarreau
2df28e8110 [MEDIUM] session: move the analysis bit field to the buffer
It makes more sense to store the list of analysers in the buffer
than in the session since they are precisely plugged onto one
buffer.
2008-08-17 15:20:19 +02:00
Willy Tarreau
f495ddf9d4 [MINOR] ensure the termination flags are set by process_xxx
When any processing remains on a buffer, it must be up to the
processing functions to set the termination flags, because they
are the only ones who know about higher levels.
2008-08-17 14:38:41 +02:00
Willy Tarreau
507385d0e1 [MEDIUM] centralize buffer timeout checks at the top of process_session
it's more efficient and easier to check all the timeouts at once and
always rely on the buffer flags than to check them everywhere.
2008-08-17 13:04:25 +02:00
Willy Tarreau
26ed74dadc [MEDIUM] use buffer->wex instead of buffer->cex for connect timeout
It's a shame not to use buffer->wex for connection timeouts since by
definition it cannot be used till the connection is not established.
Using it instead of ->cex also makes the buffer processing more
symmetric.
2008-08-17 12:11:14 +02:00
Willy Tarreau
dafde43410 [MAJOR] process_session: rely only on buffer flags
Instead of calling all functions in a loop, process_session now
calls them according to buffer flags changes. This ensures that
we almost never call functions for nothing. The flags settings
are still quite coarse, but the number of average functions
calls per session has dropped from 31 to 18 (the calls to
process_srv dropped from 13 to 7 and the calls to process_cli
dropped from 13 to 8).

This could still be improved by memorizing which flags each
function uses, but that would add a level of complexity which
is not desirable and maybe even not worth the small gain.
2008-08-17 01:15:41 +02:00
Willy Tarreau
e393fe224b [MEDIUM] buffers: add BF_EMPTY and BF_FULL to remove dependency on req/rep->l
It is not always convenient to run checks on req->l in functions to
check if a buffer is empty or full. Now the stream_sock functions
set flags BF_EMPTY and BF_FULL according to the buffer contents. Of
course, functions which touch the buffer contents adjust the flags
too.
2008-08-16 22:18:07 +02:00
Willy Tarreau
ba392cecf9 [CLEANUP] get rid of BF_SHUT*_PENDING
BF_SHUTR_PENDING and BF_SHUTW_PENDING were poor ideas because
BF_SHUTR is the pending of BF_SHUTW_DONE and BF_SHUTW is the
pending of BF_SHUTR_DONE. Remove those two useless and confusing
"pending" versions and rename buffer_shut{r,w}_* functions.
2008-08-16 21:13:23 +02:00
Willy Tarreau
a7c52761b4 [BUG] process_response: do not touch srv_state
process_response is not allowed to touch srv_state (this is an
incident which has survived the code migration). This bug was
causing connection exhaustion on frontend due to some closed
sockets marked SV_STDATA again.
2008-08-16 18:40:18 +02:00
Willy Tarreau
d9f483646d [BUG] buffers: remove BF_MAY_CONNECT and fix forwarding issue
It wasn't really wise to separate BF_MAY_CONNECT and BF_MAY_FORWARD,
as it caused trouble in TCP mode because the connection was allowed
but not the forwarding. Remove BF_MAY_CONNECT.
2008-08-16 16:39:26 +02:00
Willy Tarreau
9a8c5de375 [BUG] process_response must not enable the read FD
Since the separation of TCP and HTTP state machines, the HTTP
code must not play anymore with the file descriptor status
without checking if they are closed. Remains of such practice
have caused busy loops under some circumstances (mainly when
client closed during headers response).
2008-08-16 16:11:07 +02:00
Willy Tarreau
f853320b44 [MINOR] term_trace: add better instrumentations to trace the code
A new member has been added to the struct session. It keeps a trace
of what block of code performs a close or a shutdown on a socket, and
in what sequence. This is extremely convenient for post-mortem analysis
where flag combinations and states seem impossible. A new ABORT_NOW()
macro has also been added to make the code immediately segfault where
called.
2008-08-16 14:55:08 +02:00
Willy Tarreau
1ae3a057df [MEDIUM] remove unused references to {CL|SV}_STSHUT*
All references to CL_STSHUT* and SV_STSHUT* were removed where
possible. Some of them could not be removed because they are
still in use by the unix sockets.

A bug remains at this stage. Injecting with a very short timeout
sometimes leads to a client in close state and a server in data
state with all buffer flags indicating a shutdown but the server
fd still enable, thus causing a busy loop.
2008-08-16 10:56:30 +02:00
Willy Tarreau
461f662846 [MAJOR] clearly separate HTTP response processing from TCP server state
The HTTP response is now processed in its own function, regardless of
the TCP state. All FSMs have become fairly simpler and must still be
improved by removing useless CL_STSHUT* and SV_STSHUT* (still used by
proto_uxst). The number of calls to process_* is still huge though.

Next steps consist in :
  - removing useless assignments of CL_STSHUT* and SV_STSHUT*
  - add a BF_EMPTY flag to buffers to indicate an empty buffer
  - returning smarter values in process_* so that each callee
    may explicitly indicate whom needs to be called after it.
  - unify read and write timeouts for a same side. The way it
    is now is too complicated and error-prone
  - auditing code for regression testing

We're close to getting something which works fairly better now.
2008-08-15 23:43:19 +02:00
Willy Tarreau
cebf57e0bf [MAJOR] better separation of response processing and server state
TCP timeouts are not managed anymore by the response FSM. Warning,
the FORCE_CLOSE state does not work anymore for now. All remaining
bugs causing stale connections have been swept.
2008-08-15 18:16:37 +02:00
Willy Tarreau
f5483bf639 [MAJOR] get rid of the SV_STHEADERS state
The HTTP response code has been moved to a specific function
called "process_response" and the SV_STHEADERS state has been
removed and replaced with the flag AN_RTR_HTTP_HDR.
2008-08-14 18:35:40 +02:00
Willy Tarreau
e46ab5524f [BUG] fix recently introduced loop when client closes early
Due to a recent change in the FSMs, if the client closes with buffer
full, then the server loops waiting for headers. We can safely ignore
this case since the server FSM will have to be reworked too. Let's
fix the root cause for now.
2008-08-14 00:18:39 +02:00
Willy Tarreau
c65a3ba3d4 [MAJOR] completely separate HTTP and TCP states on the request path
For the first time, HTTP and TCP are not merged anymore. All request
processing has moved to process_request while the TCP processing of
the frontend remains in process_cli. The code is a lot cleaner,
simpler, smaller (1%) and slightly faster (1% too).

Right now, the HTTP state machine cannot easily command the TCP
state machine, but it does not cause that many difficulties.

The response processing has not yet been extracted, and the unix-stream
state machines have to be broken down that way too.

The CL_STDATA, CL_STSHUTR and CL_STSHUTW states still exist and are
exactly the sames. They will have to be all merged into CL_STDATA
once the work has stabilized. It is also possible that this single
state will disappear in favor of just buffer flags.
2008-08-14 00:18:39 +02:00
Willy Tarreau
7f875f6c8f [MEDIUM] simplify and centralize request timeout cancellation and request forwarding
Instead of playing with req->flags and request timeout everywhere,
tweak them only at precise locations.
2008-08-14 00:18:38 +02:00
Willy Tarreau
adfb8569f7 [MAJOR] get rid of SV_STANALYZE (step 2)
The SV_STANALYZE state was installed on the server side but was really
meant to be processed with the rest of the request on the client side.
It suffered from several issues, mostly related to the way timeouts were
handled while waiting for data.

All known issues related to timeouts during a request - and specifically
a request involving body processing - have been raised and fixed. At this
point, the code is a bit dirty but works fine, so next steps might be
cleanups with an ability to come back to the current state in case of
trouble.
2008-08-14 00:18:38 +02:00
Willy Tarreau
67f0eead22 [MAJOR] kill CL_STINSPECT and CL_STHEADERS (step 1)
This is a first attempt at separating data processing from the
TCP state machine. Those two states have been replaced with flags
in the session indicating what needs to be analyzed. The corresponding
code is still called before and in lieu of TCP states.

Next change should get rid of the specific SV_STANALYZE which is in
fact a client state.

Then next change should consist in making it possible to analyze
TCP contents while being in CL_STDATA (or CL_STSHUT*).
2008-08-14 00:18:38 +02:00
Aleksandar Lazic
697bbb0106 [PATCH] appsessions: cleanup DEBUG_HASH and initialize request_counter
This patch cleanup the -DDEBUG=DEBUG_HASH output setting and initialize
the request_counter for the appsessions.
2008-08-13 23:43:26 +02:00
Willy Tarreau
9f1f24bb7f [BUG] client timeout incorrectly rearmed while waiting for server
Client timeout could be refreshed in stream_sock_*, but this is
undesired when the timeout is already set to eternity. The effect
is that a session could still be aborted if client timeout was
smaller than server timeout. A second effect is that sessions
expired on the server side would expire with "cD" flags.

The fix consists in not updating it if it was not previously set.
A cleaner method might consist in updating the buffer timeout. This
is probably what will be done later when the state machines only
deal with the buffers.
2008-08-11 11:34:18 +02:00
Willy Tarreau
ce09c52187 [BUG] server timeout was not considered in some circumstances
Due to a copy-paste typo, the client timeout was refreshed instead
of the server's when waiting for server response. This means that
the server's timeout remained eternity.
2008-08-11 11:34:16 +02:00
Willy Tarreau
fb0528bd56 [BUG] fix segfault with url_param + check_post
If an HTTP/0.9-like POST request is sent to haproxy while
configured with url_param + check_post, it will crash. The
reason is that the total buffer length was computed based
on req->total (which equals the number of bytes read) and
not req->l (number of bytes in the buffer), thus leading
to wrong size calculations when calling memchr().

The affected code does not look like it could have been
exploited to run arbitrary code, only reads were performed
at wrong locations.
2008-08-11 11:34:01 +02:00
Willy Tarreau
718f0ef129 [MEDIUM] process_cli: don't rely at all on server state
A new buffer flag BF_MAY_FORWARD has been added so that the client
FSM can check whether it is allowed to forward the response to the
client. The client FSM does not have to monitor the server state
anymore.
2008-08-10 16:21:32 +02:00
Willy Tarreau
dc0a6a0dea [MEDIUM] process_srv: don't rely at all on client state
A new buffer flag BF_MAY_CONNECT has been added so that the server
FSM can check whether it is allowed to establish a connection or
not. That way, the client FSM only has to move this flag and the
server side does not need to monitor client state anymore.
2008-08-03 22:47:10 +02:00
Willy Tarreau
6468d924ea [MEDIUM] process_srv: rely on buffer flags for client shutdown
The open/close nature of each half of the client side is known
to the buffer, so let the server state machine rely on this
instead of checking the client state for CL_STSHUT* or
CL_STCLOSE.
2008-08-03 20:48:51 +02:00
Willy Tarreau
89edf5e629 [MEDIUM] buffers: ensure buffer_shut* are properly called upon shutdowns
It is important that buffer states reflect the state of both sides so
that we can remove client and server state inter-dependencies.
2008-08-03 20:48:50 +02:00
Ross West
af72a1d8ec [MINOR] permit renaming of x-forwarded-for header
Because I needed it in my situation - here's a quick patch to
allow changing of the "x-forwarded-for" header by using a suboption to
"option forwardfor".

Suboption "header XYZ" will set the header from "x-forwarded-for" to "XYZ".

Default is still "x-forwarded-for" if the header value isn't defined.
Also the suboption 'except a.b.c.d/z' still works on the same line.

So it's now: option forwardfor [except a.b.c.d[/z]] [header XYZ]
2008-08-03 10:51:45 +02:00
Willy Tarreau
0ceba5af74 [MEDIUM] acl: set types on all currently known ACL verbs
All currently known ACL verbs have been assigned a type which makes
it possible to detect inconsistencies, such as response values used
in request rules.
2008-07-25 19:31:03 +02:00
Willy Tarreau
ec6c5df018 [CLEANUP] remove many #include <types/xxx> from C files
It should be stated as a rule that a C file should never
include types/xxx.h when proto/xxx.h exists, as it gives
less exposure to declaration conflicts (one of which was
caught and fixed here) and it complicates the file headers
for nothing.

Only types/global.h, types/capture.h and types/polling.h
have been found to be valid includes from C files.
2008-07-16 10:30:42 +02:00
Willy Tarreau
284648e079 [CLEANUP] remove unused include/types/client.h
This file is not used anymore.
2008-07-16 10:30:40 +02:00
Willy Tarreau
b686644ad8 [MAJOR] implement tcp request content inspection
Some people need to inspect contents of TCP requests before
deciding to forward a connection or not. A future extension
of this demand might consist in selecting a server farm
depending on the protocol detected in the request.

For this reason, a new state CL_STINSPECT has been added on
the client side. It is immediately entered upon accept() if
the statement "tcp-request inspect-delay <xxx>" is found in
the frontend configuration. Haproxy will then wait up to
this amount of time trying to find a matching ACL, and will
either accept or reject the connection depending on the
"tcp-request content <action> {if|unless}" rules, where
<action> is either "accept" or "reject".

Note that it only waits that long if no definitive verdict
can be found earlier. That generally implies calling a fetch()
function which does not have enough information to decode
some contents, or a match() function which only finds the
beginning of what it's looking for.

It is only at the ACL level that partial data may be processed
as such, because we need to distinguish between MISS and FAIL
*before* applying the term negation.

Thus it is enough to add "| ACL_PARTIAL" to the last argument
when calling acl_exec_cond() to indicate that we expect
ACL_PAT_MISS to be returned if some data is missing (for
fetch() or match()). This is the only case we may return
this value. For this reason, the ACL check in process_cli()
has become a lot simpler.

A new ACL "req_len" of type "int" has been added. Right now
it is already possible to drop requests which talk too early
(eg: for SMTP) or which don't talk at all (eg: HTTP/SSL).

Also, the acl fetch() functions have been extended in order
to permit reporting of missing data in case of fetch failure,
using the ACL_TEST_F_MAY_CHANGE flag.

The default behaviour is unchanged, and if no rule matches,
the request is accepted.

As a side effect, all layer 7 fetching functions have been
cleaned up so that they now check for the validity of the
layer 7 pointer before dereferencing it.
2008-07-16 10:29:07 +02:00
Willy Tarreau
11382813a1 [TESTS] added test-acl.cfg to test some ACL combinations
various rules constructions can be tested with this test case.
2008-07-09 16:18:21 +02:00
Willy Tarreau
a8cfa34a9c [BUG] use_backend would not correctly consider "unless"
A copy-paste typo made use_backend not correctly consider the "unless"
case, depending on the previous "block" rule.
2008-07-09 11:23:31 +02:00
Willy Tarreau
0c303eec87 [MAJOR] convert all expiration timers from timeval to ticks
This is the first attempt at moving all internal parts from
using struct timeval to integer ticks. Those provides simpler
and faster code due to simplified operations, and this change
also saved about 64 bytes per session.

A new header file has been added : include/common/ticks.h.

It is possible that some functions should finally not be inlined
because they're used quite a lot (eg: tick_first, tick_add_ifset
and tick_is_expired). More measurements are required in order to
decide whether this is interesting or not.

Some function and variable names are still subject to change for
a better overall logics.
2008-07-07 00:09:58 +02:00
Willy Tarreau
91e99931b7 [MEDIUM] introduce task->nice and boot access to statistics
The run queue scheduler now considers task->nice to queue a task and
to pick a task out of the queue. This makes it possible to boost the
access to statistics (both via HTTP and UNIX socket). The UNIX socket
receives twice as much a boost as the HTTP socket because it is more
sensible.
2008-06-30 07:51:00 +02:00
Willy Tarreau
284c7b3195 [BUG] disable buffer read timeout when reading stats
The buffer read timeouts were not reset when stats were produced. This
caused unneeded wakeups.
2008-06-29 16:38:43 +02:00
Willy Tarreau
b7f694f20e [MEDIUM] implement a monotonic internal clock
If the system date is set backwards while haproxy is running,
some scheduled events are delayed by the amount of time the
clock went backwards. This is particularly problematic on
systems where the date is set at boot, because it seldom
happens that health-checks do not get sent for a few hours.

Before switching to use clock_gettime() on systems which
provide it, we can at least ensure that the clock is not
going backwards and maintain two clocks : the "date" which
represents what the user wants to see (mostly for logs),
and an internal date stored in "now", used for scheduled
events.
2008-06-22 17:18:02 +02:00
Willy Tarreau
7c669d7e0f [BUG] fix the dequeuing logic to ensure that all requests get served
The dequeuing logic was completely wrong. First, a task was assigned
to all servers to process the queue, but this task was never scheduled
and was only woken up on session free. Second, there was no reservation
of server entries when a task was assigned a server. This means that
as long as the task was not connected to the server, its presence was
not accounted for. This was causing trouble when detecting whether or
not a server had reached maxconn. Third, during a redispatch, a session
could lose its place at the server's and get blocked because another
session at the same moment would have stolen the entry. Fourth, the
redispatch option did not work when maxqueue was reached for a server,
and it was not possible to do so without indefinitely hanging a session.

The root cause of all those problems was the lack of pre-reservation of
connections at the server's, and the lack of tracking of servers during
a redispatch. Everything relied on combinations of flags which could
appear similarly in quite distinct situations.

This patch is a major rework but there was no other solution, as the
internal logic was deeply flawed. The resulting code is cleaner, more
understandable, uses less magics and is overall more robust.

As an added bonus, "option redispatch" now works when maxqueue has
been reached on a server.
2008-06-20 15:08:06 +02:00
Willy Tarreau
7008987813 [BUG] queue management: wake oldest request in queues
When a server terminates a connection, the next session in its
own queue was immediately processed. Because of this, if all
server queues are always filled, then no new anonymous request
will be processed. Consider oldest request between global and
server queues to choose from which to pick the request.

An improvement over this will consist in adding a configurable
offset when comparing expiration dates, so that cookie-less
requests can get either less or more priority.
2008-06-20 15:07:40 +02:00
Willy Tarreau
b463dfb2de [MEDIUM] add support for conditional HTTP redirection
A new "redirect" keyword adds the ability to send an HTTP 301/302/303
redirection to either an absolute location or to a prefix followed by
the original URI. The redirection is conditionned by ACL rules, so it
becomes very easy to move parts of a site to another site using this.

This work was almost entirely done at Exceliance by Emeric Brun.

A test-case has been added in the tests/ directory.
2008-06-07 23:08:56 +02:00
Krzysztof Piotr Oledzki
1acf217366 [BUG/CLEANUP] cookiedomain -> cookie_domain rename + free(p->cookie_domain)
Rename cookiedomain -> cookie_domain to be consistent with current
naming scheme. Also make sure cookie_domain is deallocated at deinit()
2008-05-30 07:03:22 +02:00
Krzysztof Piotr Oledzki
efe3b6f524 [MINOR] Allow to specify a domain for a cookie
This patch allows to specify a domain used when inserting a cookie
providing a session stickiness. Usefull for example with wildcard domains.

The patch adds one new variable to the struct proxy: cookiedomain.
When set the domain is appended to a Set-Cookie header.

Domain name is validated using the new invalid_domainchar() function.
It is basically invalid_char() limited to [A-Za-z0-9_.-]. Yes, the test
is too trivial and does not cover all wrong situations, but the main
purpose is to detect most common mistakes, not intentional abuses.

The underscore ("_") character is not RFC-valid but as it is
often (mis)used so I decided to allow it.
2008-05-25 10:09:02 +02:00
matt.farnsworth@nokia.com
1c2ab96be5 [MAJOR] implement parameter hashing for POST requests
This patch extends the "url_param" load balancing method by introducing
the "check_post" option. Using this option enables analysis of the beginning
of POST requests to search for the specified URL parameter.

The patch also fixes a few minor typos in comments that were discovered
during code review.
2008-04-15 15:30:41 +02:00
Willy Tarreau
f899b94e63 [BUG] fix double-decrement of server connections
If a client does a sudden dirty close (CL_STCLOSE) during a server
connect turn-around, then the number of server connections is
decremented twice. This causes huge problems on the affected
server because when its connection number becomes negative, it
overflows and prevents the server from accepting new connections
due to an apparent saturation.

The fix consists in not decrementing the counter if the server is
in a turn-around state.
2008-03-28 18:19:05 +01:00
Willy Tarreau
39f7e6d516 [MEDIUM] fix stats socket limitation to 16 kB
Due to the way the stats socket work, it was not possible to
maintain the information related to the command entered, so
after filling a whole buffer, the request was lost and it was
considered that there was nothing to write anymore.

The major reason was that some flags were passed directly
during the first call to stats_dump_raw() instead of being
stored persistently in the session.

To definitely fix this problem, flags were added to the stats
member of the session structure.

A second problem appeared. When the stats were produced, a first
call to client_retnclose() was performed, then one or multiple
subsequent calls to buffer_write_chunks() were done. But once the
stats buffer was full and a reschedule operated, the buffer was
flushed, the write flag cleared from the buffer and nothing was
done to re-arm it.

For this reason, a check was added in the proto_uxst_stats()
function in order to re-call the client FSM when data were added
by stats_dump_raw(). Finally, the whole unix stats dump FSM was
rewritten to avoid all the magics it depended on. It is now
simpler and looks more like the HTTP one.
2008-03-17 22:08:01 +01:00
Willy Tarreau
51406233bb [MAJOR] implementation of the "leastconn" load balancing algorithm
The new "leastconn" LB algorithm selects the server which has the
least established or pending connections. The weights are considered,
so that a server with a weight of 20 will get twice as many connections
as the server with a weight of 10.

The algorithm respects the minconn/maxconn settings, as well as the
slowstart since it is a dynamic algorithm. It also correctly supports
backup servers (one and all).

It is generally suited for protocols with long sessions (such as remote
terminals and databases), as it will ensure that upon restart, a server
with no connection will take all new ones until its load is balanced
with others.

A test configuration has been added in order to ease regression testing.
2008-03-10 22:04:30 +01:00
Krzysztof Piotr Oledzki
5a329cf017 [MEDIUM]: Prevent redispatcher from selecting the same server, version #3
When haproxy decides that session needs to be redispatched it chose a server,
but there is no guarantee for it to be a different one. So, it often
happens that selected server is exactly the same that it was previously, so
a client ends up with a 503 error anyway, especially when one sever has
much bigger weight than others.

Changes from the previous version:
 - drop stupid and unnecessary SN_DIRECT changes

 - assign_server(): use srvtoavoid to keep the old server and clear s->srv
    so SRV_STATUS_NOSRV guarantees that t->srv == NULL (again)
    and get_server_rr_with_conns has chances to work (previously
    we were passing a NULL here)

 - srv_redispatch_connect(): remove t->srv->cum_sess and t->srv->failed_conns
   incrementing as t->srv was guaranteed to be NULL

 - add avoididx to get_server_rr_with_conns. I hope I correctly understand this code.

 - fix http_flush_cookie_flags() and move it to assign_server_and_queue()
   directly. The code here was supposed to set CK_DOWN and clear CK_VALID,
   but: (TX_CK_VALID | TX_CK_DOWN) == TX_CK_VALID == TX_CK_MASK so:
	if ((txn->flags & TX_CK_MASK) == TX_CK_VALID)
		txn->flags ^= (TX_CK_VALID | TX_CK_DOWN);
   was really a:
	if ((txn->flags & TX_CK_MASK) == TX_CK_VALID)
		txn->flags &= TX_CK_VALID

   Now haproxy logs "--DI" after redispatching connection.

 - defer srv->redispatches++ and s->be->redispatches++ so there
   are called only if a conenction was redispatched, not only
   supposed to.

 - don't increment lbconn if redispatcher selected the same sarver

 - don't count unsuccessfully redispatched connections as redispatched
   connections

 - don't count redispatched connections as errors, so:

 - the number of connections effectively served by a server is:
 srv->cum_sess - srv->failed_conns - srv->retries - srv->redispatches
   and
 SUM(servers->failed_conns) == be->failed_conns

 - requires the "Don't increment server connections too much + fix retries" patch

 - needs little more testing and probably some discussion so reverting to the RFC state

Tests #1:
 retries 4
 redispatch

i) 1 server(s): b (wght=1, down)
  b) sessions=5, lbtot=1, err_conn=1, retr=4, redis=0
  -> request failed

ii) server(s): b (wght=1, down), u (wght=1, down)
  b) sessions=4, lbtot=1, err_conn=0, retr=3, redis=1
  u) sessions=1, lbtot=1, err_conn=1, retr=0, redis=0
  -> request FAILED

iii) 2 server(s): b (wght=1, down), u (wght=1, up)
  b) sessions=4, lbtot=1, err_conn=0, retr=3, redis=1
  u) sessions=1, lbtot=1, err_conn=0, retr=0, redis=0
  -> request OK

iv) 2 server(s): b (wght=100, down), u (wght=1, up)
  b) sessions=4, lbtot=1, err_conn=0, retr=3, redis=1
  u) sessions=1, lbtot=1, err_conn=0, retr=0, redis=0
  -> request OK

v) 1 server(s): b (down for first 4 SYNS)
  b) sessions=5, lbtot=1, err_conn=0, retr=4, redis=0
  -> request OK

Tests #2:
 retries 4

i) 1 server(s): b (down)
  b) sessions=5, lbtot=1, err_conn=1, retr=4, redis=0
  -> request FAILED
2008-03-04 06:16:37 +01:00
Krzysztof Piotr Oledzki
626a19b66f [BUG] Don't increment server connections too much + fix retries
Commit 98937b8757 while fixing
one bug introduced another one. With "retries 4" and
"option redispatch" haproxy tries to connect 4 times to
one server server and 1 time to a second one. However
logs showed 5 connections to the first server (the
last one was counted twice) and 2 to the second.

This patch also fixes srv->retries and be->retries increments.

Now I get: 3 retries and 1 error in a first server (4 cum_sess)
and 1 error in a second server (1 cum_sess) with:
 retries 4
 option redispatch

and: 4 retries and 1 error (5 cum_sess) with:
 retries 4

So, the number of connections effectively served by a server is:
 srv->cum_sess - srv->failed_conns - srv->retries
2008-03-04 06:11:17 +01:00
Ryan Warnick
6d0b1fac23 [BUG] appsession lookup in URL does not work
We've been trying to use the latest release (1.3.14.2) of haproxy  to do
sticky sessions.  Cookie insertion is not an option for us, although we
would much rather use it, as we are trying to work around a problem where
cookies are unreliable.  The appsession functionality only partially worked
(it wouldn't read the session id out of a query string) until we made the
following code change to the get_srv_from_appsession function in
proto_http.c.
2008-02-17 11:24:35 +01:00
Willy Tarreau
50fd1e1e3b [BUG] failed conns were sometimes incremented in the frontend! 2008-02-15 10:09:15 +01:00
Willy Tarreau
e69eada057 [OPTIM] used unsigned ints for HTTP state and message offsets
State and offsets within http_msg were incorrectly set to signed int.
Turning them into unsigned slightly improved performance while reducing
code size.
2008-02-14 23:14:30 +01:00
Willy Tarreau
21d2af3e9f Revert "[BUILD] backend.c and checks.c did not build without tproxy !"
This reverts commit 3c3c0122f8.
This commit was buggy as it also removed previous tproxy changes !
2008-02-14 20:25:24 +01:00
Willy Tarreau
3c3c0122f8 [BUILD] backend.c and checks.c did not build without tproxy !
missing #ifdefs.
2008-02-13 22:22:56 +01:00
Willy Tarreau
9c33612f53 [MEDIUM] completely implement the server redirection method
Now when a server has "redir <prefix>" on its config line, any HEAD or GET
request addressing it will lead to a 302 with Location set to "<prefix>"
immediately followed by the relative URI of the incoming request. This makes
it very easy to send redirect to browsers to check remote static servers, as
well as to provide redirection for remote sites when the local one is down.
2008-02-13 00:55:49 +01:00
Krzysztof Piotr Oledzki
f1e1cb463f [BUG]: Restore clearing t->logs.bytes
Commit 8b3977ffe3 removed "t->logs.bytes_in = 0;"
but instead it should change it into "t->logs.bytes_out = 0;" as since
583bc96606 counters are incremented not set.

It should be incremented in session_process_counters while sending data to a
client:
        bytes = s->rep->total - s->logs.bytes_out;
        s->logs.bytes_out = s->rep->total;

However, if we increment (set) s->logs.bytes_out while processing
"logasap", statistics get wrong values added for headers: 0 or even
negative if haproxy adds some headers itself.

To test it, please enable logasap and download one empty file and look at
stats. Without my fix information available on that page are invalid, for
example:

# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,
www,b,0,0,0,1,,1,24,-92,,0,,0,0,0,,UP,1,1,0,0,0,3121,0,,1,2,1,,1,
www,BACKEND,0,0,0,1,0,1,24,-92,0,0,,0,0,0,0,UP,1,1,0,,0,3121,0,,1,2,0,,1,
2008-01-22 10:30:26 +01:00
Willy Tarreau
b881608e57 [BUILD] code did not build in full debug mode 2008-01-18 12:18:15 +01:00
Willy Tarreau
8b3977ffe3 [BUG] log response byte count, not request
Due to a shameless copy-paste typo, the number of bytes logged was
from the request and not the response. This bug has been present
for a long time.
2008-01-18 11:16:32 +01:00
Willy Tarreau
00559e7117 [BUG] fix typo in redispatched connection
a copy-paste typo was present in the reconnection code responsible
for respatching. The client's FSM would not be re-evaluated if an
error occurred. It looks harmless but better fix it.
2008-01-06 23:46:19 +01:00
Willy Tarreau
541b5c24ca [MEDIUM] add a turn-around state of one second after a connection failure
Several users have complained that when haproxy gets a connection
failure due to an active reject from a server, it immediately
retries, often leading to the same situation being repeated until
the retry counter reaches zero.

Now if a connection error shows up, a turn-around state of 1 second
is applied before retrying. This is performed by faking a connection
timeout in order not to touch much code. However, a cleaner method
would involve an extra state.
2008-01-06 23:34:21 +01:00
Krzysztof Piotr Oledzki
25b501a6b1 [MEDIUM]: Count retries and redispatches also for servers, fix redistribute_pending, extend logs, %d->%u cleanup
This patch extends a little previously added functionality to also
count retries and redispatches for servers. Now it is possible to know
which server causes redispatches as it is not always the same that takes
most retries.

While working with the code I found that redistribute_pending() does not increment
srv->redispatches && be->redispatches. I don't know how to test it but
I think the fix is correct. If not I can withdraw it.

I also extended logs to show how many retries were done and if redispatching
was necessary ('+'). I'm using an additional session flag SN_REDISP to match
redispatched connections. I had to rearrange all defines in session.h to make
more room for it.

The documentation about logs was also fixed a little (sorry, english only),
as current version uses totally different format. BTW: examples are still
outdated, maybe next time...

Finally, I changed %d -> %u for retries/redispatches as those variables
are declared as unsigned.
2008-01-06 16:43:05 +01:00
Willy Tarreau
98937b8757 [BUG] increment server connections for each connect()
It was abnormal to see more connect errors than connect attempts.
This was caused by the fact that the server's connection count was
not incremented for failed connect() attempts.

Now the per-server connections are correctly incremented for each
connect() attempt. This includes the retries too. The number of
connections effectively served by a server will then be :

   srv->cum_sess - srv->errors - srv->warnings
2008-01-06 15:43:38 +01:00
Willy Tarreau
036fae0ec9 [MEDIUM] introduce "timeout http-request" in frontends
In order to offer DoS protection, it may be required to lower the maximum
accepted time to receive a complete HTTP request without affecting the client
timeout. This helps protecting against established connections on which
nothing is sent. The client timeout cannot offer a good protection against
this abuse because it is an inactivity timeout, which means that if the
attacker sends one character every now and then, the timeout will not
trigger. With the HTTP request timeout, no matter what speed the client
types, the request will be aborted if it does not complete in time.
2008-01-06 13:24:40 +01:00
Krzysztof Oledzki
336d475d13 [MEDIUM]: Inversion for options
This patch adds a possibility to invert most of available options by
introducing the "no" keyword, available as an additional prefix.
If it is found arguments are shifted left and an additional flag (inv)
is set.

It allows to use all options from a current defaults section, except
the selected ones, for example:

-- cut here --
defaults
        contimeout      4200
        clitimeout      50000
        srvtimeout      40000
        option contstats

listen stats 1.2.3.4:80
	no option contstats
-- cut here --

Currenly inversion works only with the "option" keyword.

The patch also moves last_checks calculation at the end of the readcfgfile()
function and changes "PR_O_FORCE_CLO | PR_O_HTTP_CLOSE" into "PR_O_FORCE_CLO"
in cfg_opts so it is possible to invert forceclose without breaking httpclose
(and vice versa) and to invert tcpsplice in one proxy but to keep a proper
last_checks value when tcpsplice is used in another proxy. Now, the code
checks for PR_O_FORCE_CLO everywhere it checks for PR_O_HTTP_CLOSE.

I also decided to depreciate "redisp" and "redispatch" keywords as it is IMHO
better to use "option redispatch" which can be inverted.

Some useful documentation were added and at the same time I sorted
(alfabetically) all valid options both in the code and the documentation.
2007-12-27 11:52:06 +01:00
Willy Tarreau
d7c30f9a8c [CLEANUP] grouped all timeouts in one structure
All known timeouts in a proxy have been grouped into a
"timeout" sub-structure.
2007-12-03 01:38:36 +01:00
Willy Tarreau
1fa3126ec4 [MEDIUM] introduce separation between contimeout, and tarpit + queue
Now the connect timeout, tarpit timeout and queue timeout are
distinct. In order to retain compatibility with older versions,
if either queue or tarpit is left unset both in the proxy and
in the default proxy, then it is inherited from the connect
timeout as before.
2007-12-03 00:36:16 +01:00
Willy Tarreau
b80c230f41 [MEDIUM] add the "fail" condition to monitor requests
Under certain circumstances, it is very useful to be able to fail some
monitor requests. One specific case is when the number of servers in
the backend falls below a certain level. The new "monitor fail" construct
followed by either "if"/"unless" <condition> makes it possible to specify
ACL-based conditions which will make the monitor return 503 instead of
200. Any number of conditions can be passed. Another use may be to limit
the requests to local networks only.
2007-11-30 20:51:32 +01:00
Alexandre Cassen
5eb1a9033a [MEDIUM] New option http_proxy
Hello,

You will find attached an updated release of previously submitted patch.
It polish some part and extend ACL engine to match IP and PORT parsed in
HTTP request. (and take care of comments made by Willy ! ;))

Best regards,
Alexandre
2007-11-29 15:43:32 +01:00
Krzysztof Piotr Oledzki
583bc96606 [MEDIUM] continous statistics
By default, counters used for statistics calculation are incremented
only when a session finishes. It works quite well when serving small
objects, but with big ones (for example large images or archives) or
with A/V streaming, a graph generated from haproxy counters looks like
a hedgehog.

This patch implements a contstats (continous statistics) option.
When set counters get incremented continuously, during a whole session.
Recounting touches a hotpath directly so it is not enabled by default,
as it has small performance impact (~0.5%).
2007-11-26 20:21:47 +01:00
Willy Tarreau
5df518788d [BUG] fix missing parenthesis in check_response_for_cacheability
Parenthesis were missed when code was moved to this function.
This results in non-cacheable transactions not being ignored.
2007-11-26 20:16:53 +01:00
Willy Tarreau
396d2c6782 [MINOR] avoid calling some layer7 functions if not needed
Small optimization: in some cases, it's not interesting to call
functions which are dedicated to checking the cache headers or
cookies. Avoid calling them when not necessary.
2007-11-04 22:41:49 +01:00
Willy Tarreau
fe94460d53 [BUG] fix calls to localtime()
localtime() was called with pointers to tv_sec, which is time_t on
some platforms and long on others. A problem was encountered on
Sparc64 under OpenBSD where tv_sec is long (64 bits) and time_t is
32 bits. Since this architecture is big-endian, it exhibited the
bug because localtime() always worked with the high part of the
value which is always zero. This problem was identified and debugged
by Thierry Fournier.

The correct solution is to pass the date by value and not by pointer,
through an intermediate function. The use of localtime_r() instead of
localtime() also made it possible to get rid of the first call to
localtime() since it does not need to allocate memory anymore.
2007-10-25 10:34:16 +02:00
Krzysztof Oledzki
1cf36ba3ae [MEDIUM] stats: count server retries and redispatches
It is important to know how your installation performs. Haproxy masks
connection errors, which is extremely good for a client but it is bad for
an administrator (except people believing that "ignorance is a bless").

Attached patch adds retries and redispatches counters, so now haproxy:

1. For server:
 - counts retried connections (masked or not)

2. For backends:
 - counts retried connections (masked or not) that happened to
    a slave server
 - counts redispatched connections
 - does not count successfully redispatched connections as backend errors.
    Errors are increased only when client does not get a valid response,
    in other words: with failed redispatch or when this function is not
    enabled.

3. For statistics:
 - display Retr (retries) and Redis (redispatches) as a "Warning"
   information.
2007-10-18 19:12:30 +02:00
Willy Tarreau
55bb8450c0 [MEDIUM] implement the CSV output for the statistics
It is now possible to get CSV ouput from the statistics by
simply appending ";csv" to the HTTP request sent to get the
stats. The fields keep the same ordering as in the HTML page,
and a field "pxname" has been prepended at the beginning of
the line.
2007-10-18 14:12:28 +02:00
Willy Tarreau
9186126e1c [MEDIUM] moved stats and buffer generic functions to new files
Neither the primitives used to write data to a buffer, nor the stats
dump functions are HTTP-specific anymore. Move them to dedicated
files
2007-10-18 14:12:21 +02:00
Krzysztof Oledzki
d9db9274fe [MINOR] report haproxy's version by default on the stats page
For people who manage many haproxies, it is sometimes convenient
to be informed of their version. This patch adds this, with the
option to disable this report by specifying "stats hide-version".

Also, the feature may be permanently disabled by setting the
STATS_VERSION_STRING to "" (empty string), or the format can
simply be adjusted.
2007-10-15 10:05:11 +02:00
Krzysztof Oledzki
9198ab5e7c [MEDIUM] do not add a cache-control: header when on non-cacheable responses
I noticed that haproxy, with "cookie (...) nocache" option, always adds
"Cache-control: private" at the end of a header list received from this
server:

Cache-Control: no-cache
(...)
Set-Cookie: SERVERID=s6; path=/
Cache-control: private

or:

Set-Cookie: ASPSESSIONIDCSRCTSSB=HCCBGGACGBHDHMMKIOILPHNG; path=/
Cache-control: private
Set-Cookie: SERVERID=s5; path=/
Cache-control: private

It may be just redundant (two "Cache-control: private"), but sometimes it
may be quite confused as we may end with two different, more and less
restricted directions (no-cache & private) and even quite conflicting
directions (eg. public & private):

So, I added and rearranged a code, so now haproxy adds a "Cache-control:
private" header only when there is no the same (private) or more
restrictive (no-cache) one. It was done in three steps:

1. Use check_response_for_cacheability to check if response is
not cacheable. I simply moved this call before http_header_add_tail2.

2. Use TX_CACHEABLE (not TX_CACHE_COOK - apache <= 1.3.26) to check if we
need to add a Cache-control header. If we add it, clear TX_CACHEABLE and
TX_CACHE_COOK.

3. Check cacheability not only with PR_O_CHK_CACHE but also with
PR_O_COOK_NOC, so:

-                           unlikely(t->be->options & PR_O_CHK_CACHE))
+                           (t->be->options & (PR_O_CHK_CACHE|PR_O_COOK_NOC)))
                                txn->flags |= TX_CACHEABLE | TX_CACHE_COOK;

I removed this unlikely since I believe that now it is not so unlikely.

The patch is definitely not perfect, proxy should probably also remove
"Cache-control: public". Unfortunately, I do not know the code good enough
to do in myself, yet. ;)

Anyway, I think that even now, it should be very useful.
2007-10-15 09:33:02 +02:00
Willy Tarreau
6e4261ee2f [MAJOR] timeouts and retries could be ignored when switching backend
When switching from a frontend to a backend, the "retries" parameter
was not kept, resulting in the impossibility to reconnect after the
first connection failure. This problem was reported and analyzed by
Krzysztof Oledzki.

While fixing the code, it appeared that some of the backend's timeouts
were not updated in the session when using "use_backend" or "default_backend".
It seems this had no impact but just in case, it's better to set them as
they should have been.
2007-10-15 09:32:19 +02:00
Willy Tarreau
51041c737c [MAJOR] remove files distributed under an obscure license
src/chtbl.c, src/hashpjw.c and src/list.c are distributed under
an obscure license. While Aleks and I believe that this license
is OK for haproxy, other people think it is not compatible with
the GPL.

Whether it is or not is not the problem. The fact that it rises
a doubt is sufficient for this problem to be addressed. Arnaud
Cornet rewrote the unclear parts with clean GPLv2 and LGPL code.
The hash algorithm has changed too and the code has been slightly
simplified in the process. A lot of care has been taken in order
to respect the original API as much as possible, including the
LGPL for the exportable parts.

The new code has not been thoroughly tested but it looks OK now.
2007-09-09 21:56:53 +02:00
Willy Tarreau
e7150cdcfa [MEDIUM] stats page: added links for 'refresh' and 'hide down'
The stats page now supports an option to hide servers which are DOWN
and to enable/disable automatic refresh. It is also possible to ask
for an immediate refresh.
2007-09-09 21:09:29 +02:00
Willy Tarreau
bbd42123e1 [MINOR] add support for "stats refresh <interval>"
Sometimes it may be desirable to automatically refresh the
stats page. Most browsers support the "Refresh:" header with
an interval in seconds. Specifying "stats refresh xxx" will
automatically add this header.
2007-09-09 21:09:28 +02:00
Willy Tarreau
4b946c8564 [MINOR] fix backend's weight in the stats page.
The GCD used when computing the servers' weights causes the total
weight of the backend to appear lower than expected because it is
divided by the GCD. Easy solution consists in recomputing the GCD
from the first server and apply it to the global weight.
2007-09-09 21:09:28 +02:00
Willy Tarreau
5af3a694f5 [MEDIUM] improve behaviour with large number of servers per proxy
When a very large number of servers is configured (thousands),
shutting down many of them at once could lead to large number
of calls to recalc_server_map() which already takes some time.
This would result in an O(N^3) computation time, leading to
noticeable pauses on slow embedded CPUs on test platforms.

Instead, mark the map as dirty and recalc it only when needed.
2007-09-09 21:09:28 +02:00
Willy Tarreau
8f8e645066 [CLEANUP] shut warnings 'is*' macros from ctype.h on solaris
Solaris visibly uses an array for is*, which returns warnings
about the use of signed chars as indexes. Good opportunity to
put casts everywhere.
2007-06-17 21:51:38 +02:00
Willy Tarreau
55ea7579d7 [MAJOR] added the 'use_backend' keyword for full content-switching
The new "use_backend" keyword permits full content switching by the
use of ACLs. Its usage is simple :

   use_backend <backend_name> {if|unless} <acl_cond>
2007-06-17 19:56:27 +02:00
Willy Tarreau
c11416f22f [MEDIUM] acl: distinguish between request and response headers
hdr(x) will now still be used for request headers, and shdr(x) for
server headers (response).
2007-06-17 16:58:38 +02:00
Willy Tarreau
c8d7c96b26 [MEDIUM] acl: support '-i' to ignore case when matching
Implemented the "-i" option on ACLs to state that the matching
will have to be performed for all patterns ignoring case. The
usage is :

   acl <aclname> <aclsubject> -i pattern1 ...

If a pattern must begin with "-", either it must not be the first one,
or the "--" option should be specified first.
2007-06-17 08:20:33 +02:00
Willy Tarreau
1ad7c6dd85 [MINOR] acl: permit to return any header when no name specified
Having the ability to match on hdr_xxx in addition to hdr_xxx(yyy)
makes it possible to match any value or to count the headers easily.
2007-06-10 21:42:55 +02:00
Willy Tarreau
737b0c12a6 [MEDIUM] acl: support maching on 'path' component
'path', 'path_reg', 'path_beg', 'path_end', 'path_sub', 'path_dir'
and 'path_dom' have been implemented to process the path component
of the URI. It starts after the host part, and stops before the
question mark.
2007-06-10 21:28:46 +02:00
Willy Tarreau
33a7e6901f [MEDIUM] acl: implement matching on header values
hdr(x), hdr_reg(x), hdr_beg(x), hdr_end(x), hdr_sub(x), hdr_dir(x),
hdr_dom(x), hdr_cnt(x) and hdr_val(x) have been implemented. They
apply to any of the possibly multiple values of header <x>.

Right now, hdr_val() is limited to integer matching, but it should
reasonably be upgraded to match long long ints.
2007-06-10 19:45:56 +02:00
Willy Tarreau
97be145991 [MINOR] acl: provide a reference to the expr to fetch()
The fetch() functions may need to access the full expr to get
their args. Turn the void *arg into a struct acl_expr *expr.
2007-06-10 11:47:14 +02:00
Willy Tarreau
d41f8d85e8 [MINOR] acl: specify the direction during fetches
Some fetches such as 'line' or 'hdr' need to know the direction of
the test (request or response). A new 'dir' parameter is now
propagated from the caller to achieve this.
2007-06-10 10:06:18 +02:00
Willy Tarreau
ae8b796722 [MEDIUM] smarter integer comparison support in ACLs
ACLs now support operators such as 'eq', 'le', 'lt', 'ge' and 'gt'
in order to give more flexibility to the language. Because of this
change, the 'dst_limit' keyword changed to 'dst_conn' and now requires
either a range or a test such as 'dst_conn lt 1000' which is more
understandable.
2007-06-09 23:10:04 +02:00
Willy Tarreau
fa64558402 [BUG] do not re-arm read timeout after writing data
A second occurrence of read-timeout rearming was present in stream_sock.c.
To fix the problem, it was necessary to put the shutdown information in
the buffer (already planned).
2007-06-03 16:03:49 +02:00
Willy Tarreau
33014d0d8d [BUG] do not re-arm read timeout in SHUTR state !
There is a long-time bug causing busy loops when either client-side
or server-side enters a SHUTR state. When writing data to the FD,
it was possible to re-arm the read side if the write had been paused.
2007-06-03 16:03:45 +02:00
Willy Tarreau
ee99136992 [BUG] pre-initialize timeouts with tv_eternity during parsing
ETERNITY is not 0 anymore, so all timeouts will not be initialized
to ETERNITY by a simple calloc(). We have to explictly assign them.

This bug caused random session aborts.
2007-05-14 14:37:50 +02:00
Willy Tarreau
cf7f320f9d [MAJOR] last bunch of capture changes for mempool v2
The header captures had lots of pools. They have all been transformed.
2007-05-13 22:46:04 +02:00
Willy Tarreau
086b3b4c9f [MAJOR] ported the captures to use the new mempool v2
The "capture.c" file has also been removed since it was empty.
2007-05-13 21:45:51 +02:00
Willy Tarreau
332f8bfc5b [MAJOR] ported requri to use mempools v2 2007-05-13 21:36:56 +02:00
Willy Tarreau
63963c62e7 [MAJOR] ported appsession to use mempools v2
Also during this process, a bug was found in appsession_refresh().
It would not automatically requeue the task in the queue, so the
old sessions would not vanish.
2007-05-13 21:29:55 +02:00
Willy Tarreau
a8b55e33da [MINOR] use non-inline tv_* functions in many locations
The __tv_* functions were abused. They are not that small and it is not
always worth using them.
2007-05-13 16:08:19 +02:00
Willy Tarreau
d825eef9c5 [MAJOR] replaced all timeouts with struct timeval
The timeout functions were difficult to manipulate because they were
rounding results to the millisecond. Thus, it was difficult to compare
and to check what expired and what did not. Also, the comparison
functions were heavy with multiplies and divides by 1000. Now, all
timeouts are stored in timevals, reducing the number of operations
for updates and leading to cleaner and more efficient code.
2007-05-12 22:35:00 +02:00
Willy Tarreau
f3d259868b [MINOR] ACL regex matching on the URI ; uri_reg
The URI can be matched on regexen now. The upcase/lowcase flag
can not be set yet and will soon have to.
2007-05-08 23:24:51 +02:00
Willy Tarreau
5c8e3e09e9 [MEDIUM] added the 'block' keyword to the config language
The new 'block' keyword makes it possible to block a request based on
ACL test results. Block accepts two optional arguments : 'if' <cond>
and 'unless' <cond>.

The request will be blocked with a 403 response if the condition is validated
(if) or if it is not (unless). Do not rely on this one too much, as it's more
of a proof of concept helping in developing other matches.
2007-05-08 23:24:51 +02:00
Willy Tarreau
8797c06327 [MEDIUM] added several ACL criteria and matches
Many ACL criteria have been added. Some others are still commented out
because some functions are still missing.
2007-05-08 23:24:50 +02:00
Willy Tarreau
c9b654b48b [BUG] fix early server close after client close
Problem reported by Andy Smith. If a client sends TCP data
and quickly closes the connection before the server connection
is established, AND the whole buffer can be sent at once when
the connection establishes, then the server side believes that
it can simply abort the connection because the buffer is empty,
without checking that some work was performed.

Fix: ensure that nothing was written before closing.
2007-05-08 14:46:53 +02:00
Willy Tarreau
9cdde230a5 [MEDIUM] always have msg->sol point to beginning of message
Since the 'data' pointer is not stored in message structures, it is
useful to have such a pointer to it when the message has been fully
parsed.
2007-05-08 14:05:14 +02:00
Willy Tarreau
42aae5c7cf [MEDIUM] many cleanups in the time functions
Now, functions whose name begins with '__tv_' are inlined. Also,
'tv_ms' is used as a prefix for functions using milliseconds.
2007-04-29 17:43:56 +02:00
Willy Tarreau
f41d4b15ee [MINOR] tell the compiler that debug more is unlikely to happen
In process_session(), add unlikely() around debug code.
2007-04-29 13:44:48 +02:00
Willy Tarreau
8d7d1497e0 [MEDIUM] implement and use tv_cmp2_le instead of tv_cmp2_ms
tv_cmp2_ms handles multiple combinations of tv1 and tv2, but only
one form is used: (tv1 <= tv2). So it is overkill to use it everywhere.
A new function designed to do exactly this has been written for that
purpose: tv_cmp2_le. Also, removed old unused tv_* functions.
2007-04-29 13:44:43 +02:00
Willy Tarreau
a6a6a93e56 [MAJOR] changed TV_ETERNITY to ~0 instead of 0
The fact that TV_ETERNITY was 0 was very awkward because it
required that comparison functions handled the special case.
Now it is ~0 and all comparisons are performed on unsigned
values, so that it is naturally greater than any other value.

A performance gain of about 2-5% has been noticed.
2007-04-29 13:44:24 +02:00
Willy Tarreau
96bcfd75aa [MAJOR] replaced rbtree with ul2tree.
The rbtree-based wait queue consumes a lot of CPU. Use the ul2tree
instead. Lots of cleanups and code reorganizations made it possible
to reduce the task struct and simplify the code a bit.
2007-04-29 13:43:53 +02:00
Willy Tarreau
9f195293de [MAJOR] remove useless calls to shutdown(SHUT_RD)
shutdown(SHUT_RD) is useless on data TCP sockets. It does nothing
and consumes one syscall. Remove it.
2007-04-15 21:26:58 +02:00
Willy Tarreau
663193882a [MEDIUM] factor FD_ISSET/FD_CLR and !FD_ISSET/FD_SET
Use the new FD_COND_C/FD_COND_S macros to reduce the number of
operations during tests and sets.
2007-04-08 17:17:37 +02:00
Willy Tarreau
f161a34fb3 [MEDIUM] updated all files to use EV_FD_*
Removed the temporary dirty hack.
2007-04-08 16:59:42 +02:00
Willy Tarreau
a9bd19853e [BUG] initialize msg->sol before parsing first line
Before calling http_parse_{sts,req}line(), it is necessary
to make msg->sol point to the beginning of the line. This
was not done, resulting in the proxy sometimes crashing when
URI rewriting or result rewriting was used.
2007-04-03 20:03:18 +02:00
Willy Tarreau
02785764a4 [BUG] Status line in HTTP response could not be rewritten
Typo implied use of HTTP_MSG_RQMETH state instead of HTTP_MSG_RPVER.
2007-04-03 14:45:44 +02:00
Willy Tarreau
422505801f [MEDIUM] splitted logs into two versions : TCP and HTTP
logs are handled better with dedicated functions. The HTTP implementation
moved to proto_http.c. It has been cleaned up a bit. Now a frontend with
option httplog and no log will not call the function anymore.
2007-04-01 01:30:43 +02:00
Willy Tarreau
e2e27a5c8d [MEDIUM] removed now unused fiprm and beprm from proxies
The fiprm and beprm were added to ease the transition between
a single listener mode to frontends+backends. They are no longer
needed and make the code a bit more complicated. Remove them.
2007-04-01 00:01:37 +02:00
Willy Tarreau
f2f0ee81ad [BUG] fix reqadd when no option httpclose is used.
Due to a code indentation mismatch, the rspadd headers were only
added if option httpclose was not set.
2007-03-30 12:02:43 +02:00
Willy Tarreau
2807efdb02 [MEDIUM] do not add Connection: close in HTTP/1.0 mode
If we already are in HTTP/1.0 and if no connection: has been seen,
it is not necessary to add Connection: close.
2007-03-25 23:47:23 +02:00
Willy Tarreau
f2b74c26c5 [CLEANUP] added a few missing newlines to the HTML report
Sometimes it is preferable that the HTML output can be parsed.
Ensure better use of the newlines for this.
2007-03-25 22:44:08 +02:00
Willy Tarreau
417fae0e60 [MINOR] changed server weight storage from char to unsigned int
This change does not affect memory usage much, but it simplifies the
code a lot by removing many +1/-1 operations on weights.
2007-03-25 21:16:40 +02:00
Willy Tarreau
7ac51f61f5 [MEDIUM] add the "except" keyword to the "forwardfor" option
Patch from Bryan Germann for 1.2.17.
In some circumstances, it is useful not to add the X-Forwarded-For
header, for instance when the client is another reverse-proxy or
stunnel running on the same machine and which already adds it. This
patch adds the "except" keyword to the "forwardfor" option, allowing
to specify an address or network which will not be added to this
header.
2007-03-25 16:00:04 +02:00
Willy Tarreau
aa9dce3bd6 [MINOR] added new function http_header_match2()
HTTP header matching is now made easier with http_header_match2().
Various locations have been adapted to use it. A small bug was also
fixed causing empty headers to be matched till next one.
2007-03-18 23:50:16 +01:00
Willy Tarreau
4af6f3a9ea [MINOR] HTTP: factorize all the header insertions
Two new functions http_header_add_tail() and http_header_add_tail2()
make it easier to append headers, and also reduce the number of
sprintf() calls and perform stricter checks.
2007-03-18 22:36:26 +01:00
Willy Tarreau
a5e65754e6 [MINOR] used http_flush_cookie_flags() instead of a dirty code block 2007-03-18 20:53:22 +01:00
Willy Tarreau
3d300596bb [MINOR] move some flags from session.h to proto_http.h
Some session flags were clearly related to HTTP transactions.
A new 'flags' field has been added to http_txn, and the
associated flags moved to proto_http.h.
2007-03-18 18:34:41 +01:00
Willy Tarreau
3bac9ffe20 [CLEANUP] move http_txn out of session.h
The http_txn structure definitions moved to proto_http.h
2007-03-18 17:31:28 +01:00
Willy Tarreau
b49871738e [MINOR] fix accounting for response bytes
A remaining reference to rep->h was replaced.
2007-03-18 16:28:03 +01:00
Willy Tarreau
a15645d435 [MAJOR] completed the HTTP response processing.
Now the response is correctly processed in the backend first
then in the frontend. It has followed intensive tests to
catch regressions, and everything seems OK now, but the code
is young anyway.
2007-03-18 16:22:39 +01:00
Willy Tarreau
117f59e282 [MINOR] code factoring : capture_headers() serves requests and responses
Both request and response captures will have to parse headers following
the same methods. It's better to factorize the code, hence the new
capture_headers() function.
2007-03-04 18:17:17 +01:00
Willy Tarreau
4b89ad4358 [MINOR] implement http_is_ver_token to fix response parsing
This new character map improves accuracy when parsing HTTP version,
which helps inspecting requests, and fixes response handling.
2007-03-04 18:13:58 +01:00
Willy Tarreau
bb046ac8c5 [MINOR] option forwardfor is for frontends too
Finally, if the "option forwardfor" is specified in the frontend
and not in the backend, apply it.
2007-03-03 20:54:01 +01:00
Willy Tarreau
4dbc4a2ee4 [CLEANUP] replaced occurrences of 'hreq' with 'txn'
In many places, the variable "hreq" designated a transaction more than
a request. This has been changed to avoid confusion.
2007-03-03 16:23:22 +01:00
Willy Tarreau
b326fcc46a [CLEANUP] renamed several HTTP structures
Some parts of HTTP processing were incorrectly called "request" while
they are messages or transactions. The following structure members
have changed :

  http_msg.hdr_state => msg_state
  http_msg.sor => som
  http_req.req_state => removed
  http_req => http_txn
2007-03-03 13:54:32 +01:00
Willy Tarreau
92f2ab1b1f [BUG] fix crash when no cookie is set on server
In cookie prefix or rewrite modes, if the elected server had no
cookie, a NULL pointer was passed to the rewrite function, causing
a SIGSEGV.
2007-02-02 22:14:47 +01:00
Willy Tarreau
b9ebf70a3a [CRITICAL] an empty header may lead to a crash
A missing pointer assignment in case of an empty header
will result in this header's length being 65535, causing
a SEGV when accessing the next header. It should not be
possible to exploit this problem to run arbitrary code
because the crash occurs while reading the data.
2007-01-26 23:39:38 +01:00
Willy Tarreau
f0d058e8ab [BUG] hdr_idx might be left uninitialized in some cases
When a request is invalid during RQ_BEFORE AND the debug mode is active,
the hdr_idx might be used uninitialized. Let's initialize it right after
the accept() for now.
2007-01-25 12:03:42 +01:00
Willy Tarreau
83969f42ba [MAJOR] invalid header offset broke cookies and authentication
Since the request is no longer part of the headers, cookies and
authentication did not work anymore. Obvious fix is to add the
request offset to the start pointer.
2007-01-22 08:55:47 +01:00
Willy Tarreau
8973c70f7d [MEDIUM] implemented the status-line parser in http_msg_analyzer().
The status line parser has been written. With it, it should not
be too hard to replace the response parser to benefit from the
new header facilities.
2007-01-21 23:58:29 +01:00
Willy Tarreau
362b34d05c [MINOR] move the response headers to the http_req 2007-01-21 20:49:31 +01:00
Willy Tarreau
8d5d7f20b9 [MAJOR] huge rework of the HTTP request FSM
The HTTP parser has been rewritten for better compliance to RFC2616.
The same parser is now usable for both requests and responses, and
it now supports HTTP/0.9 as well as multi-line headers. It has also
been improved for speed ; a typicial HTTP request is parsed in about
2 microseconds on a 1 GHz processor.

The monitor-uri check has been moved so that the requests are not
logged. The httpclose option now tries to change as little as
possible in the request, and does not affect the first header if
it is already set to 'close'. HTTP/0.9 requests are converted to
HTTP/1.0 before being forwarded.

Headers and request transformations are now distinct. The headers
list is updated after each insertion/removal/transformation. The
request is re-parsed and checked after each transformation. It is
not possible anymore to remove a request, and requests which lead
to invalid request lines are now rejected.
2007-01-21 19:16:41 +01:00
Willy Tarreau
0f7562b8d3 [MEDIUM] separate the http request from the session (step 1)
A struct http_req has been created to collect every information
related to an HTTP request being processed. Right now, it is
still in the struct session but the frontier is clear now.
2007-01-07 15:46:13 +01:00
Willy Tarreau
0214c3a307 [MEDIUM] Stats: add support for the HEAD method
There are browsers which sometimes send HEAD requests to the stats
page, but it was not handled so it returned a 503 server error or
was simply sent to the default backend servers.

Now with a HEAD request, the stats return the headers and finish
there. Normally, other methods should be blocked so that the stats
page really catches the whole URI. Other methods would need to cause
a 405 Method not allowed to be returned.
2007-01-07 13:47:30 +01:00
Willy Tarreau
733fef4add Merge branch 'tcpsplice' 2007-01-07 02:16:59 +01:00
Willy Tarreau
368e96ad88 [MINOR] [STATS] swap color sets for active and backup servers
colors had incidently been swapped during the stats page rewrite.
Thanks to Sin Yu for noticing it.
2007-01-07 02:08:18 +01:00
Willy Tarreau
6d1a9884f9 [MAJOR] complete support and doc for tcp-splicing
The tcp-splicing code has been merged, and a doc has been written.
A configuration example has been derived from the previous content
switching sample.
2007-01-07 02:03:04 +01:00
Willy Tarreau
35d66b0c28 [MINOR] added byte count to sessions and statistics.
Now the stats page reports the IN and OUT byte counts per FE,
BE and SRV.
2007-01-02 00:28:21 +01:00
Willy Tarreau
5fdfb911a0 [MEDIUM] implemented the "default_backend" keyword
The "default_backend" keyword used in a frontend sets the
default backend which will be used if no setbe rule matches.
2007-01-01 23:11:07 +01:00
Willy Tarreau
128e954663 [MINOR] stats: factorize many chunk_printf()
Improve code size, speed and readability by factoring many
calls to chunk_printf().
2007-01-01 22:01:43 +01:00
Willy Tarreau
c0dde7a8ed [MAJOR] udpated the stats page to clearly distinguish FEs and BEs
The stats page could not tell the difference between a FE and a BE.
It has been revamped to indicate all relevant information. The font
is also slightly smaller in order for all the info to fit into small
screens. The data output path has been greatly simplified to use
string chunks.
2007-01-01 21:38:07 +01:00
Willy Tarreau
2b5652f9fa [MINOR] indicate the proxy type in the logs after a loss of servers
When the last server goes down in a backend, indicate 'backend' or
'listener' in the log message depending on the type of the backend.
2006-12-31 17:46:05 +01:00
Willy Tarreau
e01954f45e [MINOR] option httpclose is now checked both in FE and BE
The "httpclose" option affects both frontend and backend, so it
was logical to check for its presence at both places. A request
which traverses either a frontend or a backend with this option
set will have a "Connection: close" header appended.
2006-12-30 23:43:54 +01:00
Willy Tarreau
97de624c17 [MEDIUM] session logging is now defined by the frontend
To solve the logging maze, it has been decided that the frontend
and nothing else will define how a session will be logged. It might
change in the future but at least this choice allows all sort of
fantasies.
2006-12-27 17:18:38 +01:00
Willy Tarreau
8058743d7a [MEDIUM] errorloc now checked first from backend then from frontend
It is now possible to define an errorloc in the backend as well as
in the frontend. The backend's will be used first, and if undefined,
then the frontend's will be used instead. If none is used, then the
original error messages will be used.
2006-12-24 17:47:20 +01:00
Willy Tarreau
0f77253a22 [MINOR] store HTTP error messages into a chunk array
HTTP error messages were all specific cases handled by an IF.
Now they are all in an array so that it will be easier to add
new ones. Also, the return functions now use chunks as inputs
so that it should be easier to provide alternative return
messages if needed.
2006-12-23 20:51:41 +01:00
Willy Tarreau
a496b6042b [MAJOR] merged the 'setbe' actions to switch the backend on a regex
Sin Yu's patch to permit to change the proxy from a regex was merged
with little changes :
  - req_cap/rsp_cap are not reassigned to the new proxy, they stay
    attached to the frontend

  - the actions have been renamed "reqsetbe" and "reqisetbe" for
    "set BackEnd".

  - the buffer is not reset after the switch, instead, the headers are
    parsed again by the backend

  - in Sin's patch, it was theorically possible to switch multiple times,
    but the switching track was lost, making it impossible to apply
    server responsesin the reverse order. Now switching is limited to
    1 action (separation between frontend and backend) but the filters
    remain.

Now it will be extremely easy to add other switching conditions, such
as host matching, URI matching, etc...

There's still a hard work to be done on the logs and stats.
2006-12-17 23:15:24 +01:00
Willy Tarreau
f1221aa19f [MEDIUM] separated nbconn into feconn and beconn
The nbconn attribute in the proxies was not relevant anymore because
a frontend A may use backend B and both of them must account for their
respective connections. For this reason, there now are two separate
counters for frontend and backend connections.

The stats page has been updated to reflect the backend, but a separate
line entry for the frontend with error counts would be good.

Note that as of now, beconn may be higher than maxconn, because maxconn
applies to the frontend, while beconn may be increased due to sessions
passed from another frontend.
2006-12-17 22:14:12 +01:00
Willy Tarreau
830ff458de [MAJOR] reworked ->be, ->fe and ->fi in sessions
There was a confusion about the way to find filters and backend
parameters from sessions. The chaining has been changed between
the session and the proxy.

Now, a session knows only two proxies : one frontend (->fe) and
one backend (->be). Each proxy has a link to the proxy providing
filters and to the proxy providing backend parameters (both self
by default).

The captures (cookies and headers) have been attached to the
frontend's filters for now.

The uri_auth and the statistics are attached to the backend's
filters so that the uri can depend on a hostname for instance.
2006-12-17 19:31:23 +01:00
Willy Tarreau
b251390f7e [MEDIUM] moved uri_auth check to a separate function
The check of uri_auth is now in a separate function which is
checked after every backend switch, so that it will be possible
to have an uri_auth for the frontend and another one for the
backend.
2006-12-17 14:52:38 +01:00
Willy Tarreau
921d7c0a70 [MINOR] removed the SN_POST flag and string checks on method
Now that hreq.meth is known, use it everywhere a method is required.
2006-12-17 13:50:27 +01:00
Willy Tarreau
53b6c74d06 [MEDIUM] check the HTTP method after all filters have been applied
The HTTP method is now checked and saved into hreq.meth. It will be
usable at several places instead of those dirty string comparisons.
2006-12-17 13:37:46 +01:00
Willy Tarreau
230fd0bfdf [MEDIUM] optimized the request parser a bit more
Some while() constructs are not very efficient with gcc, yet they are
used to scan all the text in the start line and the headers. Replacing
them with more efficient (but ugly) loops provides a global gain of
about 2%, which is not bad at all !
2006-12-17 12:05:00 +01:00
Willy Tarreau
976f1ee561 [MINOR] reorganized the request parser states to improve speed
The most commonly branched states have been grouped in the first
ifs.
2006-12-17 10:06:03 +01:00
Willy Tarreau
06619265b1 [MEDIUM] reorganized request handling to prepare for content-switching
The filters are now iterated for FE, FI, BE.

Some grey areas remain :
  - uri_auth has been propagated to the backend, but in fact it
    should be checked at every level (fe, fi, be), depending
    where it is declared, and before the filters.

  - the HTTP method and URI should be stored and propagated everywhere
    they are used. For this, we would need to first apply filters to
    be aware of filter changes which affect them.

  - there seems to be no need anymore for hdr_idx[0] being empty.
    It may contain the start line, which will slightly improve
    performance and make the code easier to read.
2006-12-17 08:37:22 +01:00
Willy Tarreau
45e73e3cd9 [MEDIUM] move all HTTP Request-related session material to struct hreq
The req_cap, hdr_state, hdr_idx, auth_hdr and req_line have been moved
to a dedicated hreq structure in the session. It makes is easier to
add HTTP-specific fields such as SOR (start of request) and EOF (end
of headers).

It also made it possible to fix two bugs introduced by last commit :
 - end of headers not correctly detected
 - hdr_idx not freed upon one specific error during session creation

When the backend side will be reworked, it should rely on a similar
structure.
2006-12-17 00:05:15 +01:00
Willy Tarreau
a4cd1f50cc [MEDIUM] make process_cli() not depend on req->h anymore
Local variables now keep the start and end of line at any moment.
req->h has been removed and will soon be removable from the buffer.
2006-12-16 19:57:26 +01:00
Willy Tarreau
f224273df3 [BUILD] last commit did not build 2006-12-16 19:00:29 +01:00
Willy Tarreau
e15d9132df [MEDIUM] reference and index appended request headers
When headers are appended to the end of a request, they must
be indexed.
2006-12-14 22:26:42 +01:00
Willy Tarreau
2a32428926 [MAJOR] finished replacement of the client-side HTTP parser with a new one
The code is working again, but not as clean as it could be.
Many blocks should still move to dedicated functions. req->h
must be removed everywhere and updated everytime needed.

A few functions or macros should take care of the headers
during header insertion/deletion/change.
2006-12-05 00:05:46 +01:00
Willy Tarreau
58f10d7478 [MAJOR] replaced the client-side HTTP parser with a new one
The new parser uses an FSM to strictly follow RFC2616.
Headers are indexed and parsed only once they're all available.
That way, complex regexes make more sense.

HTTP processing is now performed in several phases by calling
multiple functions, making the code cleaner and easier to read.

Note that req[i]pass does not work anymore because it would
require that we mark a header to be ignored. What is really
needed is to have the ability to add an exception to a matching
(match xx except yy).

Several bugs have been fixed in appsession during the conversion
to the new FSM (method length and recovery on malloc errors).

The code does build and work with the debug examples, but is
not usable yet to connect to anything as it does not forward
the requests yet.
2006-12-04 02:26:12 +01:00
Willy Tarreau
09536952b3 Merge branch 'rfc2616' into switch 2006-12-02 20:13:39 +01:00
Willy Tarreau
669e6da163 [BUG] implemented support for multi-line headers as required by RFC2616.
This patch was added in 1.2.9 but was then incidentely reverted by
  manipulation error when merging next patch (enforce max number of
  conns). It's now merged again.
2006-12-02 20:12:55 +01:00
Willy Tarreau
73de9899a6 [MAJOR] separate sess->proxy into sess->{fe,fi,be}
The references to the proxy from the session have been turned into
Frontend (fe), Filters (fi) and Backend (be). This should ease the
migration to the L7 switching features. Next step will be to kill
the struct proxy and have 3 independant structs instead, each
referenced from entities called listener, frontend, filters and
backend.
2006-11-30 11:40:23 +01:00
Willy Tarreau
b17916e89b [CLEANUP] add a few "const char *" where appropriate
As suggested by Markus Elfring, a few "const char *" have replaced
some "char *" declarations where a function is not expected to
modify a value. It does not change the code but it helps detecting
coding errors.
2006-10-15 15:17:57 +02:00
Willy Tarreau
2a429503e0 [MINOR] turn every FD_* into functions
On recent CPUs, functions are about twice as fast as inline FD_*, so
there is now a #define CONFIG_HAP_INLINE_FD_SET to choose between the
two modes.
2006-10-15 14:53:07 +02:00
Willy Tarreau
0bbc3cf157 [MEDIUM] fix broken redispatch option
Since the connection queueing was introduced, the "redispatch"
option could not cover the cases where a connection has been
refused by the server after having been marked "in progress".
The fix consists in doing a redispatch in the delayed connection
handling code.

Problem reported by Konrad Rzentarzewski.
2006-10-15 14:26:02 +02:00
Willy Tarreau
08fa2e37fd [MINOR] tarpit: close the connection if the client closes.
There's no point at maintaining an open tarpitted connection
if the client has left.
2006-09-03 10:47:37 +02:00
Willy Tarreau
b8750a82a2 [MEDIUM] added the "reqtarpit" and "reqitarpit" features
It is now possible to tarpit connections based on regex matches.
The tarpit timeout is equal to the contimeout. A 500 server error
response is faked, and the logs show the status flags as "PT" which
indicate the connection has been tarpitted.
2006-09-03 09:56:00 +02:00
Willy Tarreau
d797128d6e [MEDIUM] got rid of event_{cli,srv}_read() in favor of stream_sock_read() 2006-07-29 18:36:34 +02:00
Willy Tarreau
0f9f5056f9 [MEDIUM] removed all res_* and RES_*
The read-, write-, end- and error- status are now stored in the buffer.
2006-07-29 17:39:25 +02:00
Willy Tarreau
1c47f85292 [MEDIUM] implemented the 'monitor-uri' keyword.
It is used to test haproxy's status with an HTTP request to which
it will reply with HTTP/1.0 200 OK.
2006-07-09 17:01:40 +02:00
Willy Tarreau
791d66d363 [MINOR] added lots of Content-Type: text/html to HTML responses and stats.
This suggestion from Cameron Simpson is perfectly valid and should have been
implemented from the beginning.
2006-07-09 16:13:17 +02:00
Willy Tarreau
2dd0d4799e [CLEANUP] renamed include/haproxy to include/common 2006-06-29 17:53:05 +02:00
Willy Tarreau
baaee00406 [BIGMOVE] exploded the monolithic haproxy.c file into multiple files.
The files are now stored under :
  - include/haproxy for the generic includes
  - include/types.h for the structures needed within prototypes
  - include/proto.h for function prototypes and inline functions
  - src/*.c for the C files

Most include files are now covered by LGPL. A last move still needs
to be done to put inline functions under GPL and not LGPL.

Version has been set to 1.3.0 in the code but some control still
needs to be done before releasing.
2006-06-26 02:48:02 +02:00