]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] http: add support for conditional request header addition
authorWilly Tarreau <w@1wt.eu>
Sun, 31 Jan 2010 13:30:44 +0000 (14:30 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 31 Jan 2010 14:12:45 +0000 (15:12 +0100)
Now the reqadd rules also support ACLs. All req* rules are converted
now.

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

index e3d38f13bfdc7d2e9b84f88fc127f4d13f2fb68d..e6cffa97730809ac0d810289d274913ec1a8dd66 100644 (file)
@@ -3578,7 +3578,7 @@ redispatch (deprecated)
   See also : "option redispatch"
 
 
-reqadd  <string>
+reqadd  <string> [{if | unless} <cond>]
   Add a header at the end of the HTTP request
   May be used in sections :   defaults | frontend | listen | backend
                                  no    |    yes   |   yes  |   yes
@@ -3587,6 +3587,9 @@ reqadd  <string>
               must be escaped using a backslash ('\'). Please refer to section
               6 about HTTP header manipulation for more information.
 
+    <cond>    is an optional matching condition built from ACLs. It makes it
+              possible to ignore this rule when other conditions are not met.
+
   A new line consisting in <string> followed by a line feed will be added after
   the last header of an HTTP request.
 
@@ -3594,7 +3597,12 @@ reqadd  <string>
   and not to traffic generated by HAProxy, such as health-checks or error
   responses.
 
-  See also: "rspadd" and section 6 about HTTP header manipulation
+  Example : add "X-Proto: SSL" to requests coming via port 81
+     acl is-ssl  dst_port       81
+     reqadd      X-Proto:\ SSL  if is-ssl
+
+  See also: "rspadd", section 6 about HTTP header manipulation, and section 7
+            about ACLs.
 
 
 reqallow  <search> [{if | unless} <cond>]
index 4e724b2e050078025209c18412b816c72de3c90f..c7f549d3ebcdd4b48b67c31525f8979ab5ff8fe4 100644 (file)
@@ -3738,7 +3738,24 @@ stats_error_parsing:
                        goto out;
                }
 
+               if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
+                       if ((cond = build_acl_cond(file, linenum, curproxy, (const char **)args+2)) == NULL) {
+                               Alert("parsing [%s:%d] : error detected while parsing a '%s' condition.\n",
+                                     file, linenum, args[0]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       err_code |= warnif_cond_requires_resp(cond, file, linenum);
+               }
+               else if (*args[2]) {
+                       Alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
+                             file, linenum, args[0], args[2]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
                wl = calloc(1, sizeof(*wl));
+               wl->cond = cond;
                wl->s = strdup(args[1]);
                LIST_ADDQ(&curproxy->req_add, &wl->list);
                warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
index 975963504b0d9579a0d5e2c8082cf310a618b613..1ee230712cb0755d4302690b01d8e57b16e3ceb1 100644 (file)
@@ -2851,6 +2851,15 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
 
        /* add request headers from the rule sets in the same order */
        list_for_each_entry(wl, &px->req_add, list) {
+               if (wl->cond) {
+                       int ret = acl_exec_cond(wl->cond, px, s, txn, ACL_DIR_REQ);
+                       ret = acl_pass(ret);
+                       if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
+                               ret = !ret;
+                       if (!ret)
+                               continue;
+               }
+
                if (unlikely(http_header_add_tail(req, &txn->req, &txn->hdr_idx, wl->s) < 0))
                        goto return_bad_req;
        }