[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.
This commit is contained in:
Willy Tarreau 2011-03-01 20:35:49 +01:00
parent 124d99181c
commit 61a21a34da
3 changed files with 9 additions and 11 deletions

View File

@ -1279,8 +1279,8 @@ balance url_param <param> [check_post [<max_wait>]]
If the modifier "check_post" is used, then an HTTP POST
request entity will be searched for the parameter argument,
when the question mark indicating a query string ('?') is not
present in the URL. Optionally, specify a number of octets to
when it is not found in a query string after a question mark
('?') in the URL. Optionally, specify a number of octets to
wait for before attempting to search the message body. If the
entity can not be searched, then round robin is used for each
request. For instance, if your clients always send the LB

View File

@ -558,14 +558,13 @@ int assign_server(struct session *s)
/* URL Parameter hashing */
if (s->txn.req.msg_state < HTTP_MSG_BODY)
break;
if (s->txn.meth == HTTP_METH_POST &&
memchr(s->txn.req.sol + s->txn.req.sl.rq.u, '&',
s->txn.req.sl.rq.u_l ) == NULL)
s->srv = get_server_ph(s->be,
s->txn.req.sol + s->txn.req.sl.rq.u,
s->txn.req.sl.rq.u_l);
if (!s->srv && s->txn.meth == HTTP_METH_POST)
s->srv = get_server_ph_post(s);
else
s->srv = get_server_ph(s->be,
s->txn.req.sol + s->txn.req.sl.rq.u,
s->txn.req.sl.rq.u_l);
break;
case BE_LB_HASH_HDR:

View File

@ -3631,8 +3631,7 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit)
if (!(s->flags & (SN_ASSIGNED|SN_DIRECT)) &&
s->txn.meth == HTTP_METH_POST && s->be->url_param_name != NULL &&
s->be->url_param_post_limit != 0 &&
(txn->flags & (TX_REQ_CNT_LEN|TX_REQ_TE_CHNK)) &&
memchr(msg->sol + msg->sl.rq.u, '?', msg->sl.rq.u_l) == NULL) {
(txn->flags & (TX_REQ_CNT_LEN|TX_REQ_TE_CHNK))) {
buffer_dont_connect(req);
req->analysers |= AN_REQ_HTTP_BODY;
}