58 lines
1.2 KiB
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
|
|
}
|