aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/html/urlutil
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-04-07 16:41:09 +0200
committerAleksandr Nogikh <nogikh@google.com>2025-04-08 10:15:40 +0000
commitb899e60d5c5004525d9a554d1d5074d062c3fb95 (patch)
tree67909f2e7cc8fec4a50ba6bb9b3bf7ed478e55b9 /pkg/html/urlutil
parent9e5bf1f8e420b27de381ad20643abb794ea5900e (diff)
pkg/html: split off URL helpers
The existing pkg/html package transitively takes too many dependencies, which complicates the reuse of some of its methods. Split off a pkg/html/urlutil package.
Diffstat (limited to 'pkg/html/urlutil')
-rw-r--r--pkg/html/urlutil/urls.go56
-rw-r--r--pkg/html/urlutil/urls_test.go49
2 files changed, 105 insertions, 0 deletions
diff --git a/pkg/html/urlutil/urls.go b/pkg/html/urlutil/urls.go
new file mode 100644
index 000000000..42ab505c8
--- /dev/null
+++ b/pkg/html/urlutil/urls.go
@@ -0,0 +1,56 @@
+// Copyright 2025 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package urlutil
+
+import "net/url"
+
+// SetParam overrides the specific key from the URL.
+// It does not take into account that there may be multiple parameters with the same name.
+func SetParam(baseURL, key, value string) string {
+ return TransformParam(baseURL, key, func(_ []string) []string {
+ if value == "" {
+ return nil
+ }
+ return []string{value}
+ })
+}
+
+// DropParam removes the specific key=value pair from the URL
+// (it's possible to have many of parameters with the same name).
+// Set value="" to remove the key regardless of the value.
+func DropParam(baseURL, key, value string) string {
+ return TransformParam(baseURL, key, func(oldValues []string) []string {
+ if value == "" {
+ return nil
+ }
+ var newValues []string
+ for _, iterVal := range oldValues {
+ if iterVal != value {
+ newValues = append(newValues, iterVal)
+ }
+ }
+ return newValues
+ })
+}
+
+// TransformParam is a generic method that transforms the set of values
+// for the specified URL parameter key.
+func TransformParam(baseURL, key string, f func([]string) []string) string {
+ if baseURL == "" {
+ return ""
+ }
+ parsed, err := url.Parse(baseURL)
+ if err != nil {
+ return ""
+ }
+ values := parsed.Query()
+ ret := f(values[key])
+ if len(ret) == 0 {
+ values.Del(key)
+ } else {
+ values[key] = ret
+ }
+ parsed.RawQuery = values.Encode()
+ return parsed.String()
+}
diff --git a/pkg/html/urlutil/urls_test.go b/pkg/html/urlutil/urls_test.go
new file mode 100644
index 000000000..a8782c35e
--- /dev/null
+++ b/pkg/html/urlutil/urls_test.go
@@ -0,0 +1,49 @@
+// Copyright 2023 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package urlutil
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestDropParam(t *testing.T) {
+ tests := []struct {
+ in string
+ key string
+ value string
+ out string
+ }{
+ {
+ in: `/upstream?first=a&second=b`,
+ key: `first`,
+ value: ``,
+ out: `/upstream?second=b`,
+ },
+ {
+ in: `/upstream?first=a&first=b&second=c`,
+ key: `second`,
+ value: ``,
+ out: `/upstream?first=a&first=b`,
+ },
+ {
+ in: `/upstream?first=a&first=b&second=c`,
+ key: `first`,
+ value: ``,
+ out: `/upstream?second=c`,
+ },
+ {
+ in: `/upstream?first=a&first=b&second=c`,
+ key: `first`,
+ value: `b`,
+ out: `/upstream?first=a&second=c`,
+ },
+ }
+
+ for _, test := range tests {
+ got := DropParam(test.in, test.key, test.value)
+ assert.Equal(t, test.out, got)
+ }
+}