|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## What is Hoverfly |
| 6 | + |
| 7 | +Hoverfly is an HTTP/HTTPS proxy for simulating APIs and services. It can capture, simulate, modify, synthesize, spy on, or diff HTTP traffic. It ships two binaries: `hoverfly` (the proxy server) and `hoverctl` (the CLI to manage it). |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +# Build both binaries to target/ |
| 13 | +make build |
| 14 | + |
| 15 | +# Run all tests (unit + functional + vet) |
| 16 | +make test |
| 17 | + |
| 18 | +# Hoverfly unit tests only |
| 19 | +make hoverfly-test |
| 20 | + |
| 21 | +# Hoverctl unit tests only |
| 22 | +make hoverctl-test |
| 23 | + |
| 24 | +# Functional tests (requires built binaries) |
| 25 | +make hoverfly-functional-test |
| 26 | +make hoverctl-functional-test |
| 27 | + |
| 28 | +# Run a single test (from the relevant package directory) |
| 29 | +cd core && go test -v ./... -run TestFunctionName |
| 30 | + |
| 31 | +# Format and vet |
| 32 | +make fmt |
| 33 | +make vet |
| 34 | +``` |
| 35 | + |
| 36 | +Tests use the **Ginkgo/Gomega** BDD framework. Functional tests in `functional-tests/` spin up actual hoverfly instances. |
| 37 | + |
| 38 | +## Architecture |
| 39 | + |
| 40 | +### Entry Points |
| 41 | + |
| 42 | +- **`core/cmd/hoverfly/main.go`** — parses 50+ flags, wires up Hoverfly, starts proxy + admin API |
| 43 | +- **`hoverctl/main.go`** — Cobra-based CLI; communicates with a running hoverfly instance via HTTP API |
| 44 | + |
| 45 | +### Core Request Flow |
| 46 | + |
| 47 | +1. **goproxy** intercepts incoming HTTP(S) requests (`core/proxy.go`) |
| 48 | +2. The active **Mode** processes the request (`core/modes/`) |
| 49 | +3. **Matching** finds a recorded response against the simulation store (`core/matching/`) |
| 50 | +4. **Templating** renders dynamic response bodies if configured (`core/templating/`) |
| 51 | +5. **Middleware** optionally transforms request/response (local binary or remote HTTP) (`core/middleware/`) |
| 52 | +6. **Delay** is applied (`core/delay/`) |
| 53 | +7. **Post-serve actions** fire (webhooks, scripts) (`core/action/`) |
| 54 | +8. **Journal** records the exchange (`core/journal/`) |
| 55 | + |
| 56 | +### Mode System |
| 57 | + |
| 58 | +Six modes implement the `Mode` interface with a `Process()` method (`core/modes/`): |
| 59 | + |
| 60 | +| Mode | Behavior | |
| 61 | +|------|----------| |
| 62 | +| **Simulate** | Return recorded responses from simulation store | |
| 63 | +| **Capture** | Forward requests and record request/response pairs | |
| 64 | +| **Spy** | Simulate if matched, else pass through | |
| 65 | +| **Modify** | Pass through but run middleware on traffic | |
| 66 | +| **Synthesize** | Generate responses entirely via middleware | |
| 67 | +| **Diff** | Forward requests and diff responses against simulation | |
| 68 | + |
| 69 | +Mode can be switched dynamically at runtime via the admin API. |
| 70 | + |
| 71 | +### Key Packages |
| 72 | + |
| 73 | +- **`core/hoverfly.go`** — `Hoverfly` struct, the central coordinator; holds references to all subsystems |
| 74 | +- **`core/models/`** — `Simulation`, `RequestResponsePair`, `RequestMatcher`, `ResponseDetails` — the core data model |
| 75 | +- **`core/matching/`** — two strategies: `StrongestMatchStrategy` (weighted field scoring) and `FirstMatchStrategy`; wrapped by `CacheMatcher` (LRU) |
| 76 | +- **`core/handlers/v2/`** — 54 REST handler files for the admin API (v1 is legacy) |
| 77 | +- **`core/templating/`** — Handlebars templating via `raymond`; supports CSV/SQL data sources and journal variable injection |
| 78 | +- **`core/middleware/`** — executes local binaries or calls remote HTTP endpoints; passes JSON request/response payloads |
| 79 | +- **`core/authentication/`** — opt-in JWT/basic auth; disabled by default |
| 80 | +- **`hoverctl/wrapper/`** — HTTP client wrapper that hoverctl uses to call the admin API |
| 81 | + |
| 82 | +### Simulation Format |
| 83 | + |
| 84 | +The canonical data format is the `Simulation` JSON structure (`core/models/simulation.go`). It contains an array of `RequestResponsePair` entries, each with a `RequestMatcher` (supporting exact, regex, glob, xpath, jsonpath matchers per field) and a `ResponseDetails`. Test fixtures are in `functional-tests/testdata/`. |
| 85 | + |
| 86 | +### Matching |
| 87 | + |
| 88 | +Matchers operate per HTTP field (method, path, query, headers, body, scheme, destination). Multiple matchers on the same field are ANDed. `StrongestMatchStrategy` picks the most specific match; `FirstMatchStrategy` picks the first. The `CacheMatcher` wraps either strategy with an LRU cache keyed on the request fingerprint. |
| 89 | + |
| 90 | +## Tech Stack |
| 91 | + |
| 92 | +- **Go 1.26.1**, modules in `go.mod` |
| 93 | +- **Proxy:** `github.com/SpectoLabs/goproxy` (custom MITM fork) |
| 94 | +- **CLI:** `cobra` + `viper` |
| 95 | +- **Routing (admin API):** `gorilla/mux`, `go-zoo/bone` |
| 96 | +- **Testing:** `ginkgo` + `gomega` |
| 97 | +- **Logging:** `logrus` |
| 98 | +- **Templating:** `github.com/SpectoLabs/raymond` (Handlebars) |
| 99 | +- **Fake data:** `gofakeit/v6` |
0 commit comments