Home | Trees | Indices | Help |
|
---|
|
1 import os 2 import sys 3 4 from cherrypy._cpcompat import HTTPConnection, HTTPSConnection, ntob 5 from cherrypy._cpcompat import BytesIO 6 7 curdir = os.path.join(os.getcwd(), os.path.dirname(__file__)) 8 has_space_filepath = os.path.join(curdir, 'static', 'has space.html') 9 bigfile_filepath = os.path.join(curdir, "static", "bigfile.log") 10 BIGFILE_SIZE = 1024 * 1024 11 12 import cherrypy 13 from cherrypy.lib import static 14 from cherrypy.test import helper 15 161838 tell.exposed = True 39 40 def fileobj(self): 41 f = open(os.path.join(curdir, 'style.css'), 'rb') 42 return static.serve_fileobj(f, content_type='text/css') 43 fileobj.exposed = True 44 45 def bytesio(self): 46 f = BytesIO(ntob('Fee\nfie\nfo\nfum')) 47 return static.serve_fileobj(f, content_type='text/plain') 48 bytesio.exposed = True 49 50 class Static: 51 52 def index(self): 53 return 'You want the Baron? You can have the Baron!' 54 index.exposed = True 55 56 def dynamic(self): 57 return "This is a DYNAMIC page" 58 dynamic.exposed = True 59 60 root = Root() 61 root.static = Static() 62 63 rootconf = { 64 '/static': { 65 'tools.staticdir.on': True, 66 'tools.staticdir.dir': 'static', 67 'tools.staticdir.root': curdir, 68 }, 69 '/style.css': { 70 'tools.staticfile.on': True, 71 'tools.staticfile.filename': os.path.join(curdir, 'style.css'), 72 }, 73 '/docroot': { 74 'tools.staticdir.on': True, 75 'tools.staticdir.root': curdir, 76 'tools.staticdir.dir': 'static', 77 'tools.staticdir.index': 'index.html', 78 }, 79 '/error': { 80 'tools.staticdir.on': True, 81 'request.show_tracebacks': True, 82 }, 83 '/404test': { 84 'tools.staticdir.on': True, 85 'tools.staticdir.root': curdir, 86 'tools.staticdir.dir': 'static', 87 'error_page.404': error_page_404, 88 } 89 } 90 rootApp = cherrypy.Application(root) 91 rootApp.merge(rootconf) 92 93 test_app_conf = { 94 '/test': { 95 'tools.staticdir.index': 'index.html', 96 'tools.staticdir.on': True, 97 'tools.staticdir.root': curdir, 98 'tools.staticdir.dir': 'static', 99 }, 100 } 101 testApp = cherrypy.Application(Static()) 102 testApp.merge(test_app_conf) 103 104 vhost = cherrypy._cpwsgi.VirtualHost(rootApp, {'virt.net': testApp}) 105 cherrypy.tree.graft(vhost) 106 setup_server = staticmethod(setup_server) 10720 if not os.path.exists(has_space_filepath): 21 open(has_space_filepath, 'wb').write(ntob('Hello, world\r\n')) 22 if not os.path.exists(bigfile_filepath): 23 open(bigfile_filepath, 'wb').write(ntob("x" * BIGFILE_SIZE)) 24 25 class Root: 26 27 def bigfile(self): 28 from cherrypy.lib import static 29 self.f = static.serve_file(bigfile_filepath) 30 return self.f31 bigfile.exposed = True 32 bigfile._cp_config = {'response.stream': True} 33 34 def tell(self): 35 if self.f.input.closed: 36 return '' 37 return repr(self.f.input.tell()).rstrip('L')109 for f in (has_space_filepath, bigfile_filepath): 110 if os.path.exists(f): 111 try: 112 os.unlink(f) 113 except: 114 pass115 teardown_server = staticmethod(teardown_server) 116118 self.getPage("/static/index.html") 119 self.assertStatus('200 OK') 120 self.assertHeader('Content-Type', 'text/html') 121 self.assertBody('Hello, world\r\n') 122 123 # Using a staticdir.root value in a subdir... 124 self.getPage("/docroot/index.html") 125 self.assertStatus('200 OK') 126 self.assertHeader('Content-Type', 'text/html') 127 self.assertBody('Hello, world\r\n') 128 129 # Check a filename with spaces in it 130 self.getPage("/static/has%20space.html") 131 self.assertStatus('200 OK') 132 self.assertHeader('Content-Type', 'text/html') 133 self.assertBody('Hello, world\r\n') 134 135 self.getPage("/style.css") 136 self.assertStatus('200 OK') 137 self.assertHeader('Content-Type', 'text/css') 138 # Note: The body should be exactly 'Dummy stylesheet\n', but 139 # unfortunately some tools such as WinZip sometimes turn \n 140 # into \r\n on Windows when extracting the CherryPy tarball so 141 # we just check the content 142 self.assertMatchesBody('^Dummy stylesheet')143145 # Test that NotFound will then try dynamic handlers (see [878]). 146 self.getPage("/static/dynamic") 147 self.assertBody("This is a DYNAMIC page") 148 149 # Check a directory via fall-through to dynamic handler. 150 self.getPage("/static/") 151 self.assertStatus('200 OK') 152 self.assertHeader('Content-Type', 'text/html;charset=utf-8') 153 self.assertBody('You want the Baron? You can have the Baron!')154156 # Check a directory via "staticdir.index". 157 self.getPage("/docroot/") 158 self.assertStatus('200 OK') 159 self.assertHeader('Content-Type', 'text/html') 160 self.assertBody('Hello, world\r\n') 161 # The same page should be returned even if redirected. 162 self.getPage("/docroot") 163 self.assertStatus(301) 164 self.assertHeader('Location', '%s/docroot/' % self.base()) 165 self.assertMatchesBody("This resource .* <a href=(['\"])%s/docroot/\\1>" 166 "%s/docroot/</a>." % (self.base(), self.base()))167169 # Check that we get an error if no .file or .dir 170 self.getPage("/error/thing.html") 171 self.assertErrorPage(500) 172 if sys.version_info >= (3, 3): 173 errmsg = ntob("TypeError: staticdir\(\) missing 2 " 174 "required positional arguments") 175 else: 176 errmsg = ntob("TypeError: staticdir\(\) takes at least 2 " 177 "(positional )?arguments \(0 given\)") 178 self.assertMatchesBody(errmsg)179181 # Test up-level security 182 self.getPage("/static/../../test/style.css") 183 self.assertStatus((400, 403))184186 # Test modified-since on a reasonably-large file 187 self.getPage("/static/dirback.jpg") 188 self.assertStatus("200 OK") 189 lastmod = "" 190 for k, v in self.headers: 191 if k == 'Last-Modified': 192 lastmod = v 193 ims = ("If-Modified-Since", lastmod) 194 self.getPage("/static/dirback.jpg", headers=[ims]) 195 self.assertStatus(304) 196 self.assertNoHeader("Content-Type") 197 self.assertNoHeader("Content-Length") 198 self.assertNoHeader("Content-Disposition") 199 self.assertBody("")200202 self.getPage("/test/", [('Host', 'virt.net')]) 203 self.assertStatus(200) 204 self.getPage("/test", [('Host', 'virt.net')]) 205 self.assertStatus(301) 206 self.assertHeader('Location', self.scheme + '://virt.net/test/')207209 self.getPage("/fileobj") 210 self.assertStatus('200 OK') 211 self.assertHeader('Content-Type', 'text/css;charset=utf-8') 212 self.assertMatchesBody('^Dummy stylesheet')213215 self.getPage("/bytesio") 216 self.assertStatus('200 OK') 217 self.assertHeader('Content-Type', 'text/plain;charset=utf-8') 218 self.assertHeader('Content-Length', 14) 219 self.assertMatchesBody('Fee\nfie\nfo\nfum')220222 if cherrypy.server.protocol_version != "HTTP/1.1": 223 return self.skip() 224 225 self.PROTOCOL = "HTTP/1.1" 226 227 # Make an initial request 228 self.persistent = True 229 conn = self.HTTP_CONN 230 conn.putrequest("GET", "/bigfile", skip_host=True) 231 conn.putheader("Host", self.HOST) 232 conn.endheaders() 233 response = conn.response_class(conn.sock, method="GET") 234 response.begin() 235 self.assertEqual(response.status, 200) 236 237 body = ntob('') 238 remaining = BIGFILE_SIZE 239 while remaining > 0: 240 data = response.fp.read(65536) 241 if not data: 242 break 243 body += data 244 remaining -= len(data) 245 246 if self.scheme == "https": 247 newconn = HTTPSConnection 248 else: 249 newconn = HTTPConnection 250 s, h, b = helper.webtest.openURL( 251 ntob("/tell"), headers=[], host=self.HOST, port=self.PORT, 252 http_conn=newconn) 253 if not b: 254 # The file was closed on the server. 255 tell_position = BIGFILE_SIZE 256 else: 257 tell_position = int(b) 258 259 expected = len(body) 260 if tell_position >= BIGFILE_SIZE: 261 # We can't exactly control how much content the server asks 262 # for. 263 # Fudge it by only checking the first half of the reads. 264 if expected < (BIGFILE_SIZE / 2): 265 self.fail( 266 "The file should have advanced to position %r, but " 267 "has already advanced to the end of the file. It " 268 "may not be streamed as intended, or at the wrong " 269 "chunk size (64k)" % expected) 270 elif tell_position < expected: 271 self.fail( 272 "The file should have advanced to position %r, but has " 273 "only advanced to position %r. It may not be streamed " 274 "as intended, or at the wrong chunk size (65536)" % 275 (expected, tell_position)) 276 277 if body != ntob("x" * BIGFILE_SIZE): 278 self.fail("Body != 'x' * %d. Got %r instead (%d bytes)." % 279 (BIGFILE_SIZE, body[:50], len(body))) 280 conn.close()281283 if cherrypy.server.protocol_version != "HTTP/1.1": 284 return self.skip() 285 286 self.PROTOCOL = "HTTP/1.1" 287 288 # Make an initial request but abort early. 289 self.persistent = True 290 conn = self.HTTP_CONN 291 conn.putrequest("GET", "/bigfile", skip_host=True) 292 conn.putheader("Host", self.HOST) 293 conn.endheaders() 294 response = conn.response_class(conn.sock, method="GET") 295 response.begin() 296 self.assertEqual(response.status, 200) 297 body = response.fp.read(65536) 298 if body != ntob("x" * len(body)): 299 self.fail("Body != 'x' * %d. Got %r instead (%d bytes)." % 300 (65536, body[:50], len(body))) 301 response.close() 302 conn.close() 303 304 # Make a second request, which should fetch the whole file. 305 self.persistent = False 306 self.getPage("/bigfile") 307 if self.body != ntob("x" * BIGFILE_SIZE): 308 self.fail("Body != 'x' * %d. Got %r instead (%d bytes)." % 309 (BIGFILE_SIZE, self.body[:50], len(body)))310312 self.getPage("/404test/yunyeen") 313 self.assertStatus(404) 314 self.assertInBody("I couldn't find that thing")315317 import os.path 318 return static.serve_file(os.path.join(curdir, 'static', '404.html'), 319 content_type='text/html')320
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Fri Jun 20 20:23:44 2014 | http://epydoc.sourceforge.net |