mirror of
https://github.com/kennethreitz/httpbin.git
synced 2026-06-05 23:00:18 +00:00
Merge pull request #60 from randomir/master
Bugfix: JSON-safe encoding of raw binary data/files
This commit is contained in:
@@ -14,4 +14,5 @@ Patches and Suggestions
|
||||
- Andrey Petrov
|
||||
- Lispython
|
||||
- Kyle Conroy
|
||||
- Flavio Percoco
|
||||
- Flavio Percoco
|
||||
- Radomir Stevanovic (http://github.com/randomir)
|
||||
+25
-3
@@ -7,7 +7,8 @@ httpbin.helpers
|
||||
This module provides helper functions for httpbin.
|
||||
"""
|
||||
|
||||
import json
|
||||
import base64
|
||||
import simplejson as json
|
||||
from hashlib import md5
|
||||
from werkzeug.http import parse_authorization_header
|
||||
|
||||
@@ -62,13 +63,34 @@ ANGRY_ASCII ="""
|
||||
YOU SHOUDN'T BE HERE
|
||||
"""
|
||||
|
||||
|
||||
def json_safe(string, content_type='application/octet-stream'):
|
||||
"""Returns JSON-safe version of `string`.
|
||||
|
||||
If `string` is a Unicode string or a valid UTF-8, it is returned unmodified,
|
||||
as it can safely be encoded to JSON string.
|
||||
|
||||
If `string` contains raw/binary data, it is Base64-encoded, formatted and
|
||||
returned according to "data" URL scheme (RFC2397). Since JSON is not
|
||||
suitable for binary data, some additional encoding was necessary; "data"
|
||||
URL scheme was chosen for its simplicity.
|
||||
"""
|
||||
|
||||
try:
|
||||
_encoded = json.dumps(string)
|
||||
return string
|
||||
except ValueError:
|
||||
return ''.join(['data:%s;base64,' % content_type,
|
||||
base64.b64encode(string)])
|
||||
|
||||
|
||||
def get_files():
|
||||
"""Returns files dict from request context."""
|
||||
|
||||
files = dict()
|
||||
|
||||
for k, v in request.files.items():
|
||||
files[k] = v.read()
|
||||
files[k] = json_safe(v.read(), request.files[k].content_type)
|
||||
|
||||
return files
|
||||
|
||||
@@ -120,7 +142,7 @@ def get_dict(*keys, **extras):
|
||||
url=request.url,
|
||||
args=request.args,
|
||||
form=form,
|
||||
data=data,
|
||||
data=json_safe(data),
|
||||
origin=request.remote_addr,
|
||||
headers=get_headers(),
|
||||
files=get_files(),
|
||||
|
||||
@@ -25,6 +25,22 @@ class HttpbinTestCase(unittest.TestCase):
|
||||
content = response.data.decode('utf-8')
|
||||
self.assertEquals(greeting, content)
|
||||
|
||||
def test_post_binary(self):
|
||||
response = self.app.post('/post',
|
||||
data='\x01\x02\x03\x81\x82\x83',
|
||||
content_type='application/octet-stream')
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def test_post_file_text(self):
|
||||
with open('httpbin/core.py') as f:
|
||||
response = self.app.post('/post', data={"file": f})
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def test_post_file_binary(self):
|
||||
with open('httpbin/core.pyc') as f:
|
||||
response = self.app.post('/post', data={"file": f})
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user