@@ -50,7 +50,7 @@ def hello_app(environ,start_response):
5050def run_amock (app = hello_app , data = b"GET / HTTP/1.0\n \n " ):
5151 server = make_server ("" , 80 , app , MockServer , MockHandler )
5252 inp = BufferedReader (BytesIO (data ))
53- out = StringIO ()
53+ out = BytesIO ()
5454 olderr = sys .stderr
5555 err = sys .stderr = StringIO ()
5656
@@ -128,13 +128,13 @@ class IntegrationTests(TestCase):
128128
129129 def check_hello (self , out , has_length = True ):
130130 self .assertEqual (out ,
131- "HTTP/1.0 200 OK\r \n "
131+ ( "HTTP/1.0 200 OK\r \n "
132132 "Server: WSGIServer/0.1 Python/" + sys .version .split ()[0 ]+ "\r \n "
133133 "Content-Type: text/plain\r \n "
134134 "Date: Mon, 05 Jun 2006 18:49:54 GMT\r \n " +
135135 (has_length and "Content-Length: 13\r \n " or "" ) +
136136 "\r \n "
137- "Hello, world!"
137+ "Hello, world!" ). encode ( "iso-8859-1" )
138138 )
139139
140140 def test_plain_hello (self ):
@@ -152,15 +152,44 @@ def bad_app(environ,start_response):
152152 return ["Hello, world!" ]
153153 out , err = run_amock (validator (bad_app ))
154154 self .failUnless (out .endswith (
155- "A server error occurred. Please contact the administrator."
155+ b "A server error occurred. Please contact the administrator."
156156 ))
157157 self .assertEqual (
158158 err .splitlines ()[- 2 ],
159159 "AssertionError: Headers (('Content-Type', 'text/plain')) must"
160160 " be of type list: <class 'tuple'>"
161161 )
162162
163+ def test_wsgi_input (self ):
164+ def bad_app (e ,s ):
165+ e ["wsgi.input" ].read ()
166+ s (b"200 OK" , [(b"Content-Type" , b"text/plain; charset=utf-8" )])
167+ return [b"data" ]
168+ out , err = run_amock (validator (bad_app ))
169+ self .failUnless (out .endswith (
170+ b"A server error occurred. Please contact the administrator."
171+ ))
172+ self .assertEqual (
173+ err .splitlines ()[- 2 ], "AssertionError"
174+ )
163175
176+ def test_bytes_validation (self ):
177+ def app (e , s ):
178+ s (b"200 OK" , [
179+ (b"Content-Type" , b"text/plain; charset=utf-8" ),
180+ ("Date" , "Wed, 24 Dec 2008 13:29:32 GMT" ),
181+ ])
182+ return [b"data" ]
183+ out , err = run_amock (validator (app ))
184+ self .failUnless (err .endswith ('"GET / HTTP/1.0" 200 4\n ' ))
185+ self .assertEqual (
186+ b"HTTP/1.0 200 OK\r \n "
187+ b"Server: WSGIServer/0.1 Python/3.1a0\r \n "
188+ b"Content-Type: text/plain; charset=utf-8\r \n "
189+ b"Date: Wed, 24 Dec 2008 13:29:32 GMT\r \n "
190+ b"\r \n "
191+ b"data" ,
192+ out )
164193
165194
166195
@@ -181,6 +210,8 @@ def checkDefault(self, key, value, alt=None):
181210 util .setup_testing_defaults (env )
182211 if isinstance (value ,StringIO ):
183212 self .failUnless (isinstance (env [key ],StringIO ))
213+ elif isinstance (value ,BytesIO ):
214+ self .failUnless (isinstance (env [key ],BytesIO ))
184215 else :
185216 self .assertEqual (env [key ],value )
186217
@@ -260,7 +291,7 @@ def testDefaults(self):
260291 ('wsgi.run_once' , 0 ),
261292 ('wsgi.multithread' , 0 ),
262293 ('wsgi.multiprocess' , 0 ),
263- ('wsgi.input' , StringIO ( "" )),
294+ ('wsgi.input' , BytesIO ( )),
264295 ('wsgi.errors' , StringIO ()),
265296 ('wsgi.url_scheme' ,'http' ),
266297 ]:
@@ -386,14 +417,31 @@ def testExtras(self):
386417 '\r \n '
387418 )
388419
420+ def testBytes (self ):
421+ h = Headers ([
422+ (b"Content-Type" , b"text/plain; charset=utf-8" ),
423+ ])
424+ self .assertEqual ("text/plain; charset=utf-8" , h .get ("Content-Type" ))
425+
426+ h [b"Foo" ] = bytes (b"bar" )
427+ self .assertEqual ("bar" , h .get ("Foo" ))
428+
429+ h .setdefault (b"Bar" , b"foo" )
430+ self .assertEqual ("foo" , h .get ("Bar" ))
431+
432+ h .add_header (b'content-disposition' , b'attachment' ,
433+ filename = b'bud.gif' )
434+ self .assertEqual ('attachment; filename="bud.gif"' ,
435+ h .get ("content-disposition" ))
436+
389437
390438class ErrorHandler (BaseCGIHandler ):
391439 """Simple handler subclass for testing BaseHandler"""
392440
393441 def __init__ (self ,** kw ):
394442 setup_testing_defaults (kw )
395443 BaseCGIHandler .__init__ (
396- self , StringIO ( '' ), StringIO (), StringIO (), kw ,
444+ self , BytesIO ( ), BytesIO (), StringIO (), kw ,
397445 multithread = True , multiprocess = True
398446 )
399447
@@ -474,21 +522,32 @@ def trivial_app2(e,s):
474522 s ('200 OK' ,[])(e ['wsgi.url_scheme' ])
475523 return []
476524
525+ def trivial_app3 (e ,s ):
526+ s ('200 OK' ,[])
527+ return ['\u0442 \u0435 \u0441 \u0442 ' .encode ("utf-8" )]
528+
477529 h = TestHandler ()
478530 h .run (trivial_app1 )
479531 self .assertEqual (h .stdout .getvalue (),
480- "Status: 200 OK\r \n "
532+ ( "Status: 200 OK\r \n "
481533 "Content-Length: 4\r \n "
482534 "\r \n "
483- "http" )
535+ "http" ). encode ( "iso-8859-1" ))
484536
485537 h = TestHandler ()
486538 h .run (trivial_app2 )
487539 self .assertEqual (h .stdout .getvalue (),
488- "Status: 200 OK\r \n "
540+ ( "Status: 200 OK\r \n "
489541 "\r \n "
490- "http" )
542+ "http" ). encode ( "iso-8859-1" ))
491543
544+ h = TestHandler ()
545+ h .run (trivial_app3 )
546+ self .assertEqual (h .stdout .getvalue (),
547+ b'Status: 200 OK\r \n '
548+ b'Content-Length: 8\r \n '
549+ b'\r \n '
550+ b'\xd1 \x82 \xd0 \xb5 \xd1 \x81 \xd1 \x82 ' )
492551
493552
494553
@@ -507,18 +566,19 @@ def error_app(e,s):
507566 h = ErrorHandler ()
508567 h .run (non_error_app )
509568 self .assertEqual (h .stdout .getvalue (),
510- "Status: 200 OK\r \n "
569+ ( "Status: 200 OK\r \n "
511570 "Content-Length: 0\r \n "
512- "\r \n " )
571+ "\r \n " ). encode ( "iso-8859-1" ))
513572 self .assertEqual (h .stderr .getvalue (),"" )
514573
515574 h = ErrorHandler ()
516575 h .run (error_app )
517576 self .assertEqual (h .stdout .getvalue (),
518- "Status: %s\r \n "
577+ ( "Status: %s\r \n "
519578 "Content-Type: text/plain\r \n "
520579 "Content-Length: %d\r \n "
521- "\r \n %s" % (h .error_status ,len (h .error_body ),h .error_body ))
580+ "\r \n %s" % (h .error_status ,len (h .error_body ),h .error_body )
581+ ).encode ("iso-8859-1" ))
522582
523583 self .failUnless ("AssertionError" in h .stderr .getvalue ())
524584
@@ -531,8 +591,8 @@ def error_app(e,s):
531591 h = ErrorHandler ()
532592 h .run (error_app )
533593 self .assertEqual (h .stdout .getvalue (),
534- "Status: 200 OK\r \n "
535- "\r \n " + MSG )
594+ ( "Status: 200 OK\r \n "
595+ "\r \n " + MSG ). encode ( "iso-8859-1" ))
536596 self .failUnless ("AssertionError" in h .stderr .getvalue ())
537597
538598
@@ -549,7 +609,7 @@ def non_error_app(e,s):
549609 )
550610 shortpat = (
551611 "Status: 200 OK\r \n " "Content-Length: 0\r \n " "\r \n "
552- )
612+ ). encode ( "iso-8859-1" )
553613
554614 for ssw in "FooBar/1.0" , None :
555615 sw = ssw and "Server: %s\r \n " % ssw or ""
@@ -570,13 +630,31 @@ def non_error_app(e,s):
570630 h .server_software = ssw
571631 h .run (non_error_app )
572632 if proto == "HTTP/0.9" :
573- self .assertEqual (h .stdout .getvalue (),"" )
633+ self .assertEqual (h .stdout .getvalue (),b "" )
574634 else :
575635 self .failUnless (
576- re .match (stdpat % (version ,sw ), h .stdout .getvalue ()),
577- (stdpat % (version ,sw ), h .stdout .getvalue ())
636+ re .match ((stdpat % (version ,sw )).encode ("iso-8859-1" ),
637+ h .stdout .getvalue ()),
638+ ((stdpat % (version ,sw )).encode ("iso-8859-1" ),
639+ h .stdout .getvalue ())
578640 )
579641
642+ def testBytesData (self ):
643+ def app (e , s ):
644+ s (b"200 OK" , [
645+ (b"Content-Type" , b"text/plain; charset=utf-8" ),
646+ ])
647+ return [b"data" ]
648+
649+ h = TestHandler ()
650+ h .run (app )
651+ self .assertEqual (b"Status: 200 OK\r \n "
652+ b"Content-Type: text/plain; charset=utf-8\r \n "
653+ b"Content-Length: 4\r \n "
654+ b"\r \n "
655+ b"data" ,
656+ h .stdout .getvalue ())
657+
580658# This epilogue is needed for compatibility with the Python 2.5 regrtest module
581659
582660def test_main ():
0 commit comments