120 lines
2.2 KiB
Go
120 lines
2.2 KiB
Go
package entity
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/url"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type UrlValue map[string]string
|
|
|
|
func QueryToMap(query string) (result UrlValue) {
|
|
result = UrlValue{}
|
|
var value url.Values
|
|
fUrl, _ := url.Parse(query)
|
|
if fUrl.Scheme == "" {
|
|
q, _ := url.ParseQuery(query)
|
|
value = q
|
|
} else {
|
|
value = fUrl.Query()
|
|
}
|
|
for k, v := range value {
|
|
result[k] = v[0]
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (value *UrlValue) Reader() *strings.Reader {
|
|
b, _ := json.Marshal(value)
|
|
return strings.NewReader(string(b))
|
|
}
|
|
|
|
func (value *UrlValue) Body() *strings.Reader {
|
|
return strings.NewReader(value.Encode())
|
|
}
|
|
|
|
func (value UrlValue) JsonString() string {
|
|
b, _ := json.Marshal(value)
|
|
return string(b)
|
|
}
|
|
|
|
func (value *UrlValue) Encode() string {
|
|
values := url.Values{}
|
|
for k, v := range *value {
|
|
values.Set(k, v)
|
|
}
|
|
return values.Encode()
|
|
}
|
|
|
|
func (value UrlValue) Query() string {
|
|
var buf strings.Builder
|
|
keys := make([]string, 0, len(value))
|
|
for k := range value {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, k := range keys {
|
|
v := value[k]
|
|
if buf.Len() > 0 {
|
|
buf.WriteByte('&')
|
|
}
|
|
buf.WriteString(k)
|
|
buf.WriteByte('=')
|
|
buf.WriteString(v)
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
func UrlMergeQuery(rawUrl, query string) string {
|
|
q, _ := url.Parse(rawUrl)
|
|
rawKeys, rawValues := parseQuery(q.RawQuery)
|
|
keys, values := parseQuery(query)
|
|
for idx, k := range keys {
|
|
value := values[idx]
|
|
cidx := containsIndex(rawKeys, k)
|
|
if cidx == -1 {
|
|
rawKeys = append(rawKeys, k)
|
|
rawValues = append(rawValues, value)
|
|
} else {
|
|
rawValues[cidx] = value
|
|
}
|
|
}
|
|
rawQuery := []string{}
|
|
for idx, key := range rawKeys {
|
|
rawQuery = append(rawQuery, key+"="+rawValues[idx])
|
|
}
|
|
q.RawQuery = strings.Join(rawQuery, "&")
|
|
return q.String()
|
|
}
|
|
|
|
func parseQuery(query string) (keys, values []string) {
|
|
for query != "" {
|
|
key := query
|
|
if i := strings.IndexAny(key, "&;"); i >= 0 {
|
|
key, query = key[:i], key[i+1:]
|
|
} else {
|
|
query = ""
|
|
}
|
|
if key == "" {
|
|
continue
|
|
}
|
|
value := ""
|
|
if i := strings.Index(key, "="); i >= 0 {
|
|
key, value = key[:i], key[i+1:]
|
|
}
|
|
keys = append(keys, key)
|
|
values = append(values, value)
|
|
}
|
|
return
|
|
}
|
|
|
|
func containsIndex(list []string, elem string) int {
|
|
for idx, v := range list {
|
|
if elem == v {
|
|
return idx
|
|
}
|
|
}
|
|
return -1
|
|
}
|