]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] http: balance url_param did not work with first parameters on POST
authorWilly Tarreau <w@1wt.eu>
Tue, 1 Mar 2011 19:35:49 +0000 (20:35 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 1 Mar 2011 19:42:20 +0000 (20:42 +0100)
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.

doc/configuration.txt
src/backend.c
src/proto_http.c

index 3c10e4d1620f2b5689226ebf112797164f334db8..7a5ace2860e58ceb0d6b9d15ff436afbd42b5928 100644 (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
index 7554923d9666995e546fddc85ac9d2a602a2ae45..f3d9f095e939225afe3f3cd6d8d134083df38cec 100644 (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:
index eb6ba30b3cf4550a4f047b75d7d0473bd022bd50..1061c35ec8ba8dd6e44c5143e45e0c654e3757ca 100644 (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;
        }