Skip to content

Commit b2877db

Browse files
committed
MINOR: http-ana: Add option to keep query-string on a localtion-based redirect
On prefix-based redirect, there is an option to drop the query-string of the location. Here it is the opposite. an option is added to preserve the query-string of the original URI for a localtion-based redirect. By setting "keep-query" option, for a location-based redirect only, the query-string of the original URI is appended to the location. If there is no query-string, nothing is added (no empty '?'). If there is already a non-empty query-string on the localtion, the original one is appended with '&' separator. This patch should fix issue #2728.
1 parent 7848692 commit b2877db

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

doc/configuration.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11461,6 +11461,14 @@ redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]
1146111461
cookie set with "NAME=value". You have to clear the cookie "NAME=" for
1146211462
that, because the browser makes the difference.
1146311463

11464+
- "keep-query"
11465+
When this keyword is used in a location-based redirection, then the
11466+
query-string of the original URI, if any, will be appended to the
11467+
location. If no query-string is found, nothing is added. If the
11468+
location already contains a query-string, the original one will be
11469+
appended with the '&' delimiter.
11470+
11471+
1146411472
Example: move the login URL only to HTTPS.
1146511473
acl clear dst_port 80
1146611474
acl secure dst_port 8080

include/haproxy/http_ana-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ enum {
167167
REDIRECT_FLAG_APPEND_SLASH = 2, /* append a slash if missing at the end */
168168
REDIRECT_FLAG_FROM_REQ = 4, /* redirect rule on the request path */
169169
REDIRECT_FLAG_IGNORE_EMPTY = 8, /* silently ignore empty location expressions */
170+
REDIRECT_FLAG_KEEP_QS = 16, /* append the query string to location, if any */
170171
};
171172

172173
/* Redirect types (location, prefix, extended ) */

src/http_ana.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2420,6 +2420,7 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
24202420
}
24212421
case REDIRECT_TYPE_LOCATION:
24222422
default:
2423+
memset(chunk->area, 0x50, chunk->size);
24232424
if (rule->rdr_str) { /* this is an old "redirect" rule */
24242425
/* add location */
24252426
if (!chunk_memcat(chunk, rule->rdr_str, rule->rdr_len))
@@ -2437,6 +2438,36 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
24372438

24382439
chunk->data += len;
24392440
}
2441+
2442+
if (rule->flags & REDIRECT_FLAG_KEEP_QS) {
2443+
struct ist path;
2444+
struct http_uri_parser parser;
2445+
char *ptr, *end;
2446+
char sep = '?';
2447+
2448+
ptr = memchr(chunk->area, '?', chunk->data);
2449+
if (ptr != NULL)
2450+
sep = ((ptr+1 != b_tail(chunk)) ? '&' : '\0');
2451+
2452+
sl = http_get_stline(htx);
2453+
parser = http_uri_parser_init(htx_sl_req_uri(sl));
2454+
path = http_parse_path(&parser);
2455+
ptr = istptr(path);
2456+
end = istend(path);
2457+
2458+
/* look up the '?' */
2459+
do {
2460+
if (ptr == end)
2461+
return 0;
2462+
} while (*ptr++ != '?');
2463+
2464+
if (ptr == end)
2465+
break;
2466+
if (sep != '\0' && !chunk_memcat(chunk, &sep, 1))
2467+
goto fail;
2468+
if (!chunk_memcat(chunk, ptr, end-ptr))
2469+
goto fail;
2470+
}
24402471
break;
24412472
}
24422473
location = ist2(chunk->area, chunk->data);

src/http_rules.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ struct redirect_rule *http_parse_redirect_rule(const char *file, int linenum, st
402402
else if (strcmp(args[cur_arg], "drop-query") == 0) {
403403
flags |= REDIRECT_FLAG_DROP_QS;
404404
}
405+
else if (strcmp(args[cur_arg], "keep-query") == 0) {
406+
flags |= REDIRECT_FLAG_KEEP_QS;
407+
}
405408
else if (strcmp(args[cur_arg], "append-slash") == 0) {
406409
flags |= REDIRECT_FLAG_APPEND_SLASH;
407410
}
@@ -419,7 +422,7 @@ struct redirect_rule *http_parse_redirect_rule(const char *file, int linenum, st
419422
}
420423
else {
421424
memprintf(errmsg,
422-
"expects 'code', 'prefix', 'location', 'scheme', 'set-cookie', 'clear-cookie', 'drop-query', 'ignore-empty' or 'append-slash' (was '%s')",
425+
"expects 'code', 'prefix', 'location', 'scheme', 'set-cookie', 'clear-cookie', 'drop-query', 'keep-query', 'ignore-empty' or 'append-slash' (was '%s')",
423426
args[cur_arg]);
424427
goto err;
425428
}

0 commit comments

Comments
 (0)