37 lines
1.2 KiB
Go
37 lines
1.2 KiB
Go
package api
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
// handleRemoteConfig serves one app-scoped, immutable-at-runtime document. It is public
|
|
// for the same reason the update verdict is public: a fresh install and a signed-out TV
|
|
// must be able to warm the next launch. No viewer or session data belongs in this answer.
|
|
func (s *Server) handleRemoteConfig(w http.ResponseWriter, r *http.Request) {
|
|
body, err := json.Marshal(s.cfg.RemoteConfig)
|
|
if err != nil {
|
|
// Config is validated during start-up, so this is defensive rather than an expected
|
|
// operational failure.
|
|
writeError(w, http.StatusInternalServerError, "remote configuration unavailable")
|
|
return
|
|
}
|
|
digest := sha256.Sum256(body)
|
|
etag := `"rc-` + hex.EncodeToString(digest[:12]) + `"`
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
w.Header().Set("ETag", etag)
|
|
w.Header().Set("X-Memby-Config-Version", configVersionHeader(s.cfg.RemoteConfig.ConfigVersion))
|
|
if r.Header.Get("If-None-Match") == etag {
|
|
w.WriteHeader(http.StatusNotModified)
|
|
return
|
|
}
|
|
writeRaw(w, http.StatusOK, body)
|
|
}
|
|
|
|
func configVersionHeader(version int64) string {
|
|
return strconv.FormatInt(version, 10)
|
|
}
|