- Use URL as endpoint ID so handler path-segment lookups resolve correctly.
Previously CreateEndpoint generated a random UUID for the ID, but the
handler always queries by the path segment — every GetEndpoint call
missed, causing duplicate UNIQUE violations on subsequent requests
and orphaned request records (endpoint_id mismatch).
- Register both /{endpoint} and /{endpoint}/ patterns so bare and
nested capture paths both route to the handler (Go 1.22+ ServeMux).
- Strip query string in extractID for robustness, even though the
library never sends ? in r.URL.Path.
- Remove unused net/http import from handler_test.go (caught by vet).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
48 lines
1.3 KiB
Go
48 lines
1.3 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/elfoundation/hatch/internal/store"
|
|
)
|
|
|
|
type Handler struct{ Repo store.Repository }
|
|
|
|
func New(repo store.Repository) *Handler { return &Handler{Repo: repo} }
|
|
|
|
func (h *Handler) RegisterRoutes(mux *http.ServeMux) {
|
|
mux.Handle("/{endpoint}", h)
|
|
mux.Handle("/{endpoint}/", h)
|
|
}
|
|
|
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
eid := extractID(r.URL.Path)
|
|
ctx := context.Background()
|
|
if _, err := h.Repo.GetEndpoint(ctx, eid); err != nil {
|
|
h.Repo.CreateEndpoint(ctx, eid)
|
|
}
|
|
hdr := map[string]string{}
|
|
for k, v := range r.Header { hdr[k] = strings.Join(v, ", ") }
|
|
hdrJSON, _ := json.Marshal(hdr)
|
|
var body []byte
|
|
if r.Body != nil { body, _ = io.ReadAll(r.Body); r.Body.Close() }
|
|
h.Repo.AppendRequest(ctx, eid, &store.Request{
|
|
Method: r.Method, Path: r.URL.Path, Headers: string(hdrJSON),
|
|
Query: r.URL.RawQuery, Body: body,
|
|
})
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{})
|
|
}
|
|
|
|
func extractID(p string) string {
|
|
t := strings.TrimLeft(p, "/")
|
|
if i := strings.IndexByte(t, '?'); i >= 0 { t = t[:i] }
|
|
if i := strings.IndexByte(t, '/'); i >= 0 { return t[:i] }
|
|
return t
|
|
}
|