add api for access log events

This commit is contained in:
pascal
2026-01-29 14:27:57 +01:00
parent f204da0d68
commit 8e0b7b6c25
23 changed files with 745 additions and 189 deletions

View File

@@ -2,14 +2,54 @@ package proxy
import (
"context"
"sync"
)
type requestContextKey string
const (
serviceIdKey requestContextKey = "serviceId"
serviceIdKey requestContextKey = "serviceId"
accountIdKey requestContextKey = "accountId"
capturedDataKey requestContextKey = "capturedData"
)
// CapturedData is a mutable struct that allows downstream handlers
// to pass data back up the middleware chain.
type CapturedData struct {
mu sync.RWMutex
ServiceId string
AccountId string
}
// SetServiceId safely sets the service ID
func (c *CapturedData) SetServiceId(serviceId string) {
c.mu.Lock()
defer c.mu.Unlock()
c.ServiceId = serviceId
}
// SetAccountId safely sets the account ID
func (c *CapturedData) SetAccountId(accountId string) {
c.mu.Lock()
defer c.mu.Unlock()
c.AccountId = accountId
}
// WithCapturedData adds a CapturedData struct to the context
func WithCapturedData(ctx context.Context, data *CapturedData) context.Context {
return context.WithValue(ctx, capturedDataKey, data)
}
// CapturedDataFromContext retrieves the CapturedData from context
func CapturedDataFromContext(ctx context.Context) *CapturedData {
v := ctx.Value(capturedDataKey)
data, ok := v.(*CapturedData)
if !ok {
return nil
}
return data
}
func withServiceId(ctx context.Context, serviceId string) context.Context {
return context.WithValue(ctx, serviceIdKey, serviceId)
}
@@ -22,3 +62,15 @@ func ServiceIdFromContext(ctx context.Context) string {
}
return serviceId
}
func withAccountId(ctx context.Context, accountId string) context.Context {
return context.WithValue(ctx, accountIdKey, accountId)
}
func AccountIdFromContext(ctx context.Context) string {
v := ctx.Value(accountIdKey)
accountId, ok := v.(string)
if !ok {
return ""
}
return accountId
}

View File

@@ -26,7 +26,7 @@ func NewReverseProxy(transport http.RoundTripper) *ReverseProxy {
}
func (p *ReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
target, serviceId, exists := p.findTargetForRequest(r)
target, serviceId, accountID, exists := p.findTargetForRequest(r)
if !exists {
// No mapping found so return an error here.
// TODO: prettier error page.
@@ -36,6 +36,8 @@ func (p *ReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Set the serviceId in the context for later retrieval.
ctx := withServiceId(r.Context(), serviceId)
// Set the accountId in the context for later retrieval.
ctx = withAccountId(ctx, accountID)
// Set up a reverse proxy using the transport and then use it to serve the request.
proxy := httputil.NewSingleHostReverseProxy(target)

View File

@@ -8,12 +8,13 @@ import (
)
type Mapping struct {
ID string
Host string
Paths map[string]*url.URL
ID string
AccountID string
Host string
Paths map[string]*url.URL
}
func (p *ReverseProxy) findTargetForRequest(req *http.Request) (*url.URL, string, bool) {
func (p *ReverseProxy) findTargetForRequest(req *http.Request) (*url.URL, string, string, bool) {
p.mappingsMux.RLock()
if p.mappings == nil {
p.mappingsMux.RUnlock()
@@ -21,12 +22,12 @@ func (p *ReverseProxy) findTargetForRequest(req *http.Request) (*url.URL, string
defer p.mappingsMux.Unlock()
p.mappings = make(map[string]Mapping)
// There cannot be any loaded Mappings as we have only just initialized.
return nil, "", false
return nil, "", "", false
}
defer p.mappingsMux.RUnlock()
m, exists := p.mappings[req.Host]
if !exists {
return nil, "", false
return nil, "", "", false
}
// Sort paths by length (longest first) in a naive attempt to match the most specific route first.
@@ -40,10 +41,10 @@ func (p *ReverseProxy) findTargetForRequest(req *http.Request) (*url.URL, string
for _, path := range paths {
if strings.HasPrefix(req.URL.Path, path) {
return m.Paths[path], m.ID, true
return m.Paths[path], m.ID, m.AccountID, true
}
}
return nil, "", false
return nil, "", "", false
}
func (p *ReverseProxy) AddMapping(m Mapping) {