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  }