Mercurial > hg
comparison mercurial/hgweb/server.py @ 4860:f3802f9f1840
Add SSL support to hg serve, activated via --certificate option
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Mon, 09 Jul 2007 22:12:28 -0700 |
parents | 63b9d2deed48 |
children | 192cd95c2ba8 |
comparison
equal
deleted
inserted
replaced
4859:8c5aca855b5d | 4860:f3802f9f1840 |
---|---|
51 accesslog = self.server.accesslog | 51 accesslog = self.server.accesslog |
52 accesslog.write("%s - - [%s] %s\n" % (self.client_address[0], | 52 accesslog.write("%s - - [%s] %s\n" % (self.client_address[0], |
53 self.log_date_time_string(), | 53 self.log_date_time_string(), |
54 format % args)) | 54 format % args)) |
55 | 55 |
56 def do_write(self): | |
57 try: | |
58 self.do_hgweb() | |
59 except socket.error, inst: | |
60 if inst[0] != errno.EPIPE: | |
61 raise | |
62 | |
56 def do_POST(self): | 63 def do_POST(self): |
57 try: | 64 try: |
58 try: | 65 self.do_write() |
59 self.do_hgweb() | |
60 except socket.error, inst: | |
61 if inst[0] != errno.EPIPE: | |
62 raise | |
63 except StandardError, inst: | 66 except StandardError, inst: |
64 self._start_response("500 Internal Server Error", []) | 67 self._start_response("500 Internal Server Error", []) |
65 self._write("Internal Server Error") | 68 self._write("Internal Server Error") |
66 tb = "".join(traceback.format_exception(*sys.exc_info())) | 69 tb = "".join(traceback.format_exception(*sys.exc_info())) |
67 self.log_error("Exception happened during processing request '%s':\n%s", | 70 self.log_error("Exception happened during processing request '%s':\n%s", |
162 raise AssertionError("Content-length header sent, but more bytes than specified are being written.") | 165 raise AssertionError("Content-length header sent, but more bytes than specified are being written.") |
163 self.length = self.length - len(data) | 166 self.length = self.length - len(data) |
164 self.wfile.write(data) | 167 self.wfile.write(data) |
165 self.wfile.flush() | 168 self.wfile.flush() |
166 | 169 |
170 class _shgwebhandler(_hgwebhandler): | |
171 def setup(self): | |
172 self.connection = self.request | |
173 self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) | |
174 self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) | |
175 | |
176 def do_write(self): | |
177 from OpenSSL.SSL import SysCallError | |
178 try: | |
179 super(_shgwebhandler, self).do_write() | |
180 except SysCallError, inst: | |
181 if inst.args[0] != errno.EPIPE: | |
182 raise | |
183 | |
184 def handle_one_request(self): | |
185 from OpenSSL.SSL import SysCallError, ZeroReturnError | |
186 try: | |
187 super(_shgwebhandler, self).handle_one_request() | |
188 except (SysCallError, ZeroReturnError): | |
189 self.close_connection = True | |
190 pass | |
191 | |
167 def create_server(ui, repo): | 192 def create_server(ui, repo): |
168 use_threads = True | 193 use_threads = True |
169 | 194 |
170 def openlog(opt, default): | 195 def openlog(opt, default): |
171 if opt and opt != '-': | 196 if opt and opt != '-': |
174 | 199 |
175 address = ui.config("web", "address", "") | 200 address = ui.config("web", "address", "") |
176 port = int(ui.config("web", "port", 8000)) | 201 port = int(ui.config("web", "port", 8000)) |
177 use_ipv6 = ui.configbool("web", "ipv6") | 202 use_ipv6 = ui.configbool("web", "ipv6") |
178 webdir_conf = ui.config("web", "webdir_conf") | 203 webdir_conf = ui.config("web", "webdir_conf") |
204 ssl_cert = ui.config("web", "certificate") | |
179 accesslog = openlog(ui.config("web", "accesslog", "-"), sys.stdout) | 205 accesslog = openlog(ui.config("web", "accesslog", "-"), sys.stdout) |
180 errorlog = openlog(ui.config("web", "errorlog", "-"), sys.stderr) | 206 errorlog = openlog(ui.config("web", "errorlog", "-"), sys.stderr) |
181 | 207 |
182 if use_threads: | 208 if use_threads: |
183 try: | 209 try: |
220 if addr in ('', '::'): | 246 if addr in ('', '::'): |
221 addr = socket.gethostname() | 247 addr = socket.gethostname() |
222 | 248 |
223 self.addr, self.port = addr, port | 249 self.addr, self.port = addr, port |
224 | 250 |
251 if ssl_cert: | |
252 try: | |
253 from OpenSSL import SSL | |
254 ctx = SSL.Context(SSL.SSLv23_METHOD) | |
255 except ImportError: | |
256 raise util.Abort("SSL support is unavailable") | |
257 ctx.use_privatekey_file(ssl_cert) | |
258 ctx.use_certificate_file(ssl_cert) | |
259 sock = socket.socket(self.address_family, self.socket_type) | |
260 self.socket = SSL.Connection(ctx, sock) | |
261 self.server_bind() | |
262 self.server_activate() | |
263 | |
225 class IPv6HTTPServer(MercurialHTTPServer): | 264 class IPv6HTTPServer(MercurialHTTPServer): |
226 address_family = getattr(socket, 'AF_INET6', None) | 265 address_family = getattr(socket, 'AF_INET6', None) |
227 | 266 |
228 def __init__(self, *args, **kwargs): | 267 def __init__(self, *args, **kwargs): |
229 if self.address_family is None: | 268 if self.address_family is None: |
230 raise hg.RepoError(_('IPv6 not available on this system')) | 269 raise hg.RepoError(_('IPv6 not available on this system')) |
231 super(IPv6HTTPServer, self).__init__(*args, **kwargs) | 270 super(IPv6HTTPServer, self).__init__(*args, **kwargs) |
232 | 271 |
272 if ssl_cert: | |
273 handler = _shgwebhandler | |
274 else: | |
275 handler = _hgwebhandler | |
276 | |
233 try: | 277 try: |
234 if use_ipv6: | 278 if use_ipv6: |
235 return IPv6HTTPServer((address, port), _hgwebhandler) | 279 return IPv6HTTPServer((address, port), handler) |
236 else: | 280 else: |
237 return MercurialHTTPServer((address, port), _hgwebhandler) | 281 return MercurialHTTPServer((address, port), handler) |
238 except socket.error, inst: | 282 except socket.error, inst: |
239 raise util.Abort(_('cannot start server: %s') % inst.args[1]) | 283 raise util.Abort(_('cannot start server: %s') % inst.args[1]) |