]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] redirect: add support for the "drop-query" option
authorWilly Tarreau <w@1wt.eu>
Wed, 19 Nov 2008 19:03:04 +0000 (20:03 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 7 Dec 2008 22:42:01 +0000 (23:42 +0100)
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)

doc/configuration.txt
include/types/proto_http.h
include/types/proxy.h
src/cfgparse.c
src/proto_http.c
tests/test-redirect.cfg

index f37981b04417b19845c71d886c241d3da58bc503..2467007f9941c0147cdb500e69d3fbbb1ca48d77 100644 (file)
@@ -2336,7 +2336,8 @@ no option transparent
             "transparent" option of the "bind" keyword.
 
 
-redirect {location | prefix} <to> [code <code>] {if | unless} <condition>
+redirect location <to> [code <code>] {if | unless} <condition>
+redirect prefix <to> [drop-query] [code <code>] {if | unless} <condition>
   Return an HTTP redirection if/unless a condition is matched
   May be used in sections :   defaults | frontend | listen | backend
                                  no    |    yes   |   yes  |   yes
@@ -2345,7 +2346,10 @@ redirect {location | prefix} <to> [code <code>] {if | unless} <condition>
   response. There are currently two types of redirections : "location" and
   "prefix". With "location", the exact value in <to> is placed into the HTTP
   "Location" header. With "prefix", the "Location" header is built from the
-  concatenation of <to> and the URI. It is particularly suited for global site
+  concatenation of <to> and the URI. If the optional "drop-query" keyword is
+  used in a prefix-based redirection, then the location will be set without any
+  possible query-string, which is useful for directing users to a non-secure
+  page for instance. The "prefix" mode is particularly suited for global site
   redirections.
 
   The code is optional. It indicates in <code> which type of HTTP redirection
@@ -2356,8 +2360,10 @@ redirect {location | prefix} <to> [code <code>] {if | unless} <condition>
         acl clear      dst_port  80
         acl secure     dst_port  8080
         acl login_page url_beg   /login
-        redirect prefix   https://mysite.com  if login_page !secure
-        redirect location http://mysite.com/  if !login_page secure
+        acl uid_given  url_reg   /login?userid=[^&]+
+        redirect prefix   https://mysite.com           if login_page !secure
+        redirect prefix   http://mysite.com drop-query if login_page !uid_given
+        redirect location http://mysite.com/           if !login_page secure
 
   See section 2.3 about ACL usage.
 
index c9a28f7e28ccc72034c4f4b50cf39b8dd596fb01..7313e25c79ef3ebc6f43829702e899c04cfdc00f 100644 (file)
@@ -165,7 +165,11 @@ enum {
        DATA_ST_PX_FIN,
 };
 
-
+/* Redirect flags */
+enum {
+       REDIRECT_FLAG_NONE = 0,
+       REDIRECT_FLAG_DROP_QS = 1,      /* drop query string */
+};
 
 /* Redirect types (location, prefix, extended ) */
 enum {
index 721d7c0326f4fbb5e867861e31ff5948a648f55e..a7d2c404f2cc1d6502f63e261932079b97089a90 100644 (file)
@@ -266,6 +266,7 @@ struct redirect_rule {
        int rdr_len;
        char *rdr_str;
        int code;
+       unsigned int flags;
 };
 
 extern struct proxy *proxy;
index 5394b6bc4b1e0ac68c29ea2a22709c307430f748..ede1b22f65ff9650fe0453cf066cdffb7aaf305f 100644 (file)
@@ -1118,6 +1118,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
                int type = REDIRECT_TYPE_NONE;
                int code = 302;
                char *destination = NULL;
+               unsigned int flags = REDIRECT_FLAG_NONE;
 
                cur_arg = 1;
                while (*(args[cur_arg])) {
@@ -1157,6 +1158,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
                                        return -1;
                                }
                        }
+                       else if (!strcmp(args[cur_arg],"drop-query")) {
+                               flags |= REDIRECT_FLAG_DROP_QS;
+                       }
                        else if (!strcmp(args[cur_arg], "if")) {
                                pol = ACL_COND_IF;
                                cur_arg++;
@@ -1200,6 +1204,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
                rule->rdr_len = strlen(destination);
                rule->type = type;
                rule->code = code;
+               rule->flags = flags;
                LIST_INIT(&rule->list);
                LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
        }
index 71013d4707d996bfc8cd91a4a2921d0a516c9c79..6a9f7054aae245cb3977c945833aea208b8530e3 100644 (file)
@@ -1894,6 +1894,16 @@ int http_process_request(struct session *s, struct buffer *req)
                                        /* build message using path */
                                        if (path) {
                                                pathlen = txn->req.sl.rq.u_l + (txn->req.sol+txn->req.sl.rq.u) - path;
+                                               if (rule->flags & REDIRECT_FLAG_DROP_QS) {
+                                                       int qs = 0;
+                                                       while (qs < pathlen) {
+                                                               if (path[qs] == '?') {
+                                                                       pathlen = qs;
+                                                                       break;
+                                                               }
+                                                               qs++;
+                                                       }
+                                               }
                                        } else {
                                                path = "/";
                                                pathlen = 1;
index efafa4fa7541da986b0c4f8ecfa8f05e76c991eb..a3bf2ab0d9acd1308a2c0adb0355e74e285676f4 100644 (file)
@@ -17,9 +17,10 @@ listen  sample1
 
        acl        url_test1 url_reg test1
        acl        url_test2 url_reg test2
+       acl        url_test3 url_reg test3
        redirect   location /abs/test code 301 if url_test1
        redirect   prefix   /pfx/test code 302 if url_test2
-       redirect   prefix   /pfx/test code 303 if url_test2
+       redirect   prefix   /pfx/test code 303 drop-query if url_test3
 
        ### unconditional redirection
        #redirect   location https://example.com/ if TRUE