Skip to content
Browse files

Added a new example for checksums on input data. This fixes #601

  • Loading branch information...
1 parent c4f2075 commit b5bb49d080475e4fb90f6a47dacab60b53470e9d @mitsuhiko committed
Showing with 56 additions and 0 deletions.
  1. +1 −0 docs/patterns/index.rst
  2. +55 −0 docs/patterns/requestchecksum.rst
View
1 docs/patterns/index.rst
@@ -38,3 +38,4 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_.
streaming
deferredcallbacks
methodoverrides
+ requestchecksum
View
55 docs/patterns/requestchecksum.rst
@@ -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

0 comments on commit b5bb49d

Please sign in to comment.
Something went wrong with that request. Please try again.