diff --git a/doc/configuration.txt b/doc/configuration.txt index f37981b04..2467007f9 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2336,7 +2336,8 @@ no option transparent "transparent" option of the "bind" keyword. -redirect {location | prefix} [code ] {if | unless} +redirect location [code ] {if | unless} +redirect prefix [drop-query] [code ] {if | unless} 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} [code ] {if | unless} response. There are currently two types of redirections : "location" and "prefix". With "location", the exact value in is placed into the HTTP "Location" header. With "prefix", the "Location" header is built from the - concatenation of and the URI. It is particularly suited for global site + concatenation of 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 which type of HTTP redirection @@ -2356,8 +2360,10 @@ redirect {location | prefix} [code ] {if | unless} 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. diff --git a/include/types/proto_http.h b/include/types/proto_http.h index c9a28f7e2..7313e25c7 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -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 { diff --git a/include/types/proxy.h b/include/types/proxy.h index 721d7c032..a7d2c404f 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -266,6 +266,7 @@ struct redirect_rule { int rdr_len; char *rdr_str; int code; + unsigned int flags; }; extern struct proxy *proxy; diff --git a/src/cfgparse.c b/src/cfgparse.c index 5394b6bc4..ede1b22f6 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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); } diff --git a/src/proto_http.c b/src/proto_http.c index 71013d470..6a9f7054a 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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; diff --git a/tests/test-redirect.cfg b/tests/test-redirect.cfg index efafa4fa7..a3bf2ab0d 100644 --- a/tests/test-redirect.cfg +++ b/tests/test-redirect.cfg @@ -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