mirror of https://github.com/mitsuhiko/flask.git
Armin Ronacher
12 years ago
2 changed files with 56 additions and 0 deletions
@ -0,0 +1,55 @@ |
|||||||
|
Request Content Checksums |
||||||
|
========================= |
||||||
|
|
||||||
|
Various pieces of code can consume the request data and preprocess it. |
||||||
|
For instance JSON data ends up on the request object already read and |
||||||
|
processed, form data ends up there as well but goes through a different |
||||||
|
code path. This seems inconvenient when you want to calculate the |
||||||
|
checksum of the incoming request data. This is necessary sometimes for |
||||||
|
some APIs. |
||||||
|
|
||||||
|
Fortunately this is however very simple to change by wrapping the input |
||||||
|
stream. |
||||||
|
|
||||||
|
The following example calculates the SHA1 checksum of the incoming data as |
||||||
|
it gets read and stores it in the WSGI environment:: |
||||||
|
|
||||||
|
import hashlib |
||||||
|
|
||||||
|
class ChecksumCalcStream(object): |
||||||
|
|
||||||
|
def __init__(self, stream): |
||||||
|
self._stream = stream |
||||||
|
self._hash = hashlib.sha1() |
||||||
|
|
||||||
|
def read(self, bytes): |
||||||
|
rv = self._stream.read(bytes) |
||||||
|
self._hash.update(rv) |
||||||
|
return rv |
||||||
|
|
||||||
|
def readline(self, size_hint): |
||||||
|
rv = self._stream.readline(size_hint) |
||||||
|
self._hash.update(rv) |
||||||
|
return rv |
||||||
|
|
||||||
|
def generate_checksum(request): |
||||||
|
env = request.environ |
||||||
|
stream = ChecksumCalcStream(env['wsgi.input']) |
||||||
|
env['wsgi.input'] = stream |
||||||
|
return stream._hash |
||||||
|
|
||||||
|
To use this, all you need to do is to hook the calculating stream in |
||||||
|
before the request starts consuming data. (Eg: be careful accessing |
||||||
|
``request.form`` or anything of that nature. ``before_request_handlers`` |
||||||
|
for instance should be careful not to access it). |
||||||
|
|
||||||
|
Example usage:: |
||||||
|
|
||||||
|
@app.route('/special-api', methods=['POST']) |
||||||
|
def special_api(): |
||||||
|
hash = generate_checksum(request) |
||||||
|
# Accessing this parses the input stream |
||||||
|
files = request.files |
||||||
|
# At this point the hash is fully constructed. |
||||||
|
checksum = hash.hexdigest() |
||||||
|
return 'Hash was: %s' % checksum |
Loading…
Reference in new issue