mercurial/hgweb/server.py
changeset 2508 ab460a3f0e3a
parent 2507 7e01da2bc7f3
child 2582 276de216d2c5
equal deleted inserted replaced
2507:7e01da2bc7f3 2508:ab460a3f0e3a
   107 
   107 
   108         self.close_connection = True
   108         self.close_connection = True
   109         self.saved_status = None
   109         self.saved_status = None
   110         self.saved_headers = []
   110         self.saved_headers = []
   111         self.sent_headers = False
   111         self.sent_headers = False
       
   112         self.length = None
   112         req = self.server.reqmaker(env, self._start_response)
   113         req = self.server.reqmaker(env, self._start_response)
   113         for data in req:
   114         for data in req:
   114             if data:
   115             if data:
   115                 self._write(data)
   116                 self._write(data)
   116 
   117 
   118         if not self.saved_status:
   119         if not self.saved_status:
   119             raise AssertionError("Sending headers before start_response() called")
   120             raise AssertionError("Sending headers before start_response() called")
   120         saved_status = self.saved_status.split(None, 1)
   121         saved_status = self.saved_status.split(None, 1)
   121         saved_status[0] = int(saved_status[0])
   122         saved_status[0] = int(saved_status[0])
   122         self.send_response(*saved_status)
   123         self.send_response(*saved_status)
       
   124         should_close = True
   123         for h in self.saved_headers:
   125         for h in self.saved_headers:
   124             self.send_header(*h)
   126             self.send_header(*h)
       
   127             if h[0].lower() == 'content-length':
       
   128                 should_close = False
       
   129                 self.length = int(h[1])
       
   130         if should_close:
       
   131             self.send_header('Connection', 'close')
       
   132         self.close_connection = should_close
   125         self.end_headers()
   133         self.end_headers()
   126         self.sent_headers = True
   134         self.sent_headers = True
   127 
   135 
   128     def _start_response(self, http_status, headers, exc_info=None):
   136     def _start_response(self, http_status, headers, exc_info=None):
   129         code, msg = http_status.split(None, 1)
   137         code, msg = http_status.split(None, 1)
   130         code = int(code)
   138         code = int(code)
   131         self.saved_status = http_status
   139         self.saved_status = http_status
   132         self.saved_headers = headers
   140         bad_headers = ('connection', 'transfer-encoding')
       
   141         self.saved_headers = [ h for h in headers \
       
   142                                if h[0].lower() not in bad_headers ]
   133         return self._write
   143         return self._write
   134 
   144 
   135     def _write(self, data):
   145     def _write(self, data):
   136         if not self.saved_status:
   146         if not self.saved_status:
   137             raise AssertionError("data written before start_response() called")
   147             raise AssertionError("data written before start_response() called")
   138         elif not self.sent_headers:
   148         elif not self.sent_headers:
   139             self.send_headers()
   149             self.send_headers()
       
   150         if self.length is not None:
       
   151             if len(data) > self.length:
       
   152                 raise AssertionError("Content-length header sent, but more bytes than specified are being written.")
       
   153             self.length = self.length - len(data)
   140         self.wfile.write(data)
   154         self.wfile.write(data)
   141         self.wfile.flush()
   155         self.wfile.flush()
   142 
   156 
   143 def create_server(ui, repo):
   157 def create_server(ui, repo):
   144     use_threads = True
   158     use_threads = True