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 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 self.buffer += buf | 51 self.buffer += buf |
| 52 return buf | 52 return buf |
| 53 | 53 |
| 54 def flush(self): | 54 def flush(self): |
| 55 self.file.flush() | 55 self.file.flush() |
| 56 | 56 |
| 57 def close(self): | 57 def close(self): |
| 58 self.file.close() | 58 self.file.close() |
| 59 | 59 |
| 60 | 60 |
| 61 # Everything to be written to stdout is collected into this string. It can’t be | |
| 62 # written to stdout until after the HTTP transaction is complete, because | |
| 63 # stdout is a pipe being read by a test program that’s also the HTTP client. The | |
| 64 # test program expects to complete the entire HTTP transaction before it even | |
| 65 # starts reading this script’s stdout. If the stdout pipe buffer fills up during | |
| 66 # an HTTP transaction, deadlock would result. | |
| 67 to_write_to_stdout = '' | |
|
Mark Mentovai
2015/08/18 21:26:19
I don’t like that this is a global, but BaseHTTPSe
Robert Sesek
2015/08/18 21:42:49
You could move it to RequestHandler.written_respon
| |
| 68 | |
| 61 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 69 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 62 response_code = 500 | 70 response_code = 500 |
| 63 response_body = '' | 71 response_body = '' |
| 64 | 72 |
| 65 def handle_one_request(self): | 73 def handle_one_request(self): |
| 66 # Wrap the rfile in the buffering file object so that the raw header block | 74 # Wrap the rfile in the buffering file object so that the raw header block |
| 67 # can be written to stdout after it is parsed. | 75 # can be written to stdout after it is parsed. |
| 68 self.rfile = BufferedReadFile(self.rfile) | 76 self.rfile = BufferedReadFile(self.rfile) |
| 69 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self) | 77 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self) |
| 70 | 78 |
| 71 def do_POST(self): | 79 def do_POST(self): |
| 72 writer = sys.stdout | 80 global to_write_to_stdout |
| 73 | 81 |
| 74 writer.write(self.rfile.buffer) | 82 to_write_to_stdout = self.rfile.buffer |
| 75 self.rfile.buffer = '' | 83 self.rfile.buffer = '' |
| 76 | 84 |
| 77 if self.headers.get('Transfer-Encoding', '') == 'Chunked': | 85 if self.headers.get('Transfer-Encoding', '') == 'Chunked': |
| 78 body = self.handle_chunked_encoding() | 86 body = self.handle_chunked_encoding() |
| 79 else: | 87 else: |
| 80 length = int(self.headers.get('Content-Length', -1)) | 88 length = int(self.headers.get('Content-Length', -1)) |
| 81 body = self.rfile.read(length) | 89 body = self.rfile.read(length) |
| 82 | 90 |
| 91 to_write_to_stdout += body | |
| 92 | |
| 83 self.send_response(self.response_code) | 93 self.send_response(self.response_code) |
| 84 self.end_headers() | 94 self.end_headers() |
| 85 if self.response_code == 200: | 95 if self.response_code == 200: |
| 86 self.wfile.write(self.response_body) | 96 self.wfile.write(self.response_body) |
| 87 self.wfile.write('\r\n') | 97 self.wfile.write('\r\n') |
| 88 | 98 |
| 89 writer.write(body) | |
| 90 writer.flush() | |
| 91 | |
| 92 def handle_chunked_encoding(self): | 99 def handle_chunked_encoding(self): |
| 93 """This parses a "Transfer-Encoding: Chunked" body in accordance with | 100 """This parses a "Transfer-Encoding: Chunked" body in accordance with |
| 94 RFC 7230 §4.1. This returns the result as a string. | 101 RFC 7230 §4.1. This returns the result as a string. |
| 95 """ | 102 """ |
| 96 body = '' | 103 body = '' |
| 97 chunk_size = self.read_chunk_size() | 104 chunk_size = self.read_chunk_size() |
| 98 while chunk_size > 0: | 105 while chunk_size > 0: |
| 99 # Read the body. | 106 # Read the body. |
| 100 data = self.rfile.read(chunk_size) | 107 data = self.rfile.read(chunk_size) |
| 101 chunk_size -= len(data) | 108 chunk_size -= len(data) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 sys.stdout.flush() | 146 sys.stdout.flush() |
| 140 | 147 |
| 141 # Read the desired test response code as an unsigned short and the desired | 148 # Read the desired test response code as an unsigned short and the desired |
| 142 # response body as an 8-byte string from the parent process. | 149 # response body as an 8-byte string from the parent process. |
| 143 RequestHandler.response_code, RequestHandler.response_body = \ | 150 RequestHandler.response_code, RequestHandler.response_body = \ |
| 144 struct.unpack('=H8s', sys.stdin.read(struct.calcsize('=H8s'))) | 151 struct.unpack('=H8s', sys.stdin.read(struct.calcsize('=H8s'))) |
| 145 | 152 |
| 146 # Handle the request. | 153 # Handle the request. |
| 147 server.handle_request() | 154 server.handle_request() |
| 148 | 155 |
| 156 # Share the entire request with the test program, which will validate it. | |
| 157 sys.stdout.write(to_write_to_stdout) | |
| 158 sys.stdout.flush() | |
| 159 | |
| 149 if __name__ == '__main__': | 160 if __name__ == '__main__': |
| 150 Main() | 161 Main() |
| OLD | NEW |