• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

api/H24-Feb-2020-11561

auth/H24-Feb-2020-388241

body/H24-Feb-2020-536388

cmd/H24-Feb-2020-947582

cookie/H24-Feb-2020-733516

cors/H24-Feb-2020-197123

cybervillains/H24-Feb-2020-5532

failure/H24-Feb-2020-213140

fifo/H24-Feb-2020-604429

filter/H24-Feb-2020-484308

har/H24-Feb-2020-1,9311,424

header/H24-Feb-2020-2,6211,677

httpspec/H24-Feb-2020-12868

ipauth/H24-Feb-2020-244151

log/H24-Feb-2020-15084

marbl/H24-Feb-2020-1,095746

martianhttp/H24-Feb-2020-651440

martianlog/H24-Feb-2020-335192

martiantest/H24-Feb-2020-388249

martianurl/H24-Feb-2020-1,6071,148

messageview/H24-Feb-2020-1,051800

method/H24-Feb-2020-578415

mitm/H24-Feb-2020-496352

mobile/H24-Feb-2020-328220

nosigpipe/H24-Feb-2020-4833

parse/H24-Feb-2020-325217

pingback/H24-Feb-2020-280183

port/H24-Feb-2020-699512

priority/H24-Feb-2020-485329

proxyauth/H24-Feb-2020-293193

proxyutil/H24-Feb-2020-736560

querystring/H24-Feb-2020-999697

servemux/H24-Feb-2020-227132

skip/H24-Feb-2020-13070

stash/H24-Feb-2020-277192

static/H24-Feb-2020-709512

status/H24-Feb-2020-372230

trafficshape/H24-Feb-2020-2,4401,670

verify/H24-Feb-2020-393255

.gitignoreH A D24-Feb-202028 43

.travis.ymlH A D24-Feb-2020249 1612

CONTRIBUTINGH A D24-Feb-20201.4 KiB2521

LICENSEH A D24-Feb-202011.1 KiB203169

README.mdH A D24-Feb-202010.5 KiB306225

context.goH A D24-Feb-20207 KiB313193

context_test.goH A D24-Feb-20203.3 KiB139101

go.modH A D24-Feb-2020106 63

go.sumH A D24-Feb-2020504 65

init.goH A D24-Feb-2020851 3212

martian.goH A D24-Feb-20202 KiB5920

martian_test.goH A D24-Feb-20201.7 KiB5835

multierror.goH A D24-Feb-20201.8 KiB7238

multierror_test.goH A D24-Feb-20201.2 KiB4928

noop.goH A D24-Feb-20201.2 KiB4521

proxy.goH A D24-Feb-202016.5 KiB626476

proxy_test.goH A D24-Feb-202034.4 KiB1,348975

proxy_trafficshaping_test.goH A D24-Feb-202015.1 KiB665515

README.md

1# Martian Proxy [![Build Status](https://travis-ci.org/google/martian.svg?branch=master)](https://travis-ci.org/google/martian)
2
3Martian Proxy is a programmable HTTP proxy designed to be used for testing.
4
5Martian is a great tool to use if you want to:
6
7* Verify that all (or some subset) of requests are secure
8* Mock external services at the network layer
9* Inject headers, modify cookies or perform other mutations of HTTP requests
10  and responses
11* Verify that pingbacks happen when you think they should
12* Unwrap encrypted traffic (requires install of CA certificate in browser)
13
14By taking advantage of Go cross-compilation, Martian can be deployed
15anywhere that Go can target.
16
17## Latest Version
18
19v3.0.0
20
21## Requirements
22
23Go 1.11
24
25## Go Modules Support
26
27Martian Proxy added support for Go modules since v3.0.0.  If you use a Go version that does not support modules, this will break you.  The latest version without Go modules support was tagged v2.1.0.
28
29## Getting Started
30
31### Installation
32Martian Proxy can be installed using `go install`
33
34    go get github.com/google/martian/ && \
35    go install github.com/google/martian/cmd/proxy
36
37### Start the Proxy
38Assuming you've installed Martian, running the proxy is as simple as
39
40    $GOPATH/bin/proxy
41
42If you want to see system logs as Martian is running, pass in the verbosity
43flag:
44
45    $GOPATH/bin/proxy -v=2
46
47By default, Martian will be running on port 8080, and the Martian API will be running on 8181
48. The port can be specified via flags:
49
50    $GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
51
52### Logging
53For logging of requests and responses a [logging
54modifier](https://github.com/google/martian/wiki/Modifier-Reference#logging) is
55available or [HAR](http://www.softwareishard.com/blog/har-12-spec/) logs are
56available if the `-har` flag is used.
57
58#### HAR Logging
59To enable HAR logging in Martian call the binary with the `-har` flag:
60
61    $GOPATH/bin/proxy -har
62
63If the `-har` flag has been enabled two HAR related endpoints will be
64available:
65
66    GET http://martian.proxy/logs
67
68Will retrieve the HAR log of all requests and responses seen by the proxy since
69the last reset.
70
71    DELETE http://martian.proxy/logs/reset
72
73Will reset the in-memory HAR log. Note that the log will grow unbounded unless
74it is periodically reset.
75
76### Configure
77Once Martian is running, you need to configure its behavior. Without
78configuration, Martian is just proxying without doing anything to the requests
79or responses. If enabled, logging will take place without additional
80configuration.
81
82Martian is configured by JSON messages sent over HTTP that take the general
83form of:
84
85    {
86      "header.Modifier": {
87        "scope": ["response"],
88        "name": "Test-Header",
89        "value": "true"
90      }
91    }
92
93The above configuration tells Martian to inject a header with the name
94"Test-Header" and the value "true" on all responses.
95
96Let's break down the parts of this message.
97
98* `[package.Type]`: The package.Type of the modifier that you want to use. In
99  this case, it's "header.Modifier", which is the name of the modifier that
100  sets headers (to learn more about the `header.Modifier`, please
101  refer to the [modifier reference](https://github.com/google/martian/wiki/Modifier-Reference)).
102
103* `[package.Type].scope`: Indicates whether to apply to the modifier to
104  requests, responses or both. This can be an array containing "request",
105  "response", or both.
106
107* `[package.Type].[key]`: Modifier specific data. In the case of the header
108  modifier, we need the `name` and `value` of the header.
109
110This is a simple configuration, for more complex configurations, modifiers are
111combined with groups and filters to compose the desired behavior.
112
113To configure Martian, `POST` the JSON to `http://martian.proxy/modifiers`. You'll
114want to use whatever mechanism your language of choice provides you to make
115HTTP requests, but for demo purposes, curl works (assuming your configuration
116is in a file called `modifier.json`).
117
118        curl -x localhost:8080 \
119             -X POST \
120             -H "Content-Type: application/json" \
121             -d @modifier.json \
122                "http://martian.proxy/configure"
123
124### Intercepting HTTPS Requests and Responses
125Martian supports modifying HTTPS requests and responses if configured to do so.
126
127In order for Martian to intercept HTTPS traffic a custom CA certificate must be
128installed in the browser so that connection warnings are not shown.
129
130The easiest way to install the CA certificate is to start the proxy with the
131necessary flags to use a custom CA certificate and private key using the `-cert`
132and `-key` flags, or to have the proxy generate one using the `-generate-ca-cert`
133flag.
134
135After the proxy has started, visit http://martian.proxy/authority.cer in the
136browser configured to use the proxy and a prompt will be displayed to install
137the certificate.
138
139Several flags are available in `examples/main.go` to help configure MITM
140functionality:
141
142    -key=""
143      PEM encoded private key file of the CA certificate provided in -cert; used
144      to sign certificates that are generated on-the-fly
145    -cert=""
146      PEM encoded CA certificate file used to generate certificates
147    -generate-ca-cert=false
148      generates a CA certificate and private key to use for man-in-the-middle;
149      most users choosing this option will immediately visit
150      http://martian.proxy/authority.cer in the browser whose traffic is to be
151      intercepted to install the newly generated CA certificate
152    -organization="Martian Proxy"
153      organization name set on the dynamically-generated certificates during
154      man-in-the-middle
155    -validity="1h"
156      window of time around the time of request that the dynamically-generated
157      certificate is valid for; the duration is set such that the total valid
158      timeframe is double the value of validity (1h before & 1h after)
159
160### Check Verifiers
161Let's assume that you've configured Martian to verify the presence a specific
162header in responses to a specific URL.
163
164Here's a configuration to verify that all requests to `example.com` return
165responses with a `200 OK`.
166
167          {
168            "url.Filter": {
169              "scope": ["request", "response"],
170              "host" : "example.com",
171              "modifier" : {
172                "status.Verifier": {
173                  "scope" : ["response"],
174                  "statusCode": 200
175                }
176              }
177            }
178          }
179
180Once Martian is running, configured and the requests and resultant responses you
181wish to verify have taken place, you can verify your expectation that you only
182got back `200 OK` responses.
183
184To check verifications, perform
185
186    GET http://martian.proxy/verify
187
188Failed expectations are tracked as errors, and the list of errors are retrieved
189by making a `GET` request to `host:port/martian/verify`, which will return
190a list of errors:
191
192      {
193          "errors" : [
194              {
195                  "message": "response(http://example.com) status code verify failure: got 500, want 200"
196              },
197              {
198                  "message": "response(http://example.com/foo) status code verify failure: got 500, want 200"
199              }
200          ]
201      }
202
203Verification errors are held in memory until they are explicitly cleared by
204
205    POST http://martian.proxy/verify/reset
206
207## Martian as a Library
208Martian can also be included into any Go program and used as a library.
209
210## Modifiers All The Way Down
211Martian's request and response modification system is designed to be general
212and extensible. The design objective is to provide individual modifier
213behaviors that can arranged to build out nearly any desired modification.
214
215When working with Martian to compose behaviors, you'll need to be familiar with
216these different types of interactions:
217
218* Modifiers: Changes the state of a request or a response
219* Filters: Conditionally allows a contained Modifier to execute
220* Groups: Bundles multiple modifiers to be executed in the order specified in
221  the group
222* Verifiers: Tracks network traffic against expectations
223
224Modifiers, filters and groups all implement `RequestModifier`,
225`ResponseModifier` or `RequestResponseModifier` (defined in
226[`martian.go`](https://github.com/google/martian/blob/master/martian.go)).
227
228```go
229ModifyRequest(req *http.Request) error
230
231ModifyResponse(res *http.Response) error
232```
233
234Throughout the code (and this documentation) you'll see the word "modifier"
235used as a term that encompasses modifiers, groups and filters. Even though a
236group does not modify a request or response, we still refer to it as a
237"modifier".
238
239We refer to anything that implements the `modifier` interface as a Modifier.
240
241### Parser Registration
242Each modifier must register its own parser with Martian. The parser is
243responsible for parsing a JSON message into a Go struct that implements a
244modifier interface.
245
246Martian holds modifier parsers as a map of strings to functions that is built
247out at run-time. Each modifier is responsible for registering its parser with a
248call to `parse.Register` in `init()`.
249
250Signature of parse.Register:
251
252```go
253Register(name string, parseFunc func(b []byte) (interface{}, error))
254```
255
256Register takes in the key as a string in the form `package.Type`. For
257instance, `cookie_modifier` registers itself with the key `cookie.Modifier` and
258`query_string_filter` registers itself as `querystring.Filter`. This string is
259the same as the value of `name` in the JSON configuration message.
260
261In the following configuration message, `header.Modifier` is how the header
262modifier is registered in the `init()` of `header_modifier.go`.
263
264    {
265      "header.Modifier": {
266        "scope": ["response"],
267        "name" : "Test-Header",
268        "value" : "true"
269      }
270    }
271
272Example of parser registration from `header_modifier.go`:
273
274```go
275func init() {
276  parse.Register("header.Modifier", modifierFromJSON)
277}
278
279func modifierFromJSON(b []byte) (interface{}, error) {
280  ...
281}
282```
283
284### Adding Your Own Modifier
285If you have a use-case in mind that we have not developed modifiers, filters or
286verifiers for, you can easily extend Martian to your very specific needs.
287
288There are 2 mandatory parts of a modifier:
289
290* Implement the modifier interface
291* Register the parser
292
293Any Go struct that implements those interfaces can act as a `modifier`.
294
295## Contact
296For questions and comments on how to use Martian, features announcements, or
297design discussions check out our public Google Group at
298https://groups.google.com/forum/#!forum/martianproxy-users.
299
300For security related issues please send a detailed report to our private core
301group at martianproxy-core@googlegroups.com.
302
303## Disclaimer
304This is not an official Google product (experimental or otherwise), it is just
305code that happens to be owned by Google.
306