carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "net/http"
6 "reflect"
7 "runtime"
8 "slices"
9 "sync"
10)
11
12type claimEntry struct{ Kind, Pattern, Handler string }
13type claimEntryKey struct{}
14type claimInventory struct {
15 mu sync.Mutex
16 entries map[string]claimEntry
17}
18
19func (i *claimInventory) add(e claimEntry) {
20 i.mu.Lock()
21 defer i.mu.Unlock()
22 if i.entries == nil {
23 i.entries = make(map[string]claimEntry)
24 }
25 key := e.Kind + " " + e.Pattern
26 if _, exists := i.entries[key]; exists {
27 panic("duplicate console entry: " + key)
28 }
29 i.entries[key] = e
30}
31func (i *claimInventory) snapshot() []claimEntry {
32 i.mu.Lock()
33 defer i.mu.Unlock()
34 out := make([]claimEntry, 0, len(i.entries))
35 for _, e := range i.entries {
36 out = append(out, e)
37 }
38 slices.SortFunc(out, func(a, b claimEntry) int {
39 if a.Kind+a.Pattern < b.Kind+b.Pattern {
40 return -1
41 }
42 if a.Kind+a.Pattern > b.Kind+b.Pattern {
43 return 1
44 }
45 return 0
46 })
47 return out
48}
49func claimHandlerName(h any) string {
50 f := runtime.FuncForPC(reflect.ValueOf(h).Pointer())
51 if f == nil {
52 panic("console entry has no handler")
53 }
54 return f.Name()
55}
56
57// registerRoute preserves each handler's existing authorization order. It adds
58// provenance for the effect-boundary audit; provenance does not grant a permit.
59func (s *Server) registerRoute(pattern string, h http.HandlerFunc) {
60 e := claimEntry{Kind: "route", Pattern: pattern, Handler: claimHandlerName(h)}
61 s.claimEntries.add(e)
62 if !s.cfg.HostClaim {
63 s.mux.HandleFunc(pattern, h)
64 return
65 }
66 s.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
67 h(w, r.WithContext(context.WithValue(r.Context(), claimEntryKey{}, e)))
68 })
69}
70func (s *Server) registerClaimWorker(name string, h func(context.Context) error) func(context.Context) error {
71 e := claimEntry{Kind: "worker", Pattern: name, Handler: claimHandlerName(h)}
72 s.claimEntries.add(e)
73 return func(ctx context.Context) error { return h(context.WithValue(ctx, claimEntryKey{}, e)) }
74}
75