请求内容的校验和(Checksum)¶
在处理请求时,不同的代码模块可能会读取并预处理请求的数据。 例如,JSON 数据会被读取并处理后存放在 request 对象中, 表单数据也是如此,但它会走另一条处理路径。当你希望对传入的请求数据计算校验和时,这种自动处理就可能变得不方便。 在某些 API 场景中,计算请求数据的校验和是必要的。
幸运的是,通过包装输入流,这件事变得非常简单。
下面的示例展示了如何在数据被读取的同时计算其 SHA1 校验和, 并将其保存到 WSGI 环境中:
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
要使用这个方法,你只需在请求开始读取数据之前插入计算用的输入流。 (例如,要避免在此之前访问 request.form 或类似的内容。 像 before_request_handlers 这样的钩子应当注意不要提前访问请求体)。
示例用法如下:
@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 f"Hash was: {checksum}"