mercurial/hgweb/request.py
changeset 36855 2cdf47e14c30
parent 36854 290fc4c3d1e0
child 36856 1f7d9024674c
equal deleted inserted replaced
36854:290fc4c3d1e0 36855:2cdf47e14c30
   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: