OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Constrained Network Server. Serves files with supplied network constraints. | 6 """Constrained Network Server. Serves files with supplied network constraints. |
7 | 7 |
8 The CNS exposes a web based API allowing network constraints to be imposed on | 8 The CNS exposes a web based API allowing network constraints to be imposed on |
9 file serving. | 9 file serving. |
10 | 10 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 194 |
195 Args: | 195 Args: |
196 f: path relative to http root of file to serve. | 196 f: path relative to http root of file to serve. |
197 bandwidth: maximum allowed bandwidth for the provided port (integer | 197 bandwidth: maximum allowed bandwidth for the provided port (integer |
198 in kbit/s). | 198 in kbit/s). |
199 latency: time to add to each packet (integer in ms). | 199 latency: time to add to each packet (integer in ms). |
200 loss: percentage of packets to drop (integer, 0-100). | 200 loss: percentage of packets to drop (integer, 0-100). |
201 new_port: whether to use a new port for this request or not. | 201 new_port: whether to use a new port for this request or not. |
202 no_cache: Set reponse's cache-control to no-cache. | 202 no_cache: Set reponse's cache-control to no-cache. |
203 """ | 203 """ |
204 cherrypy.log('Got request string: %s' % cherrypy.request.request_line) | |
205 | |
206 if no_cache: | 204 if no_cache: |
207 response = cherrypy.response | 205 response = cherrypy.response |
208 response.headers['Pragma'] = 'no-cache' | 206 response.headers['Pragma'] = 'no-cache' |
209 response.headers['Cache-Control'] = 'no-cache' | 207 response.headers['Cache-Control'] = 'no-cache' |
210 | 208 |
211 # CherryPy is a bit wonky at detecting parameters, so just make them all | 209 # CherryPy is a bit wonky at detecting parameters, so just make them all |
212 # optional and validate them ourselves. | 210 # optional and validate them ourselves. |
213 if not f: | 211 if not f: |
214 raise cherrypy.HTTPError(400, 'Invalid request. File must be specified.') | 212 raise cherrypy.HTTPError(400, 'Invalid request. File must be specified.') |
215 | 213 |
(...skipping 20 matching lines...) Expand all Loading... |
236 | 234 |
237 # Allocate a port using the given constraints. If a port with the requested | 235 # Allocate a port using the given constraints. If a port with the requested |
238 # key is already allocated, it will be reused. | 236 # key is already allocated, it will be reused. |
239 # | 237 # |
240 # TODO(dalecurtis): The key cherrypy.request.remote.ip might not be unique | 238 # TODO(dalecurtis): The key cherrypy.request.remote.ip might not be unique |
241 # if build slaves are sharing the same VM. | 239 # if build slaves are sharing the same VM. |
242 start_time = time.time() | 240 start_time = time.time() |
243 constrained_port = self._port_allocator.Get( | 241 constrained_port = self._port_allocator.Get( |
244 cherrypy.request.remote.ip, server_port=self._options.port, | 242 cherrypy.request.remote.ip, server_port=self._options.port, |
245 interface=self._options.interface, bandwidth=bandwidth, latency=latency, | 243 interface=self._options.interface, bandwidth=bandwidth, latency=latency, |
246 loss=loss, new_port=new_port) | 244 loss=loss, new_port=new_port, file=f, **kwargs) |
247 end_time = time.time() | 245 end_time = time.time() |
248 | 246 |
249 if not constrained_port: | 247 if not constrained_port: |
250 raise cherrypy.HTTPError(503, 'Service unavailable. Out of ports.') | 248 raise cherrypy.HTTPError(503, 'Service unavailable. Out of ports.') |
251 | 249 |
252 cherrypy.log('Time to set up port %d = %ssec.' % | 250 cherrypy.log('Time to set up port %d = %ssec.' % |
253 (constrained_port, end_time - start_time)) | 251 (constrained_port, end_time - start_time)) |
254 | 252 |
255 # Build constrained URL using the constrained port and original URL | 253 # Build constrained URL using the constrained port and original URL |
256 # parameters except the network constraints (bandwidth, latency, and loss). | 254 # parameters except the network constraints (bandwidth, latency, and loss). |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 324 |
327 if options.expiry_time < 0: | 325 if options.expiry_time < 0: |
328 parser.error('Invalid expiry time specified.') | 326 parser.error('Invalid expiry time specified.') |
329 | 327 |
330 # Convert the path to an absolute to remove any . or .. | 328 # Convert the path to an absolute to remove any . or .. |
331 options.www_root = os.path.abspath(options.www_root) | 329 options.www_root = os.path.abspath(options.www_root) |
332 | 330 |
333 # Required so that cherrypy logs do not get propagated to root logger causing | 331 # Required so that cherrypy logs do not get propagated to root logger causing |
334 # the logs to be printed twice. | 332 # the logs to be printed twice. |
335 cherrypy.log.error_log.propagate = False | 333 cherrypy.log.error_log.propagate = False |
| 334 cherrypy.log.access_log.propagate = False |
336 | 335 |
337 _SetLogger(options.verbose) | 336 _SetLogger(options.verbose) |
338 | 337 |
339 return options | 338 return options |
340 | 339 |
341 | 340 |
342 def _SetLogger(verbose): | 341 def _SetLogger(verbose): |
343 # Logging is used for traffic_control debug statements. | 342 # Logging is used for traffic_control debug statements. |
344 log_level = _DEFAULT_LOG_LEVEL | 343 log_level = _DEFAULT_LOG_LEVEL |
345 if verbose: | 344 if verbose: |
(...skipping 24 matching lines...) Expand all Loading... |
370 try: | 369 try: |
371 cherrypy.quickstart(ConstrainedNetworkServer(options, pa)) | 370 cherrypy.quickstart(ConstrainedNetworkServer(options, pa)) |
372 finally: | 371 finally: |
373 # Disable Ctrl-C handler to prevent interruption of cleanup. | 372 # Disable Ctrl-C handler to prevent interruption of cleanup. |
374 signal.signal(signal.SIGINT, lambda signal, frame: None) | 373 signal.signal(signal.SIGINT, lambda signal, frame: None) |
375 pa.Cleanup(options.interface, all_ports=True) | 374 pa.Cleanup(options.interface, all_ports=True) |
376 | 375 |
377 | 376 |
378 if __name__ == '__main__': | 377 if __name__ == '__main__': |
379 Main() | 378 Main() |
OLD | NEW |