252 keep_blank_values=1)) |
252 keep_blank_values=1)) |
253 self._start_response = start_response |
253 self._start_response = start_response |
254 self.server_write = None |
254 self.server_write = None |
255 self.headers = [] |
255 self.headers = [] |
256 |
256 |
257 def drain(self): |
|
258 '''need to read all data from request, httplib is half-duplex''' |
|
259 length = int(self.env.get('CONTENT_LENGTH') or 0) |
|
260 for s in util.filechunkiter(self.inp, limit=length): |
|
261 pass |
|
262 |
|
263 def respond(self, status, type, filename=None, body=None): |
257 def respond(self, status, type, filename=None, body=None): |
264 if not isinstance(type, str): |
258 if not isinstance(type, str): |
265 type = pycompat.sysstr(type) |
259 type = pycompat.sysstr(type) |
266 if self._start_response is not None: |
260 if self._start_response is not None: |
267 self.headers.append((r'Content-Type', type)) |
261 self.headers.append((r'Content-Type', type)) |
290 elif status == 200: |
284 elif status == 200: |
291 status = '200 Script output follows' |
285 status = '200 Script output follows' |
292 elif isinstance(status, int): |
286 elif isinstance(status, int): |
293 status = statusmessage(status) |
287 status = statusmessage(status) |
294 |
288 |
|
289 # Various HTTP clients (notably httplib) won't read the HTTP |
|
290 # response until the HTTP request has been sent in full. If servers |
|
291 # (us) send a response before the HTTP request has been fully sent, |
|
292 # the connection may deadlock because neither end is reading. |
|
293 # |
|
294 # We work around this by "draining" the request data before |
|
295 # sending any response in some conditions. |
|
296 drain = False |
|
297 close = False |
|
298 |
|
299 # If the client sent Expect: 100-continue, we assume it is smart |
|
300 # enough to deal with the server sending a response before reading |
|
301 # the request. (httplib doesn't do this.) |
|
302 if self.env.get(r'HTTP_EXPECT', r'').lower() == r'100-continue': |
|
303 pass |
|
304 # Only tend to request methods that have bodies. Strictly speaking, |
|
305 # we should sniff for a body. But this is fine for our existing |
|
306 # WSGI applications. |
|
307 elif self.env[r'REQUEST_METHOD'] not in (r'POST', r'PUT'): |
|
308 pass |
|
309 else: |
|
310 # If we don't know how much data to read, there's no guarantee |
|
311 # that we can drain the request responsibly. The WSGI |
|
312 # specification only says that servers *should* ensure the |
|
313 # input stream doesn't overrun the actual request. So there's |
|
314 # no guarantee that reading until EOF won't corrupt the stream |
|
315 # state. |
|
316 if not isinstance(self.inp, util.cappedreader): |
|
317 close = True |
|
318 else: |
|
319 # We /could/ only drain certain HTTP response codes. But 200 |
|
320 # and non-200 wire protocol responses both require draining. |
|
321 # Since we have a capped reader in place for all situations |
|
322 # where we drain, it is safe to read from that stream. We'll |
|
323 # either do a drain or no-op if we're already at EOF. |
|
324 drain = True |
|
325 |
|
326 if close: |
|
327 self.headers.append((r'Connection', r'Close')) |
|
328 |
|
329 if drain: |
|
330 assert isinstance(self.inp, util.cappedreader) |
|
331 while True: |
|
332 chunk = self.inp.read(32768) |
|
333 if not chunk: |
|
334 break |
|
335 |
295 self.server_write = self._start_response( |
336 self.server_write = self._start_response( |
296 pycompat.sysstr(status), self.headers) |
337 pycompat.sysstr(status), self.headers) |
297 self._start_response = None |
338 self._start_response = None |
298 self.headers = [] |
339 self.headers = [] |
299 if body is not None: |
340 if body is not None: |