Skip to content

Commit 43fbea5

Browse files
committed
Add example and documentation for request-hash.
1 parent 9039d74 commit 43fbea5

File tree

6 files changed

+75
-1
lines changed

6 files changed

+75
-1
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ The directory `httpbin` must already exist before running.
4343

4444
See `chameleon -help` for more information.
4545

46+
### Specifying custom hash
47+
48+
There may be a reason in your tests to manually create responses - perhaps the backing service doesn't exist yet, or in test mode a service behaves differently than production. When this is the case, you can create custom responses and signal to chameleon the hash you want to use for a given request.
49+
50+
Set the `chameleon-request-hash` header with a unique hash value (which is a valid filename) and chameleon will look for that hash in the `spec.json` file and for all subsequent requests.
51+
52+
This allows you to not only have total control over the response for a given request but also makes your test code easier to reason about -- it is clear where the "special case" response is coming from.
53+
54+
### Getting the hash for a given request
55+
56+
All responses from chameleon will have a `chameleon-request-hash` header set which is the hash used for that request. This header is present even if you did not set it on the incoming request.
57+
4658
### Preseeding the cache
4759

4860
If you want to configure the cache at runtime without having to depend on an external service, you may preseed the cache

example/app.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,23 @@ def do_SEEDED(self):
8686
self.end_headers()
8787
self.wfile.write(resp.read())
8888

89+
def do_REQUESTHASH(self):
90+
content_len = int(self.headers.getheader('content-length', 0))
91+
body = self.rfile.read(content_len)
92+
93+
req = urllib2.Request(POST_SERVICE_URL, body, self.headers)
94+
req.get_method = lambda: 'POST'
95+
try:
96+
resp = urllib2.urlopen(req)
97+
except urllib2.HTTPError as exc:
98+
resp = exc
99+
100+
self.send_response(200)
101+
for k, v in resp.headers.dict.viewitems():
102+
self.send_header(k, v)
103+
self.end_headers()
104+
self.wfile.write(resp.read())
105+
89106

90107
def main():
91108
print('Serving on port {}'.format(TEST_APP_PORT))

example/testing_data/foo_bar_hash

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"args": {},
3+
"data": "{\"foo\": \"bar\"}",
4+
"files": {},
5+
"form": {},
6+
"headers": {
7+
"Accept-Encoding": "identity",
8+
"Chameleon-Request-Hash": "foo_bar_hash",
9+
"Content-Length": "14",
10+
"Content-Type": "application/json",
11+
"Host": "httpbin.org",
12+
"User-Agent": "Python-urllib/2.7",
13+
"X-Forwarded-Ssl": "on"
14+
},
15+
"json": {
16+
"foo": "bar"
17+
},
18+
"origin": "99.245.54.15",
19+
"url": "http://httpbin.org/post"
20+
}

example/testing_data/spec.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,20 @@
110110
}
111111
},
112112
"key": "9835adf25e3ecc09431cdf3079bb822a"
113+
},
114+
{
115+
"response": {
116+
"status_code": 200,
117+
"content": "foo_bar_hash",
118+
"headers": {
119+
"Access-Control-Allow-Credentials": "true",
120+
"Access-Control-Allow-Origin": "*",
121+
"Content-Length": "452",
122+
"Content-Type": "application/json",
123+
"Date": "Sun, 18 Jan 2015 23:30:57 GMT",
124+
"Server": "nginx"
125+
}
126+
},
127+
"key": "foo_bar_hash"
113128
}
114129
]

example/tests.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,17 @@ def test_preseed(self):
109109
self.assertEqual(942, resp.getcode())
110110
self.assertEqual({'key': 'value'}, json.loads(resp.read()))
111111

112+
def test_specify_hash_in_request(self):
113+
url = 'http://localhost:{}/post'.format(TEST_APP_PORT)
114+
req = urllib2.Request(url, json.dumps({'foo': 'bar'}), {
115+
'Content-type': 'application/json', 'chameleon-request-hash': 'foo_bar_hash'})
116+
req.get_method = lambda: 'REQUESTHASH'
117+
resp = urllib2.urlopen(req)
118+
content = resp.read()
119+
parsed = json.loads(content)
120+
self.assertEqual({'foo': 'bar'}, parsed['json'])
121+
self.assertEqual('foo_bar_hash', resp.headers['chameleon-request-hash'])
122+
112123

113124
if __name__ == '__main__':
114125
unittest.main()

handlers.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ func CachedProxyHandler(serverURL *url.URL, cacher Cacher, hasher Hasher) http.H
9191

9292
hash := r.Header.Get("chameleon-request-hash")
9393
if hash == "" {
94-
log.Printf("-> Hashing Request %v", r.URL)
9594
hash = hasher.Hash(r)
9695
}
9796
response := cacher.Get(hash)

0 commit comments

Comments
 (0)