2024-01-11 17:59:26 +00:00
|
|
|
// Copyright (C) 2024 Umorpha Systems
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
2024-01-11 20:36:03 +00:00
|
|
|
package gitcache
|
2024-01-11 17:59:26 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2024-01-20 18:07:48 +00:00
|
|
|
func URL2NS(url string) string {
|
2024-01-11 17:59:26 +00:00
|
|
|
// > Clients MUST strip a trailing `/`, if present, from the
|
|
|
|
// > user supplied `$GIT_URL` string
|
|
|
|
// -- gitprotocol-http(5)
|
|
|
|
url = strings.TrimRight(url, "/")
|
|
|
|
|
|
|
|
var id strings.Builder
|
|
|
|
id.Grow(len(url))
|
|
|
|
for _, r := range url {
|
|
|
|
switch {
|
|
|
|
case r == '!', // our own escape
|
|
|
|
// see: git-check-ref-format(1)
|
|
|
|
r <= ' ', r == '\x7F', // never: ASCII control characters
|
|
|
|
r == '~', r == '^', r == ':', // never: gitrevision meaning
|
|
|
|
r == '?', r == '*', r == '[', // never: refspec pattern
|
|
|
|
r == '\\', // never: backslash
|
|
|
|
r == '.', r == '@', r == '/': // sometimes: special rules
|
|
|
|
fmt.Fprintf(&id, "!%02x", r)
|
|
|
|
default:
|
|
|
|
id.WriteRune(r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return id.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
var reEsc = regexp.MustCompile("![0-9a-f]{2}")
|
|
|
|
|
|
|
|
func hex2int(h byte) byte {
|
|
|
|
switch {
|
|
|
|
case '0' <= h && h <= '9':
|
|
|
|
return h - '0'
|
|
|
|
case 'a' <= h && h <= 'f':
|
|
|
|
return h - 'a'
|
|
|
|
default:
|
|
|
|
panic("should not happen")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-20 18:07:48 +00:00
|
|
|
func NS2URL(id string) string {
|
2024-01-11 17:59:26 +00:00
|
|
|
return reEsc.ReplaceAllStringFunc(id, func(esc string) string {
|
|
|
|
r := rune(hex2int(esc[1]))<<4 | rune(hex2int(esc[2]))
|
|
|
|
return string([]rune{r})
|
|
|
|
})
|
|
|
|
}
|