| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 Copyright 2013 Google Inc. | 4 Copyright 2013 Google Inc. |
| 5 | 5 |
| 6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
| 7 found in the LICENSE file. | 7 found in the LICENSE file. |
| 8 | 8 |
| 9 HTTP server for our HTML rebaseline viewer. | 9 HTTP server for our HTML rebaseline viewer. |
| 10 """ | 10 """ |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 self._url = 'http://%s:%d' % (host, http_server.server_port) | 253 self._url = 'http://%s:%d' % (host, http_server.server_port) |
| 254 logging.info('Listening for requests on %s' % self._url) | 254 logging.info('Listening for requests on %s' % self._url) |
| 255 http_server.serve_forever() | 255 http_server.serve_forever() |
| 256 | 256 |
| 257 | 257 |
| 258 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 258 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 259 """ HTTP request handlers for various types of queries this server knows | 259 """ HTTP request handlers for various types of queries this server knows |
| 260 how to handle (static HTML and Javascript, expected/actual results, etc.) | 260 how to handle (static HTML and Javascript, expected/actual results, etc.) |
| 261 """ | 261 """ |
| 262 def do_GET(self): | 262 def do_GET(self): |
| 263 """ Handles all GET requests, forwarding them to the appropriate | 263 """ |
| 264 do_GET_* dispatcher. """ | 264 Handles all GET requests, forwarding them to the appropriate |
| 265 if self.path == '' or self.path == '/' or self.path == '/index.html' : | 265 do_GET_* dispatcher. |
| 266 self.redirect_to('/static/index.html') | |
| 267 return | |
| 268 if self.path == '/favicon.ico' : | |
| 269 self.redirect_to('/static/favicon.ico') | |
| 270 return | |
| 271 | 266 |
| 272 # All requests must be of this form: | 267 If we see any Exceptions, return a 404. This fixes http://skbug.com/2147 |
| 273 # /dispatcher/remainder | 268 """ |
| 274 # where 'dispatcher' indicates which do_GET_* dispatcher to run | 269 try: |
| 275 # and 'remainder' is the remaining path sent to that dispatcher. | 270 logging.debug('do_GET: path="%s"' % self.path) |
| 276 normpath = posixpath.normpath(self.path) | 271 if self.path == '' or self.path == '/' or self.path == '/index.html' : |
| 277 (dispatcher_name, remainder) = PATHSPLIT_RE.match(normpath).groups() | 272 self.redirect_to('/static/index.html') |
| 278 dispatchers = { | 273 return |
| 279 'results': self.do_GET_results, | 274 if self.path == '/favicon.ico' : |
| 280 'static': self.do_GET_static, | 275 self.redirect_to('/static/favicon.ico') |
| 281 } | 276 return |
| 282 dispatcher = dispatchers[dispatcher_name] | 277 |
| 283 dispatcher(remainder) | 278 # All requests must be of this form: |
| 279 # /dispatcher/remainder |
| 280 # where 'dispatcher' indicates which do_GET_* dispatcher to run |
| 281 # and 'remainder' is the remaining path sent to that dispatcher. |
| 282 normpath = posixpath.normpath(self.path) |
| 283 (dispatcher_name, remainder) = PATHSPLIT_RE.match(normpath).groups() |
| 284 dispatchers = { |
| 285 'results': self.do_GET_results, |
| 286 'static': self.do_GET_static, |
| 287 } |
| 288 dispatcher = dispatchers[dispatcher_name] |
| 289 dispatcher(remainder) |
| 290 except: |
| 291 self.send_error(404) |
| 292 raise |
| 284 | 293 |
| 285 def do_GET_results(self, type): | 294 def do_GET_results(self, type): |
| 286 """ Handle a GET request for GM results. | 295 """ Handle a GET request for GM results. |
| 287 | 296 |
| 288 Args: | 297 Args: |
| 289 type: string indicating which set of results to return; | 298 type: string indicating which set of results to return; |
| 290 must be one of the results.RESULTS_* constants | 299 must be one of the results.RESULTS_* constants |
| 291 """ | 300 """ |
| 292 logging.debug('do_GET_results: sending results of type "%s"' % type) | 301 logging.debug('do_GET_results: sending results of type "%s"' % type) |
| 293 try: | 302 # Since we must make multiple calls to the Results object, grab a |
| 294 # Since we must make multiple calls to the Results object, grab a | 303 # reference to it in case it is updated to point at a new Results |
| 295 # reference to it in case it is updated to point at a new Results | 304 # object within another thread. |
| 296 # object within another thread. | 305 # |
| 297 # | 306 # TODO(epoger): Rather than using a global variable for the handler |
| 298 # TODO(epoger): Rather than using a global variable for the handler | 307 # to refer to the Server object, make Server a subclass of |
| 299 # to refer to the Server object, make Server a subclass of | 308 # HTTPServer, and then it could be available to the handler via |
| 300 # HTTPServer, and then it could be available to the handler via | 309 # the handler's .server instance variable. |
| 301 # the handler's .server instance variable. | 310 results_obj = _SERVER.results |
| 302 results_obj = _SERVER.results | 311 if results_obj: |
| 303 if results_obj: | 312 response_dict = self.package_results(results_obj, type) |
| 304 response_dict = self.package_results(results_obj, type) | 313 else: |
| 305 else: | 314 now = int(time.time()) |
| 306 now = int(time.time()) | 315 response_dict = { |
| 307 response_dict = { | 316 'header': { |
| 308 'header': { | 317 'resultsStillLoading': True, |
| 309 'resultsStillLoading': True, | 318 'timeUpdated': now, |
| 310 'timeUpdated': now, | 319 'timeNextUpdateAvailable': now + RELOAD_INTERVAL_UNTIL_READY, |
| 311 'timeNextUpdateAvailable': now + RELOAD_INTERVAL_UNTIL_READY, | 320 }, |
| 312 }, | 321 } |
| 313 } | 322 self.send_json_dict(response_dict) |
| 314 self.send_json_dict(response_dict) | |
| 315 except: | |
| 316 self.send_error(404) | |
| 317 raise | |
| 318 | 323 |
| 319 def package_results(self, results_obj, type): | 324 def package_results(self, results_obj, type): |
| 320 """ Given a nonempty "results" object, package it as a response_dict | 325 """ Given a nonempty "results" object, package it as a response_dict |
| 321 as needed within do_GET_results. | 326 as needed within do_GET_results. |
| 322 | 327 |
| 323 Args: | 328 Args: |
| 324 results_obj: nonempty "results" object | 329 results_obj: nonempty "results" object |
| 325 type: string indicating which set of results to return; | 330 type: string indicating which set of results to return; |
| 326 must be one of the results.RESULTS_* constants | 331 must be one of the results.RESULTS_* constants |
| 327 """ | 332 """ |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 'Attempted do_GET_static() of path [%s] outside of static dir [%s]' | 381 'Attempted do_GET_static() of path [%s] outside of static dir [%s]' |
| 377 % (full_path, static_dir)) | 382 % (full_path, static_dir)) |
| 378 self.send_error(404) | 383 self.send_error(404) |
| 379 | 384 |
| 380 def do_POST(self): | 385 def do_POST(self): |
| 381 """ Handles all POST requests, forwarding them to the appropriate | 386 """ Handles all POST requests, forwarding them to the appropriate |
| 382 do_POST_* dispatcher. """ | 387 do_POST_* dispatcher. """ |
| 383 # All requests must be of this form: | 388 # All requests must be of this form: |
| 384 # /dispatcher | 389 # /dispatcher |
| 385 # where 'dispatcher' indicates which do_POST_* dispatcher to run. | 390 # where 'dispatcher' indicates which do_POST_* dispatcher to run. |
| 391 logging.debug('do_POST: path="%s"' % self.path) |
| 386 normpath = posixpath.normpath(self.path) | 392 normpath = posixpath.normpath(self.path) |
| 387 dispatchers = { | 393 dispatchers = { |
| 388 '/edits': self.do_POST_edits, | 394 '/edits': self.do_POST_edits, |
| 389 } | 395 } |
| 390 try: | 396 try: |
| 391 dispatcher = dispatchers[normpath] | 397 dispatcher = dispatchers[normpath] |
| 392 dispatcher() | 398 dispatcher() |
| 393 self.send_response(200) | 399 self.send_response(200) |
| 394 except: | 400 except: |
| 395 self.send_error(404) | 401 self.send_error(404) |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 args = parser.parse_args() | 541 args = parser.parse_args() |
| 536 global _SERVER | 542 global _SERVER |
| 537 _SERVER = Server(actuals_dir=args.actuals_dir, | 543 _SERVER = Server(actuals_dir=args.actuals_dir, |
| 538 port=args.port, export=args.export, editable=args.editable, | 544 port=args.port, export=args.export, editable=args.editable, |
| 539 reload_seconds=args.reload) | 545 reload_seconds=args.reload) |
| 540 _SERVER.run() | 546 _SERVER.run() |
| 541 | 547 |
| 542 | 548 |
| 543 if __name__ == '__main__': | 549 if __name__ == '__main__': |
| 544 main() | 550 main() |
| OLD | NEW |