mirror of
https://github.com/rclone/rclone.git
synced 2025-07-09 08:47:11 +02:00
Add a new backend to support mounting datasets published with a digital object identifier (DOI).
76 lines
1.5 KiB
Go
76 lines
1.5 KiB
Go
package doi
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var linkRegex = regexp.MustCompile(`^<(.+)>$`)
|
|
var valueRegex = regexp.MustCompile(`^"(.+)"$`)
|
|
|
|
// headerLink represents a link as presented in HTTP headers
|
|
// MDN Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
type headerLink struct {
|
|
Href string
|
|
Rel string
|
|
Type string
|
|
Extras map[string]string
|
|
}
|
|
|
|
func parseLinkHeader(header string) (links []headerLink) {
|
|
for _, link := range strings.Split(header, ",") {
|
|
link = strings.TrimSpace(link)
|
|
parsed := parseLink(link)
|
|
if parsed != nil {
|
|
links = append(links, *parsed)
|
|
}
|
|
}
|
|
return links
|
|
}
|
|
|
|
func parseLink(link string) (parsedLink *headerLink) {
|
|
var parts []string
|
|
for _, part := range strings.Split(link, ";") {
|
|
parts = append(parts, strings.TrimSpace(part))
|
|
}
|
|
|
|
match := linkRegex.FindStringSubmatch(parts[0])
|
|
if match == nil {
|
|
return nil
|
|
}
|
|
|
|
result := &headerLink{
|
|
Href: match[1],
|
|
Extras: map[string]string{},
|
|
}
|
|
|
|
for _, keyValue := range parts[1:] {
|
|
parsed := parseKeyValue(keyValue)
|
|
if parsed != nil {
|
|
key, value := parsed[0], parsed[1]
|
|
switch strings.ToLower(key) {
|
|
case "rel":
|
|
result.Rel = value
|
|
case "type":
|
|
result.Type = value
|
|
default:
|
|
result.Extras[key] = value
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func parseKeyValue(keyValue string) []string {
|
|
parts := strings.SplitN(keyValue, "=", 2)
|
|
if parts[0] == "" || len(parts) < 2 {
|
|
return nil
|
|
}
|
|
match := valueRegex.FindStringSubmatch(parts[1])
|
|
if match != nil {
|
|
parts[1] = match[1]
|
|
return parts
|
|
}
|
|
return parts
|
|
}
|