diff --git a/cmd/pkgserver/api.go b/cmd/pkgserver/api.go index 8409f71..8f67365 100644 --- a/cmd/pkgserver/api.go +++ b/cmd/pkgserver/api.go @@ -8,9 +8,9 @@ import ( "net/http" "path" "strconv" - "strings" "hakurei.app/internal/info" + "hakurei.app/internal/pkg" "hakurei.app/internal/rosa" ) @@ -36,14 +36,14 @@ func serveInfo(index *PackageIndex) func(http.ResponseWriter, *http.Request) { } } -func serveStatus(index *PackageIndex) func(w http.ResponseWriter, r *http.Request) { +func serveStatus(index *PackageIndex, cache *pkg.Cache) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { + download := path.Dir(r.URL.Path) == "/status" if index == nil { http.Error(w, "index is nil", http.StatusInternalServerError) return } - base := path.Base(r.URL.Path) - name := strings.TrimSuffix(base, ".log") + name := path.Base(r.URL.Path) p, ok := rosa.ResolveName(name) if !ok { http.NotFound(w, r) @@ -56,7 +56,21 @@ func serveStatus(index *PackageIndex) func(w http.ResponseWriter, r *http.Reques return } if len(pk.status) > 0 { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") + if download { + w.Header().Set("Content-Type", "application/octet-stream") + } else { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + } + if download { + var version string + if pk.Version != "\u0000" { + version = pk.Version + } else { + version = "unknown" + } + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s-%s-%s.log\"", pk.Name, version, pkg.Encode(pk.ident.Value()))) + } + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.WriteHeader(http.StatusOK) _, err := io.Copy(w, bytes.NewReader(pk.status)) @@ -111,10 +125,11 @@ func serveGet(index *PackageIndex) func(http.ResponseWriter, *http.Request) { const ApiVersion = "v1" -func apiRoutes(index *PackageIndex) { +func apiRoutes(index *PackageIndex, cache *pkg.Cache) { http.HandleFunc(fmt.Sprintf("GET /api/%s/info", ApiVersion), serveInfo(index)) http.HandleFunc(fmt.Sprintf("GET /api/%s/get", ApiVersion), serveGet(index)) - http.HandleFunc(fmt.Sprintf("GET /api/%s/status/", ApiVersion), serveStatus(index)) + http.HandleFunc(fmt.Sprintf("GET /api/%s/status/", ApiVersion), serveStatus(index, cache)) + http.HandleFunc("GET /status/", serveStatus(index, cache)) } func WritePayload(w http.ResponseWriter, payload any) { diff --git a/cmd/pkgserver/index.go b/cmd/pkgserver/index.go index 29ba371..3768d08 100644 --- a/cmd/pkgserver/index.go +++ b/cmd/pkgserver/index.go @@ -2,8 +2,8 @@ package main import ( "cmp" - "fmt" "slices" + "unique" "hakurei.app/internal/pkg" "hakurei.app/internal/rosa" @@ -25,12 +25,13 @@ type PackageIndex struct { } type PackageIndexEntry struct { - Name string `json:"name"` - Description string `json:"description,omitempty"` - Website string `json:"website,omitempty"` - Version string `json:"version"` - Status string `json:"report,omitempty"` - status []byte `json:"-"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + Website string `json:"website,omitempty"` + Version string `json:"version"` + HasReport bool `json:"report,omitempty"` + ident unique.Handle[pkg.ID] `json:"-"` + status []byte `json:"-"` } func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, err error) { @@ -45,20 +46,18 @@ func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, id := cache.Ident(a) st, n := report.ArtifactOf(id) var status []byte - var statusUrl string if n < 1 { status = nil - statusUrl = "" } else { status = st - statusUrl = fmt.Sprintf("/api/%s/status/%s.log", ApiVersion, m.Name) } entry := PackageIndexEntry{ Name: m.Name, Description: m.Description, Website: m.Website, Version: v, - Status: statusUrl, + HasReport: len(status) > 0, + ident: id, status: status, } work[p] = entry diff --git a/cmd/pkgserver/main.go b/cmd/pkgserver/main.go index 701f769..065b1b6 100644 --- a/cmd/pkgserver/main.go +++ b/cmd/pkgserver/main.go @@ -50,7 +50,7 @@ func main() { return err } uiRoutes() - apiRoutes(index) + apiRoutes(index, cache) err = http.ListenAndServe(fmt.Sprintf(":%d", flagPort), nil) if err != nil { return err diff --git a/cmd/pkgserver/ui/static/index.js b/cmd/pkgserver/ui/static/index.js index e53f8d0..92ca877 100644 --- a/cmd/pkgserver/ui/static/index.js +++ b/cmd/pkgserver/ui/static/index.js @@ -9,7 +9,7 @@ function toHTML(entry) { let v = entry.version != null ? `${escapeHtml(entry.version)}` : ""; let d = entry.description != null ? `
${escapeHtml(entry.description)}
` : ""; let w = entry.website != null ? `Website` : ""; - let r = entry.report != null ? `Log` : ""; + let r = entry.report ? `Log (View | Download)` : ""; let row = (document.createElement('tr')); row.innerHTML = `${escapeHtml(entry.description)}
` : "" let w = entry.website != null ? `Website` : "" - let r = entry.report != null ? `Log` : "" + let r = entry.report ? `Log (View | Download)` : "" let row =