Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # coding: utf-8 | 2 # coding: utf-8 |
| 3 | 3 |
| 4 # Copyright 2014 The Crashpad Authors. All rights reserved. | 4 # Copyright 2014 The Crashpad Authors. All rights reserved. |
| 5 # | 5 # |
| 6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
| 8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
| 9 # | 9 # |
| 10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
| 11 # | 11 # |
| 12 # Unless required by applicable law or agreed to in writing, software | 12 # Unless required by applicable law or agreed to in writing, software |
| 13 # distributed under the License is distributed on an "AS IS" BASIS, | 13 # distributed under the License is distributed on an "AS IS" BASIS, |
| 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 # See the License for the specific language governing permissions and | 15 # See the License for the specific language governing permissions and |
| 16 # limitations under the License. | 16 # limitations under the License. |
| 17 | 17 |
| 18 """A one-shot testing webserver. | 18 """A one-shot testing webserver. |
| 19 | 19 |
| 20 When invoked, this server will write an integer to stdout, indiciating on which | 20 When invoked, this server will write an integer to stdout, indiciating on which |
| 21 port the server is listening. It will then read one integer from stdin, | 21 port the server is listening. It will then read one integer from stdin, |
|
Robert Sesek
2015/02/05 21:46:12
Update this comment.
| |
| 22 indiciating the response code to set for a request. The server will process | 22 indiciating the response code to set for a request. The server will process |
| 23 one HTTP request, writing it out entirely to stdout, and will then terminate. | 23 one HTTP request, writing it out entirely to stdout, and will then terminate. |
| 24 | 24 |
| 25 This server is written in Python since it provides a simple HTTP stack, and | 25 This server is written in Python since it provides a simple HTTP stack, and |
| 26 because parsing Chunked encoding is safer and easier in a memory-safe language. | 26 because parsing Chunked encoding is safer and easier in a memory-safe language. |
| 27 This could easily have been written in C++ instead. | 27 This could easily have been written in C++ instead. |
| 28 """ | 28 """ |
| 29 | 29 |
| 30 import BaseHTTPServer | 30 import BaseHTTPServer |
| 31 import struct | 31 import struct |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 50 | 50 |
| 51 def flush(self): | 51 def flush(self): |
| 52 self.file.flush() | 52 self.file.flush() |
| 53 | 53 |
| 54 def close(self): | 54 def close(self): |
| 55 self.file.close() | 55 self.file.close() |
| 56 | 56 |
| 57 | 57 |
| 58 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 58 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 59 response_code = 500 | 59 response_code = 500 |
| 60 response_body = '' | |
| 60 | 61 |
| 61 def handle_one_request(self): | 62 def handle_one_request(self): |
| 62 # Wrap the rfile in the buffering file object so that the raw header block | 63 # Wrap the rfile in the buffering file object so that the raw header block |
| 63 # can be written to stdout after it is parsed. | 64 # can be written to stdout after it is parsed. |
| 64 self.rfile = BufferedReadFile(self.rfile) | 65 self.rfile = BufferedReadFile(self.rfile) |
| 65 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self) | 66 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self) |
| 66 | 67 |
| 67 def do_POST(self): | 68 def do_POST(self): |
| 68 writer = sys.stdout | 69 writer = sys.stdout |
| 69 | 70 |
| 70 writer.write(self.rfile.buffer) | 71 writer.write(self.rfile.buffer) |
| 71 self.rfile.buffer = '' | 72 self.rfile.buffer = '' |
| 72 | 73 |
| 73 if self.headers.get('Transfer-Encoding', '') == 'Chunked': | 74 if self.headers.get('Transfer-Encoding', '') == 'Chunked': |
| 74 body = self.handle_chunked_encoding() | 75 body = self.handle_chunked_encoding() |
| 75 else: | 76 else: |
| 76 length = int(self.headers.get('Content-Length', -1)) | 77 length = int(self.headers.get('Content-Length', -1)) |
| 77 body = self.rfile.read(length) | 78 body = self.rfile.read(length) |
| 78 | 79 |
| 79 self.send_response(self.response_code) | 80 self.send_response(self.response_code) |
| 80 self.end_headers() | 81 self.end_headers() |
| 82 if self.response_code == 200: | |
| 83 self.wfile.write(self.response_body) | |
| 84 self.wfile.write('\r\n') | |
| 81 | 85 |
| 82 writer.write(body) | 86 writer.write(body) |
| 83 writer.flush() | 87 writer.flush() |
| 84 | 88 |
| 85 def handle_chunked_encoding(self): | 89 def handle_chunked_encoding(self): |
| 86 """This parses a "Transfer-Encoding: Chunked" body in accordance with | 90 """This parses a "Transfer-Encoding: Chunked" body in accordance with |
| 87 RFC 7230 §4.1. This returns the result as a string. | 91 RFC 7230 §4.1. This returns the result as a string. |
| 88 """ | 92 """ |
| 89 body = '' | 93 body = '' |
| 90 chunk_size = self.read_chunk_size() | 94 chunk_size = self.read_chunk_size() |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 | 130 |
| 127 # Start the server. | 131 # Start the server. |
| 128 server = BaseHTTPServer.HTTPServer(('127.0.0.1', 0), RequestHandler) | 132 server = BaseHTTPServer.HTTPServer(('127.0.0.1', 0), RequestHandler) |
| 129 | 133 |
| 130 # Write the port as an unsigned short to the parent process. | 134 # Write the port as an unsigned short to the parent process. |
| 131 sys.stdout.write(struct.pack('=H', server.server_address[1])) | 135 sys.stdout.write(struct.pack('=H', server.server_address[1])) |
| 132 sys.stdout.flush() | 136 sys.stdout.flush() |
| 133 | 137 |
| 134 # Read the desired test response code as an unsigned short from the parent | 138 # Read the desired test response code as an unsigned short from the parent |
| 135 # process. | 139 # process. |
| 136 RequestHandler.response_code = \ | 140 RequestHandler.response_code, RequestHandler.response_body = \ |
| 137 struct.unpack('=H', sys.stdin.read(struct.calcsize('=H')))[0] | 141 struct.unpack('=H8s', sys.stdin.read(struct.calcsize('=H8s'))) |
| 138 | 142 |
| 139 # Handle the request. | 143 # Handle the request. |
| 140 server.handle_request() | 144 server.handle_request() |
| 141 | 145 |
| 142 if __name__ == '__main__': | 146 if __name__ == '__main__': |
| 143 Main() | 147 Main() |
| OLD | NEW |