| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 61 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 62 # Everything to be written to stdout is collected into this string. It can’t |
| 63 # be written to stdout until after the HTTP transaction is complete, because |
| 64 # stdout is a pipe being read by a test program that’s also the HTTP client. |
| 65 # The test program expects to complete the entire HTTP transaction before it |
| 66 # even starts reading this script’s stdout. If the stdout pipe buffer fills up |
| 67 # during an HTTP transaction, deadlock would result. |
| 68 raw_request = '' |
| 69 |
| 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 RequestHandler.raw_request = self.rfile.buffer |
| 73 | |
| 74 writer.write(self.rfile.buffer) | |
| 75 self.rfile.buffer = '' | 81 self.rfile.buffer = '' |
| 76 | 82 |
| 77 if self.headers.get('Transfer-Encoding', '') == 'Chunked': | 83 if self.headers.get('Transfer-Encoding', '') == 'Chunked': |
| 78 body = self.handle_chunked_encoding() | 84 body = self.handle_chunked_encoding() |
| 79 else: | 85 else: |
| 80 length = int(self.headers.get('Content-Length', -1)) | 86 length = int(self.headers.get('Content-Length', -1)) |
| 81 body = self.rfile.read(length) | 87 body = self.rfile.read(length) |
| 82 | 88 |
| 89 RequestHandler.raw_request += body |
| 90 |
| 83 self.send_response(self.response_code) | 91 self.send_response(self.response_code) |
| 84 self.end_headers() | 92 self.end_headers() |
| 85 if self.response_code == 200: | 93 if self.response_code == 200: |
| 86 self.wfile.write(self.response_body) | 94 self.wfile.write(self.response_body) |
| 87 self.wfile.write('\r\n') | 95 self.wfile.write('\r\n') |
| 88 | 96 |
| 89 writer.write(body) | |
| 90 writer.flush() | |
| 91 | |
| 92 def handle_chunked_encoding(self): | 97 def handle_chunked_encoding(self): |
| 93 """This parses a "Transfer-Encoding: Chunked" body in accordance with | 98 """This parses a "Transfer-Encoding: Chunked" body in accordance with |
| 94 RFC 7230 §4.1. This returns the result as a string. | 99 RFC 7230 §4.1. This returns the result as a string. |
| 95 """ | 100 """ |
| 96 body = '' | 101 body = '' |
| 97 chunk_size = self.read_chunk_size() | 102 chunk_size = self.read_chunk_size() |
| 98 while chunk_size > 0: | 103 while chunk_size > 0: |
| 99 # Read the body. | 104 # Read the body. |
| 100 data = self.rfile.read(chunk_size) | 105 data = self.rfile.read(chunk_size) |
| 101 chunk_size -= len(data) | 106 chunk_size -= len(data) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 sys.stdout.flush() | 144 sys.stdout.flush() |
| 140 | 145 |
| 141 # Read the desired test response code as an unsigned short and the desired | 146 # 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. | 147 # response body as an 8-byte string from the parent process. |
| 143 RequestHandler.response_code, RequestHandler.response_body = \ | 148 RequestHandler.response_code, RequestHandler.response_body = \ |
| 144 struct.unpack('=H8s', sys.stdin.read(struct.calcsize('=H8s'))) | 149 struct.unpack('=H8s', sys.stdin.read(struct.calcsize('=H8s'))) |
| 145 | 150 |
| 146 # Handle the request. | 151 # Handle the request. |
| 147 server.handle_request() | 152 server.handle_request() |
| 148 | 153 |
| 154 # Share the entire request with the test program, which will validate it. |
| 155 sys.stdout.write(RequestHandler.raw_request) |
| 156 sys.stdout.flush() |
| 157 |
| 149 if __name__ == '__main__': | 158 if __name__ == '__main__': |
| 150 Main() | 159 Main() |
| OLD | NEW |