Re: [RFC PATCH 6/8] MINOR: uri_normalizer: Add support for supressing leading `../` for dotdot normalizer

2021-04-13 Thread Christopher Faulet

Le 08/04/2021 à 20:59, Tim Duesterhus a écrit :

Willy,
Christopher,

most of the patch is moving around the config parser to support ingesting the
new argument.



This one looks good.

--
Christopher Faulet



[RFC PATCH 6/8] MINOR: uri_normalizer: Add support for supressing leading `../` for dotdot normalizer

2021-04-08 Thread Tim Duesterhus
Willy,
Christopher,

most of the patch is moving around the config parser to support ingesting the
new argument.

Best regards
Tim Düsterhus

Apply with `git am --scissors` to automatically cut the commit message.

-- >8 --
This adds an option to supress `../` at the start of the resulting path.
---
 doc/configuration.txt  | 11 ++
 include/haproxy/action-t.h |  1 +
 include/haproxy/uri_normalizer.h   |  2 +-
 reg-tests/http-rules/normalize_uri.vtc | 16 ++
 src/http_act.c | 29 +++---
 src/uri_normalizer.c   | 22 ---
 6 files changed, 65 insertions(+), 16 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index eacd8ff26..3422d3aa6 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -6012,6 +6012,9 @@ http-request early-hint   [ { if | unless } 
 ]
   See RFC 8297 for more information.
 
 http-request normalize-uri  [ { if | unless }  ]
+http-request normalize-uri dotdot [ full ] [ { if | unless }  ]
+http-request normalize-uri merge-slashes [ { if | unless }  ]
+http-request normalize-uri sort-query [ { if | unless }  ]
 
   Performs normalization of the request's URI. The following normalizers are
   available:
@@ -6026,8 +6029,16 @@ http-request normalize-uri  [ { if | unless 
}  ]
   - /foo/../bar/ -> /bar/
   - /foo/bar/../ -> /foo/
   - /../bar/ -> /../bar/
+  - /bar/../../  -> /../
   - /foo//../-> /foo/
 
+  If the "full" option is specified then `../` at the beginning will be
+  removed as well:
+
+  Example:
+  - /../bar/ -> /bar/
+  - /bar/../../  -> /
+
   - merge-slashes: Merges adjacent slashes within the "path" component into a
   single slash.
 
diff --git a/include/haproxy/action-t.h b/include/haproxy/action-t.h
index 332be513f..ae43a936d 100644
--- a/include/haproxy/action-t.h
+++ b/include/haproxy/action-t.h
@@ -104,6 +104,7 @@ enum act_timeout_name {
 enum act_normalize_uri {
ACT_NORMALIZE_URI_MERGE_SLASHES,
ACT_NORMALIZE_URI_DOTDOT,
+   ACT_NORMALIZE_URI_DOTDOT_FULL,
ACT_NORMALIZE_URI_SORT_QUERY,
 };
 
diff --git a/include/haproxy/uri_normalizer.h b/include/haproxy/uri_normalizer.h
index 5884e5ab9..52bb004db 100644
--- a/include/haproxy/uri_normalizer.h
+++ b/include/haproxy/uri_normalizer.h
@@ -16,7 +16,7 @@
 
 #include 
 
-struct ist uri_normalizer_path_dotdot(const struct ist path, char *trash, 
size_t len);
+struct ist uri_normalizer_path_dotdot(const struct ist path, int full, char 
*trash, size_t len);
 struct ist uri_normalizer_path_merge_slashes(const struct ist path, char 
*trash, size_t len);
 struct ist uri_normalizer_query_sort(const struct ist query, const char delim, 
char *trash, size_t len);
 
diff --git a/reg-tests/http-rules/normalize_uri.vtc 
b/reg-tests/http-rules/normalize_uri.vtc
index 8be81c574..cb3fa2f63 100644
--- a/reg-tests/http-rules/normalize_uri.vtc
+++ b/reg-tests/http-rules/normalize_uri.vtc
@@ -36,8 +36,13 @@ haproxy h1 -conf {
 http-request normalize-uri dotdot
 http-request set-var(txn.after) url
 
+http-request set-uri %[var(txn.before)]
+http-request normalize-uri dotdot full
+http-request set-var(txn.after_full) url
+
 http-response add-header before  %[var(txn.before)]
 http-response add-header after  %[var(txn.after)]
+http-response add-header after-full  %[var(txn.after_full)]
 
 default_backend be
 
@@ -115,56 +120,67 @@ client c2 -connect ${h1_fe_dotdot_sock} {
 rxresp
 expect resp.http.before == "/foo/bar"
 expect resp.http.after == "/foo/bar"
+expect resp.http.after-full == "/foo/bar"
 
 txreq -url "/foo/.."
 rxresp
 expect resp.http.before == "/foo/.."
 expect resp.http.after == "/"
+expect resp.http.after-full == "/"
 
 txreq -url "/foo/../"
 rxresp
 expect resp.http.before == "/foo/../"
 expect resp.http.after == "/"
+expect resp.http.after-full == "/"
 
 txreq -url "/foo/bar/../"
 rxresp
 expect resp.http.before == "/foo/bar/../"
 expect resp.http.after == "/foo/"
+expect resp.http.after-full == "/foo/"
 
 txreq -url "/foo/../bar"
 rxresp
 expect resp.http.before == "/foo/../bar"
 expect resp.http.after == "/bar"
+expect resp.http.after-full == "/bar"
 
 txreq -url "/foo/../bar/"
 rxresp
 expect resp.http.before == "/foo/../bar/"
 expect resp.http.after == "/bar/"
+expect resp.http.after-full == "/bar/"
 
 txreq -url "/foo/../../bar/"
 rxresp
 expect resp.http.before == "/foo/../../bar/"
 expect resp.http.after == "/../bar/"
+expect resp.http.after-full == "/bar/"
 
 txreq -url "/foo//../../bar/"
 rxresp
 expect resp.http.before == "/foo//../../bar/"
 expect resp.http.after == "/bar/"
+expect resp.http.after-full == "/bar/"
 
 txreq -url "/foo/?bar=/foo/../"