Author: chrisz
Date: Thu Jan 26 01:23:38 2012
New Revision: 8227
Log:
Support use of semicolon as alternative separator in FieldStorage.
Added:
Webware/trunk/WebUtils/Tests/TestFieldStorage.py
Modified:
Webware/trunk/WebUtils/FieldStorage.py
Modified: Webware/trunk/WebUtils/FieldStorage.py
==============================================================================
--- Webware/trunk/WebUtils/FieldStorage.py Wed Sep 21 04:56:10 2011 (r8226)
+++ Webware/trunk/WebUtils/FieldStorage.py Thu Jan 26 01:23:38 2012 (r8227)
@@ -20,6 +20,9 @@
for parameters with the same name. With other words, our FieldStorage class
overrides the query string parameters with the parameters sent via POST.
+ As recommended by W3C in section B.2.2 of the HTML 4.01 specification,
+ we also support use of ';' in place of '&' as separator in query strings.
+
"""
def __init__(self, fp=None, headers=None, outerboundary='',
@@ -42,18 +45,19 @@
"""Add all non-existing parameters from the given query string."""
r = {}
for name_value in qs.split('&'):
- nv = name_value.split('=', 2)
- if len(nv) != 2:
- if self.strict_parsing:
- raise ValueError('bad query field: %r' % (name_value,))
- continue
- name = urllib.unquote(nv[0].replace('+', ' '))
- value = urllib.unquote(nv[1].replace('+', ' '))
- if len(value) or self.keep_blank_values:
- if name in r:
- r[name].append(value)
- else:
- r[name] = [value]
+ for name_value in name_value.split(';'):
+ nv = name_value.split('=', 2)
+ if len(nv) != 2:
+ if self.strict_parsing:
+ raise ValueError('bad query field: %r' % (name_value,))
+ continue
+ name = urllib.unquote(nv[0].replace('+', ' '))
+ value = urllib.unquote(nv[1].replace('+', ' '))
+ if len(value) or self.keep_blank_values:
+ if name in r:
+ r[name].append(value)
+ else:
+ r[name] = [value]
if self.list is None:
# This makes sure self.keys() are available, even
# when valid POST data wasn't encountered.
Added: Webware/trunk/WebUtils/Tests/TestFieldStorage.py
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ Webware/trunk/WebUtils/Tests/TestFieldStorage.py Thu Jan 26 01:23:38 2012 (r8227)
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import unittest
+from StringIO import StringIO
+
+sys.path.insert(1, os.path.abspath('../..'))
+
+from WebUtils.FieldStorage import FieldStorage
+
+
+class TestFieldStorage(unittest.TestCase):
+
+ def testGetRequest(self):
+ fs = FieldStorage(environ=dict(
+ REQUEST_METHOD='GET', QUERY_STRING='a=1&b=2&b=3&c=3'))
+ self.assertEqual(fs.getfirst('a'), '1')
+ self.assertEqual(fs.getfirst('b'), '2')
+ self.assertEqual(fs.getfirst('c'), '3')
+ self.assertEqual(fs.getlist('a'), ['1'])
+ self.assertEqual(fs.getlist('b'), ['2', '3'])
+ self.assertEqual(fs.getlist('c'), ['3'])
+
+ def testPostRequestWithQuery(self):
+ fs = FieldStorage(fp=StringIO(), environ=dict(
+ REQUEST_METHOD='GET', QUERY_STRING='a=1&b=2&b=3&c=3'))
+ self.assertEqual(fs.getfirst('a'), '1')
+ self.assertEqual(fs.getfirst('b'), '2')
+ self.assertEqual(fs.getfirst('c'), '3')
+ self.assertEqual(fs.getlist('a'), ['1'])
+ self.assertEqual(fs.getlist('b'), ['2', '3'])
+ self.assertEqual(fs.getlist('c'), ['3'])
+
+ def testPostRequestWithBody(self):
+ fs = FieldStorage(
+ fp=StringIO('d=4&e=5&e=6&f=6'), environ=dict(
+ REQUEST_METHOD='POST'))
+ self.assertEqual(fs.getfirst('d'), '4')
+ self.assertEqual(fs.getfirst('e'), '5')
+ self.assertEqual(fs.getfirst('f'), '6')
+ self.assertEqual(fs.getlist('d'), ['4'])
+ self.assertEqual(fs.getlist('e'), ['5', '6'])
+ self.assertEqual(fs.getlist('f'), ['6'])
+
+ def testPostRequestOverrides(self):
+ fs = FieldStorage(
+ fp=StringIO('b=8&c=9&d=4&e=5&e=6&f=6'), environ=dict(
+ REQUEST_METHOD='POST', QUERY_STRING='a=1&b=2&b=3&c=3'))
+ self.assertEqual(fs.getfirst('a'), '1')
+ self.assertEqual(fs.getfirst('b'), '8')
+ self.assertEqual(fs.getfirst('c'), '9')
+ self.assertEqual(fs.getfirst('d'), '4')
+ self.assertEqual(fs.getfirst('e'), '5')
+ self.assertEqual(fs.getfirst('f'), '6')
+ self.assertEqual(fs.getlist('a'), ['1'])
+ self.assertEqual(fs.getlist('b'), ['8'])
+ self.assertEqual(fs.getlist('c'), ['9'])
+ self.assertEqual(fs.getlist('d'), ['4'])
+ self.assertEqual(fs.getlist('e'), ['5', '6'])
+ self.assertEqual(fs.getlist('f'), ['6'])
+
+ def testPostRequestWithQueryWithSemicolon1(self):
+ fs = FieldStorage(fp=StringIO(), environ=dict(
+ REQUEST_METHOD='GET', QUERY_STRING='a=1&b=2;b=3&c=3'))
+ self.assertEqual(fs.getfirst('a'), '1')
+ self.assertEqual(fs.getfirst('b'), '2')
+ self.assertEqual(fs.getfirst('c'), '3')
+ self.assertEqual(fs.getlist('a'), ['1'])
+ self.assertEqual(fs.getlist('b'), ['2', '3'])
+ self.assertEqual(fs.getlist('c'), ['3'])
+
+ def testPostRequestWithQueryWithSemicolon2(self):
+ fs = FieldStorage(fp=StringIO(), environ=dict(
+ REQUEST_METHOD='GET', QUERY_STRING='a=1;b=2&b=3;c=3'))
+ self.assertEqual(fs.getfirst('a'), '1')
+ self.assertEqual(fs.getfirst('b'), '2')
+ self.assertEqual(fs.getfirst('c'), '3')
+ self.assertEqual(fs.getlist('a'), ['1'])
+ self.assertEqual(fs.getlist('b'), ['2', '3'])
+ self.assertEqual(fs.getlist('c'), ['3'])
+
+
+if __name__ == '__main__':
+ unittest.main()
|