forked from security/hakurei
cmd/pkgserver: add get endpoint
This commit is contained in:
@@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
@@ -53,7 +55,58 @@ func serveStatus(index *PackageIndex) func(w http.ResponseWriter, r *http.Reques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetPayload struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Values []PackageIndexEntry `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetPayload(values []*PackageIndexEntry) GetPayload {
|
||||||
|
count := len(values)
|
||||||
|
v := make([]PackageIndexEntry, count)
|
||||||
|
for i, _ := range values {
|
||||||
|
v[i] = *values[i]
|
||||||
|
}
|
||||||
|
return GetPayload{
|
||||||
|
Count: count,
|
||||||
|
Values: v,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func serveGet(index *PackageIndex) func(http.ResponseWriter, *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
q := r.URL.Query()
|
||||||
|
limit, err := strconv.Atoi(q.Get("limit"))
|
||||||
|
if err != nil || limit > 100 || limit < 1 {
|
||||||
|
http.Error(w, fmt.Sprintf("limit must be an integer between 1 and 100"), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i, err := strconv.Atoi(q.Get("index"))
|
||||||
|
if err != nil || i >= len(index.sorts[0]) || i < 0 {
|
||||||
|
http.Error(w, fmt.Sprintf("index must be an integer between 0 and %d", len(index.sorts[0])-1), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sort, err := strconv.Atoi(q.Get("sort"))
|
||||||
|
if err != nil || sort >= len(index.sorts) || sort < 0 {
|
||||||
|
http.Error(w, fmt.Sprintf("sort must be an integer between 0 and %d", len(index.sorts)-1), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
values := index.sorts[sort][i:min(i+limit, len(index.sorts[sort]))]
|
||||||
|
payload := NewGetPayload(values)
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
b, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
_, err = bytes.NewBuffer(b).WriteTo(w)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
func apiRoutes(index *PackageIndex) {
|
func apiRoutes(index *PackageIndex) {
|
||||||
http.HandleFunc("GET /api/count", serveCount(index))
|
http.HandleFunc("GET /api/count", serveCount(index))
|
||||||
|
http.HandleFunc("GET /api/get", serveGet(index))
|
||||||
http.HandleFunc("GET /api/status/", serveStatus(index))
|
http.HandleFunc("GET /api/status/", serveStatus(index))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cmp"
|
"cmp"
|
||||||
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
@@ -25,10 +26,11 @@ type PackageIndex struct {
|
|||||||
|
|
||||||
type PackageIndexEntry struct {
|
type PackageIndexEntry struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description,omitempty"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website,omitempty"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
status []byte
|
Status string `json:"report,omitempty"`
|
||||||
|
status []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, err error) {
|
func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, err error) {
|
||||||
@@ -43,16 +45,20 @@ func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex,
|
|||||||
id := cache.Ident(a)
|
id := cache.Ident(a)
|
||||||
st, n := report.ArtifactOf(id)
|
st, n := report.ArtifactOf(id)
|
||||||
var status []byte
|
var status []byte
|
||||||
|
var statusUrl string
|
||||||
if n < 1 {
|
if n < 1 {
|
||||||
status = nil
|
status = nil
|
||||||
|
statusUrl = ""
|
||||||
} else {
|
} else {
|
||||||
status = st
|
status = st
|
||||||
|
statusUrl = fmt.Sprintf("/api/status/%s.log", m.Name)
|
||||||
}
|
}
|
||||||
entry := PackageIndexEntry{
|
entry := PackageIndexEntry{
|
||||||
Name: m.Name,
|
Name: m.Name,
|
||||||
Description: m.Description,
|
Description: m.Description,
|
||||||
Website: m.Website,
|
Website: m.Website,
|
||||||
Version: v,
|
Version: v,
|
||||||
|
Status: statusUrl,
|
||||||
status: status,
|
status: status,
|
||||||
}
|
}
|
||||||
work[p] = entry
|
work[p] = entry
|
||||||
|
|||||||
Reference in New Issue
Block a user