Select Git revision
http-handler.go

Volker Schukai authored
http-handler.go 2.77 KiB
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package configuration
import (
"bytes"
"context"
negotiation "gitlab.schukai.com/oss/libraries/go/network/http-negotiation"
"net/http"
)
// ContextKey is the key used to store the configuration in the request context
// This is used by the middleware
func (s *Settings[C]) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = context.WithValue(ctx, contextKey, s.config)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
// serveGet handles GET requests
func (s *Settings[C]) serveGet(w http.ResponseWriter, r *http.Request) {
n := negotiation.New(r.Header)
m := n.Type("application/json", "text/json", "application/yaml", "text/yaml", "application/toml", "text/toml", "application/properties", "text/properties", "text/x-java-properties", "text/x-properties")
if m == "" {
w.WriteHeader(http.StatusNotAcceptable)
return
}
buf := new(bytes.Buffer)
switch m {
case "application/json", "text/json":
w.Header().Set("Content-Type", "application/json")
s.Write(buf, Json)
case "application/yaml", "text/yaml":
w.Header().Set("Content-Type", "application/yaml")
s.Write(buf, Yaml)
case "application/toml", "text/toml":
w.Header().Set("Content-Type", "application/toml")
s.Write(buf, Toml)
case "application/properties", "text/properties", "text/x-java-properties", "text/x-properties":
w.Header().Set("Content-Type", "application/properties")
s.Write(buf, Properties)
}
if s.HasErrors() {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(buf.Bytes())
}
func (s *Settings[C]) servePost(w http.ResponseWriter, r *http.Request) {
n := negotiation.New(r.Header)
m := n.ContentType("application/json", "text/json", "application/yaml", "text/yaml", "application/toml", "text/toml", "application/properties", "text/properties", "text/x-java-properties", "text/x-properties")
rs := reader{
reader: r.Body,
}
switch m {
case "application/json", "text/json":
rs.format = Json
case "application/yaml", "text/yaml":
rs.format = Yaml
case "application/toml", "text/toml":
rs.format = Toml
case "application/properties", "text/properties", "text/x-java-properties", "text/x-properties":
rs.format = Properties
default:
w.WriteHeader(http.StatusUnsupportedMediaType)
return
}
s.Lock()
defer s.Unlock()
b := s.config
s.importStream(rs)
x := s.config
s.config = b
s.setConfigInternal(x, false)
}
// ServeHTTP implements the http.Handler interface
func (s *Settings[C]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
s.serveGet(w, r)
case http.MethodPost:
s.servePost(w, r)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
}