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 15 matching lines...) Expand all Loading... |
26 write the entire request to stdout. It will then terminate. | 26 write the entire request to stdout. It will then terminate. |
27 | 27 |
28 This server is written in Python since it provides a simple HTTP stack, and | 28 This server is written in Python since it provides a simple HTTP stack, and |
29 because parsing chunked encoding is safer and easier in a memory-safe language. | 29 because parsing chunked encoding is safer and easier in a memory-safe language. |
30 This could easily have been written in C++ instead. | 30 This could easily have been written in C++ instead. |
31 """ | 31 """ |
32 | 32 |
33 import BaseHTTPServer | 33 import BaseHTTPServer |
34 import struct | 34 import struct |
35 import sys | 35 import sys |
| 36 import zlib |
36 | 37 |
37 class BufferedReadFile(object): | 38 class BufferedReadFile(object): |
38 """A File-like object that stores all read contents into a buffer.""" | 39 """A File-like object that stores all read contents into a buffer.""" |
39 | 40 |
40 def __init__(self, real_file): | 41 def __init__(self, real_file): |
41 self.file = real_file | 42 self.file = real_file |
42 self.buffer = "" | 43 self.buffer = "" |
43 | 44 |
44 def read(self, size=-1): | 45 def read(self, size=-1): |
45 buf = self.file.read(size) | 46 buf = self.file.read(size) |
(...skipping 28 matching lines...) Expand all Loading... |
74 # Wrap the rfile in the buffering file object so that the raw header block | 75 # Wrap the rfile in the buffering file object so that the raw header block |
75 # can be written to stdout after it is parsed. | 76 # can be written to stdout after it is parsed. |
76 self.rfile = BufferedReadFile(self.rfile) | 77 self.rfile = BufferedReadFile(self.rfile) |
77 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self) | 78 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self) |
78 | 79 |
79 def do_POST(self): | 80 def do_POST(self): |
80 RequestHandler.raw_request = self.rfile.buffer | 81 RequestHandler.raw_request = self.rfile.buffer |
81 self.rfile.buffer = '' | 82 self.rfile.buffer = '' |
82 | 83 |
83 if self.headers.get('Transfer-Encoding', '').lower() == 'chunked': | 84 if self.headers.get('Transfer-Encoding', '').lower() == 'chunked': |
| 85 if 'Content-Length' in self.headers: |
| 86 raise AssertionError |
84 body = self.handle_chunked_encoding() | 87 body = self.handle_chunked_encoding() |
85 else: | 88 else: |
86 length = int(self.headers.get('Content-Length', -1)) | 89 length = int(self.headers.get('Content-Length', -1)) |
87 body = self.rfile.read(length) | 90 body = self.rfile.read(length) |
88 | 91 |
| 92 if self.headers.get('Content-Encoding', '').lower() == 'gzip': |
| 93 # 15 is the value of |wbits|, which should be at the maximum possible |
| 94 # value to ensure that any gzip stream can be decoded. The offset of 16 |
| 95 # specifies that the stream to decompress will be formatted with a gzip |
| 96 # wrapper. |
| 97 body = zlib.decompress(body, 16 + 15) |
| 98 |
89 RequestHandler.raw_request += body | 99 RequestHandler.raw_request += body |
90 | 100 |
91 self.send_response(self.response_code) | 101 self.send_response(self.response_code) |
92 self.end_headers() | 102 self.end_headers() |
93 if self.response_code == 200: | 103 if self.response_code == 200: |
94 self.wfile.write(self.response_body) | 104 self.wfile.write(self.response_body) |
95 self.wfile.write('\r\n') | 105 self.wfile.write('\r\n') |
96 | 106 |
97 def handle_chunked_encoding(self): | 107 def handle_chunked_encoding(self): |
98 """This parses a "Transfer-Encoding: Chunked" body in accordance with | 108 """This parses a "Transfer-Encoding: Chunked" body in accordance with |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 164 |
155 # Handle the request. | 165 # Handle the request. |
156 server.handle_request() | 166 server.handle_request() |
157 | 167 |
158 # Share the entire request with the test program, which will validate it. | 168 # Share the entire request with the test program, which will validate it. |
159 sys.stdout.write(RequestHandler.raw_request) | 169 sys.stdout.write(RequestHandler.raw_request) |
160 sys.stdout.flush() | 170 sys.stdout.flush() |
161 | 171 |
162 if __name__ == '__main__': | 172 if __name__ == '__main__': |
163 Main() | 173 Main() |
OLD | NEW |