Chromium Code Reviews| 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 """ |
| 11 | 11 |
| 12 # System-level imports | 12 # System-level imports |
| 13 import argparse | 13 import argparse |
| 14 import BaseHTTPServer | 14 import BaseHTTPServer |
| 15 import json | 15 import json |
| 16 import logging | 16 import logging |
| 17 import os | 17 import os |
| 18 import posixpath | 18 import posixpath |
| 19 import re | 19 import re |
| 20 import shutil | 20 import shutil |
| 21 import socket | |
| 21 import sys | 22 import sys |
| 22 import thread | 23 import thread |
| 23 import time | 24 import time |
| 24 import urlparse | 25 import urlparse |
| 25 | 26 |
| 26 # Imports from within Skia | 27 # Imports from within Skia |
| 27 # | 28 # |
| 28 # We need to add the 'tools' directory, so that we can import svn.py within | 29 # We need to add the 'tools' directory, so that we can import svn.py within |
| 29 # that directory. | 30 # that directory. |
| 30 # Make sure that the 'tools' dir is in the PYTHONPATH, but add it at the *end* | 31 # Make sure that the 'tools' dir is in the PYTHONPATH, but add it at the *end* |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 58 | 59 |
| 59 DEFAULT_ACTUALS_DIR = '.gm-actuals' | 60 DEFAULT_ACTUALS_DIR = '.gm-actuals' |
| 60 DEFAULT_EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm') | 61 DEFAULT_EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm') |
| 61 DEFAULT_PORT = 8888 | 62 DEFAULT_PORT = 8888 |
| 62 | 63 |
| 63 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' | 64 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' |
| 64 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' | 65 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' |
| 65 | 66 |
| 66 _SERVER = None # This gets filled in by main() | 67 _SERVER = None # This gets filled in by main() |
| 67 | 68 |
| 69 def get_routable_ip_address(): | |
| 70 """Returns routable IP address of this host (the IP address of its network | |
| 71 interface that would be used for most traffic, not its localhost | |
| 72 interface).""" | |
| 73 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
| 74 sock.connect(('8.8.8.8', 80)) | |
|
jcgregorio
2013/10/29 20:30:49
Should sock be closed()?
epoger
2013/10/29 20:35:04
Done.
| |
| 75 return sock.getsockname()[0] | |
| 76 | |
| 77 | |
| 68 class Server(object): | 78 class Server(object): |
| 69 """ HTTP server for our HTML rebaseline viewer. """ | 79 """ HTTP server for our HTML rebaseline viewer. """ |
| 70 | 80 |
| 71 def __init__(self, | 81 def __init__(self, |
| 72 actuals_dir=DEFAULT_ACTUALS_DIR, | 82 actuals_dir=DEFAULT_ACTUALS_DIR, |
| 73 expectations_dir=DEFAULT_EXPECTATIONS_DIR, | 83 expectations_dir=DEFAULT_EXPECTATIONS_DIR, |
| 74 port=DEFAULT_PORT, export=False, editable=True, | 84 port=DEFAULT_PORT, export=False, editable=True, |
| 75 reload_seconds=0): | 85 reload_seconds=0): |
| 76 """ | 86 """ |
| 77 Args: | 87 Args: |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 time.sleep(self._reload_seconds) | 167 time.sleep(self._reload_seconds) |
| 158 self.update_results() | 168 self.update_results() |
| 159 | 169 |
| 160 def run(self): | 170 def run(self): |
| 161 self.results_lock = thread.allocate_lock() | 171 self.results_lock = thread.allocate_lock() |
| 162 self.update_results() | 172 self.update_results() |
| 163 thread.start_new_thread(self._result_reloader, ()) | 173 thread.start_new_thread(self._result_reloader, ()) |
| 164 | 174 |
| 165 if self._export: | 175 if self._export: |
| 166 server_address = ('', self._port) | 176 server_address = ('', self._port) |
| 177 host = get_routable_ip_address() | |
| 167 if self._editable: | 178 if self._editable: |
| 168 logging.warning('Running with combination of "export" and "editable" ' | 179 logging.warning('Running with combination of "export" and "editable" ' |
| 169 'flags. Users on other machines will ' | 180 'flags. Users on other machines will ' |
| 170 'be able to modify your GM expectations!') | 181 'be able to modify your GM expectations!') |
| 171 else: | 182 else: |
| 172 server_address = ('127.0.0.1', self._port) | 183 host = '127.0.0.1' |
| 184 server_address = (host, self._port) | |
| 173 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) | 185 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) |
| 174 logging.info('Ready for requests on http://%s:%d' % ( | 186 logging.info('Ready for requests on http://%s:%d' % (host, http_server.serve r_port)) |
|
epoger
2013/10/29 20:25:28
As of patchset 2, it seems to work OK.
Before thi
| |
| 175 http_server.server_name, http_server.server_port)) | |
| 176 http_server.serve_forever() | 187 http_server.serve_forever() |
| 177 | 188 |
| 178 | 189 |
| 179 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 190 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 180 """ HTTP request handlers for various types of queries this server knows | 191 """ HTTP request handlers for various types of queries this server knows |
| 181 how to handle (static HTML and Javascript, expected/actual results, etc.) | 192 how to handle (static HTML and Javascript, expected/actual results, etc.) |
| 182 """ | 193 """ |
| 183 def do_GET(self): | 194 def do_GET(self): |
| 184 """ Handles all GET requests, forwarding them to the appropriate | 195 """ Handles all GET requests, forwarding them to the appropriate |
| 185 do_GET_* dispatcher. """ | 196 do_GET_* dispatcher. """ |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 args = parser.parse_args() | 436 args = parser.parse_args() |
| 426 global _SERVER | 437 global _SERVER |
| 427 _SERVER = Server(actuals_dir=args.actuals_dir, | 438 _SERVER = Server(actuals_dir=args.actuals_dir, |
| 428 expectations_dir=args.expectations_dir, | 439 expectations_dir=args.expectations_dir, |
| 429 port=args.port, export=args.export, editable=args.editable, | 440 port=args.port, export=args.export, editable=args.editable, |
| 430 reload_seconds=args.reload) | 441 reload_seconds=args.reload) |
| 431 _SERVER.run() | 442 _SERVER.run() |
| 432 | 443 |
| 433 if __name__ == '__main__': | 444 if __name__ == '__main__': |
| 434 main() | 445 main() |
| OLD | NEW |