Files
mstore/pkg/repocli/referer.go
T
2026-03-11 19:47:40 +02:00

147 lines
3.2 KiB
Go

/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package repocli
import (
"net/url"
"path"
"strings"
)
type Referer struct {
urlobj *url.URL
user, pass string
base, tag string
}
func NewReferer(rawref string) (*Referer, error) {
ref := &Referer{}
if !strings.Contains(rawref, "://") {
rawref = "https://" + rawref
}
urlobj, err := url.Parse(rawref)
if err != nil {
return ref, err
}
if urlobj.User != nil {
ref.user = urlobj.User.Username()
ref.pass, _ = urlobj.User.Password()
urlobj.User = nil
}
ref.urlobj = urlobj
if strings.Contains(ref.urlobj.Path, ":") {
m := strings.SplitN(ref.urlobj.Path, ":", 2)
ref.base = m[0]
ref.tag = m[1]
} else {
ref.base = ref.urlobj.Path
}
ref.urlobj.Path = "/"
ref.urlobj = urlobj
return ref, err
}
func (ref *Referer) RawWithTag(tag string) string {
return path.Join(ref.urlobj.Host, ref.base+":"+tag)
}
func (ref *Referer) Raw() string {
if ref.tag != "" {
return path.Join(ref.urlobj.Host, ref.base+":"+ref.tag)
}
return path.Join(ref.urlobj.Host, ref.base)
}
func (ref *Referer) RawRepo() string {
return path.Join(ref.urlobj.Host, ref.base)
}
func (ref *Referer) Tag() string {
return ref.tag
}
func (ref *Referer) ManifestEP() string {
curl := ref.urlobj.JoinPath("/v2", ref.base, "/manifests", ref.tag)
return curl.String()
}
func (ref *Referer) BlobEP(digest string) string {
curl := ref.urlobj.JoinPath("/v2", ref.base, "/blobs", digest)
return curl.String()
}
func (ref *Referer) UploadEP() string {
curl := ref.urlobj.JoinPath("/v2", ref.base, "/blobs/uploads/")
return curl.String()
}
func (ref *Referer) PatchEP(loc string) (string, error) {
var curl *url.URL
var out string
var err error
if isUUID(loc) {
curl = ref.urlobj.JoinPath("/v2/", ref.base, "/blobs/uploads/", loc)
return curl.String(), nil
}
if strings.Contains(loc, "://") {
curl, err = url.Parse(loc)
if err != nil {
return out, err
}
} else {
curl = ref.urlobj.JoinPath(loc)
}
out = curl.String()
return out, err
}
func (ref *Referer) PutEP(loc, digest string) (string, error) {
var curl *url.URL
var out string
var err error
if isUUID(loc) {
curl = ref.urlobj.JoinPath("/v2/", ref.base, "/blobs/uploads/", loc)
} else if strings.Contains(loc, "://") {
curl, err = url.Parse(loc)
if err != nil {
return out, err
}
} else {
curl = ref.urlobj.JoinPath(loc)
}
query := curl.Query()
query.Set("digest", digest)
curl.RawQuery = query.Encode()
out = curl.String()
return out, err
}
func (ref *Referer) TagsEP() string {
curl := ref.urlobj.JoinPath("/v2", ref.base, "/tags/list")
return curl.String()
}
func (ref *Referer) ReferersEP(digest string) string {
curl := ref.urlobj.JoinPath("/v2", ref.base, "/referers/", digest)
return curl.String()
}
func (ref *Referer) CatalogEP() string {
curl := ref.urlobj.JoinPath("/v2/_catalog")
return curl.String()
}
func (ref *Referer) Userinfo() (string, string) {
return ref.user, ref.pass
}