fix: fix issue #292, change query params type to map[string][]string

This commit is contained in:
dudaodong
2025-03-28 14:00:11 +08:00
parent 169f280c9c
commit 0ef45b533b
5 changed files with 238 additions and 17 deletions

View File

@@ -48,6 +48,9 @@ import (
- [UploadFile](#UploadFile)
- [IsPingConnected](#IsPingConnected)
- [IsTelnetConnected](#IsTelnetConnected)
- [IsTelnetConnected](#IsTelnetConnected)
- [BuildUrl](#BuildUrl)
- [AddQueryParams](#AddQueryParams)
<div STYLE="page-break-after: always;"></div>
@@ -1031,3 +1034,83 @@ func main() {
// false
}
```
### <span id="BuildUrl">BuildUrl</span>
<p>创建url字符串。</p>
<b>函数签名:</b>
```go
func BuildUrl(scheme, host, path string, query map[string][]string) (string, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
urlStr, err := netutil.BuildUrl(
"https",
"example.com",
"query",
map[string][]string{
"a": {"foo", "bar"},
"b": {"baz"},
},
)
fmt.Println(urlStr)
fmt.Println(err)
// Output:
// https://example.com/query?a=foo&a=bar&b=baz
// <nil>
}
```
### <span id="AddQueryParams">AddQueryParams</span>
<p>向url添加查询参数。</p>
<b>函数签名:</b>
```go
func AddQueryParams(urlStr string, params map[string][]string) (string, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
urlStr, err := netutil.BuildUrl(
"https",
"example.com",
"query",
map[string][]string{
"a": {"foo", "bar"},
"b": {"baz"},
},
)
fmt.Println(urlStr)
fmt.Println(err)
// Output:
// https://example.com/query?a=foo&a=bar&b=baz
// <nil>
}
```

View File

@@ -48,6 +48,9 @@ import (
- [UploadFile](#UploadFile)
- [IsPingConnected](#IsPingConnected)
- [IsTelnetConnected](#IsTelnetConnected)
- [BuildUrl](#BuildUrl)
- [AddQueryParams](#AddQueryParams)
<div STYLE="page-break-after: always;"></div>
@@ -1031,3 +1034,83 @@ func main() {
// false
}
```
### <span id="BuildUrl">BuildUrl</span>
<p>Builds a URL from the given params.</p>
<b>Signature:</b>
```go
func BuildUrl(scheme, host, path string, query map[string][]string) (string, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
urlStr, err := netutil.BuildUrl(
"https",
"example.com",
"query",
map[string][]string{
"a": {"foo", "bar"},
"b": {"baz"},
},
)
fmt.Println(urlStr)
fmt.Println(err)
// Output:
// https://example.com/query?a=foo&a=bar&b=baz
// <nil>
}
```
### <span id="AddQueryParams">AddQueryParams</span>
<p>Adds query parameters to the given URL.</p>
<b>Signature:</b>
```go
func AddQueryParams(urlStr string, params map[string][]string) (string, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/netutil"
)
func main() {
urlStr, err := netutil.BuildUrl(
"https",
"example.com",
"query",
map[string][]string{
"a": {"foo", "bar"},
"b": {"baz"},
},
)
fmt.Println(urlStr)
fmt.Println(err)
// Output:
// https://example.com/query?a=foo&a=bar&b=baz
// <nil>
}
```

View File

@@ -310,7 +310,7 @@ func IsTelnetConnected(host string, port string) bool {
// BuildUrl builds a URL from the given params.
// Play: todo
func BuildUrl(scheme, host, path string, query map[string]string) (string, error) {
func BuildUrl(scheme, host, path string, query map[string][]string) (string, error) {
if err := validateScheme(scheme); err != nil {
return "", err
}
@@ -329,15 +329,17 @@ func BuildUrl(scheme, host, path string, query map[string]string) (string, error
if path == "" {
parsedUrl.Path = "/"
} else if !strings.HasPrefix(path, "/") {
path = "/" + path
parsedUrl.Path = "/" + path
} else {
parsedUrl.Path = path
}
queryParams := parsedUrl.Query()
for key, value := range query {
queryParams.Add(key, value)
for key, values := range query {
for _, value := range values {
queryParams.Add(key, value)
}
}
parsedUrl.RawQuery = queryParams.Encode()
@@ -370,14 +372,15 @@ var alphaNumericRegex = regexp.MustCompile(`^[a-zA-Z0-9]+$`)
// AddQueryParams adds query parameters to the given URL.
// Play: todoå
func AddQueryParams(urlStr string, params map[string]string) (string, error) {
func AddQueryParams(urlStr string, params map[string][]string) (string, error) {
parsedUrl, err := url.Parse(urlStr)
if err != nil {
return "", err
}
queryParams := parsedUrl.Query()
for k, v := range params {
for k, values := range params {
if k == "" {
return "", errors.New("empty key is not allowed")
}
@@ -386,11 +389,12 @@ func AddQueryParams(urlStr string, params map[string]string) (string, error) {
return "", fmt.Errorf("query parameter key %s must be alphanumeric", k)
}
if !alphaNumericRegex.MatchString(v) {
return "", fmt.Errorf("query parameter value %s must be alphanumeric", v)
for _, v := range values {
if !alphaNumericRegex.MatchString(v) {
return "", fmt.Errorf("query parameter value %s must be alphanumeric", v)
}
queryParams.Add(k, v)
}
queryParams.Add(k, v)
}
parsedUrl.RawQuery = queryParams.Encode()

View File

@@ -201,3 +201,40 @@ func ExampleIsTelnetConnected() {
// true
// false
}
func ExampleBuildUrl() {
urlStr, err := BuildUrl(
"https",
"example.com",
"query",
map[string][]string{
"a": {"foo", "bar"},
"b": {"baz"},
},
)
fmt.Println(urlStr)
fmt.Println(err)
// Output:
// https://example.com/query?a=foo&a=bar&b=baz
// <nil>
}
func ExampleAddQueryParams() {
urlStr := "https://example.com"
params := map[string][]string{
"a": {"foo", "bar"},
"b": {"baz"},
}
urlStr, err := AddQueryParams(urlStr, params)
fmt.Println(urlStr)
fmt.Println(err)
// Output:
// https://example.com?a=foo&a=bar&b=baz
// <nil>
}

View File

@@ -152,7 +152,7 @@ func TestBuildUrl(t *testing.T) {
scheme string
host string
path string
query map[string]string
query map[string][]string
want string
wantErr bool
}{
@@ -160,7 +160,7 @@ func TestBuildUrl(t *testing.T) {
scheme: "http",
host: "www.test.com",
path: "/path/subpath",
query: map[string]string{"a": "1", "b": "2"},
query: map[string][]string{"a": {"1"}, "b": {"2"}},
want: "http://www.test.com/path/subpath?a=1&b=2",
wantErr: false,
},
@@ -168,10 +168,18 @@ func TestBuildUrl(t *testing.T) {
scheme: "http",
host: "www.test.com",
path: "/simple-path",
query: map[string]string{"a": "1", "b": "2"},
query: map[string][]string{"a": {"1"}, "b": {"2"}},
want: "http://www.test.com/simple-path?a=1&b=2",
wantErr: false,
},
{
scheme: "http",
host: "www.test.com",
path: "",
query: map[string][]string{"a": {"foo", "bar"}, "b": {"baz"}},
want: "http://www.test.com/?a=foo&a=bar&b=baz",
wantErr: false,
},
{
scheme: "https",
host: "www.test. com",
@@ -205,25 +213,31 @@ func TestAddQueryParams(t *testing.T) {
tests := []struct {
url string
query map[string]string
query map[string][]string
want string
wantErr bool
}{
{
url: "http://www.test.com",
query: map[string]string{"a": "1", "b": "2"},
query: map[string][]string{"a": {"1"}, "b": {"2"}},
want: "http://www.test.com?a=1&b=2",
wantErr: false,
},
{
url: "http://www.test.com",
query: map[string]string{},
query: map[string][]string{"a": {"foo", "bar"}, "b": {"baz"}},
want: "http://www.test.com?a=foo&a=bar&b=baz",
wantErr: false,
},
{
url: "http://www.test.com",
query: map[string][]string{},
want: "http://www.test.com",
wantErr: false,
},
{
url: "http://www.test.com",
query: map[string]string{"a": "$%"},
query: map[string][]string{"a": {"$%"}},
want: "",
wantErr: true,
},