Skip to content

Commit 72c94e8

Browse files
committed
Support posting binary data with query string (#16)
1 parent 9b49eb9 commit 72c94e8

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

webware/WebUtils/FieldStorage.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,18 @@ def read_single(self):
413413
else:
414414
self.read_lines()
415415
self.file.seek(0)
416+
# contrary to the standard library, we also parse the query string
417+
if self.qs_on_post:
418+
kwargs = {
419+
'keep_blank_values': self.keep_blank_values,
420+
'strict_parsing': self.strict_parsing,
421+
'encoding': self.encoding, 'errors': self.errors}
422+
if self.max_num_fields is not None: # Python >= 3.8
423+
kwargs['max_num_fields'] = self.max_num_fields
424+
if self.separator != '&': # Python >= 3.9.2
425+
kwargs['separator'] = self.separator
426+
query = parse_qsl(self.qs_on_post, **kwargs)
427+
self.list = [MiniFieldStorage(key, value) for key, value in query]
416428

417429
bufsize = 8 * 1024
418430

webware/WebUtils/Tests/TestFieldStorageModified.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,46 @@ def testPostRequestWithNonUtf8TextData(self):
257257
self.assertEqual(fs.bytes_read, length)
258258
self.assertEqual(fs.file.read(), content)
259259

260+
def testPostRequestWithTextDataAndQueryParams(self):
261+
text = 'The \u2603 by Raymond Briggs'
262+
content = text.encode('utf-8')
263+
length = len(content)
264+
fs = FieldStorage(fp=BytesIO(content), environ={
265+
'CONTENT_LENGTH': length, 'REQUEST_METHOD': 'POST',
266+
'CONTENT_TYPE': 'text/plain',
267+
'QUERY_STRING': 'a=1&b=2&b=2'})
268+
self.assertEqual(fs.headers, {
269+
'content-type': 'text/plain',
270+
'content-length': length})
271+
self.assertEqual(fs.type, 'text/plain')
272+
self.assertEqual(fs.length, length)
273+
self.assertEqual(fs.bytes_read, length)
274+
self.assertEqual(fs.file.read(), text)
275+
self.assertEqual(fs.getfirst('a'), '1')
276+
self.assertEqual(fs.getfirst('b'), '2')
277+
self.assertEqual(fs.getlist('a'), ['1'])
278+
self.assertEqual(fs.getlist('b'), ['2', '2'])
279+
280+
def testPostRequestWithBinaryDataAndQueryParams(self):
281+
content = b'\xfe\xff\xc0'
282+
length = len(content)
283+
fs = FieldStorage(fp=BytesIO(content), environ={
284+
'REQUEST_METHOD': 'POST',
285+
'CONTENT_LENGTH': length,
286+
'CONTENT_TYPE': 'application/octet-stream',
287+
'QUERY_STRING': 'a=1&b=2&b=2'})
288+
self.assertEqual(fs.headers, {
289+
'content-type': 'application/octet-stream',
290+
'content-length': length})
291+
self.assertEqual(fs.type, 'application/octet-stream')
292+
self.assertEqual(fs.length, length)
293+
self.assertEqual(fs.bytes_read, length)
294+
self.assertEqual(fs.file.read(), content)
295+
self.assertEqual(fs.getfirst('a'), '1')
296+
self.assertEqual(fs.getfirst('b'), '2')
297+
self.assertEqual(fs.getlist('a'), ['1'])
298+
self.assertEqual(fs.getlist('b'), ['2', '2'])
299+
260300
def testPostRequestWithSmallPayloadWithContentLength(self):
261301
length = 1000 # much smaller than buffer size
262302
payload = 'x' * length

0 commit comments

Comments
 (0)