mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
fix: fix issue #292, change query params type to map[string][]string
This commit is contained in:
@@ -48,6 +48,9 @@ import (
|
|||||||
- [UploadFile](#UploadFile)
|
- [UploadFile](#UploadFile)
|
||||||
- [IsPingConnected](#IsPingConnected)
|
- [IsPingConnected](#IsPingConnected)
|
||||||
- [IsTelnetConnected](#IsTelnetConnected)
|
- [IsTelnetConnected](#IsTelnetConnected)
|
||||||
|
- [IsTelnetConnected](#IsTelnetConnected)
|
||||||
|
- [BuildUrl](#BuildUrl)
|
||||||
|
- [AddQueryParams](#AddQueryParams)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -1031,3 +1034,83 @@ func main() {
|
|||||||
// false
|
// 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>
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -48,6 +48,9 @@ import (
|
|||||||
- [UploadFile](#UploadFile)
|
- [UploadFile](#UploadFile)
|
||||||
- [IsPingConnected](#IsPingConnected)
|
- [IsPingConnected](#IsPingConnected)
|
||||||
- [IsTelnetConnected](#IsTelnetConnected)
|
- [IsTelnetConnected](#IsTelnetConnected)
|
||||||
|
- [BuildUrl](#BuildUrl)
|
||||||
|
- [AddQueryParams](#AddQueryParams)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -1031,3 +1034,83 @@ func main() {
|
|||||||
// false
|
// 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>
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -310,7 +310,7 @@ func IsTelnetConnected(host string, port string) bool {
|
|||||||
|
|
||||||
// BuildUrl builds a URL from the given params.
|
// BuildUrl builds a URL from the given params.
|
||||||
// Play: todo
|
// 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 {
|
if err := validateScheme(scheme); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -329,15 +329,17 @@ func BuildUrl(scheme, host, path string, query map[string]string) (string, error
|
|||||||
if path == "" {
|
if path == "" {
|
||||||
parsedUrl.Path = "/"
|
parsedUrl.Path = "/"
|
||||||
} else if !strings.HasPrefix(path, "/") {
|
} else if !strings.HasPrefix(path, "/") {
|
||||||
path = "/" + path
|
parsedUrl.Path = "/" + path
|
||||||
} else {
|
} else {
|
||||||
parsedUrl.Path = path
|
parsedUrl.Path = path
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParams := parsedUrl.Query()
|
queryParams := parsedUrl.Query()
|
||||||
|
|
||||||
for key, value := range query {
|
for key, values := range query {
|
||||||
queryParams.Add(key, value)
|
for _, value := range values {
|
||||||
|
queryParams.Add(key, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedUrl.RawQuery = queryParams.Encode()
|
parsedUrl.RawQuery = queryParams.Encode()
|
||||||
@@ -370,14 +372,15 @@ var alphaNumericRegex = regexp.MustCompile(`^[a-zA-Z0-9]+$`)
|
|||||||
|
|
||||||
// AddQueryParams adds query parameters to the given URL.
|
// AddQueryParams adds query parameters to the given URL.
|
||||||
// Play: todoå
|
// 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)
|
parsedUrl, err := url.Parse(urlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParams := parsedUrl.Query()
|
queryParams := parsedUrl.Query()
|
||||||
for k, v := range params {
|
|
||||||
|
for k, values := range params {
|
||||||
if k == "" {
|
if k == "" {
|
||||||
return "", errors.New("empty key is not allowed")
|
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)
|
return "", fmt.Errorf("query parameter key %s must be alphanumeric", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !alphaNumericRegex.MatchString(v) {
|
for _, v := range values {
|
||||||
return "", fmt.Errorf("query parameter value %s must be alphanumeric", v)
|
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()
|
parsedUrl.RawQuery = queryParams.Encode()
|
||||||
|
|||||||
@@ -201,3 +201,40 @@ func ExampleIsTelnetConnected() {
|
|||||||
// true
|
// true
|
||||||
// false
|
// 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>
|
||||||
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func TestBuildUrl(t *testing.T) {
|
|||||||
scheme string
|
scheme string
|
||||||
host string
|
host string
|
||||||
path string
|
path string
|
||||||
query map[string]string
|
query map[string][]string
|
||||||
want string
|
want string
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
@@ -160,7 +160,7 @@ func TestBuildUrl(t *testing.T) {
|
|||||||
scheme: "http",
|
scheme: "http",
|
||||||
host: "www.test.com",
|
host: "www.test.com",
|
||||||
path: "/path/subpath",
|
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",
|
want: "http://www.test.com/path/subpath?a=1&b=2",
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
@@ -168,10 +168,18 @@ func TestBuildUrl(t *testing.T) {
|
|||||||
scheme: "http",
|
scheme: "http",
|
||||||
host: "www.test.com",
|
host: "www.test.com",
|
||||||
path: "/simple-path",
|
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",
|
want: "http://www.test.com/simple-path?a=1&b=2",
|
||||||
wantErr: false,
|
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",
|
scheme: "https",
|
||||||
host: "www.test. com",
|
host: "www.test. com",
|
||||||
@@ -205,25 +213,31 @@ func TestAddQueryParams(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
url string
|
url string
|
||||||
query map[string]string
|
query map[string][]string
|
||||||
want string
|
want string
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
url: "http://www.test.com",
|
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",
|
want: "http://www.test.com?a=1&b=2",
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: "http://www.test.com",
|
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",
|
want: "http://www.test.com",
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: "http://www.test.com",
|
url: "http://www.test.com",
|
||||||
query: map[string]string{"a": "$%"},
|
query: map[string][]string{"a": {"$%"}},
|
||||||
want: "",
|
want: "",
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user