Skip to content

Commit 49dee4f

Browse files
committed
Use content type in FieldStorage (#14)
1 parent 509a7c3 commit 49dee4f

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

webware/WebUtils/FieldStorage.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ def __init__(self, fp=None, headers=None, outerboundary=b'',
187187
ctype, pdict = 'application/x-www-form-urlencoded', {}
188188
self.type = ctype
189189
self.type_options = pdict
190+
if not self._binary_file and isBinaryType(ctype, pdict):
191+
self._binary_file = True
190192
self.innerboundary = pdict['boundary'].encode(
191193
self.encoding, self.errors) if 'boundary' in pdict else b''
192194

@@ -637,3 +639,13 @@ def hasSeparator():
637639
except TypeError: # Python < 3.9.2
638640
return False
639641
return True
642+
643+
644+
def isBinaryType(ctype, pdict=None):
645+
""""Check whether the given MIME type uses binary data."""
646+
if pdict and pdict.get('charset') == 'binary':
647+
return True
648+
return not (
649+
ctype.startswith('text/') or ctype.endswith(('+json', '+xml')) or
650+
(ctype.startswith('application') and
651+
ctype.endswith(('/json', '/xml', '/ecmascript', '/javascript'))))

webware/WebUtils/Tests/TestFieldStorageModified.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from io import BytesIO
66

7-
from WebUtils.FieldStorage import FieldStorage, hasSeparator
7+
from WebUtils.FieldStorage import FieldStorage, hasSeparator, isBinaryType
88

99

1010
class TestFieldStorage(unittest.TestCase):
@@ -206,7 +206,7 @@ def testPostRequestWithUtf8BinaryData(self):
206206
self.assertEqual(fs.type, 'application/octet-stream')
207207
self.assertEqual(fs.length, length)
208208
self.assertEqual(fs.bytes_read, length)
209-
self.assertEqual(fs.file.read(), text)
209+
self.assertEqual(fs.file.read(), content)
210210

211211
def testPostRequestWithNonUtf8BinaryData(self):
212212
# see https://github.com/WebwareForPython/w4py3/issues/14
@@ -224,3 +224,57 @@ def testPostRequestWithNonUtf8BinaryData(self):
224224
self.assertEqual(fs.length, length)
225225
self.assertEqual(fs.bytes_read, length)
226226
self.assertEqual(fs.file.read(), content)
227+
228+
def testPostRequestWithUtf8TextData(self):
229+
text = 'The \u2603 by Raymond Briggs'
230+
content = text.encode('utf-8')
231+
length = len(content)
232+
fs = FieldStorage(fp=BytesIO(content), environ={
233+
'CONTENT_LENGTH': length, 'REQUEST_METHOD': 'POST',
234+
'CONTENT_TYPE': 'text/plain'})
235+
self.assertEqual(fs.headers, {
236+
'content-type': 'text/plain',
237+
'content-length': length})
238+
self.assertEqual(fs.type, 'text/plain')
239+
self.assertEqual(fs.length, length)
240+
self.assertEqual(fs.bytes_read, length)
241+
self.assertEqual(fs.file.read(), text)
242+
243+
def testPostRequestWithNonUtf8TextData(self):
244+
# see https://github.com/WebwareForPython/w4py3/issues/14
245+
content = b'\xfe\xff\xc0'
246+
with self.assertRaises(UnicodeDecodeError):
247+
content.decode('utf-8')
248+
length = len(content)
249+
fs = FieldStorage(fp=BytesIO(content), environ={
250+
'CONTENT_LENGTH': length, 'REQUEST_METHOD': 'POST',
251+
'CONTENT_TYPE': 'text/plain'})
252+
self.assertEqual(fs.headers, {
253+
'content-type': 'text/plain',
254+
'content-length': length})
255+
self.assertEqual(fs.type, 'text/plain')
256+
self.assertEqual(fs.length, length)
257+
self.assertEqual(fs.bytes_read, length)
258+
self.assertEqual(fs.file.read(), content)
259+
260+
def testIsBinaryType(self):
261+
self.assertIs(isBinaryType('application/json'), False)
262+
self.assertIs(isBinaryType('application/xml'), False)
263+
self.assertIs(isBinaryType('application/calendar+json'), False)
264+
self.assertIs(isBinaryType('application/calendar+xml'), False)
265+
self.assertIs(isBinaryType('model/x3d+xml'), False)
266+
self.assertIs(isBinaryType('text/csv'), False)
267+
self.assertIs(isBinaryType('text/html'), False)
268+
self.assertIs(isBinaryType('text/plain'), False)
269+
self.assertIs(isBinaryType('x3d+xml'), False)
270+
self.assertIs(isBinaryType('application/octet-stream'), True)
271+
self.assertIs(isBinaryType('application/pdf'), True)
272+
self.assertIs(isBinaryType('application/zip'), True)
273+
self.assertIs(isBinaryType('audio/ogg'), True)
274+
self.assertIs(isBinaryType('font/otf'), True)
275+
self.assertIs(isBinaryType('image/png'), True)
276+
self.assertIs(isBinaryType('video/mp4'), True)
277+
self.assertIs(isBinaryType('application/json',
278+
{'charset': 'utf8'}), False)
279+
self.assertIs(isBinaryType('text/csv',
280+
{'charset': 'binary'}), True)

0 commit comments

Comments
 (0)