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 |