OLD | NEW |
---|---|
1 #!/usr/bin/python2.4 | 1 #!/usr/bin/python2.4 |
2 # Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2010 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 server used for testing Chrome. | 6 """This is a simple HTTP server used for testing Chrome. |
7 | 7 |
8 It supports several test URLs, as specified by the handlers in TestPageHandler. | 8 It supports several test URLs, as specified by the handlers in TestPageHandler. |
9 By default, it listens on an ephemeral port and sends the port number back to | 9 By default, it listens on an ephemeral port and sends the port number back to |
10 the originating process over a pipe. The originating process can specify an | 10 the originating process over a pipe. The originating process can specify an |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 # request is subject to value of the request header being echoed. | 586 # request is subject to value of the request header being echoed. |
587 if len(header_name) > 0: | 587 if len(header_name) > 0: |
588 self.send_header('Vary', header_name) | 588 self.send_header('Vary', header_name) |
589 self.end_headers() | 589 self.end_headers() |
590 | 590 |
591 if len(header_name) > 0: | 591 if len(header_name) > 0: |
592 self.wfile.write(self.headers.getheader(header_name)) | 592 self.wfile.write(self.headers.getheader(header_name)) |
593 | 593 |
594 return True | 594 return True |
595 | 595 |
596 def ReadRequestBody(self): | |
597 """This function reads the body of the current HTTP request, handling""" | |
598 """both plain and chunked transfer encoded requests.""" | |
wtc
2011/01/21 19:35:54
Your multi-line comment format seems non-ideal. P
Satish
2011/01/21 20:29:57
Sure :) I saw lines 558-560 which were in this for
| |
599 if self.headers.getheader('transfer-encoding') != 'chunked': | |
600 length = int(self.headers.getheader('content-length')) | |
601 return self.rfile.read(length) | |
602 | |
603 # Read the response body as chunks. | |
wtc
2011/01/21 19:35:54
Typo: response body => request body
| |
604 body = "" | |
605 while True: | |
606 line = self.rfile.readline() | |
607 if line == "0\r\n": | |
608 self.rfile.readline() | |
609 break | |
wtc
2011/01/21 19:35:54
Nit: you can check for "0\r\n" below, after line 6
| |
610 length = int(line, 16) | |
wtc
2011/01/21 19:35:54
What does the argument "16" mean?
Satish
2011/01/21 20:29:57
The second argument is the base and we pass 16 sin
| |
611 body += self.rfile.read(length) | |
612 self.rfile.read(2) | |
613 return body | |
614 | |
596 def EchoHandler(self): | 615 def EchoHandler(self): |
597 """This handler just echoes back the payload of the request, for testing | 616 """This handler just echoes back the payload of the request, for testing |
598 form submission.""" | 617 form submission.""" |
599 | 618 |
600 if not self._ShouldHandleRequest("/echo"): | 619 if not self._ShouldHandleRequest("/echo"): |
601 return False | 620 return False |
602 | 621 |
603 self.send_response(200) | 622 self.send_response(200) |
604 self.send_header('Content-type', 'text/html') | 623 self.send_header('Content-type', 'text/html') |
605 self.end_headers() | 624 self.end_headers() |
606 length = int(self.headers.getheader('content-length')) | 625 self.wfile.write(self.ReadRequestBody()) |
607 request = self.rfile.read(length) | |
608 self.wfile.write(request) | |
609 return True | 626 return True |
610 | 627 |
611 def EchoTitleHandler(self): | 628 def EchoTitleHandler(self): |
612 """This handler is like Echo, but sets the page title to the request.""" | 629 """This handler is like Echo, but sets the page title to the request.""" |
613 | 630 |
614 if not self._ShouldHandleRequest("/echotitle"): | 631 if not self._ShouldHandleRequest("/echotitle"): |
615 return False | 632 return False |
616 | 633 |
617 self.send_response(200) | 634 self.send_response(200) |
618 self.send_header('Content-type', 'text/html') | 635 self.send_header('Content-type', 'text/html') |
619 self.end_headers() | 636 self.end_headers() |
620 length = int(self.headers.getheader('content-length')) | 637 request = self.ReadRequestBody() |
621 request = self.rfile.read(length) | |
622 self.wfile.write('<html><head><title>') | 638 self.wfile.write('<html><head><title>') |
623 self.wfile.write(request) | 639 self.wfile.write(request) |
624 self.wfile.write('</title></head></html>') | 640 self.wfile.write('</title></head></html>') |
625 return True | 641 return True |
626 | 642 |
627 def EchoAllHandler(self): | 643 def EchoAllHandler(self): |
628 """This handler yields a (more) human-readable page listing information | 644 """This handler yields a (more) human-readable page listing information |
629 about the request header & contents.""" | 645 about the request header & contents.""" |
630 | 646 |
631 if not self._ShouldHandleRequest("/echoall"): | 647 if not self._ShouldHandleRequest("/echoall"): |
632 return False | 648 return False |
633 | 649 |
634 self.send_response(200) | 650 self.send_response(200) |
635 self.send_header('Content-type', 'text/html') | 651 self.send_header('Content-type', 'text/html') |
636 self.end_headers() | 652 self.end_headers() |
637 self.wfile.write('<html><head><style>' | 653 self.wfile.write('<html><head><style>' |
638 'pre { border: 1px solid black; margin: 5px; padding: 5px }' | 654 'pre { border: 1px solid black; margin: 5px; padding: 5px }' |
639 '</style></head><body>' | 655 '</style></head><body>' |
640 '<div style="float: right">' | 656 '<div style="float: right">' |
641 '<a href="/echo">back to referring page</a></div>' | 657 '<a href="/echo">back to referring page</a></div>' |
642 '<h1>Request Body:</h1><pre>') | 658 '<h1>Request Body:</h1><pre>') |
643 | 659 |
644 if self.command == 'POST' or self.command == 'PUT': | 660 if self.command == 'POST' or self.command == 'PUT': |
645 length = int(self.headers.getheader('content-length')) | 661 qs = self.ReadRequestBody() |
646 qs = self.rfile.read(length) | |
647 params = cgi.parse_qs(qs, keep_blank_values=1) | 662 params = cgi.parse_qs(qs, keep_blank_values=1) |
648 | 663 |
649 for param in params: | 664 for param in params: |
650 self.wfile.write('%s=%s\n' % (param, params[param][0])) | 665 self.wfile.write('%s=%s\n' % (param, params[param][0])) |
651 | 666 |
652 self.wfile.write('</pre>') | 667 self.wfile.write('</pre>') |
653 | 668 |
654 self.wfile.write('<h1>Request Headers:</h1><pre>%s</pre>' % self.headers) | 669 self.wfile.write('<h1>Request Headers:</h1><pre>%s</pre>' % self.headers) |
655 | 670 |
656 self.wfile.write('</body></html>') | 671 self.wfile.write('</body></html>') |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
738 def FileHandler(self): | 753 def FileHandler(self): |
739 """This handler sends the contents of the requested file. Wow, it's like | 754 """This handler sends the contents of the requested file. Wow, it's like |
740 a real webserver!""" | 755 a real webserver!""" |
741 | 756 |
742 prefix = self.server.file_root_url | 757 prefix = self.server.file_root_url |
743 if not self.path.startswith(prefix): | 758 if not self.path.startswith(prefix): |
744 return False | 759 return False |
745 | 760 |
746 # Consume a request body if present. | 761 # Consume a request body if present. |
747 if self.command == 'POST' or self.command == 'PUT' : | 762 if self.command == 'POST' or self.command == 'PUT' : |
748 self.rfile.read(int(self.headers.getheader('content-length'))) | 763 self.ReadRequestBody() |
749 | 764 |
750 _, _, url_path, _, query, _ = urlparse.urlparse(self.path) | 765 _, _, url_path, _, query, _ = urlparse.urlparse(self.path) |
751 sub_path = url_path[len(prefix):] | 766 sub_path = url_path[len(prefix):] |
752 entries = sub_path.split('/') | 767 entries = sub_path.split('/') |
753 file_path = os.path.join(self.server.data_dir, *entries) | 768 file_path = os.path.join(self.server.data_dir, *entries) |
754 if os.path.isdir(file_path): | 769 if os.path.isdir(file_path): |
755 file_path = os.path.join(file_path, 'index.html') | 770 file_path = os.path.join(file_path, 'index.html') |
756 | 771 |
757 if not os.path.isfile(file_path): | 772 if not os.path.isfile(file_path): |
758 print "File not found " + sub_path + " full path:" + file_path | 773 print "File not found " + sub_path + " full path:" + file_path |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1255 self.send_header("Content-Length", len(contents)) | 1270 self.send_header("Content-Length", len(contents)) |
1256 self.end_headers() | 1271 self.end_headers() |
1257 self.wfile.write(contents) | 1272 self.wfile.write(contents) |
1258 return True | 1273 return True |
1259 | 1274 |
1260 def DeviceManagementHandler(self): | 1275 def DeviceManagementHandler(self): |
1261 """Delegates to the device management service used for cloud policy.""" | 1276 """Delegates to the device management service used for cloud policy.""" |
1262 if not self._ShouldHandleRequest("/device_management"): | 1277 if not self._ShouldHandleRequest("/device_management"): |
1263 return False | 1278 return False |
1264 | 1279 |
1265 length = int(self.headers.getheader('content-length')) | 1280 raw_request = self.ReadRequestBody() |
1266 raw_request = self.rfile.read(length) | |
1267 | 1281 |
1268 if not self.server._device_management_handler: | 1282 if not self.server._device_management_handler: |
1269 import device_management | 1283 import device_management |
1270 policy_path = os.path.join(self.server.data_dir, 'device_management') | 1284 policy_path = os.path.join(self.server.data_dir, 'device_management') |
1271 self.server._device_management_handler = ( | 1285 self.server._device_management_handler = ( |
1272 device_management.TestServer(policy_path)) | 1286 device_management.TestServer(policy_path)) |
1273 | 1287 |
1274 http_response, raw_reply = ( | 1288 http_response, raw_reply = ( |
1275 self.server._device_management_handler.HandleRequest(self.path, | 1289 self.server._device_management_handler.HandleRequest(self.path, |
1276 self.headers, | 1290 self.headers, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1317 def ChromiumSyncCommandHandler(self): | 1331 def ChromiumSyncCommandHandler(self): |
1318 """Handle a chromiumsync command arriving via http. | 1332 """Handle a chromiumsync command arriving via http. |
1319 | 1333 |
1320 This covers all sync protocol commands: authentication, getupdates, and | 1334 This covers all sync protocol commands: authentication, getupdates, and |
1321 commit. | 1335 commit. |
1322 """ | 1336 """ |
1323 test_name = "/chromiumsync/command" | 1337 test_name = "/chromiumsync/command" |
1324 if not self._ShouldHandleRequest(test_name): | 1338 if not self._ShouldHandleRequest(test_name): |
1325 return False | 1339 return False |
1326 | 1340 |
1327 length = int(self.headers.getheader('content-length')) | 1341 raw_request = self.ReadRequestBody() |
1328 raw_request = self.rfile.read(length) | |
1329 | 1342 |
1330 http_response, raw_reply = self.server.HandleCommand( | 1343 http_response, raw_reply = self.server.HandleCommand( |
1331 self.path, raw_request) | 1344 self.path, raw_request) |
1332 self.send_response(http_response) | 1345 self.send_response(http_response) |
1333 self.end_headers() | 1346 self.end_headers() |
1334 self.wfile.write(raw_reply) | 1347 self.wfile.write(raw_reply) |
1335 return True | 1348 return True |
1336 | 1349 |
1337 | 1350 |
1338 def MakeDataDir(): | 1351 def MakeDataDir(): |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1498 'option may appear multiple times, indicating ' | 1511 'option may appear multiple times, indicating ' |
1499 'multiple algorithms should be enabled.'); | 1512 'multiple algorithms should be enabled.'); |
1500 option_parser.add_option('', '--file-root-url', default='/files/', | 1513 option_parser.add_option('', '--file-root-url', default='/files/', |
1501 help='Specify a root URL for files served.') | 1514 help='Specify a root URL for files served.') |
1502 option_parser.add_option('', '--startup-pipe', type='int', | 1515 option_parser.add_option('', '--startup-pipe', type='int', |
1503 dest='startup_pipe', | 1516 dest='startup_pipe', |
1504 help='File handle of pipe to parent process') | 1517 help='File handle of pipe to parent process') |
1505 options, args = option_parser.parse_args() | 1518 options, args = option_parser.parse_args() |
1506 | 1519 |
1507 sys.exit(main(options, args)) | 1520 sys.exit(main(options, args)) |
OLD | NEW |