···
···
-
// TODO: proper statuses here on early exit
func (rp *Repo) DownloadArtifact(w http.ResponseWriter, r *http.Request) {
-
tagParam := chi.URLParam(r, "tag")
-
filename := chi.URLParam(r, "file")
f, err := rp.repoResolver.Resolve(r)
log.Println("failed to get repo and knot", err)
tag, err := rp.resolveTag(r.Context(), f, tagParam)
log.Println("failed to resolve tag", err)
···
-
client, err := rp.oauth.AuthorizedClient(r)
-
log.Println("failed to get authorized client", err)
artifacts, err := db.GetArtifact(
db.FilterEq("repo_at", f.RepoAt()),
···
log.Println("failed to get artifacts", err)
-
log.Printf("too many or too little artifacts found")
-
getBlobResp, err := client.SyncGetBlob(r.Context(), artifact.BlobCid.String(), artifact.Did)
-
log.Println("failed to get blob from pds", err)
-
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", filename))
// TODO: proper statuses here on early exit
···
···
func (rp *Repo) DownloadArtifact(w http.ResponseWriter, r *http.Request) {
f, err := rp.repoResolver.Resolve(r)
log.Println("failed to get repo and knot", err)
+
http.Error(w, "failed to resolve repo", http.StatusInternalServerError)
+
tagParam := chi.URLParam(r, "tag")
+
filename := chi.URLParam(r, "file")
tag, err := rp.resolveTag(r.Context(), f, tagParam)
log.Println("failed to resolve tag", err)
···
artifacts, err := db.GetArtifact(
db.FilterEq("repo_at", f.RepoAt()),
···
log.Println("failed to get artifacts", err)
+
http.Error(w, "failed to get artifact", http.StatusInternalServerError)
+
log.Printf("too many or too few artifacts found")
+
http.Error(w, "artifact not found", http.StatusNotFound)
+
ownerPds := f.OwnerId.PDSEndpoint()
+
url, _ := url.Parse(fmt.Sprintf("%s/xrpc/com.atproto.sync.getBlob", ownerPds))
+
q.Set("cid", artifact.BlobCid.String())
+
q.Set("did", artifact.Did)
+
url.RawQuery = q.Encode()
+
req, err := http.NewRequest(http.MethodGet, url.String(), nil)
+
log.Println("failed to create request", err)
+
http.Error(w, "failed to create request", http.StatusInternalServerError)
+
req.Header.Set("Content-Type", "application/json")
+
resp, err := http.DefaultClient.Do(req)
+
log.Println("failed to make request", err)
+
http.Error(w, "failed to make request to PDS", http.StatusInternalServerError)
+
defer resp.Body.Close()
+
// copy status code and relevant headers from upstream response
+
w.WriteHeader(resp.StatusCode)
+
for key, values := range resp.Header {
+
for _, v := range values {
+
// stream the body directly to the client
+
if _, err := io.Copy(w, resp.Body); err != nil {
+
log.Println("error streaming response to client:", err)
// TODO: proper statuses here on early exit