4649878a6d
ci/woodpecker/tag/docker Pipeline was successful
Go clients need one GOPROXY for internal and public modules; goproxy has no virtual type, so a local goproxy repo and proxy.golang.org cannot be served together. - union member `@v/list`s; compute `@latest` over the union (highest release, else highest prerelease) - 302 `@latest` and `.info`/`.mod`/`.zip` to the first member with that version, root-relative and `no-store`; probe `.info` for unlisted pseudo-versions - validate case-encoded module paths and versions - fail closed with 502 on a member error, skip members answering 404/410 - cache merged lists, keyed on list and version owners, and module misses for the merge TTL - add `docs/goproxy/virtual.md` and a stock `golang:1.25` e2e-docker case requires unkin/artifactapi#143 Reviewed-on: #159 Co-authored-by: unkin-agent <unkin-agent@unkin.net> Co-committed-by: unkin-agent <unkin-agent@unkin.net>
34 lines
1.1 KiB
Go
34 lines
1.1 KiB
Go
package v1
|
|
|
|
import (
|
|
"errors"
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"git.unkin.net/unkin/artifactapi/internal/virtual"
|
|
"git.unkin.net/unkin/artifactapi/pkg/models"
|
|
)
|
|
|
|
// serveVirtualGoProxy serves the merged @v/list and 302s @latest and version
|
|
// files to the member owning that version.
|
|
func (h *ProxyHandler) serveVirtualGoProxy(w http.ResponseWriter, r *http.Request, virt models.Virtual, path string) {
|
|
body, loc, err := h.virtualEngine.GoProxy(r.Context(), virt, path, r.URL.RawQuery)
|
|
switch {
|
|
case errors.Is(err, virtual.ErrNotFound):
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
case errors.Is(err, virtual.ErrBadPath):
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
case err != nil:
|
|
slog.Error("virtual goproxy fetch failed", "virtual", virt.Name, "path", path, "error", err)
|
|
http.Error(w, "bad gateway", http.StatusBadGateway)
|
|
case loc != "":
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
http.Redirect(w, r, loc, http.StatusFound)
|
|
default:
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
w.Header().Set("X-Artifact-Source", "virtual")
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write(body)
|
|
}
|
|
}
|