Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/hgweb/server.py @ 5124:06154aff2b1a
merge with -stable
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> |
---|---|
date | Wed, 08 Aug 2007 23:00:01 +0200 |
parents | f94dbc6c7eaf cdd33a048289 |
children | ff461baa9c4e |
comparison
equal
deleted
inserted
replaced
5123:f94dbc6c7eaf | 5124:06154aff2b1a |
---|---|
35 def writelines(self, seq): | 35 def writelines(self, seq): |
36 for msg in seq: | 36 for msg in seq: |
37 self.handler.log_error("HG error: %s", msg) | 37 self.handler.log_error("HG error: %s", msg) |
38 | 38 |
39 class _hgwebhandler(object, BaseHTTPServer.BaseHTTPRequestHandler): | 39 class _hgwebhandler(object, BaseHTTPServer.BaseHTTPRequestHandler): |
40 | |
41 url_scheme = 'http' | |
42 | |
40 def __init__(self, *args, **kargs): | 43 def __init__(self, *args, **kargs): |
41 self.protocol_version = 'HTTP/1.1' | 44 self.protocol_version = 'HTTP/1.1' |
42 BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs) | 45 BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs) |
43 | 46 |
44 def log_error(self, format, *args): | 47 def log_error(self, format, *args): |
51 accesslog = self.server.accesslog | 54 accesslog = self.server.accesslog |
52 accesslog.write("%s - - [%s] %s\n" % (self.client_address[0], | 55 accesslog.write("%s - - [%s] %s\n" % (self.client_address[0], |
53 self.log_date_time_string(), | 56 self.log_date_time_string(), |
54 format % args)) | 57 format % args)) |
55 | 58 |
59 def do_write(self): | |
60 try: | |
61 self.do_hgweb() | |
62 except socket.error, inst: | |
63 if inst[0] != errno.EPIPE: | |
64 raise | |
65 | |
56 def do_POST(self): | 66 def do_POST(self): |
57 try: | 67 try: |
58 try: | 68 self.do_write() |
59 self.do_hgweb() | |
60 except socket.error, inst: | |
61 if inst[0] != errno.EPIPE: | |
62 raise | |
63 except StandardError, inst: | 69 except StandardError, inst: |
64 self._start_response("500 Internal Server Error", []) | 70 self._start_response("500 Internal Server Error", []) |
65 self._write("Internal Server Error") | 71 self._write("Internal Server Error") |
66 tb = "".join(traceback.format_exception(*sys.exc_info())) | 72 tb = "".join(traceback.format_exception(*sys.exc_info())) |
67 self.log_error("Exception happened during processing request '%s':\n%s", | 73 self.log_error("Exception happened during processing request '%s':\n%s", |
99 hval = hval.replace('\n', '').strip() | 105 hval = hval.replace('\n', '').strip() |
100 if hval: | 106 if hval: |
101 env[hkey] = hval | 107 env[hkey] = hval |
102 env['SERVER_PROTOCOL'] = self.request_version | 108 env['SERVER_PROTOCOL'] = self.request_version |
103 env['wsgi.version'] = (1, 0) | 109 env['wsgi.version'] = (1, 0) |
104 env['wsgi.url_scheme'] = 'http' | 110 env['wsgi.url_scheme'] = self.url_scheme |
105 env['wsgi.input'] = self.rfile | 111 env['wsgi.input'] = self.rfile |
106 env['wsgi.errors'] = _error_logger(self) | 112 env['wsgi.errors'] = _error_logger(self) |
107 env['wsgi.multithread'] = isinstance(self.server, | 113 env['wsgi.multithread'] = isinstance(self.server, |
108 SocketServer.ThreadingMixIn) | 114 SocketServer.ThreadingMixIn) |
109 env['wsgi.multiprocess'] = isinstance(self.server, | 115 env['wsgi.multiprocess'] = isinstance(self.server, |
162 raise AssertionError("Content-length header sent, but more bytes than specified are being written.") | 168 raise AssertionError("Content-length header sent, but more bytes than specified are being written.") |
163 self.length = self.length - len(data) | 169 self.length = self.length - len(data) |
164 self.wfile.write(data) | 170 self.wfile.write(data) |
165 self.wfile.flush() | 171 self.wfile.flush() |
166 | 172 |
173 class _shgwebhandler(_hgwebhandler): | |
174 | |
175 url_scheme = 'https' | |
176 | |
177 def setup(self): | |
178 self.connection = self.request | |
179 self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) | |
180 self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) | |
181 | |
182 def do_write(self): | |
183 from OpenSSL.SSL import SysCallError | |
184 try: | |
185 super(_shgwebhandler, self).do_write() | |
186 except SysCallError, inst: | |
187 if inst.args[0] != errno.EPIPE: | |
188 raise | |
189 | |
190 def handle_one_request(self): | |
191 from OpenSSL.SSL import SysCallError, ZeroReturnError | |
192 try: | |
193 super(_shgwebhandler, self).handle_one_request() | |
194 except (SysCallError, ZeroReturnError): | |
195 self.close_connection = True | |
196 pass | |
197 | |
167 def create_server(ui, repo): | 198 def create_server(ui, repo): |
168 use_threads = True | 199 use_threads = True |
169 | 200 |
170 def openlog(opt, default): | 201 def openlog(opt, default): |
171 if opt and opt != '-': | 202 if opt and opt != '-': |
190 getconfig, getconfigbool = create_getconfig("web", ui, repo.ui) | 221 getconfig, getconfigbool = create_getconfig("web", ui, repo.ui) |
191 address = getconfig("address", "") | 222 address = getconfig("address", "") |
192 port = int(getconfig("port", 8000)) | 223 port = int(getconfig("port", 8000)) |
193 use_ipv6 = getconfigbool("ipv6") | 224 use_ipv6 = getconfigbool("ipv6") |
194 webdir_conf = getconfig("webdir_conf") | 225 webdir_conf = getconfig("webdir_conf") |
226 ssl_cert = getconfig("certificate") | |
195 accesslog = openlog(getconfig("accesslog", "-"), sys.stdout) | 227 accesslog = openlog(getconfig("accesslog", "-"), sys.stdout) |
196 errorlog = openlog(getconfig("errorlog", "-"), sys.stderr) | 228 errorlog = openlog(getconfig("errorlog", "-"), sys.stderr) |
197 | 229 |
198 if use_threads: | 230 if use_threads: |
199 try: | 231 try: |
236 if addr in ('', '::'): | 268 if addr in ('', '::'): |
237 addr = socket.gethostname() | 269 addr = socket.gethostname() |
238 | 270 |
239 self.addr, self.port = addr, port | 271 self.addr, self.port = addr, port |
240 | 272 |
273 if ssl_cert: | |
274 try: | |
275 from OpenSSL import SSL | |
276 ctx = SSL.Context(SSL.SSLv23_METHOD) | |
277 except ImportError: | |
278 raise util.Abort("SSL support is unavailable") | |
279 ctx.use_privatekey_file(ssl_cert) | |
280 ctx.use_certificate_file(ssl_cert) | |
281 sock = socket.socket(self.address_family, self.socket_type) | |
282 self.socket = SSL.Connection(ctx, sock) | |
283 self.server_bind() | |
284 self.server_activate() | |
285 | |
241 class IPv6HTTPServer(MercurialHTTPServer): | 286 class IPv6HTTPServer(MercurialHTTPServer): |
242 address_family = getattr(socket, 'AF_INET6', None) | 287 address_family = getattr(socket, 'AF_INET6', None) |
243 | 288 |
244 def __init__(self, *args, **kwargs): | 289 def __init__(self, *args, **kwargs): |
245 if self.address_family is None: | 290 if self.address_family is None: |
246 raise hg.RepoError(_('IPv6 not available on this system')) | 291 raise hg.RepoError(_('IPv6 not available on this system')) |
247 super(IPv6HTTPServer, self).__init__(*args, **kwargs) | 292 super(IPv6HTTPServer, self).__init__(*args, **kwargs) |
248 | 293 |
294 if ssl_cert: | |
295 handler = _shgwebhandler | |
296 else: | |
297 handler = _hgwebhandler | |
298 | |
249 try: | 299 try: |
250 if use_ipv6: | 300 if use_ipv6: |
251 return IPv6HTTPServer((address, port), _hgwebhandler) | 301 return IPv6HTTPServer((address, port), handler) |
252 else: | 302 else: |
253 return MercurialHTTPServer((address, port), _hgwebhandler) | 303 return MercurialHTTPServer((address, port), handler) |
254 except socket.error, inst: | 304 except socket.error, inst: |
255 raise util.Abort(_('cannot start server: %s') % inst.args[1]) | 305 raise util.Abort(_('cannot start server: %s') % inst.args[1]) |