github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/services/v0/download.go (about) 1 package v0 2 3 import ( 4 "net/http" 5 "strings" 6 7 log "github.com/authzed/spicedb/internal/logging" 8 9 "gopkg.in/yaml.v3" 10 ) 11 12 const downloadPath = "/download/" 13 14 func DownloadHandler(shareStore ShareStore) http.Handler { 15 mux := http.NewServeMux() 16 mux.HandleFunc(downloadPath, downloadHandler(shareStore)) 17 return mux 18 } 19 20 func downloadHandler(shareStore ShareStore) func(w http.ResponseWriter, r *http.Request) { 21 return func(w http.ResponseWriter, r *http.Request) { 22 if r.Method != http.MethodGet { 23 w.WriteHeader(http.StatusMethodNotAllowed) 24 return 25 } 26 ref := strings.TrimPrefix(r.URL.Path, downloadPath) 27 if ref == "" { 28 http.Error(w, "ref is missing", http.StatusBadRequest) 29 return 30 } 31 if strings.Contains(ref, "/") { 32 http.Error(w, "ref may not contain a '/'", http.StatusBadRequest) 33 return 34 } 35 shared, status, err := shareStore.LookupSharedByReference(ref) 36 if err != nil { 37 log.Ctx(r.Context()).Debug().Str("id", ref).Err(err).Msg("Lookup Shared Error") 38 w.WriteHeader(http.StatusServiceUnavailable) 39 return 40 } 41 if status == LookupNotFound { 42 log.Ctx(r.Context()).Debug().Str("id", ref).Msg("Lookup Shared Not Found") 43 http.NotFound(w, r) 44 return 45 } 46 out, err := yaml.Marshal(&shared) 47 if err != nil { 48 log.Ctx(r.Context()).Debug().Str("id", ref).Err(err).Msg("Couldn't marshall as yaml") 49 w.WriteHeader(http.StatusInternalServerError) 50 return 51 } 52 if _, err := w.Write(out); err != nil { 53 log.Ctx(r.Context()).Debug().Str("id", ref).Err(err).Msg("Couldn't write as yaml") 54 w.WriteHeader(http.StatusInternalServerError) 55 return 56 } 57 } 58 }