equal
deleted
inserted
replaced
35 |
35 |
36 __author__ = 'Marcel Hellkamp' |
36 __author__ = 'Marcel Hellkamp' |
37 __version__ = '0.1' |
37 __version__ = '0.1' |
38 __license__ = 'MIT' |
38 __license__ = 'MIT' |
39 |
39 |
|
40 from io import BytesIO |
40 from tempfile import TemporaryFile |
41 from tempfile import TemporaryFile |
|
42 from urllib.parse import parse_qs |
41 from wsgiref.headers import Headers |
43 from wsgiref.headers import Headers |
42 import re, sys |
44 import re, sys |
43 try: |
45 |
44 from io import BytesIO |
|
45 except ImportError: # pragma: no cover (fallback for Python 2.5) |
|
46 from StringIO import StringIO as BytesIO |
|
47 |
|
48 from six import PY3, text_type |
|
49 from six.moves.urllib.parse import parse_qs |
|
50 |
46 |
51 ############################################################################## |
47 ############################################################################## |
52 ################################ Helper & Misc ################################ |
48 ################################ Helper & Misc ################################ |
53 ############################################################################## |
49 ############################################################################## |
54 # Some of these were copied from bottle: http://bottle.paws.de/ |
50 # Some of these were copied from bottle: http://bottle.paws.de/ |
86 for key, values in self.dict.items(): |
82 for key, values in self.dict.items(): |
87 for value in values: |
83 for value in values: |
88 yield key, value |
84 yield key, value |
89 |
85 |
90 def tob(data, enc='utf8'): # Convert strings to bytes (py2 and py3) |
86 def tob(data, enc='utf8'): # Convert strings to bytes (py2 and py3) |
91 return data.encode(enc) if isinstance(data, text_type) else data |
87 return data.encode(enc) if isinstance(data, str) else data |
92 |
88 |
93 def copy_file(stream, target, maxread=-1, buffer_size=2*16): |
89 def copy_file(stream, target, maxread=-1, buffer_size=2*16): |
94 ''' Read from :stream and write to :target until :maxread or EOF. ''' |
90 ''' Read from :stream and write to :target until :maxread or EOF. ''' |
95 size, read = 0, stream.read |
91 size, read = 0, stream.read |
96 while 1: |
92 while 1: |
398 if content_length > mem_limit: |
394 if content_length > mem_limit: |
399 raise MultipartError("Request too big. Increase MAXMEM.") |
395 raise MultipartError("Request too big. Increase MAXMEM.") |
400 data = stream.read(mem_limit) |
396 data = stream.read(mem_limit) |
401 if stream.read(1): # These is more that does not fit mem_limit |
397 if stream.read(1): # These is more that does not fit mem_limit |
402 raise MultipartError("Request too big. Increase MAXMEM.") |
398 raise MultipartError("Request too big. Increase MAXMEM.") |
403 if PY3: |
399 data = data.decode('ascii') |
404 data = data.decode('ascii') |
|
405 data = parse_qs(data, keep_blank_values=True) |
400 data = parse_qs(data, keep_blank_values=True) |
406 for key, values in data.items(): |
401 for key, values in data.items(): |
407 for value in values: |
402 for value in values: |
408 if PY3: |
403 forms[key] = value |
409 forms[key] = value |
|
410 else: |
|
411 forms[key.decode(charset)] = value.decode(charset) |
|
412 else: |
404 else: |
413 raise MultipartError("Unsupported content type.") |
405 raise MultipartError("Unsupported content type.") |
414 except MultipartError: |
406 except MultipartError: |
415 if strict: raise |
407 if strict: raise |
416 return forms, files |
408 return forms, files |