NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

test_conn.py (20852B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\test\test_conn.py
      2 import socket
      3 import sys
      4 import time
      5 timeout = 1
      6 import cherrypy
      7 from cherrypy._cpcompat import HTTPConnection, HTTPSConnection, NotConnected, BadStatusLine
      8 from cherrypy._cpcompat import ntob, urlopen, unicodestr
      9 from cherrypy.test import webtest
     10 from cherrypy import _cperror
     11 pov = 'pPeErRsSiIsStTeEnNcCeE oOfF vViIsSiIoOnN'
     12 
     13 def setup_server():
     14 
     15     def raise500():
     16         raise cherrypy.HTTPError(500)
     17 
     18     class Root:
     19 
     20         def index(self):
     21             return pov
     22 
     23         index.exposed = True
     24         page1 = index
     25         page2 = index
     26         page3 = index
     27 
     28         def hello(self):
     29             return 'Hello, world!'
     30 
     31         hello.exposed = True
     32 
     33         def timeout(self, t):
     34             return str(cherrypy.server.httpserver.timeout)
     35 
     36         timeout.exposed = True
     37 
     38         def stream(self, set_cl = False):
     39             if set_cl:
     40                 cherrypy.response.headers['Content-Length'] = 10
     41 
     42             def content():
     43                 for x in range(10):
     44                     yield str(x)
     45 
     46             return content()
     47 
     48         stream.exposed = True
     49         stream._cp_config = {'response.stream': True}
     50 
     51         def error(self, code = 500):
     52             raise cherrypy.HTTPError(code)
     53 
     54         error.exposed = True
     55 
     56         def upload(self):
     57             if not cherrypy.request.method == 'POST':
     58                 raise AssertionError("'POST' != request.method %r" % cherrypy.request.method)
     59             return "thanks for '%s'" % cherrypy.request.body.read()
     60 
     61         upload.exposed = True
     62 
     63         def custom(self, response_code):
     64             cherrypy.response.status = response_code
     65             return 'Code = %s' % response_code
     66 
     67         custom.exposed = True
     68 
     69         def err_before_read(self):
     70             return 'ok'
     71 
     72         err_before_read.exposed = True
     73         err_before_read._cp_config = {'hooks.on_start_resource': raise500}
     74 
     75         def one_megabyte_of_a(self):
     76             return ['a' * 1024] * 1024
     77 
     78         one_megabyte_of_a.exposed = True
     79 
     80         def custom_cl(self, body, cl):
     81             cherrypy.response.headers['Content-Length'] = cl
     82             if not isinstance(body, list):
     83                 body = [body]
     84             newbody = []
     85             for chunk in body:
     86                 if isinstance(chunk, unicodestr):
     87                     chunk = chunk.encode('ISO-8859-1')
     88                 newbody.append(chunk)
     89 
     90             return newbody
     91 
     92         custom_cl.exposed = True
     93         custom_cl._cp_config = {'tools.encode.on': False}
     94 
     95     cherrypy.tree.mount(Root())
     96     cherrypy.config.update({'server.max_request_body_size': 1001,
     97      'server.socket_timeout': timeout})
     98 
     99 
    100 from cherrypy.test import helper
    101 
    102 class ConnectionCloseTests(helper.CPWebCase):
    103     setup_server = staticmethod(setup_server)
    104 
    105     def test_HTTP11(self):
    106         if cherrypy.server.protocol_version != 'HTTP/1.1':
    107             return self.skip()
    108         self.PROTOCOL = 'HTTP/1.1'
    109         self.persistent = True
    110         self.getPage('/')
    111         self.assertStatus('200 OK')
    112         self.assertBody(pov)
    113         self.assertNoHeader('Connection')
    114         self.getPage('/page1')
    115         self.assertStatus('200 OK')
    116         self.assertBody(pov)
    117         self.assertNoHeader('Connection')
    118         self.getPage('/page2', headers=[('Connection', 'close')])
    119         self.assertStatus('200 OK')
    120         self.assertBody(pov)
    121         self.assertHeader('Connection', 'close')
    122         self.assertRaises(NotConnected, self.getPage, '/')
    123 
    124     def test_Streaming_no_len(self):
    125         self._streaming(set_cl=False)
    126 
    127     def test_Streaming_with_len(self):
    128         self._streaming(set_cl=True)
    129 
    130     def _streaming(self, set_cl):
    131         if cherrypy.server.protocol_version == 'HTTP/1.1':
    132             self.PROTOCOL = 'HTTP/1.1'
    133             self.persistent = True
    134             self.getPage('/')
    135             self.assertStatus('200 OK')
    136             self.assertBody(pov)
    137             self.assertNoHeader('Connection')
    138             if set_cl:
    139                 self.getPage('/stream?set_cl=Yes')
    140                 self.assertHeader('Content-Length')
    141                 self.assertNoHeader('Connection', 'close')
    142                 self.assertNoHeader('Transfer-Encoding')
    143                 self.assertStatus('200 OK')
    144                 self.assertBody('0123456789')
    145             else:
    146                 self.getPage('/stream')
    147                 self.assertNoHeader('Content-Length')
    148                 self.assertStatus('200 OK')
    149                 self.assertBody('0123456789')
    150                 chunked_response = False
    151                 for k, v in self.headers:
    152                     if k.lower() == 'transfer-encoding':
    153                         if str(v) == 'chunked':
    154                             chunked_response = True
    155 
    156                 if chunked_response:
    157                     self.assertNoHeader('Connection', 'close')
    158                 else:
    159                     self.assertHeader('Connection', 'close')
    160                     self.assertRaises(NotConnected, self.getPage, '/')
    161                 self.getPage('/stream', method='HEAD')
    162                 self.assertStatus('200 OK')
    163                 self.assertBody('')
    164                 self.assertNoHeader('Transfer-Encoding')
    165         else:
    166             self.PROTOCOL = 'HTTP/1.0'
    167             self.persistent = True
    168             self.getPage('/', headers=[('Connection', 'Keep-Alive')])
    169             self.assertStatus('200 OK')
    170             self.assertBody(pov)
    171             self.assertHeader('Connection', 'Keep-Alive')
    172             if set_cl:
    173                 self.getPage('/stream?set_cl=Yes', headers=[('Connection', 'Keep-Alive')])
    174                 self.assertHeader('Content-Length')
    175                 self.assertHeader('Connection', 'Keep-Alive')
    176                 self.assertNoHeader('Transfer-Encoding')
    177                 self.assertStatus('200 OK')
    178                 self.assertBody('0123456789')
    179             else:
    180                 self.getPage('/stream', headers=[('Connection', 'Keep-Alive')])
    181                 self.assertStatus('200 OK')
    182                 self.assertBody('0123456789')
    183                 self.assertNoHeader('Content-Length')
    184                 self.assertNoHeader('Connection', 'Keep-Alive')
    185                 self.assertNoHeader('Transfer-Encoding')
    186                 self.assertRaises(NotConnected, self.getPage, '/')
    187 
    188     def test_HTTP10_KeepAlive(self):
    189         self.PROTOCOL = 'HTTP/1.0'
    190         if self.scheme == 'https':
    191             self.HTTP_CONN = HTTPSConnection
    192         else:
    193             self.HTTP_CONN = HTTPConnection
    194         self.getPage('/page2')
    195         self.assertStatus('200 OK')
    196         self.assertBody(pov)
    197         self.persistent = True
    198         self.getPage('/page3', headers=[('Connection', 'Keep-Alive')])
    199         self.assertStatus('200 OK')
    200         self.assertBody(pov)
    201         self.assertHeader('Connection', 'Keep-Alive')
    202         self.getPage('/page3')
    203         self.assertStatus('200 OK')
    204         self.assertBody(pov)
    205 
    206 
    207 class PipelineTests(helper.CPWebCase):
    208     setup_server = staticmethod(setup_server)
    209 
    210     def test_HTTP11_Timeout(self):
    211         if cherrypy.server.protocol_version != 'HTTP/1.1':
    212             return self.skip()
    213         self.PROTOCOL = 'HTTP/1.1'
    214         self.persistent = True
    215         conn = self.HTTP_CONN
    216         conn.auto_open = False
    217         conn.connect()
    218         time.sleep(timeout * 2)
    219         response = conn.response_class(conn.sock, method='GET')
    220         response.begin()
    221         self.assertEqual(response.status, 408)
    222         conn.close()
    223         self.persistent = True
    224         conn = self.HTTP_CONN
    225         conn.auto_open = False
    226         conn.connect()
    227         conn.send(ntob('GET /hello HTTP/1.1'))
    228         conn.send(('Host: %s' % self.HOST).encode('ascii'))
    229         time.sleep(timeout * 2)
    230         response = conn.response_class(conn.sock, method='GET')
    231         response.begin()
    232         self.assertEqual(response.status, 408)
    233         conn.close()
    234 
    235     def test_HTTP11_Timeout_after_request(self):
    236         if cherrypy.server.protocol_version != 'HTTP/1.1':
    237             return self.skip()
    238         self.PROTOCOL = 'HTTP/1.1'
    239         self.persistent = True
    240         conn = self.HTTP_CONN
    241         conn.putrequest('GET', '/timeout?t=%s' % timeout, skip_host=True)
    242         conn.putheader('Host', self.HOST)
    243         conn.endheaders()
    244         response = conn.response_class(conn.sock, method='GET')
    245         response.begin()
    246         self.assertEqual(response.status, 200)
    247         self.body = response.read()
    248         self.assertBody(str(timeout))
    249         conn._output(ntob('GET /hello HTTP/1.1'))
    250         conn._output(ntob('Host: %s' % self.HOST, 'ascii'))
    251         conn._send_output()
    252         response = conn.response_class(conn.sock, method='GET')
    253         response.begin()
    254         self.assertEqual(response.status, 200)
    255         self.body = response.read()
    256         self.assertBody('Hello, world!')
    257         time.sleep(timeout * 2)
    258         conn._output(ntob('GET /hello HTTP/1.1'))
    259         conn._output(ntob('Host: %s' % self.HOST, 'ascii'))
    260         conn._send_output()
    261         response = conn.response_class(conn.sock, method='GET')
    262         try:
    263             response.begin()
    264         except:
    265             if not isinstance(sys.exc_info()[1], (socket.error, BadStatusLine)):
    266                 self.fail("Writing to timed out socket didn't fail as it should have: %s" % sys.exc_info()[1])
    267         else:
    268             if response.status != 408:
    269                 self.fail("Writing to timed out socket didn't fail as it should have: %s" % response.read())
    270 
    271         conn.close()
    272         self.persistent = True
    273         conn = self.HTTP_CONN
    274         conn.putrequest('GET', '/', skip_host=True)
    275         conn.putheader('Host', self.HOST)
    276         conn.endheaders()
    277         response = conn.response_class(conn.sock, method='GET')
    278         response.begin()
    279         self.assertEqual(response.status, 200)
    280         self.body = response.read()
    281         self.assertBody(pov)
    282         conn.send(ntob('GET /hello HTTP/1.1'))
    283         time.sleep(timeout * 2)
    284         response = conn.response_class(conn.sock, method='GET')
    285         try:
    286             response.begin()
    287         except:
    288             if not isinstance(sys.exc_info()[1], (socket.error, BadStatusLine)):
    289                 self.fail("Writing to timed out socket didn't fail as it should have: %s" % sys.exc_info()[1])
    290         else:
    291             self.fail("Writing to timed out socket didn't fail as it should have: %s" % response.read())
    292 
    293         conn.close()
    294         self.persistent = True
    295         conn = self.HTTP_CONN
    296         conn.putrequest('GET', '/', skip_host=True)
    297         conn.putheader('Host', self.HOST)
    298         conn.endheaders()
    299         response = conn.response_class(conn.sock, method='GET')
    300         response.begin()
    301         self.assertEqual(response.status, 200)
    302         self.body = response.read()
    303         self.assertBody(pov)
    304         conn.close()
    305 
    306     def test_HTTP11_pipelining(self):
    307         if cherrypy.server.protocol_version != 'HTTP/1.1':
    308             return self.skip()
    309         self.PROTOCOL = 'HTTP/1.1'
    310         self.persistent = True
    311         conn = self.HTTP_CONN
    312         conn.putrequest('GET', '/hello', skip_host=True)
    313         conn.putheader('Host', self.HOST)
    314         conn.endheaders()
    315         for trial in range(5):
    316             conn._output(ntob('GET /hello HTTP/1.1'))
    317             conn._output(ntob('Host: %s' % self.HOST, 'ascii'))
    318             conn._send_output()
    319             response = conn.response_class(conn.sock, method='GET')
    320             response.begin()
    321             body = response.read(13)
    322             self.assertEqual(response.status, 200)
    323             self.assertEqual(body, ntob('Hello, world!'))
    324 
    325         response = conn.response_class(conn.sock, method='GET')
    326         response.begin()
    327         body = response.read()
    328         self.assertEqual(response.status, 200)
    329         self.assertEqual(body, ntob('Hello, world!'))
    330         conn.close()
    331 
    332     def test_100_Continue(self):
    333         if cherrypy.server.protocol_version != 'HTTP/1.1':
    334             return self.skip()
    335         self.PROTOCOL = 'HTTP/1.1'
    336         self.persistent = True
    337         conn = self.HTTP_CONN
    338         conn.putrequest('POST', '/upload', skip_host=True)
    339         conn.putheader('Host', self.HOST)
    340         conn.putheader('Content-Type', 'text/plain')
    341         conn.putheader('Content-Length', '4')
    342         conn.endheaders()
    343         conn.send(ntob("d'oh"))
    344         response = conn.response_class(conn.sock, method='POST')
    345         version, status, reason = response._read_status()
    346         self.assertNotEqual(status, 100)
    347         conn.close()
    348         conn.connect()
    349         conn.putrequest('POST', '/upload', skip_host=True)
    350         conn.putheader('Host', self.HOST)
    351         conn.putheader('Content-Type', 'text/plain')
    352         conn.putheader('Content-Length', '17')
    353         conn.putheader('Expect', '100-continue')
    354         conn.endheaders()
    355         response = conn.response_class(conn.sock, method='POST')
    356         version, status, reason = response._read_status()
    357         self.assertEqual(status, 100)
    358         while True:
    359             line = response.fp.readline().strip()
    360             if line:
    361                 self.fail('100 Continue should not output any headers. Got %r' % line)
    362             else:
    363                 break
    364 
    365         body = ntob('I am a small file')
    366         conn.send(body)
    367         response.begin()
    368         self.status, self.headers, self.body = webtest.shb(response)
    369         self.assertStatus(200)
    370         self.assertBody("thanks for '%s'" % body)
    371         conn.close()
    372 
    373 
    374 class ConnectionTests(helper.CPWebCase):
    375     setup_server = staticmethod(setup_server)
    376 
    377     def test_readall_or_close(self):
    378         if cherrypy.server.protocol_version != 'HTTP/1.1':
    379             return self.skip()
    380         self.PROTOCOL = 'HTTP/1.1'
    381         if self.scheme == 'https':
    382             self.HTTP_CONN = HTTPSConnection
    383         else:
    384             self.HTTP_CONN = HTTPConnection
    385         old_max = cherrypy.server.max_request_body_size
    386         for new_max in (0, old_max):
    387             cherrypy.server.max_request_body_size = new_max
    388             self.persistent = True
    389             conn = self.HTTP_CONN
    390             conn.putrequest('POST', '/err_before_read', skip_host=True)
    391             conn.putheader('Host', self.HOST)
    392             conn.putheader('Content-Type', 'text/plain')
    393             conn.putheader('Content-Length', '1000')
    394             conn.putheader('Expect', '100-continue')
    395             conn.endheaders()
    396             response = conn.response_class(conn.sock, method='POST')
    397             version, status, reason = response._read_status()
    398             self.assertEqual(status, 100)
    399             while True:
    400                 skip = response.fp.readline().strip()
    401                 if not skip:
    402                     break
    403 
    404             conn.send(ntob('x' * 1000))
    405             response.begin()
    406             self.status, self.headers, self.body = webtest.shb(response)
    407             self.assertStatus(500)
    408             conn._output(ntob('POST /upload HTTP/1.1'))
    409             conn._output(ntob('Host: %s' % self.HOST, 'ascii'))
    410             conn._output(ntob('Content-Type: text/plain'))
    411             conn._output(ntob('Content-Length: 17'))
    412             conn._output(ntob('Expect: 100-continue'))
    413             conn._send_output()
    414             response = conn.response_class(conn.sock, method='POST')
    415             version, status, reason = response._read_status()
    416             self.assertEqual(status, 100)
    417             while True:
    418                 skip = response.fp.readline().strip()
    419                 if not skip:
    420                     break
    421 
    422             body = ntob('I am a small file')
    423             conn.send(body)
    424             response.begin()
    425             self.status, self.headers, self.body = webtest.shb(response)
    426             self.assertStatus(200)
    427             self.assertBody("thanks for '%s'" % body)
    428             conn.close()
    429 
    430     def test_No_Message_Body(self):
    431         if cherrypy.server.protocol_version != 'HTTP/1.1':
    432             return self.skip()
    433         self.PROTOCOL = 'HTTP/1.1'
    434         self.persistent = True
    435         self.getPage('/')
    436         self.assertStatus('200 OK')
    437         self.assertBody(pov)
    438         self.assertNoHeader('Connection')
    439         self.getPage('/custom/204')
    440         self.assertStatus(204)
    441         self.assertNoHeader('Content-Length')
    442         self.assertBody('')
    443         self.assertNoHeader('Connection')
    444         self.getPage('/custom/304')
    445         self.assertStatus(304)
    446         self.assertNoHeader('Content-Length')
    447         self.assertBody('')
    448         self.assertNoHeader('Connection')
    449 
    450     def test_Chunked_Encoding(self):
    451         if cherrypy.server.protocol_version != 'HTTP/1.1':
    452             return self.skip()
    453         if hasattr(self, 'harness') and 'modpython' in self.harness.__class__.__name__.lower():
    454             return self.skip()
    455         self.PROTOCOL = 'HTTP/1.1'
    456         self.persistent = True
    457         conn = self.HTTP_CONN
    458         body = ntob('8;key=value\r\nxx\r\nxxxx\r\n5\r\nyyyyy\r\n0\r\nContent-Type: application/json\r\n\r\n')
    459         conn.putrequest('POST', '/upload', skip_host=True)
    460         conn.putheader('Host', self.HOST)
    461         conn.putheader('Transfer-Encoding', 'chunked')
    462         conn.putheader('Trailer', 'Content-Type')
    463         conn.putheader('Content-Length', '3')
    464         conn.endheaders()
    465         conn.send(body)
    466         response = conn.getresponse()
    467         self.status, self.headers, self.body = webtest.shb(response)
    468         self.assertStatus('200 OK')
    469         self.assertBody("thanks for '%s'" % ntob('xx\r\nxxxxyyyyy'))
    470         body = ntob('3e3\r\n' + 'x' * 995 + '\r\n0\r\n\r\n')
    471         conn.putrequest('POST', '/upload', skip_host=True)
    472         conn.putheader('Host', self.HOST)
    473         conn.putheader('Transfer-Encoding', 'chunked')
    474         conn.putheader('Content-Type', 'text/plain')
    475         conn.endheaders()
    476         conn.send(body)
    477         response = conn.getresponse()
    478         self.status, self.headers, self.body = webtest.shb(response)
    479         self.assertStatus(413)
    480         conn.close()
    481 
    482     def test_Content_Length_in(self):
    483         self.persistent = True
    484         conn = self.HTTP_CONN
    485         conn.putrequest('POST', '/upload', skip_host=True)
    486         conn.putheader('Host', self.HOST)
    487         conn.putheader('Content-Type', 'text/plain')
    488         conn.putheader('Content-Length', '9999')
    489         conn.endheaders()
    490         response = conn.getresponse()
    491         self.status, self.headers, self.body = webtest.shb(response)
    492         self.assertStatus(413)
    493         self.assertBody('The entity sent with the request exceeds the maximum allowed bytes.')
    494         conn.close()
    495 
    496     def test_Content_Length_out_preheaders(self):
    497         self.persistent = True
    498         conn = self.HTTP_CONN
    499         conn.putrequest('GET', '/custom_cl?body=I+have+too+many+bytes&cl=5', skip_host=True)
    500         conn.putheader('Host', self.HOST)
    501         conn.endheaders()
    502         response = conn.getresponse()
    503         self.status, self.headers, self.body = webtest.shb(response)
    504         self.assertStatus(500)
    505         self.assertBody('The requested resource returned more bytes than the declared Content-Length.')
    506         conn.close()
    507 
    508     def test_Content_Length_out_postheaders(self):
    509         self.persistent = True
    510         conn = self.HTTP_CONN
    511         conn.putrequest('GET', '/custom_cl?body=I+too&body=+have+too+many&cl=5', skip_host=True)
    512         conn.putheader('Host', self.HOST)
    513         conn.endheaders()
    514         response = conn.getresponse()
    515         self.status, self.headers, self.body = webtest.shb(response)
    516         self.assertStatus(200)
    517         self.assertBody('I too')
    518         conn.close()
    519 
    520     def test_598(self):
    521         remote_data_conn = urlopen('%s://%s:%s/one_megabyte_of_a/' % (self.scheme, self.HOST, self.PORT))
    522         buf = remote_data_conn.read(512)
    523         time.sleep(timeout * 0.6)
    524         remaining = 1048064
    525         while remaining:
    526             data = remote_data_conn.read(remaining)
    527             if not data:
    528                 break
    529             else:
    530                 buf += data
    531             remaining -= len(data)
    532 
    533         self.assertEqual(len(buf), 1048576)
    534         self.assertEqual(buf, ntob('a' * 1024 * 1024))
    535         self.assertEqual(remaining, 0)
    536         remote_data_conn.close()
    537 
    538 
    539 class BadRequestTests(helper.CPWebCase):
    540     setup_server = staticmethod(setup_server)
    541 
    542     def test_No_CRLF(self):
    543         self.persistent = True
    544         conn = self.HTTP_CONN
    545         conn.send(ntob('GET /hello HTTP/1.1\n\n'))
    546         response = conn.response_class(conn.sock, method='GET')
    547         response.begin()
    548         self.body = response.read()
    549         self.assertBody('HTTP requires CRLF terminators')
    550         conn.close()
    551         conn.connect()
    552         conn.send(ntob('GET /hello HTTP/1.1\r\n\n'))
    553         response = conn.response_class(conn.sock, method='GET')
    554         response.begin()
    555         self.body = response.read()
    556         self.assertBody('HTTP requires CRLF terminators')
    557         conn.close()