2024-04-10 22:10:09 +08:00
|
|
|
package handler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
2024-12-23 00:07:44 -08:00
|
|
|
"strings"
|
|
|
|
|
2024-04-10 22:10:09 +08:00
|
|
|
"nf-repo/internal/interfaces"
|
|
|
|
"nf-repo/internal/model"
|
|
|
|
"nf-repo/internal/model/types"
|
2024-12-23 00:07:44 -08:00
|
|
|
"nf-repo/internal/tool/rerr"
|
|
|
|
|
|
|
|
"github.com/loveuer/nf"
|
2024-04-10 22:10:09 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func handleReferrers(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
|
|
|
if ctx.Method() != "GET" {
|
|
|
|
return rerr.Error(ctx, &rerr.RepositoryError{
|
|
|
|
Status: http.StatusBadRequest,
|
|
|
|
Code: "METHOD_UNKNOWN",
|
|
|
|
Message: "We don't understand your method + url",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
elem := strings.Split(ctx.Path(), "/")
|
|
|
|
elem = elem[1:]
|
|
|
|
target := elem[len(elem)-1]
|
|
|
|
repo := strings.Join(elem[1:len(elem)-2], "/")
|
|
|
|
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
re *rerr.RepositoryError
|
|
|
|
im *model.IndexManifest
|
|
|
|
)
|
|
|
|
|
|
|
|
// Validate that incoming target is a valid digest
|
|
|
|
if _, err := model.NewHash(target); err != nil {
|
|
|
|
return rerr.Error(ctx, &rerr.RepositoryError{
|
|
|
|
Status: http.StatusBadRequest,
|
|
|
|
Code: "UNSUPPORTED",
|
|
|
|
Message: "Target must be a valid digest",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if im, re = m.Referrers(ctx.Request.Context(), repo, target); re != nil {
|
|
|
|
return rerr.Error(ctx, re)
|
|
|
|
}
|
|
|
|
|
|
|
|
msg, _ := json.Marshal(im)
|
|
|
|
ctx.Set("Content-Length", fmt.Sprint(len(msg)))
|
|
|
|
ctx.Set("Content-Type", string(types.OCIImageIndex))
|
|
|
|
ctx.Status(http.StatusOK)
|
2024-12-23 00:07:44 -08:00
|
|
|
_, err = io.Copy(ctx.Writer, bytes.NewReader(msg))
|
2024-04-10 22:10:09 +08:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|