package handler import ( "bytes" "fmt" "io" "net/http" "strings" "gitea.loveuer.com/loveuer/cluster/internal/model" "gitea.loveuer.com/loveuer/cluster/internal/rerr" "github.com/gofiber/fiber/v3" ) func handleManifest(c fiber.Ctx) error { elem := strings.Split(c.Path(), "/") elem = elem[1:] target := elem[len(elem)-1] repo := strings.Join(elem[1:len(elem)-2], "/") switch c.Method() { case http.MethodGet: reader, contentType, re := m.Get(c.Context(), repo, target) if re != nil { return rerr.Error(c, re) } bs, err := io.ReadAll(reader) if err != nil { return rerr.Error(c, rerr.ErrInternal(err)) } h, _, _ := model.SHA256(bytes.NewReader(bs)) c.Set("Docker-Content-Digest", h.String()) c.Set("Content-Type", contentType) c.Set("Content-Length", fmt.Sprint(len(bs))) return c.Send(bs) case http.MethodHead: reader, contentType, re := m.Get(c.Context(), repo, target) if re != nil { return rerr.Error(c, re) } bs, err := io.ReadAll(reader) if err != nil { return rerr.Error(c, rerr.ErrInternal(err)) } h, _, _ := model.SHA256(bytes.NewReader(bs)) c.Set("Docker-Content-Digest", h.String()) c.Set("Content-Type", contentType) c.Set("Content-Length", fmt.Sprint(len(bs))) return c.Send(bs) case http.MethodPut: buf := &bytes.Buffer{} if _, err := io.Copy(buf, bytes.NewReader(c.Body())); err != nil { return rerr.Error(c, rerr.ErrInternal(err)) } hash, _, err := model.SHA256(bytes.NewReader(buf.Bytes())) if err != nil { return rerr.Error(c, rerr.ErrInternal(err)) } digest := hash.String() mf := model.RepoSimpleManifest{ Blob: buf.Bytes(), ContentType: c.Get("Content-Type"), } if err := m.Put(c.Context(), repo, target, digest, &mf); err != nil { return rerr.Error(c, rerr.ErrInternal(err)) } c.Set("Docker-Content-Digest", digest) return c.SendStatus(http.StatusCreated) case http.MethodDelete: return c.SendStatus(http.StatusAccepted) default: return rerr.Error(c, &rerr.RepositoryError{ Status: http.StatusBadRequest, Code: "METHOD_UNKNOWN", Message: "We don't understand your method + url", }) } }