Skip to content

Commit

Permalink
Add example and documentation for request-hash.
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpresta committed Jan 18, 2015
1 parent 9039d74 commit 43fbea5
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 1 deletion.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ The directory `httpbin` must already exist before running.

See `chameleon -help` for more information.

### Specifying custom hash

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.

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.

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.

### Getting the hash for a given request

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.

### Preseeding the cache

If you want to configure the cache at runtime without having to depend on an external service, you may preseed the cache
Expand Down
17 changes: 17 additions & 0 deletions example/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@ def do_SEEDED(self):
self.end_headers()
self.wfile.write(resp.read())

def do_REQUESTHASH(self):
content_len = int(self.headers.getheader('content-length', 0))
body = self.rfile.read(content_len)

req = urllib2.Request(POST_SERVICE_URL, body, self.headers)
req.get_method = lambda: 'POST'
try:
resp = urllib2.urlopen(req)
except urllib2.HTTPError as exc:
resp = exc

self.send_response(200)
for k, v in resp.headers.dict.viewitems():
self.send_header(k, v)
self.end_headers()
self.wfile.write(resp.read())


def main():
print('Serving on port {}'.format(TEST_APP_PORT))
Expand Down
20 changes: 20 additions & 0 deletions example/testing_data/foo_bar_hash
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"args": {},
"data": "{\"foo\": \"bar\"}",
"files": {},
"form": {},
"headers": {
"Accept-Encoding": "identity",
"Chameleon-Request-Hash": "foo_bar_hash",
"Content-Length": "14",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/2.7",
"X-Forwarded-Ssl": "on"
},
"json": {
"foo": "bar"
},
"origin": "99.245.54.15",
"url": "http://httpbin.org/post"
}
15 changes: 15 additions & 0 deletions example/testing_data/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,20 @@
}
},
"key": "9835adf25e3ecc09431cdf3079bb822a"
},
{
"response": {
"status_code": 200,
"content": "foo_bar_hash",
"headers": {
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Origin": "*",
"Content-Length": "452",
"Content-Type": "application/json",
"Date": "Sun, 18 Jan 2015 23:30:57 GMT",
"Server": "nginx"
}
},
"key": "foo_bar_hash"
}
]
11 changes: 11 additions & 0 deletions example/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ def test_preseed(self):
self.assertEqual(942, resp.getcode())
self.assertEqual({'key': 'value'}, json.loads(resp.read()))

def test_specify_hash_in_request(self):
url = 'http://localhost:{}/post'.format(TEST_APP_PORT)
req = urllib2.Request(url, json.dumps({'foo': 'bar'}), {
'Content-type': 'application/json', 'chameleon-request-hash': 'foo_bar_hash'})
req.get_method = lambda: 'REQUESTHASH'
resp = urllib2.urlopen(req)
content = resp.read()
parsed = json.loads(content)
self.assertEqual({'foo': 'bar'}, parsed['json'])
self.assertEqual('foo_bar_hash', resp.headers['chameleon-request-hash'])


if __name__ == '__main__':
unittest.main()
1 change: 0 additions & 1 deletion handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ func CachedProxyHandler(serverURL *url.URL, cacher Cacher, hasher Hasher) http.H

hash := r.Header.Get("chameleon-request-hash")
if hash == "" {
log.Printf("-> Hashing Request %v", r.URL)
hash = hasher.Hash(r)
}
response := cacher.Get(hash)
Expand Down

0 comments on commit 43fbea5

Please sign in to comment.