package apiv1
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"path"
"strconv"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/utils/req"
"github.com/zeebo/xxh3"
)
func specHandler(body []byte, contentType string) http.HandlerFunc {
etag := fmt.Sprintf("%016x", xxh3.Hash(body))
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("ETag", `"`+etag+`"`)
w.Header().Set("Cache-Control", "no-cache")
if req.IfNoneMatch(r, etag) {
w.WriteHeader(http.StatusNotModified)
return
}
w.Header().Set("Content-Type", contentType)
w.WriteHeader(http.StatusOK)
_, _ = w.Write(body)
}
}
func withBasePath(body []byte, key string, quotedInBundle bool) []byte {
serverURL := path.Join(conf.Server.BasePath, consts.URLPathAPIv1)
if serverURL == consts.URLPathAPIv1 {
return body
}
oldURL := consts.URLPathAPIv1
if quotedInBundle {
oldURL = strconv.Quote(oldURL)
}
old := []byte(key + oldURL)
if bytes.Count(body, old) != 1 {
log.Error("API v1: server URL not found in the bundled spec, serving it without the base path", "key", key)
return body
}
newURL, _ := json.Marshal(serverURL)
return bytes.Replace(body, old, append([]byte(key), newURL...), 1)
}