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 os | 16 import os |
17 import posixpath | 17 import posixpath |
18 import re | 18 import re |
19 import shutil | 19 import shutil |
20 import string | |
20 import sys | 21 import sys |
21 | 22 |
22 # Imports from within Skia | 23 # Imports from within Skia |
23 # | 24 # |
24 # We need to add the 'tools' directory, so that we can import svn.py within | 25 # We need to add the 'tools' directory, so that we can import svn.py within |
25 # that directory. | 26 # that directory. |
26 # Make sure that the 'tools' dir is in the PYTHONPATH, but add it at the *end* | 27 # Make sure that the 'tools' dir is in the PYTHONPATH, but add it at the *end* |
27 # so any dirs that are already in the PYTHONPATH will be preferred. | 28 # so any dirs that are already in the PYTHONPATH will be preferred. |
28 PARENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) | 29 PARENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) |
29 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY)) | 30 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY)) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 | 121 |
121 | 122 |
122 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 123 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
123 """ HTTP request handlers for various types of queries this server knows | 124 """ HTTP request handlers for various types of queries this server knows |
124 how to handle (static HTML and Javascript, expected/actual results, etc.) | 125 how to handle (static HTML and Javascript, expected/actual results, etc.) |
125 """ | 126 """ |
126 def do_GET(self): | 127 def do_GET(self): |
127 """ Handles all GET requests, forwarding them to the appropriate | 128 """ Handles all GET requests, forwarding them to the appropriate |
128 do_GET_* dispatcher. """ | 129 do_GET_* dispatcher. """ |
129 if self.path == '' or self.path == '/' or self.path == '/index.html' : | 130 if self.path == '' or self.path == '/' or self.path == '/index.html' : |
130 self.redirect_to('/static/view.html') | 131 self.redirect_to('/static/view.html?resultsToLoad=all') |
131 return | 132 return |
132 if self.path == '/favicon.ico' : | 133 if self.path == '/favicon.ico' : |
133 self.redirect_to('/static/favicon.ico') | 134 self.redirect_to('/static/favicon.ico') |
134 return | 135 return |
135 | 136 |
136 # All requests must be of this form: | 137 # All requests must be of this form: |
137 # /dispatcher/remainder | 138 # /dispatcher/remainder |
138 # where 'dispatcher' indicates which do_GET_* dispatcher to run | 139 # where 'dispatcher' indicates which do_GET_* dispatcher to run |
139 # and 'remainder' is the remaining path sent to that dispatcher. | 140 # and 'remainder' is the remaining path sent to that dispatcher. |
140 normpath = posixpath.normpath(self.path) | 141 normpath = posixpath.normpath(self.path) |
141 (dispatcher_name, remainder) = PATHSPLIT_RE.match(normpath).groups() | 142 (dispatcher_name, remainder) = PATHSPLIT_RE.match(normpath).groups() |
142 dispatchers = { | 143 dispatchers = { |
143 'results': self.do_GET_results, | 144 'results': self.do_GET_results, |
144 'static': self.do_GET_static, | 145 'static': self.do_GET_static, |
145 } | 146 } |
146 dispatcher = dispatchers[dispatcher_name] | 147 dispatcher = dispatchers[dispatcher_name] |
147 dispatcher(remainder) | 148 dispatcher(remainder) |
148 | 149 |
149 def do_GET_results(self, result_type): | 150 def do_GET_results(self, type): |
150 """ Handle a GET request for GM results. | 151 """ Handle a GET request for GM results. |
151 For now, we ignore the remaining path info, because we only know how to | |
152 return all results. | |
153 | 152 |
154 Args: | 153 Args: |
155 result_type: currently unused | 154 type: string indicating which set of results to return; |
156 | 155 must be one of the results.RESULTS_* constants |
157 TODO(epoger): Unless we start making use of result_type, remove that | 156 """ |
158 parameter.""" | 157 print 'do_GET_results: sending results of type "%s"' % type |
jcgregorio
2013/10/10 19:59:11
Can we use the logging module instead of print?
epoger
2013/10/11 17:44:49
Done.
| |
159 print 'do_GET_results: sending results of type "%s"' % result_type | 158 try: |
160 # TODO(epoger): Cache response_dict rather than the results object, to save | 159 response_dict = _SERVER.results.get_results_of_type(type) |
161 # time on subsequent fetches (no need to regenerate the header, etc.) | |
162 response_dict = _SERVER.results.GetAll() | |
163 if response_dict: | |
164 response_dict['header'] = { | 160 response_dict['header'] = { |
165 # Hash of testData, which the client must return with any edits-- | 161 # Hash of testData, which the client must return with any edits-- |
166 # this ensures that the edits were made to a particular dataset. | 162 # this ensures that the edits were made to a particular dataset. |
167 'data-hash': str(hash(repr(response_dict['testData']))), | 163 'data-hash': str(hash(repr(response_dict['testData']))), |
168 | 164 |
169 # Whether the server will accept edits back. | 165 # Whether the server will accept edits back. |
170 # TODO(epoger): Not yet implemented, so hardcoding to False; | 166 # TODO(epoger): Not yet implemented, so hardcoding to False; |
171 # once we implement the 'browseonly' mode discussed in | 167 # once we implement the 'browseonly' mode discussed in |
172 # https://codereview.chromium.org/24274003/#msg6 , this value will vary. | 168 # https://codereview.chromium.org/24274003/#msg6 , this value will vary. |
173 'isEditable': False, | 169 'isEditable': False, |
174 | 170 |
175 # Whether the service is accessible from other hosts. | 171 # Whether the service is accessible from other hosts. |
176 'isExported': _SERVER.is_exported(), | 172 'isExported': _SERVER.is_exported(), |
177 } | 173 } |
178 self.send_json_dict(response_dict) | 174 self.send_json_dict(response_dict) |
179 else: | 175 except: |
180 self.send_error(404) | 176 self.send_error(404) |
181 | 177 |
182 def do_GET_static(self, path): | 178 def do_GET_static(self, path): |
183 """ Handle a GET request for a file under the 'static' directory. | 179 """ Handle a GET request for a file under the 'static' directory. |
184 Only allow serving of files within the 'static' directory that is a | 180 Only allow serving of files within the 'static' directory that is a |
185 filesystem sibling of this script. | 181 filesystem sibling of this script. |
186 | 182 |
187 Args: | 183 Args: |
188 path: path to file (under static directory) to retrieve | 184 path: path to file (under static directory) to retrieve |
189 """ | 185 """ |
186 i = string.find(path, '?') | |
jcgregorio
2013/10/10 19:59:11
path = urlparse.urlparse(path).path
epoger
2013/10/11 17:44:49
done.done
| |
187 if i >= 0: | |
188 path = path[:i] | |
190 print 'do_GET_static: sending file "%s"' % path | 189 print 'do_GET_static: sending file "%s"' % path |
191 static_dir = os.path.realpath(os.path.join(PARENT_DIRECTORY, 'static')) | 190 static_dir = os.path.realpath(os.path.join(PARENT_DIRECTORY, 'static')) |
192 full_path = os.path.realpath(os.path.join(static_dir, path)) | 191 full_path = os.path.realpath(os.path.join(static_dir, path)) |
193 if full_path.startswith(static_dir): | 192 if full_path.startswith(static_dir): |
194 self.send_file(full_path) | 193 self.send_file(full_path) |
195 else: | 194 else: |
196 print ('Attempted do_GET_static() of path [%s] outside of static dir [%s]' | 195 print ('Attempted do_GET_static() of path [%s] outside of static dir [%s]' |
197 % (full_path, static_dir)) | 196 % (full_path, static_dir)) |
198 self.send_error(404) | 197 self.send_error(404) |
199 | 198 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 'defaults to %(default)s'), | 266 'defaults to %(default)s'), |
268 default=DEFAULT_PORT) | 267 default=DEFAULT_PORT) |
269 args = parser.parse_args() | 268 args = parser.parse_args() |
270 global _SERVER | 269 global _SERVER |
271 _SERVER = Server(expectations_dir=args.expectations_dir, | 270 _SERVER = Server(expectations_dir=args.expectations_dir, |
272 port=args.port, export=args.export) | 271 port=args.port, export=args.export) |
273 _SERVER.run() | 272 _SERVER.run() |
274 | 273 |
275 if __name__ == '__main__': | 274 if __name__ == '__main__': |
276 main() | 275 main() |
OLD | NEW |