Show More
@@ -2464,7 +2464,7 b' def serve(ui, repo, **opts):' | |||
|
2464 | 2464 | |
|
2465 | 2465 | parentui = ui.parentui or ui |
|
2466 | 2466 | optlist = ("name templates style address port ipv6" |
|
2467 | " accesslog errorlog webdir_conf") | |
|
2467 | " accesslog errorlog webdir_conf certificate") | |
|
2468 | 2468 | for o in optlist.split(): |
|
2469 | 2469 | if opts[o]: |
|
2470 | 2470 | parentui.setconfig("web", o, str(opts[o])) |
@@ -3072,7 +3072,8 b' table = {' | |||
|
3072 | 3072 | ('', 'stdio', None, _('for remote clients')), |
|
3073 | 3073 | ('t', 'templates', '', _('web templates to use')), |
|
3074 | 3074 | ('', 'style', '', _('template style to use')), |
|
3075 |
('6', 'ipv6', None, _('use IPv6 in addition to IPv4')) |
|
|
3075 | ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), | |
|
3076 | ('', 'certificate', '', _('SSL certificate file'))], | |
|
3076 | 3077 | _('hg serve [OPTION]...')), |
|
3077 | 3078 | "^status|st": |
|
3078 | 3079 | (status, |
@@ -53,13 +53,16 b' class _hgwebhandler(object, BaseHTTPServ' | |||
|
53 | 53 | self.log_date_time_string(), |
|
54 | 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 | 63 | def do_POST(self): |
|
57 | 64 | try: |
|
58 |
|
|
|
59 | self.do_hgweb() | |
|
60 | except socket.error, inst: | |
|
61 | if inst[0] != errno.EPIPE: | |
|
62 | raise | |
|
65 | self.do_write() | |
|
63 | 66 | except StandardError, inst: |
|
64 | 67 | self._start_response("500 Internal Server Error", []) |
|
65 | 68 | self._write("Internal Server Error") |
@@ -164,6 +167,28 b' class _hgwebhandler(object, BaseHTTPServ' | |||
|
164 | 167 | self.wfile.write(data) |
|
165 | 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 | 192 | def create_server(ui, repo): |
|
168 | 193 | use_threads = True |
|
169 | 194 | |
@@ -176,6 +201,7 b' def create_server(ui, repo):' | |||
|
176 | 201 | port = int(ui.config("web", "port", 8000)) |
|
177 | 202 | use_ipv6 = ui.configbool("web", "ipv6") |
|
178 | 203 | webdir_conf = ui.config("web", "webdir_conf") |
|
204 | ssl_cert = ui.config("web", "certificate") | |
|
179 | 205 | accesslog = openlog(ui.config("web", "accesslog", "-"), sys.stdout) |
|
180 | 206 | errorlog = openlog(ui.config("web", "errorlog", "-"), sys.stderr) |
|
181 | 207 | |
@@ -222,6 +248,19 b' def create_server(ui, repo):' | |||
|
222 | 248 | |
|
223 | 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 | 264 | class IPv6HTTPServer(MercurialHTTPServer): |
|
226 | 265 | address_family = getattr(socket, 'AF_INET6', None) |
|
227 | 266 | |
@@ -230,10 +269,15 b' def create_server(ui, repo):' | |||
|
230 | 269 | raise hg.RepoError(_('IPv6 not available on this system')) |
|
231 | 270 | super(IPv6HTTPServer, self).__init__(*args, **kwargs) |
|
232 | 271 | |
|
272 | if ssl_cert: | |
|
273 | handler = _shgwebhandler | |
|
274 | else: | |
|
275 | handler = _hgwebhandler | |
|
276 | ||
|
233 | 277 | try: |
|
234 | 278 | if use_ipv6: |
|
235 |
return IPv6HTTPServer((address, port), |
|
|
279 | return IPv6HTTPServer((address, port), handler) | |
|
236 | 280 | else: |
|
237 |
return MercurialHTTPServer((address, port), |
|
|
281 | return MercurialHTTPServer((address, port), handler) | |
|
238 | 282 | except socket.error, inst: |
|
239 | 283 | raise util.Abort(_('cannot start server: %s') % inst.args[1]) |
General Comments 0
You need to be logged in to leave comments.
Login now