From 62b5913380d6820bb249672bbf57b9377ceaf9e1 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 17 Dec 2019 06:51:20 +0100 Subject: [PATCH] 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 '/'. --- doc/configuration.txt | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index cd6edc7d5..fdcdb04fa 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. + 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. + Example: + # rewrite all "http" absolute requests to "https": + http-request replace-uri ^http://(.*) https://\1 + # prefix /foo : turn /bar?q=1 into /foo/bar?q=1 : - http-request replace-uri (.*) /foo\1 - - # suffix /foo : turn /bar?q=1 into /bar/foo?q=1 : - http-request replace-uri ([^?]*)(\?(.*))? \1/foo\2 - - # 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/ } + http-request replace-uri ([^/:]*://[^/]*)?(.*) \1/foo\2 http-request replace-value [ { if | unless } ]