10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.test_support import run_unittest, check_warnings 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport cgi 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport tempfile 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass HackedSysModule: 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # The regression test will have real values in sys.argv, which 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # will completely confuse the test of the cgi module 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao argv = [] 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao stdin = sys.stdin 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaocgi.sys = HackedSysModule() 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from cStringIO import StringIO 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept ImportError: 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from StringIO import StringIO 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass ComparableException: 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, err): 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.err = err 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __str__(self): 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return str(self.err) 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __cmp__(self, anExc): 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not isinstance(anExc, Exception): 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return -1 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao x = cmp(self.err.__class__, anExc.__class__) 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if x != 0: 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return x 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return cmp(self.err.args, anExc.args) 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getattr__(self, attr): 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return getattr(self.err, attr) 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef do_test(buf, method): 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env = {} 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if method == "GET": 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp = None 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['REQUEST_METHOD'] = 'GET' 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['QUERY_STRING'] = buf 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif method == "POST": 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fp = StringIO(buf) 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['REQUEST_METHOD'] = 'POST' 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded' 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['CONTENT_LENGTH'] = str(len(buf)) 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError, "unknown method: %s" % method 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return cgi.parse(fp, env, strict_parsing=1) 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except StandardError, err: 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return ComparableException(err) 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoparse_strict_test_cases = [ 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("", ValueError("bad query field: ''")), 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("&", ValueError("bad query field: ''")), 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("&&", ValueError("bad query field: ''")), 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (";", ValueError("bad query field: ''")), 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (";&;", ValueError("bad query field: ''")), 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Should the next few really be valid? 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("=", {}), 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("=&=", {}), 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("=;=", {}), 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # This rest seem to make sense 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("=a", {'': ['a']}), 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("&=a", ValueError("bad query field: ''")), 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("=a&", ValueError("bad query field: ''")), 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("=&a", ValueError("bad query field: 'a'")), 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("b=a", {'b': ['a']}), 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("b+=a", {'b ': ['a']}), 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("a=b=a", {'a': ['b=a']}), 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("a=+b=a", {'a': [' b=a']}), 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("&b=a", ValueError("bad query field: ''")), 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("b&=a", ValueError("bad query field: 'b'")), 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}), 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("a=a+b&a=b+a", {'a': ['a b', 'b a']}), 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("x=1&y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}), 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("x=1;y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}), 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}), 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env", 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao {'Hbc5161168c542333633315dee1182227:key_store_seqid': ['400006'], 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'cuyer': ['r'], 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'expire': ['964546263'], 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'kid': ['130003.300038'], 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'lobale': ['en-US'], 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'order_id': ['0bb2e248638833d48cb7fed300000f1b'], 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'ss': ['env'], 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'view': ['bustomer'], 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao }), 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse", 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao {'SUBMIT': ['Browse'], 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '_assigned_to': ['31392'], 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '_category': ['100'], 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '_status': ['1'], 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'group_id': ['5470'], 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'set': ['custom'], 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao }) 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ] 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef first_elts(list): 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return map(lambda x:x[0], list) 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef first_second_elts(list): 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return map(lambda p:(p[0], p[1][0]), list) 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef gen_result(data, environ): 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fake_stdin = StringIO(data) 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fake_stdin.seek(0) 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao form = cgi.FieldStorage(fp=fake_stdin, environ=environ) 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = {} 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for k, v in dict(form).items(): 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result[k] = isinstance(v, list) and form.getlist(k) or v.value 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return result 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass CgiTests(unittest.TestCase): 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_escape(self): 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual("test & string", cgi.escape("test & string")) 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual("<test string>", cgi.escape("<test string>")) 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(""test string"", cgi.escape('"test string"', True)) 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_strict(self): 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for orig, expect in parse_strict_test_cases: 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Test basic parsing 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = do_test(orig, "GET") 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(d, expect, "Error parsing %s" % repr(orig)) 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = do_test(orig, "POST") 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(d, expect, "Error parsing %s" % repr(orig)) 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env = {'QUERY_STRING': orig} 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fcd = cgi.FormContentDict(env) 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sd = cgi.SvFormContentDict(env) 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fs = cgi.FieldStorage(environ=env) 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if isinstance(expect, dict): 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # test dict interface 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(len(expect), len(fcd)) 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(expect.keys(), fcd.keys()) 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(expect.values(), fcd.values()) 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(expect.items(), fcd.items()) 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(fcd.get("nonexistent field", "default"), "default") 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(len(sd), len(fs)) 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(sd.keys(), fs.keys()) 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(fs.getvalue("nonexistent field", "default"), "default") 1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # test individual fields 1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for key in expect.keys(): 1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao expect_val = expect[key] 1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(fcd.has_key(key)) 1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(fcd[key], expect[key]) 1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(fcd.get(key, "default"), fcd[key]) 1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(fs.has_key(key)) 1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if len(expect_val) > 1: 1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao single_value = 0 1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao single_value = 1 1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao val = sd[key] 1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except IndexError: 1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertFalse(single_value) 1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(fs.getvalue(key), expect_val) 1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(single_value) 1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(val, expect_val[0]) 1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(fs.getvalue(key), expect_val[0]) 1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(sd.getlist(key), expect_val) 1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if single_value: 1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(sd.values(), 1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao first_elts(expect.values())) 1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(sd.items(), 1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao first_second_elts(expect.items())) 1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_weird_formcontentdict(self): 1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Test the weird FormContentDict classes 1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"} 1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'} 1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = cgi.InterpFormContentDict(env) 1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for k, v in expect.items(): 1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(d[k], v) 1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for k, v in d.items(): 1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(expect[k], v) 1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertItemsEqual(expect.values(), d.values()) 1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_log(self): 1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.log("Testing") 1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.logfp = StringIO() 1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.initlog("%s", "Testing initlog 1") 1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.log("%s", "Testing log 2") 1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(cgi.logfp.getvalue(), "Testing initlog 1\nTesting log 2\n") 1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if os.path.exists("/dev/null"): 1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.logfp = None 1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.logfile = "/dev/null" 1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.initlog("%s", "Testing log 3") 1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.log("Testing log 4") 2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_fieldstorage_readline(self): 2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # FieldStorage uses readline, which has the capacity to read all 2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # contents of the input file into memory; we use readline's size argument 2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # to prevent that for files that do not contain any newlines in 2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # non-GET/HEAD requests 2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestReadlineFile: 2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, file): 2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file = file 2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.numcalls = 0 2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def readline(self, size=None): 2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.numcalls += 1 2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if size: 2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.file.readline(size) 2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.file.readline() 2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getattr__(self, name): 2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao file = self.__dict__['file'] 2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao a = getattr(file, name) 2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not isinstance(a, int): 2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao setattr(self, name, a) 2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return a 2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = TestReadlineFile(tempfile.TemporaryFile()) 2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f.write('x' * 256 * 1024) 2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f.seek(0) 2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env = {'REQUEST_METHOD':'PUT'} 2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fs = cgi.FieldStorage(fp=f, environ=env) 2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # if we're not chunking properly, readline is only called twice 2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # (by read_binary); if we are chunking properly, it will be called 5 times 2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # as long as the chunksize is 1 << 16. 2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(f.numcalls > 2) 2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_fieldstorage_multipart(self): 2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #Test basic FieldStorage multipart parsing 2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'} 2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao postdata = """-----------------------------721837373350705526688164684 2390a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="id" 2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao1234 2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao-----------------------------721837373350705526688164684 2430a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="title" 2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao-----------------------------721837373350705526688164684 2470a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="file"; filename="test.txt" 2480a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Type: text/plain 2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2500a8c90248264a8b26970b4473770bcc3df8515fJosh GaoTesting 123. 2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao-----------------------------721837373350705526688164684 2530a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="submit" 2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Add\x20 2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao-----------------------------721837373350705526688164684-- 2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""" 2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env) 2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(len(fs.list), 4) 2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao expect = [{'name':'id', 'filename':None, 'value':'1234'}, 2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao {'name':'title', 'filename':None, 'value':''}, 2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'}, 2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao {'name':'submit', 'filename':None, 'value':' Add '}] 2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for x in range(len(fs.list)): 2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for k, exp in expect[x].items(): 2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao got = getattr(fs.list[x], k) 2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(got, exp) 2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _qs_result = { 2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'key1': 'value1', 2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'key2': ['value2x', 'value2y'], 2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'key3': 'value3', 2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'key4': 'value4' 2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao } 2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def testQSAndUrlEncode(self): 2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = "key2=value2x&key3=value3&key4=value4" 2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ = { 2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'CONTENT_LENGTH': str(len(data)), 2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'CONTENT_TYPE': 'application/x-www-form-urlencoded', 2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'QUERY_STRING': 'key1=value1&key2=value2y', 2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'REQUEST_METHOD': 'POST', 2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao } 2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao v = gen_result(data, environ) 2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(self._qs_result, v) 2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def testQSAndFormData(self): 2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = """ 2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 2890a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="key2" 2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gaovalue2y 2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 2930a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="key3" 2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gaovalue3 2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 2970a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="key4" 2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gaovalue4 3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123-- 3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""" 3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ = { 3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'CONTENT_LENGTH': str(len(data)), 3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'CONTENT_TYPE': 'multipart/form-data; boundary=-123', 3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'QUERY_STRING': 'key1=value1&key2=value2x', 3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'REQUEST_METHOD': 'POST', 3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao } 3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao v = gen_result(data, environ) 3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(self._qs_result, v) 3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def testQSAndFormDataFile(self): 3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = """ 3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 3140a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="key2" 3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaovalue2y 3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 3180a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="key3" 3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaovalue3 3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 3220a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="key4" 3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaovalue4 3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123 3260a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Disposition: form-data; name="upload"; filename="fake.txt" 3270a8c90248264a8b26970b4473770bcc3df8515fJosh GaoContent-Type: text/plain 3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaothis is the content of the fake file 3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao---123-- 3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""" 3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao environ = { 3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'CONTENT_LENGTH': str(len(data)), 3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'CONTENT_TYPE': 'multipart/form-data; boundary=-123', 3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'QUERY_STRING': 'key1=value1&key2=value2x', 3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'REQUEST_METHOD': 'POST', 3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao } 3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = self._qs_result.copy() 3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result.update({ 3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'upload': 'this is the content of the fake file\n' 3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao }) 3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao v = gen_result(data, environ) 3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(result, v) 3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_deprecated_parse_qs(self): 3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # this func is moved to urlparse, this is just a sanity check 3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with check_warnings(('cgi.parse_qs is deprecated, use urlparse.' 3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'parse_qs instead', PendingDeprecationWarning)): 3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual({'a': ['A1'], 'B': ['B3'], 'b': ['B2']}, 3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_qs('a=A1&b=B2&B=B3')) 3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_deprecated_parse_qsl(self): 3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # this func is moved to urlparse, this is just a sanity check 3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with check_warnings(('cgi.parse_qsl is deprecated, use urlparse.' 3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'parse_qsl instead', PendingDeprecationWarning)): 3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual([('a', 'A1'), ('b', 'B2'), ('B', 'B3')], 3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_qsl('a=A1&b=B2&B=B3')) 3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_parse_header(self): 3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header("text/plain"), 3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("text/plain", {})) 3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header("text/vnd.just.made.this.up ; "), 3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("text/vnd.just.made.this.up", {})) 3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header("text/plain;charset=us-ascii"), 3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("text/plain", {"charset": "us-ascii"})) 3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header('text/plain ; charset="us-ascii"'), 3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("text/plain", {"charset": "us-ascii"})) 3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header('text/plain ; charset="us-ascii"; another=opt'), 3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("text/plain", {"charset": "us-ascii", "another": "opt"})) 3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header('attachment; filename="silly.txt"'), 3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("attachment", {"filename": "silly.txt"})) 3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header('attachment; filename="strange;name"'), 3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("attachment", {"filename": "strange;name"})) 3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header('attachment; filename="strange;name";size=123;'), 3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("attachment", {"filename": "strange;name", "size": "123"})) 3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cgi.parse_header('form-data; name="files"; filename="fo\\"o;bar"'), 3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("form-data", {"name": "files", "filename": 'fo"o;bar'})) 3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main(): 3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao run_unittest(CgiTests) 3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__': 3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao test_main() 395