From: Willy Tarreau Date: Tue, 17 Dec 2019 05:51:20 +0000 (+0100) Subject: DOC: clarify the fact that replace-uri works on a full URI X-Git-Tag: v2.2-dev1~179 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=62b5913380d6820bb249672bbf57b9377ceaf9e1;p=thirdparty%2Fhaproxy.git DOC: clarify the fact that replace-uri works on a full URI With H2 deployments becoming more common, replace-uri starts to hit users by not always matching absolute URIs due to rules expecting the URI to start with a '/'. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index cd6edc7d5f..fdcdb04fae 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4475,17 +4475,23 @@ http-request replace-uri than certain ACLs, so rare replacements may benefit from a condition to avoid performing the evaluation at all if it does not match. - Example: - # prefix /foo : turn /bar?q=1 into /foo/bar?q=1 : - http-request replace-uri (.*) /foo\1 + IMPORTANT NOTE: historically in HTTP/1.x, the vast majority of requests sent + by browsers use the "origin form", which differs from the "absolute form" in + that they do not contain a scheme nor authority in the URI portion. Mostly + only requests sent to proxies, those forged by hand and some emitted by + certain applications use the absolute form. As such, "replace-uri" usually + works fine most of the time in HTTP/1.x with rules starting with a "/". But + with HTTP/2, clients are encouraged to send absolute URIs only, which look + like the ones HTTP/1 clients use to talk to proxies. Such partial replace-uri + rules may then fail in HTTP/2 when they work in HTTP/1. Either the rules need + to be adapted to optionally match a scheme and authority. - # suffix /foo : turn /bar?q=1 into /bar/foo?q=1 : - http-request replace-uri ([^?]*)(\?(.*))? \1/foo\2 + Example: + # rewrite all "http" absolute requests to "https": + http-request replace-uri ^http://(.*) https://\1 - # strip /foo : turn /foo/bar?q=1 into /bar?q=1 - http-request replace-uri /foo/(.*) /\1 - # or more efficient if only some requests match : - http-request replace-uri /foo/(.*) /\1 if { url_beg /foo/ } + # prefix /foo : turn /bar?q=1 into /foo/bar?q=1 : + http-request replace-uri ([^/:]*://[^/]*)?(.*) \1/foo\2 http-request replace-value [ { if | unless } ]