OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2013 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 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 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for | 6 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for |
7 testing Chrome. | 7 testing Chrome. |
8 | 8 |
9 It supports several test URLs, as specified by the handlers in TestPageHandler. | 9 It supports several test URLs, as specified by the handlers in TestPageHandler. |
10 By default, it listens on an ephemeral port and sends the port number back to | 10 By default, it listens on an ephemeral port and sends the port number back to |
(...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 def DataForRange(start, end): | 1471 def DataForRange(start, end): |
1472 """Data to be provided for a particular range of bytes.""" | 1472 """Data to be provided for a particular range of bytes.""" |
1473 # Offset and scale to avoid too obvious (and hence potentially | 1473 # Offset and scale to avoid too obvious (and hence potentially |
1474 # collidable) data. | 1474 # collidable) data. |
1475 return ''.join([chr(y % 256) | 1475 return ''.join([chr(y % 256) |
1476 for y in range(start * 2 + 15, end * 2 + 15, 2)]) | 1476 for y in range(start * 2 + 15, end * 2 + 15, 2)]) |
1477 | 1477 |
1478 if not self._ShouldHandleRequest('/rangereset'): | 1478 if not self._ShouldHandleRequest('/rangereset'): |
1479 return False | 1479 return False |
1480 | 1480 |
| 1481 # HTTP/1.1 is required for ETag and range support. |
| 1482 self.protocol_version = 'HTTP/1.1' |
1481 _, _, url_path, _, query, _ = urlparse.urlparse(self.path) | 1483 _, _, url_path, _, query, _ = urlparse.urlparse(self.path) |
1482 | 1484 |
1483 # Defaults | 1485 # Defaults |
1484 size = 8000 | 1486 size = 8000 |
1485 # Note that the rst is sent just before sending the rst_boundary byte. | 1487 # Note that the rst is sent just before sending the rst_boundary byte. |
1486 rst_boundary = 4000 | 1488 rst_boundary = 4000 |
1487 respond_to_range = True | 1489 respond_to_range = True |
1488 hold_for_signal = False | 1490 hold_for_signal = False |
1489 rst_limit = -1 | 1491 rst_limit = -1 |
1490 token = 'DEFAULT' | 1492 token = 'DEFAULT' |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 | 1553 |
1552 if range_response: | 1554 if range_response: |
1553 self.send_response(206) | 1555 self.send_response(206) |
1554 self.send_header('Content-Range', | 1556 self.send_header('Content-Range', |
1555 'bytes %d-%d/%d' % (first_byte, last_byte, size)) | 1557 'bytes %d-%d/%d' % (first_byte, last_byte, size)) |
1556 else: | 1558 else: |
1557 self.send_response(200) | 1559 self.send_response(200) |
1558 self.send_header('Content-Type', 'application/octet-stream') | 1560 self.send_header('Content-Type', 'application/octet-stream') |
1559 self.send_header('Content-Length', last_byte - first_byte + 1) | 1561 self.send_header('Content-Length', last_byte - first_byte + 1) |
1560 if send_verifiers: | 1562 if send_verifiers: |
1561 self.send_header('Etag', '"XYZZY"') | 1563 # If fail_precondition is non-zero, then the ETag for each request will be |
| 1564 # different. |
| 1565 etag = "%s%d" % (token, fail_precondition) |
| 1566 self.send_header('ETag', etag) |
1562 self.send_header('Last-Modified', 'Tue, 19 Feb 2013 14:32 EST') | 1567 self.send_header('Last-Modified', 'Tue, 19 Feb 2013 14:32 EST') |
1563 self.end_headers() | 1568 self.end_headers() |
1564 | 1569 |
1565 if hold_for_signal: | 1570 if hold_for_signal: |
1566 # TODO(rdsmith/phajdan.jr): http://crbug.com/169519: Without writing | 1571 # TODO(rdsmith/phajdan.jr): http://crbug.com/169519: Without writing |
1567 # a single byte, the self.server.handle_request() below hangs | 1572 # a single byte, the self.server.handle_request() below hangs |
1568 # without processing new incoming requests. | 1573 # without processing new incoming requests. |
1569 self.wfile.write(DataForRange(first_byte, first_byte + 1)) | 1574 self.wfile.write(DataForRange(first_byte, first_byte + 1)) |
1570 first_byte = first_byte + 1 | 1575 first_byte = first_byte + 1 |
1571 # handle requests until one of them clears this flag. | 1576 # handle requests until one of them clears this flag. |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2095 '"aes128", "3des", "rc4". If omitted, all ' | 2100 '"aes128", "3des", "rc4". If omitted, all ' |
2096 'algorithms will be used. This option may ' | 2101 'algorithms will be used. This option may ' |
2097 'appear multiple times, indicating ' | 2102 'appear multiple times, indicating ' |
2098 'multiple algorithms should be enabled.'); | 2103 'multiple algorithms should be enabled.'); |
2099 self.option_parser.add_option('--file-root-url', default='/files/', | 2104 self.option_parser.add_option('--file-root-url', default='/files/', |
2100 help='Specify a root URL for files served.') | 2105 help='Specify a root URL for files served.') |
2101 | 2106 |
2102 | 2107 |
2103 if __name__ == '__main__': | 2108 if __name__ == '__main__': |
2104 sys.exit(ServerRunner().main()) | 2109 sys.exit(ServerRunner().main()) |
OLD | NEW |