93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type WellKnownGetter interface {
|
|
GetData(ctx context.Context) (wkRegistry, error)
|
|
}
|
|
|
|
// GetHealthServer returns a simple health check handler.
|
|
func GetHealthServer() http.Handler {
|
|
mux := http.NewServeMux()
|
|
|
|
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
|
endpoint := "/healthz"
|
|
requestCounter.WithLabelValues(endpoint).Inc()
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte("OK"))
|
|
})
|
|
|
|
return mux
|
|
}
|
|
|
|
// GetServer returns an HTTP handler that serves the well-known endpoints.
|
|
func GetServer(wks WellKnownGetter) http.Handler {
|
|
mux := http.NewServeMux()
|
|
|
|
mux.HandleFunc("/.well-known/", func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
reg, err := wks.GetData(ctx)
|
|
if err != nil {
|
|
http.Error(w, "Failed to fetch well-known records", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Extract the ID from the URL path (strip the prefix)
|
|
id := strings.TrimPrefix(r.URL.Path, "/.well-known/")
|
|
if id == "" {
|
|
errorCounter.WithLabelValues(id).Inc()
|
|
http.Error(w, "Not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
// First, try the exact match
|
|
val, ok := reg[id]
|
|
|
|
// If a match is found, check for the format annotation
|
|
if ok {
|
|
data := val.(map[string]interface{})["data"]
|
|
format := val.(map[string]interface{})["format"]
|
|
|
|
// If the format is locked to JSON, always return application/json
|
|
if format == "json" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
b, err := json.Marshal(data)
|
|
if err != nil {
|
|
http.Error(w, "Failed to encode JSON", http.StatusInternalServerError)
|
|
errorCounter.WithLabelValues(id).Inc()
|
|
return
|
|
}
|
|
w.Write(b)
|
|
requestCounter.WithLabelValues(id).Inc()
|
|
return
|
|
} else if format == "text" {
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
switch v := data.(type) {
|
|
case []string:
|
|
fmt.Fprint(w, strings.Join(v, "\n"))
|
|
requestCounter.WithLabelValues(id).Inc()
|
|
case string:
|
|
fmt.Fprint(w, v)
|
|
requestCounter.WithLabelValues(id).Inc()
|
|
default:
|
|
http.Error(w, "Unsupported data type for text/plain format", http.StatusInternalServerError)
|
|
errorCounter.WithLabelValues(id).Inc()
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
// If no match is found, return 404
|
|
errorCounter.WithLabelValues(id).Inc()
|
|
http.Error(w, "Not found", http.StatusNotFound)
|
|
})
|
|
|
|
return mux
|
|
}
|