auth/internal/util/http/parse_link.go

58 lines
1.2 KiB
Go

package http
import (
"fmt"
"net/url"
"strconv"
"strings"
)
type Link struct {
URL *url.URL
Params url.Values
}
// ParseLink parse Link HTTP header value into URL and it's params collection.
func ParseLink(raw string) ([]Link, error) {
links := strings.Split(raw, ",")
result := make([]Link, len(links))
for i := range links {
parts := strings.Split(links[i], ";")
start := strings.Index(parts[0], "<")
end := strings.Index(parts[0], ">")
if start == -1 || end == -1 {
continue
}
var err error
if result[i].URL, err = url.Parse(parts[0][start+1 : end]); err != nil {
return nil, fmt.Errorf("cannot parse Link header URL: %w", err)
}
result[i].Params = make(url.Values)
for _, param := range parts[1:] {
paramParts := strings.SplitN(strings.TrimSpace(param), "=", 2)
if unquotted, err := strconv.Unquote(paramParts[1]); err == nil {
result[i].Params.Add(paramParts[0], unquotted)
} else {
result[i].Params.Add(paramParts[0], paramParts[1])
}
}
}
return result, nil
}
func (l Link) String() string {
result := "<" + l.URL.String() + ">"
if len(l.Params) != 0 {
result += "; " + strings.ReplaceAll(l.Params.Encode(), "&", "; ")
}
return result
}