From cf0c70d14f50cd0e580b87b1a4814b03df2c81ba Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Mon, 13 May 2024 17:22:34 +0300 Subject: [PATCH 1/8] make argsort run before header --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5db1450..1ec7bf4 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Caddyfile: # Add this block in top-level settings: { ... - order argsort before rewrite + order argsort before header ... } From 5f4bc9c15aa0e45156feb1a2ff9a8d180779380e Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 14:31:38 +0300 Subject: [PATCH 2/8] attempt to lowercase parameters before sorting them --- argsort.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/argsort.go b/argsort.go index d1d657d..3ec1662 100644 --- a/argsort.go +++ b/argsort.go @@ -2,6 +2,8 @@ package argsort import ( "net/http" + "net/url" + "strings" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" @@ -40,7 +42,17 @@ func (m *Middleware) Validate() error { // ServeHTTP implements caddyhttp.MiddlewareHandler. func (m Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { // url.Values.Encode() will just do the sort for us - r.URL.RawQuery = r.URL.Query().Encode() + //r.URL.RawQuery = r.URL.Query().Encode() + // values = new(url.Values) + // var values url.Values + values := url.Values{} + for k, s := range r.URL.Query() { + for _, v := range s { + values.Add(strings.ToLower(k), v) + } + } + r.URL.RawQuery = values.Encode() + return next.ServeHTTP(w, r) } From aafd290d5607eb8a4f36e963f823fc51feb0bd92 Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 17:16:29 +0300 Subject: [PATCH 3/8] add the option to lowercase the parmeter names first and then sort --- argsort.go | 36 +++++++++++++++++++++++++----------- test/Caddyfile.3 | 10 ++++++++++ test/Caddyfile.4 | 10 ++++++++++ test/test-2.req | 2 +- test/test-2.res | 2 +- test/test-3.req | 1 + test/test-3.res | 1 + test/test-4.req | 1 + test/test-4.res | 1 + 9 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 test/Caddyfile.3 create mode 100644 test/Caddyfile.4 create mode 100644 test/test-3.req create mode 100644 test/test-3.res create mode 100644 test/test-4.req create mode 100644 test/test-4.res diff --git a/argsort.go b/argsort.go index 3ec1662..00beed8 100644 --- a/argsort.go +++ b/argsort.go @@ -19,6 +19,7 @@ func init() { // Middleware implements an HTTP handler that // reorders the query arguments. type Middleware struct { + Lowercase bool `json:"lowercase,omitempty"` } // CaddyModule returns the Caddy module information. @@ -41,24 +42,37 @@ func (m *Middleware) Validate() error { // ServeHTTP implements caddyhttp.MiddlewareHandler. func (m Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { - // url.Values.Encode() will just do the sort for us - //r.URL.RawQuery = r.URL.Query().Encode() - // values = new(url.Values) - // var values url.Values - values := url.Values{} - for k, s := range r.URL.Query() { - for _, v := range s { - values.Add(strings.ToLower(k), v) + // url.Values.Encode() is doing the sort for us + if m.Lowercase { + values := url.Values{} + for k, s := range r.URL.Query() { + for _, v := range s { + values.Add(strings.ToLower(k), v) + } } + r.URL.RawQuery = values.Encode() + } else { + r.URL.RawQuery = r.URL.Query().Encode() } - r.URL.RawQuery = values.Encode() return next.ServeHTTP(w, r) } // UnmarshalCaddyfile implements caddyfile.Unmarshaler. -func (m *Middleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - d.Next() // consume directive name +// argsort [lower] +func (a *Middleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + // Set default value for Lower + a.Lowercase = false + + for d.Next() { + if d.NextArg() { + if d.Val() == "lowercase" { + a.Lowercase = true + } else { + return d.ArgErr() + } + } + } return nil } diff --git a/test/Caddyfile.3 b/test/Caddyfile.3 new file mode 100644 index 0000000..0134058 --- /dev/null +++ b/test/Caddyfile.3 @@ -0,0 +1,10 @@ +{ + debug + order argsort before rewrite +} + +:2015 { + argsort + header Content-Type "text/html; charset=utf-8" + respond "{http.request.uri.query}" +} diff --git a/test/Caddyfile.4 b/test/Caddyfile.4 new file mode 100644 index 0000000..fc9cb64 --- /dev/null +++ b/test/Caddyfile.4 @@ -0,0 +1,10 @@ +{ + debug + order argsort before rewrite +} + +:2015 { + argsort lowercase + header Content-Type "text/html; charset=utf-8" + respond "{http.request.uri.query}" +} diff --git a/test/test-2.req b/test/test-2.req index be0af20..b983df6 100644 --- a/test/test-2.req +++ b/test/test-2.req @@ -1 +1 @@ -http://localhost:2015/baz?z=bar&a=foo \ No newline at end of file +http://localhost:2015/baz?z=bar&m=baz&a=foo \ No newline at end of file diff --git a/test/test-2.res b/test/test-2.res index 3162221..cc85d3c 100644 --- a/test/test-2.res +++ b/test/test-2.res @@ -1 +1 @@ -a=foo&z=bar \ No newline at end of file +a=foo&m=baz&z=bar \ No newline at end of file diff --git a/test/test-3.req b/test/test-3.req new file mode 100644 index 0000000..eb6de0a --- /dev/null +++ b/test/test-3.req @@ -0,0 +1 @@ +http://localhost:2015/baz?Z=bar&M=baz&a=foo \ No newline at end of file diff --git a/test/test-3.res b/test/test-3.res new file mode 100644 index 0000000..f68d7c2 --- /dev/null +++ b/test/test-3.res @@ -0,0 +1 @@ +M=baz&Z=bar&a=foo \ No newline at end of file diff --git a/test/test-4.req b/test/test-4.req new file mode 100644 index 0000000..eb6de0a --- /dev/null +++ b/test/test-4.req @@ -0,0 +1 @@ +http://localhost:2015/baz?Z=bar&M=baz&a=foo \ No newline at end of file diff --git a/test/test-4.res b/test/test-4.res new file mode 100644 index 0000000..cc85d3c --- /dev/null +++ b/test/test-4.res @@ -0,0 +1 @@ +a=foo&m=baz&z=bar \ No newline at end of file From c9c1885db24117d4546cb5708ce779948953182e Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 17:31:04 +0300 Subject: [PATCH 4/8] update readme --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1ec7bf4..7f2a4cd 100644 --- a/README.md +++ b/README.md @@ -6,29 +6,63 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/teodorescuserban/caddy-argsort)](https://goreportcard.com/report/github.com/teodorescuserban/caddy-argsort) This is a caddy plugin. Works with caddy 2. -Sort the request query arguments. +Sort the request query arguments. Optionally case insensitive. ## Usage -Caddyfile: +### Set the module order + +You will need to specify the execution order of this module in your caddyfile. This is done in the global options block. ```caddyfile -# Add this block in top-level settings: { ... order argsort before header ... } +``` + +### Simple usage + +Once the order has been set in the global options block, use `argsort` in any server block + +```caddyfile +{ + order argsort before header +} -# use argsort keyword in any server :8881 { header Content-Type "text/html; charset=utf-8" respond "Hello." argsort } +``` + +### Optional case insensitive usage + +Once the order has been set in the global options block, use `argsort lowecase` in any server block + +```caddyfile +{ + order argsort before header +} + +:8881 { + header Content-Type "text/html; charset=utf-8" + respond "Hello." + argsort lowercase +} +``` + +### Forward the normalized request to an upstream + +Once the order has been set in the global options block, you ensure query arguments sorting for an upstream server + +```caddyfile +{ + order argsort before header +} -# or ensure query arguments sorting then passing it to another server -# (useful when using other web server in the backend) :8882 { argsort reverse_proxy localhost:8883 From 01a0d126560b7a29b0df3e62eb15f0e6980f6be2 Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 17:40:46 +0300 Subject: [PATCH 5/8] fix tests --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8e3f090..e9cf38f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: test: strategy: matrix: - go-version: [1.20.x] + go-version: [1.21.x] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: From 4e25734e793f3223e4d60ea267b9fcd48e3d6174 Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 18:24:57 +0300 Subject: [PATCH 6/8] fix no 2 --- test/run-test | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/run-test b/test/run-test index 7927624..ce38aa2 100755 --- a/test/run-test +++ b/test/run-test @@ -31,7 +31,7 @@ echobold() { test() { echobold "test case ${1}" - $XCADDY run --config test/Caddyfile.${1}& + $XCADDY run --adapter caddyfile --config test/Caddyfile.${1}& pid="$!" retry $(cat test/test-${1}.req) > output${1} diff output${1} test/test-${1}.res @@ -51,3 +51,7 @@ $XCADDY list-modules test "1" test "2" + +test "3" + +test "4" From 16ce5d788612c209393afda0ffe3e61dd12ef8b6 Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 18:29:25 +0300 Subject: [PATCH 7/8] fix 3 --- test/test-1.req | 2 +- test/test-1.res | 2 +- test/test-2.req | 2 +- test/test-2.res | 2 +- test/test-3.req | 2 +- test/test-3.res | 2 +- test/test-4.req | 2 +- test/test-4.res | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test-1.req b/test/test-1.req index be0af20..86175bf 100644 --- a/test/test-1.req +++ b/test/test-1.req @@ -1 +1 @@ -http://localhost:2015/baz?z=bar&a=foo \ No newline at end of file +http://localhost:2015/baz?z=bar&a=foo diff --git a/test/test-1.res b/test/test-1.res index a37dfb7..ab12362 100644 --- a/test/test-1.res +++ b/test/test-1.res @@ -1 +1 @@ -z=bar&a=foo \ No newline at end of file +z=bar&a=foo diff --git a/test/test-2.req b/test/test-2.req index b983df6..28729e5 100644 --- a/test/test-2.req +++ b/test/test-2.req @@ -1 +1 @@ -http://localhost:2015/baz?z=bar&m=baz&a=foo \ No newline at end of file +http://localhost:2015/baz?z=bar&m=baz&a=foo diff --git a/test/test-2.res b/test/test-2.res index cc85d3c..ffc07e3 100644 --- a/test/test-2.res +++ b/test/test-2.res @@ -1 +1 @@ -a=foo&m=baz&z=bar \ No newline at end of file +a=foo&m=baz&z=bar diff --git a/test/test-3.req b/test/test-3.req index eb6de0a..7e082b6 100644 --- a/test/test-3.req +++ b/test/test-3.req @@ -1 +1 @@ -http://localhost:2015/baz?Z=bar&M=baz&a=foo \ No newline at end of file +http://localhost:2015/baz?Z=bar&M=baz&a=foo diff --git a/test/test-3.res b/test/test-3.res index f68d7c2..d00b966 100644 --- a/test/test-3.res +++ b/test/test-3.res @@ -1 +1 @@ -M=baz&Z=bar&a=foo \ No newline at end of file +M=baz&Z=bar&a=foo diff --git a/test/test-4.req b/test/test-4.req index eb6de0a..7e082b6 100644 --- a/test/test-4.req +++ b/test/test-4.req @@ -1 +1 @@ -http://localhost:2015/baz?Z=bar&M=baz&a=foo \ No newline at end of file +http://localhost:2015/baz?Z=bar&M=baz&a=foo diff --git a/test/test-4.res b/test/test-4.res index cc85d3c..ffc07e3 100644 --- a/test/test-4.res +++ b/test/test-4.res @@ -1 +1 @@ -a=foo&m=baz&z=bar \ No newline at end of file +a=foo&m=baz&z=bar From 948c8021cf9f9041bfa32cea29d0086822931c5a Mon Sep 17 00:00:00 2001 From: Serban Teodorescu Date: Thu, 6 Jun 2024 18:33:21 +0300 Subject: [PATCH 8/8] fix 4 --- test/test-1.req | 2 +- test/test-1.res | 2 +- test/test-2.req | 2 +- test/test-2.res | 2 +- test/test-3.req | 2 +- test/test-3.res | 2 +- test/test-4.req | 2 +- test/test-4.res | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test-1.req b/test/test-1.req index 86175bf..be0af20 100644 --- a/test/test-1.req +++ b/test/test-1.req @@ -1 +1 @@ -http://localhost:2015/baz?z=bar&a=foo +http://localhost:2015/baz?z=bar&a=foo \ No newline at end of file diff --git a/test/test-1.res b/test/test-1.res index ab12362..a37dfb7 100644 --- a/test/test-1.res +++ b/test/test-1.res @@ -1 +1 @@ -z=bar&a=foo +z=bar&a=foo \ No newline at end of file diff --git a/test/test-2.req b/test/test-2.req index 28729e5..b983df6 100644 --- a/test/test-2.req +++ b/test/test-2.req @@ -1 +1 @@ -http://localhost:2015/baz?z=bar&m=baz&a=foo +http://localhost:2015/baz?z=bar&m=baz&a=foo \ No newline at end of file diff --git a/test/test-2.res b/test/test-2.res index ffc07e3..cc85d3c 100644 --- a/test/test-2.res +++ b/test/test-2.res @@ -1 +1 @@ -a=foo&m=baz&z=bar +a=foo&m=baz&z=bar \ No newline at end of file diff --git a/test/test-3.req b/test/test-3.req index 7e082b6..eb6de0a 100644 --- a/test/test-3.req +++ b/test/test-3.req @@ -1 +1 @@ -http://localhost:2015/baz?Z=bar&M=baz&a=foo +http://localhost:2015/baz?Z=bar&M=baz&a=foo \ No newline at end of file diff --git a/test/test-3.res b/test/test-3.res index d00b966..f68d7c2 100644 --- a/test/test-3.res +++ b/test/test-3.res @@ -1 +1 @@ -M=baz&Z=bar&a=foo +M=baz&Z=bar&a=foo \ No newline at end of file diff --git a/test/test-4.req b/test/test-4.req index 7e082b6..eb6de0a 100644 --- a/test/test-4.req +++ b/test/test-4.req @@ -1 +1 @@ -http://localhost:2015/baz?Z=bar&M=baz&a=foo +http://localhost:2015/baz?Z=bar&M=baz&a=foo \ No newline at end of file diff --git a/test/test-4.res b/test/test-4.res index ffc07e3..cc85d3c 100644 --- a/test/test-4.res +++ b/test/test-4.res @@ -1 +1 @@ -a=foo&m=baz&z=bar +a=foo&m=baz&z=bar \ No newline at end of file