Skip to content

Commit 7688b0b

Browse files
committed
Render cgr history descending
This includes an "end" paramter by default and also renders Link headers so you can iterate through pages if the response is full.
1 parent 4961bb2 commit 7688b0b

1 file changed

Lines changed: 77 additions & 8 deletions

File tree

internal/explore/explore.go

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ func (h *handler) renderManifest(w http.ResponseWriter, r *http.Request, image s
571571
return nil
572572
}
573573

574-
func (h *handler) tagHistory(w http.ResponseWriter, r *http.Request, ref name.Reference, u string) ([]byte, error) {
574+
func (h *handler) tagHistory(w http.ResponseWriter, r *http.Request, ref name.Reference, u string) ([]byte, string, error) {
575575
repo := ref.Context().String()
576576

577577
auth := authn.Anonymous
@@ -590,27 +590,91 @@ func (h *handler) tagHistory(w http.ResponseWriter, r *http.Request, ref name.Re
590590
}
591591
tr, err := h.transportFromCookie(w, r, repo, auth)
592592
if err != nil {
593-
return nil, err
593+
return nil, "", err
594594
}
595595

596596
req, err := http.NewRequest(http.MethodGet, u, nil)
597597
if err != nil {
598-
return nil, err
598+
return nil, "", err
599599
}
600600

601601
req.Header.Set("User-Agent", h.userAgent)
602602

603603
resp, err := tr.RoundTrip(req)
604604
if err != nil {
605-
return nil, err
605+
return nil, "", err
606606
}
607607
defer resp.Body.Close()
608608

609609
if resp.StatusCode != http.StatusOK {
610-
return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
610+
return nil, "", fmt.Errorf("unexpected status: %d", resp.StatusCode)
611+
}
612+
613+
link := resp.Header.Get("Link")
614+
615+
b, err := io.ReadAll(resp.Body)
616+
if err != nil {
617+
return nil, "", err
611618
}
612619

613-
return io.ReadAll(resp.Body)
620+
return b, link, nil
621+
}
622+
623+
func (h *handler) renderLinks(w http.ResponseWriter, r *http.Request, links, u string) error {
624+
if links == "" {
625+
return nil
626+
}
627+
628+
uri, err := url.Parse(u)
629+
if err != nil {
630+
return err
631+
}
632+
633+
fmt.Fprintf(w, "<p>Link: ")
634+
for i, link := range strings.Split(links, ",") {
635+
clean := strings.TrimSpace(link)
636+
if !strings.HasPrefix(clean, "<") {
637+
continue
638+
}
639+
clean = strings.TrimPrefix(clean, "<")
640+
before, _, ok := strings.Cut(clean, ">")
641+
if !ok {
642+
return fmt.Errorf("weird link: %q", clean)
643+
}
644+
clean = before
645+
clean = strings.TrimSpace(clean)
646+
647+
log.Printf("clean: %q", clean)
648+
649+
relative, err := uri.Parse(clean)
650+
if err != nil {
651+
return err
652+
}
653+
654+
newUrl := *r.URL
655+
656+
q := r.URL.Query()
657+
if start := relative.Query().Get("start"); start != "" {
658+
q.Set("start", start)
659+
}
660+
if end := relative.Query().Get("end"); end != "" {
661+
q.Set("end", end)
662+
}
663+
newUrl.RawQuery = q.Encode()
664+
665+
log.Printf("newUrl: %q", newUrl)
666+
667+
href := fmt.Sprintf("<a href=%q>%s</a>", newUrl.String(), html.EscapeString(clean))
668+
withHref := strings.Replace(link, clean, href, 1)
669+
670+
if i > 0 {
671+
fmt.Fprintf(w, ", ")
672+
}
673+
fmt.Fprintf(w, "%s", withHref)
674+
}
675+
fmt.Fprintf(w, "</p>")
676+
677+
return nil
614678
}
615679

616680
// Render CGR history.
@@ -624,10 +688,11 @@ func (h *handler) renderHistory(w http.ResponseWriter, r *http.Request, image st
624688
return fmt.Errorf("not a cgr.dev image: %s", image)
625689
}
626690

627-
u := fmt.Sprintf("https://%s/v2/%s/_chainguard/history/%s", ref.Context().Registry, ref.Context().RepositoryStr(), ref.Identifier())
691+
// Make sure we are descending until I've been dead for a while.
692+
u := fmt.Sprintf("https://%s/v2/%s/_chainguard/history/%s?end=3000-01-01T00:00:00.000Z", ref.Context().Registry, ref.Context().RepositoryStr(), ref.Identifier())
628693

629694
// TODO: Do we need to cache this?
630-
th, err := h.tagHistory(w, r, ref, u)
695+
th, link, err := h.tagHistory(w, r, ref, u)
631696
if err != nil {
632697
return err
633698
}
@@ -661,6 +726,10 @@ func (h *handler) renderHistory(w http.ResponseWriter, r *http.Request, image st
661726
return fmt.Errorf("bodyTmpl: %w", err)
662727
}
663728

729+
if err := h.renderLinks(w, r, link, u); err != nil {
730+
return fmt.Errorf("renderLinks: %w", err)
731+
}
732+
664733
if err := h.renderContent(w, r, ref, b, output, copied); err != nil {
665734
return err
666735
}

0 commit comments

Comments
 (0)