diff options
Diffstat (limited to 'url/url.go')
-rw-r--r-- | url/url.go | 57 |
1 files changed, 54 insertions, 3 deletions
@@ -4,9 +4,12 @@ package url // import "miniflux.app/url" -import "net/url" -import "fmt" -import "strings" +import ( + "fmt" + "net/url" + "sort" + "strings" +) // AbsoluteURL converts the input URL as absolute URL if necessary. func AbsoluteURL(baseURL, input string) (string, error) { @@ -69,3 +72,51 @@ func Domain(websiteURL string) string { return parsedURL.Host } + +// RequestURI returns the encoded URI to be used in HTTP requests. +func RequestURI(websiteURL string) string { + u, err := url.Parse(websiteURL) + if err != nil { + return websiteURL + } + + queryValues := u.Query() + u.RawQuery = "" // Clear RawQuery to make sure it's encoded properly. + u.Fragment = "" // Clear fragment because Web browsers strip #fragment before sending the URL to a web server. + + var buf strings.Builder + buf.WriteString(u.String()) + + if len(queryValues) > 0 { + buf.WriteByte('?') + + // Sort keys. + keys := make([]string, 0, len(queryValues)) + for k := range queryValues { + keys = append(keys, k) + } + sort.Strings(keys) + + i := 0 + for _, key := range keys { + keyEscaped := url.QueryEscape(key) + values := queryValues[key] + for _, value := range values { + if i > 0 { + buf.WriteByte('&') + } + buf.WriteString(keyEscaped) + + // As opposed to the standard library, we append the = only if the value is not empty. + if value != "" { + buf.WriteByte('=') + buf.WriteString(url.QueryEscape(value)) + } + + i++ + } + } + } + + return buf.String() +} |