@@ -125,8 +125,14 @@ def do_POST(self):
125
125
raise Exception ('Unsupported Content-Type: ' + content_type )
126
126
if self .headers .getheader ('content-encoding' ) == 'gzip' :
127
127
self .log_message ('GZIP' );
128
- readsize = self .headers .getheader ('content-length' )
129
- buffer = StringIO (self .rfile .read (int (readsize )))
128
+ if self .headers .get ('Transfer-Encoding' , '' ).lower () == 'chunked' :
129
+ if 'Content-Length' in self .headers :
130
+ raise AssertionError
131
+ body = self .handle_chunked_encoding ()
132
+ buffer = StringIO (body )
133
+ else :
134
+ readsize = self .headers .getheader ('content-length' )
135
+ buffer = StringIO (self .rfile .read (int (readsize )))
130
136
with gzip .GzipFile (fileobj = buffer , mode = "r" ) as f :
131
137
post_multipart = cgi .parse_multipart (f , parameters )
132
138
else :
@@ -148,6 +154,39 @@ def do_POST(self):
148
154
self .end_headers ()
149
155
self .wfile .write (report_id )
150
156
157
+ def handle_chunked_encoding (self ):
158
+ body = ''
159
+ chunk_size = self .read_chunk_size ()
160
+ while chunk_size > 0 :
161
+ # Read the body.
162
+ data = self .rfile .read (chunk_size )
163
+ chunk_size -= len (data )
164
+ body += data
165
+
166
+ # Finished reading this chunk.
167
+ if chunk_size == 0 :
168
+ # Read through any trailer fields.
169
+ trailer_line = self .rfile .readline ()
170
+ while trailer_line .strip () != '' :
171
+ trailer_line = self .rfile .readline ()
172
+
173
+ # Read the chunk size.
174
+ chunk_size = self .read_chunk_size ()
175
+ return body
176
+
177
+ def read_chunk_size (self ):
178
+ # Read the whole line, including the \r\n.
179
+ chunk_size_and_ext_line = self .rfile .readline ()
180
+ # Look for a chunk extension.
181
+ chunk_size_end = chunk_size_and_ext_line .find (';' )
182
+ if chunk_size_end == - 1 :
183
+ # No chunk extensions; just encounter the end of line.
184
+ chunk_size_end = chunk_size_and_ext_line .find ('\r ' )
185
+ if chunk_size_end == - 1 :
186
+ self .send_response (400 ) # Bad request.
187
+ return - 1
188
+ return int (chunk_size_and_ext_line [:chunk_size_end ], base = 16 )
189
+
151
190
return MultipartFormHandler
152
191
153
192
def server_thread (crash_server ):
0 commit comments