test_core.py (18617B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\test\test_core.py 2 import os 3 localDir = os.path.dirname(__file__) 4 import sys 5 import types 6 import cherrypy 7 from cherrypy._cpcompat import IncompleteRead, itervalues, ntob 8 from cherrypy import _cptools, tools 9 from cherrypy.lib import httputil, static 10 favicon_path = os.path.join(os.getcwd(), localDir, '../favicon.ico') 11 from cherrypy.test import helper 12 13 class CoreRequestHandlingTest(helper.CPWebCase): 14 15 def setup_server(): 16 17 class Root: 18 19 def index(self): 20 return 'hello' 21 22 index.exposed = True 23 favicon_ico = tools.staticfile.handler(filename=favicon_path) 24 25 def defct(self, newct): 26 newct = 'text/%s' % newct 27 cherrypy.config.update({'tools.response_headers.on': True, 28 'tools.response_headers.headers': [('Content-Type', newct)]}) 29 30 defct.exposed = True 31 32 def baseurl(self, path_info, relative = None): 33 return cherrypy.url(path_info, relative=bool(relative)) 34 35 baseurl.exposed = True 36 37 root = Root() 38 if sys.version_info >= (2, 5): 39 from cherrypy.test._test_decorators import ExposeExamples 40 root.expose_dec = ExposeExamples() 41 42 class TestType(type): 43 44 def __init__(cls, name, bases, dct): 45 type.__init__(cls, name, bases, dct) 46 for value in itervalues(dct): 47 if isinstance(value, types.FunctionType): 48 value.exposed = True 49 50 setattr(root, name.lower(), cls()) 51 52 class Test(object): 53 __metaclass__ = TestType 54 55 class URL(Test): 56 _cp_config = {'tools.trailing_slash.on': False} 57 58 def index(self, path_info, relative = None): 59 if relative != 'server': 60 relative = bool(relative) 61 return cherrypy.url(path_info, relative=relative) 62 63 def leaf(self, path_info, relative = None): 64 if relative != 'server': 65 relative = bool(relative) 66 return cherrypy.url(path_info, relative=relative) 67 68 class Status(Test): 69 70 def index(self): 71 return 'normal' 72 73 def blank(self): 74 cherrypy.response.status = '' 75 76 def illegal(self): 77 cherrypy.response.status = 781 78 return 'oops' 79 80 def unknown(self): 81 cherrypy.response.status = '431 My custom error' 82 return 'funky' 83 84 def bad(self): 85 cherrypy.response.status = 'error' 86 return 'bad news' 87 88 class Redirect(Test): 89 90 class Error: 91 _cp_config = {'tools.err_redirect.on': True, 92 'tools.err_redirect.url': '/errpage', 93 'tools.err_redirect.internal': False} 94 95 def index(self): 96 raise NameError('redirect_test') 97 98 index.exposed = True 99 100 error = Error() 101 102 def index(self): 103 return 'child' 104 105 def custom(self, url, code): 106 raise cherrypy.HTTPRedirect(url, code) 107 108 def by_code(self, code): 109 raise cherrypy.HTTPRedirect('somewhere%20else', code) 110 111 by_code._cp_config = {'tools.trailing_slash.extra': True} 112 113 def nomodify(self): 114 raise cherrypy.HTTPRedirect('', 304) 115 116 def proxy(self): 117 raise cherrypy.HTTPRedirect('proxy', 305) 118 119 def stringify(self): 120 return str(cherrypy.HTTPRedirect('/')) 121 122 def fragment(self, frag): 123 raise cherrypy.HTTPRedirect('/some/url#%s' % frag) 124 125 def login_redir(): 126 if not getattr(cherrypy.request, 'login', None): 127 raise cherrypy.InternalRedirect('/internalredirect/login') 128 129 tools.login_redir = _cptools.Tool('before_handler', login_redir) 130 131 def redir_custom(): 132 raise cherrypy.InternalRedirect('/internalredirect/custom_err') 133 134 class InternalRedirect(Test): 135 136 def index(self): 137 raise cherrypy.InternalRedirect('/') 138 139 def choke(self): 140 return 3 / 0 141 142 choke.exposed = True 143 choke._cp_config = {'hooks.before_error_response': redir_custom} 144 145 def relative(self, a, b): 146 raise cherrypy.InternalRedirect('cousin?t=6') 147 148 def cousin(self, t): 149 return cherrypy.request.prev.query_string 150 151 def petshop(self, user_id): 152 if user_id == 'parrot': 153 raise cherrypy.InternalRedirect('/image/getImagesByUser?user_id=slug') 154 elif user_id == 'terrier': 155 raise cherrypy.InternalRedirect('/image/getImagesByUser?user_id=fish') 156 else: 157 raise cherrypy.InternalRedirect('/image/getImagesByUser?user_id=%s' % str(user_id)) 158 159 def secure(self): 160 return 'Welcome!' 161 162 secure = tools.login_redir()(secure) 163 164 def login(self): 165 return 'Please log in' 166 167 def custom_err(self): 168 return 'Something went horribly wrong.' 169 170 def early_ir(self, arg): 171 return 'whatever' 172 173 early_ir._cp_config = {'hooks.before_request_body': redir_custom} 174 175 class Image(Test): 176 177 def getImagesByUser(self, user_id): 178 return '0 images for %s' % user_id 179 180 class Flatten(Test): 181 182 def as_string(self): 183 return 'content' 184 185 def as_list(self): 186 return ['con', 'tent'] 187 188 def as_yield(self): 189 yield ntob('content') 190 191 def as_dblyield(self): 192 yield self.as_yield() 193 194 as_dblyield._cp_config = {'tools.flatten.on': True} 195 196 def as_refyield(self): 197 for chunk in self.as_yield(): 198 yield chunk 199 200 class Ranges(Test): 201 202 def get_ranges(self, bytes): 203 return repr(httputil.get_ranges('bytes=%s' % bytes, 8)) 204 205 def slice_file(self): 206 path = os.path.join(os.getcwd(), os.path.dirname(__file__)) 207 return static.serve_file(os.path.join(path, 'static/index.html')) 208 209 class Cookies(Test): 210 211 def single(self, name): 212 cookie = cherrypy.request.cookie[name] 213 cherrypy.response.cookie[str(name)] = cookie.value 214 215 def multiple(self, names): 216 for name in names: 217 cookie = cherrypy.request.cookie[name] 218 cherrypy.response.cookie[str(name)] = cookie.value 219 220 cherrypy.tree.mount(root) 221 222 setup_server = staticmethod(setup_server) 223 224 def testStatus(self): 225 self.getPage('/status/') 226 self.assertBody('normal') 227 self.assertStatus(200) 228 self.getPage('/status/blank') 229 self.assertBody('') 230 self.assertStatus(200) 231 self.getPage('/status/illegal') 232 self.assertStatus(500) 233 msg = 'Illegal response status from server (781 is out of range).' 234 self.assertErrorPage(500, msg) 235 if not getattr(cherrypy.server, 'using_apache', False): 236 self.getPage('/status/unknown') 237 self.assertBody('funky') 238 self.assertStatus(431) 239 self.getPage('/status/bad') 240 self.assertStatus(500) 241 msg = "Illegal response status from server ('error' is non-numeric)." 242 self.assertErrorPage(500, msg) 243 244 def testSlashes(self): 245 self.getPage('/redirect?id=3') 246 self.assertStatus(301) 247 self.assertInBody("<a href='%s/redirect/?id=3'>%s/redirect/?id=3</a>" % (self.base(), self.base())) 248 if self.prefix(): 249 self.getPage('') 250 self.assertStatus(301) 251 self.assertInBody("<a href='%s/'>%s/</a>" % (self.base(), self.base())) 252 self.getPage('/redirect/by_code/?code=307') 253 self.assertStatus(301) 254 self.assertInBody("<a href='%s/redirect/by_code?code=307'>%s/redirect/by_code?code=307</a>" % (self.base(), self.base())) 255 self.getPage('/url?path_info=page1') 256 self.assertBody('%s/url/page1' % self.base()) 257 self.getPage('/url/leaf/?path_info=page1') 258 self.assertBody('%s/url/page1' % self.base()) 259 260 def testRedirect(self): 261 self.getPage('/redirect/') 262 self.assertBody('child') 263 self.assertStatus(200) 264 self.getPage('/redirect/by_code?code=300') 265 self.assertMatchesBody("<a href='(.*)somewhere%20else'>\\1somewhere%20else</a>") 266 self.assertStatus(300) 267 self.getPage('/redirect/by_code?code=301') 268 self.assertMatchesBody("<a href='(.*)somewhere%20else'>\\1somewhere%20else</a>") 269 self.assertStatus(301) 270 self.getPage('/redirect/by_code?code=302') 271 self.assertMatchesBody("<a href='(.*)somewhere%20else'>\\1somewhere%20else</a>") 272 self.assertStatus(302) 273 self.getPage('/redirect/by_code?code=303') 274 self.assertMatchesBody("<a href='(.*)somewhere%20else'>\\1somewhere%20else</a>") 275 self.assertStatus(303) 276 self.getPage('/redirect/by_code?code=307') 277 self.assertMatchesBody("<a href='(.*)somewhere%20else'>\\1somewhere%20else</a>") 278 self.assertStatus(307) 279 self.getPage('/redirect/nomodify') 280 self.assertBody('') 281 self.assertStatus(304) 282 self.getPage('/redirect/proxy') 283 self.assertBody('') 284 self.assertStatus(305) 285 self.getPage('/redirect/error/') 286 self.assertStatus(('302 Found', '303 See Other')) 287 self.assertInBody('/errpage') 288 self.getPage('/redirect/stringify', protocol='HTTP/1.0') 289 self.assertStatus(200) 290 self.assertBody("(['%s/'], 302)" % self.base()) 291 if cherrypy.server.protocol_version == 'HTTP/1.1': 292 self.getPage('/redirect/stringify', protocol='HTTP/1.1') 293 self.assertStatus(200) 294 self.assertBody("(['%s/'], 303)" % self.base()) 295 frag = 'foo' 296 self.getPage('/redirect/fragment/%s' % frag) 297 self.assertMatchesBody("<a href='(.*)\\/some\\/url\\#%s'>\\1\\/some\\/url\\#%s</a>" % (frag, frag)) 298 loc = self.assertHeader('Location') 299 self.assertStatus(('302 Found', '303 See Other')) 300 self.getPage('/redirect/custom?code=303&url=/foobar/%0d%0aSet-Cookie:%20somecookie=someval') 301 self.assertStatus(303) 302 loc = self.assertHeader('Location') 303 self.assertNoHeader('Set-Cookie') 304 305 def test_InternalRedirect(self): 306 self.getPage('/internalredirect/') 307 self.assertBody('hello') 308 self.assertStatus(200) 309 self.getPage('/internalredirect/petshop?user_id=Sir-not-appearing-in-this-film') 310 self.assertBody('0 images for Sir-not-appearing-in-this-film') 311 self.assertStatus(200) 312 self.getPage('/internalredirect/petshop?user_id=parrot') 313 self.assertBody('0 images for slug') 314 self.assertStatus(200) 315 self.getPage('/internalredirect/petshop', method='POST', body='user_id=terrier') 316 self.assertBody('0 images for fish') 317 self.assertStatus(200) 318 self.getPage('/internalredirect/early_ir', method='POST', body='arg=aha!') 319 self.assertBody('Something went horribly wrong.') 320 self.assertStatus(200) 321 self.getPage('/internalredirect/secure') 322 self.assertBody('Please log in') 323 self.assertStatus(200) 324 self.getPage('/internalredirect/relative?a=3&b=5') 325 self.assertBody('a=3&b=5') 326 self.assertStatus(200) 327 self.getPage('/internalredirect/choke') 328 self.assertStatus(200) 329 self.assertBody('Something went horribly wrong.') 330 331 def testFlatten(self): 332 for url in ['/flatten/as_string', 333 '/flatten/as_list', 334 '/flatten/as_yield', 335 '/flatten/as_dblyield', 336 '/flatten/as_refyield']: 337 self.getPage(url) 338 self.assertBody('content') 339 340 def testRanges(self): 341 self.getPage('/ranges/get_ranges?bytes=3-6') 342 self.assertBody('[(3, 7)]') 343 self.getPage('/ranges/get_ranges?bytes=2-4,-1') 344 self.assertBody('[(2, 5), (7, 8)]') 345 if cherrypy.server.protocol_version == 'HTTP/1.1': 346 self.getPage('/ranges/slice_file', [('Range', 'bytes=2-5')]) 347 self.assertStatus(206) 348 self.assertHeader('Content-Type', 'text/html;charset=utf-8') 349 self.assertHeader('Content-Range', 'bytes 2-5/14') 350 self.assertBody('llo,') 351 self.getPage('/ranges/slice_file', [('Range', 'bytes=4-6,2-5')]) 352 self.assertStatus(206) 353 ct = self.assertHeader('Content-Type') 354 expected_type = 'multipart/byteranges; boundary=' 355 self.assert_(ct.startswith(expected_type)) 356 boundary = ct[len(expected_type):] 357 expected_body = '\r\n--%s\r\nContent-type: text/html\r\nContent-range: bytes 4-6/14\r\n\r\no, \r\n--%s\r\nContent-type: text/html\r\nContent-range: bytes 2-5/14\r\n\r\nllo,\r\n--%s--\r\n' % (boundary, boundary, boundary) 358 self.assertBody(expected_body) 359 self.assertHeader('Content-Length') 360 self.getPage('/ranges/slice_file', [('Range', 'bytes=2300-2900')]) 361 self.assertStatus(416) 362 self.assertHeader('Content-Range', 'bytes */14') 363 elif cherrypy.server.protocol_version == 'HTTP/1.0': 364 self.getPage('/ranges/slice_file', [('Range', 'bytes=2-5')]) 365 self.assertStatus(200) 366 self.assertBody('Hello, world\r\n') 367 368 def testFavicon(self): 369 icofilename = os.path.join(localDir, '../favicon.ico') 370 icofile = open(icofilename, 'rb') 371 data = icofile.read() 372 icofile.close() 373 self.getPage('/favicon.ico') 374 self.assertBody(data) 375 376 def testCookies(self): 377 if sys.version_info >= (2, 5): 378 header_value = lambda x: x 379 else: 380 header_value = lambda x: x + ';' 381 self.getPage('/cookies/single?name=First', [('Cookie', 'First=Dinsdale;')]) 382 self.assertHeader('Set-Cookie', header_value('First=Dinsdale')) 383 self.getPage('/cookies/multiple?names=First&names=Last', [('Cookie', 'First=Dinsdale; Last=Piranha;')]) 384 self.assertHeader('Set-Cookie', header_value('First=Dinsdale')) 385 self.assertHeader('Set-Cookie', header_value('Last=Piranha')) 386 self.getPage('/cookies/single?name=Something-With:Colon', [('Cookie', 'Something-With:Colon=some-value')]) 387 self.assertStatus(400) 388 389 def testDefaultContentType(self): 390 self.getPage('/') 391 self.assertHeader('Content-Type', 'text/html;charset=utf-8') 392 self.getPage('/defct/plain') 393 self.getPage('/') 394 self.assertHeader('Content-Type', 'text/plain;charset=utf-8') 395 self.getPage('/defct/html') 396 397 def test_cherrypy_url(self): 398 self.getPage('/url/leaf?path_info=page1') 399 self.assertBody('%s/url/page1' % self.base()) 400 self.getPage('/url/?path_info=page1') 401 self.assertBody('%s/url/page1' % self.base()) 402 host = 'www.mydomain.example' 403 self.getPage('/url/leaf?path_info=page1', headers=[('Host', host)]) 404 self.assertBody('%s://%s/url/page1' % (self.scheme, host)) 405 self.getPage('/url/leaf?path_info=/page1') 406 self.assertBody('%s/page1' % self.base()) 407 self.getPage('/url/?path_info=/page1') 408 self.assertBody('%s/page1' % self.base()) 409 self.getPage('/url/leaf?path_info=./page1') 410 self.assertBody('%s/url/page1' % self.base()) 411 self.getPage('/url/leaf?path_info=other/./page1') 412 self.assertBody('%s/url/other/page1' % self.base()) 413 self.getPage('/url/?path_info=/other/./page1') 414 self.assertBody('%s/other/page1' % self.base()) 415 self.getPage('/url/leaf?path_info=../page1') 416 self.assertBody('%s/page1' % self.base()) 417 self.getPage('/url/leaf?path_info=other/../page1') 418 self.assertBody('%s/url/page1' % self.base()) 419 self.getPage('/url/leaf?path_info=/other/../page1') 420 self.assertBody('%s/page1' % self.base()) 421 self.getPage('/url/?path_info=page1&relative=True') 422 self.assertBody('page1') 423 self.getPage('/url/leaf?path_info=/page1&relative=True') 424 self.assertBody('../page1') 425 self.getPage('/url/leaf?path_info=page1&relative=True') 426 self.assertBody('page1') 427 self.getPage('/url/leaf?path_info=leaf/page1&relative=True') 428 self.assertBody('leaf/page1') 429 self.getPage('/url/leaf?path_info=../page1&relative=True') 430 self.assertBody('../page1') 431 self.getPage('/url/?path_info=other/../page1&relative=True') 432 self.assertBody('page1') 433 self.getPage('/baseurl?path_info=ab&relative=True') 434 self.assertBody('ab') 435 self.getPage('/baseurl?path_info=/ab&relative=True') 436 self.assertBody('ab') 437 self.getPage('/url/leaf?path_info=page1&relative=server') 438 self.assertBody('/url/page1') 439 self.getPage('/url/?path_info=page1&relative=server') 440 self.assertBody('/url/page1') 441 self.getPage('/url/leaf?path_info=/page1&relative=server') 442 self.assertBody('/page1') 443 self.getPage('/url/?path_info=/page1&relative=server') 444 self.assertBody('/page1') 445 446 def test_expose_decorator(self): 447 if not sys.version_info >= (2, 5): 448 return self.skip('skipped (Python 2.5+ only) ') 449 self.getPage('/expose_dec/no_call') 450 self.assertStatus(200) 451 self.assertBody('Mr E. R. Bradshaw') 452 self.getPage('/expose_dec/call_empty') 453 self.assertStatus(200) 454 self.assertBody('Mrs. B.J. Smegma') 455 self.getPage('/expose_dec/call_alias') 456 self.assertStatus(200) 457 self.assertBody('Mr Nesbitt') 458 self.getPage('/expose_dec/nesbitt') 459 self.assertStatus(200) 460 self.assertBody('Mr Nesbitt') 461 self.getPage('/expose_dec/alias1') 462 self.assertStatus(200) 463 self.assertBody('Mr Ken Andrews') 464 self.getPage('/expose_dec/alias2') 465 self.assertStatus(200) 466 self.assertBody('Mr Ken Andrews') 467 self.getPage('/expose_dec/andrews') 468 self.assertStatus(200) 469 self.assertBody('Mr Ken Andrews') 470 self.getPage('/expose_dec/alias3') 471 self.assertStatus(200) 472 self.assertBody('Mr. and Mrs. Watson')