shiori/internal/core/url.go
Felipe Martin Garcia 0fe24d2598
fix: url modification when query param is empty (#411)
This commit fixes URL malformation when trying to remove the utm social
query parameters from an URL, which upon finishing and reconstructing
would attach the equal symbol even if the original URL didn't have it.

This is a known Go "bug" [1] that isn't going to be "fixed". I quote
that because server side should behave the same for `?a=&b=1` and
`?a&b=1` for the `a` parameter, but sometimes that's not the case.

[1]: https://github.com/golang/go/issues/20820

Fixes #409
2022-03-27 21:01:39 +02:00

58 lines
1.2 KiB
Go

package core
import (
"fmt"
nurl "net/url"
"sort"
"strings"
)
// queryEncodeWithoutEmptyValues is a copy of `values.Encode` but checking if the queryparam
// value is empty to prevent sending the = symbol empty which breaks in some servers.
func queryEncodeWithoutEmptyValues(v nurl.Values) string {
if v == nil {
return ""
}
var buf strings.Builder
keys := make([]string, 0, len(v))
for k := range v {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
vs := v[k]
keyEscaped := nurl.QueryEscape(k)
for _, v := range vs {
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(keyEscaped)
if v != "" {
buf.WriteByte('=')
buf.WriteString(nurl.QueryEscape(v))
}
}
}
return buf.String()
}
// RemoveUTMParams removes the UTM parameters from URL.
func RemoveUTMParams(url string) (string, error) {
// Parse string URL
tmp, err := nurl.Parse(url)
if err != nil || tmp.Scheme == "" || tmp.Hostname() == "" {
return url, fmt.Errorf("URL is not valid")
}
// Remove UTM queries
queries := tmp.Query()
for key := range queries {
if strings.HasPrefix(key, "utm_") {
queries.Del(key)
}
}
tmp.Fragment = ""
tmp.RawQuery = queryEncodeWithoutEmptyValues(queries)
return tmp.String(), nil
}