martian
A programmable HTTP/1.1 proxy for Go, used to inspect, mutate, and verify requests and responses via composable modifiers.
Repository Health
Technical Analysis
Martian is a Go library (with a reference CLI binary) that implements an HTTP/1.1 proxy whose behavior is entirely driven by pluggable modifiers, filters, groups, and verifiers rather than hardcoded logic. Every modifier implements a small ModifyRequest/ModifyResponse interface defined in the root martian package, and each one self-registers a JSON parser so the proxy’s behavior can be configured at runtime by POSTing a JSON message describing which modifiers to activate and in what scope (request, response, or both).
The project ships with dozens of built-in modifiers covering common needs — header injection, cookie manipulation, URL rewriting, HAR logging, status/header verification, CORS, traffic shaping, and MITM certificate generation for intercepting HTTPS traffic — each in its own subpackage (header, cookie, martianurl, har, status, cors, trafficshape, mitm, and more). Because the core interfaces are so small, teams commonly import Martian directly into Go test harnesses and integration suites to mock external services, inject synthetic latency or errors, or assert that specific requests were made, rather than running the bundled cmd/proxy binary standalone.
What You Get
- Modifier interfaces -
RequestModifier,ResponseModifier, andRequestResponseModifierin the rootmartianpackage define the entire extension surface, so any Go struct implementingModifyRequest/ModifyResponsecan plug into the proxy. - JSON-driven runtime configuration - modifiers register a parser via
parse.Registerin theirinit(), letting you POST a JSON body describing which modifiers to enable, on which scope, without recompiling. - Built-in modifier library - ready-made packages for headers, cookies, URL rewriting (martianurl), CORS, status/header verification, HAR logging, and traffic shaping, each independently importable.
- MITM support for HTTPS - the mitm package generates or accepts a CA certificate so Martian can transparently decrypt, inspect, and re-encrypt HTTPS traffic passing through the proxy.
- Verifier framework - verifiers track expectations (e.g. “all responses to example.com return 200”) across a run and expose accumulated failures via a
/verifyHTTP endpoint. - Reference CLI proxy -
cmd/proxyis a ready-to-run binary exposing the configuration/verification/HAR endpoints over HTTP so the library can be exercised without writing Go code.
Common Use Cases
- Test harness mocking - embed Martian in a Go integration test to mock external service responses at the network layer instead of standing up real fakes.
- Traffic verification in CI - use built-in verifiers to assert that a test run produced only expected status codes or headers, then fetch accumulated failures from
/verify. - HTTPS interception for debugging - install Martian’s generated CA certificate in a browser or device to inspect and mutate TLS traffic during development.
- Request/response mutation pipelines - chain header, cookie, and URL modifiers to rewrite traffic for local development against a proxied upstream service.
- Custom proxy behaviors - implement a new modifier type by satisfying the
ModifyRequest/ModifyResponseinterfaces and registering a JSON parser, without forking the proxy core.
Under The Hood
Architecture
The entire library radiates outward from three tiny interfaces defined in martian.go (RequestModifier, ResponseModifier, RequestResponseModifier), which every modifier, filter, group, and verifier implements. proxy.go holds the Proxy type — an http.RoundTripper-backed struct that owns the TCP dial function, MITM config, and a single composed reqmod/resmod pair set once via SetRequestModifier/SetResponseModifier — so the proxy core itself has almost no knowledge of what modifiers actually do. Runtime composability comes from the parse package: each modifier subpackage calls parse.Register("pkg.Type", parseFunc) in its own init(), building a global string-keyed registry that turns incoming JSON configuration messages into live modifier instances via parse.NewResult. This means the dependency direction is inverted from a typical plugin system — the core proxy depends on nothing but the martian and parse packages, while every capability (header, cookie, mitm, trafficshape, verify) is an independent leaf package that only depends inward. Changing the core ModifyRequest/ModifyResponse signatures would ripple through every one of the dozens of modifier packages, but adding a new modifier never touches the proxy core.
Tech Stack
Martian is pure Go (module github.com/google/martian/v3, requiring Go 1.18+ per go.mod though the README cites 1.11) with a deliberately small external dependency surface: github.com/golang/snappy for compression, golang.org/x/net for HTTP/2 and websocket support, and google.golang.org/grpc plus google.golang.org/protobuf for the marbl binary logging format. It builds entirely on the standard library’s net/http, net/http/httputil, and crypto/tls for the proxy and MITM machinery, has no database or ORM layer, and ships a single CLI entry point at cmd/proxy plus a secondary cmd/marbl log viewer. CI (.travis.yml) runs golint ./... and go test -v ./... --race against Go 1.13.x.
Code Quality
Test coverage is substantial and consistent across the codebase — 70 _test.go files against roughly 100 non-test .go files, with large table-driven suites in files like proxy_test.go (35KB) and proxy_trafficshaping_test.go (15KB) exercising the proxy’s connection handling and traffic-shaping logic directly rather than through mocks. Error handling favors explicit returned error values throughout the modifier interfaces rather than panics, and naming is consistent Go convention (exported New* constructors, unexported struct fields). The project enforces golint in CI alongside race-detector test runs, though it predates Go generics and modern linters like golangci-lint.
What Makes It Unique
Martian’s distinguishing choice is treating an HTTP proxy’s behavior as entirely runtime-configurable data rather than compiled logic: modifiers are registered by name against a JSON schema so a proxy’s request/response handling can be reconfigured over HTTP without a rebuild or restart, which is uncommon among Go HTTP proxy libraries that typically expose only a Go-level middleware chain. Combining this with a built-in verifier framework (traffic assertions queryable over /verify) makes it function as much as a testing/observability tool as a proxy, which explains why it’s commonly embedded in test harnesses rather than run standalone.
Used by 2 apps in this directory
Authgear
Authentication
Open-source, self-hostable authentication platform with passkeys, biometric login, SSO, MFA, and GraphQL admin API — a full Auth0/Clerk/Firebase alternative for SaaS and mobile apps.
Jitsu
Data Engineering
Open-source, fully-scriptable data ingestion engine that streams events from web, apps, and APIs to any data warehouse in real time.