Show More
@@ -2464,7 +2464,7 b' def serve(ui, repo, **opts):' | |||||
2464 |
|
2464 | |||
2465 | parentui = ui.parentui or ui |
|
2465 | parentui = ui.parentui or ui | |
2466 | optlist = ("name templates style address port ipv6" |
|
2466 | optlist = ("name templates style address port ipv6" | |
2467 | " accesslog errorlog webdir_conf") |
|
2467 | " accesslog errorlog webdir_conf certificate") | |
2468 | for o in optlist.split(): |
|
2468 | for o in optlist.split(): | |
2469 | if opts[o]: |
|
2469 | if opts[o]: | |
2470 | parentui.setconfig("web", o, str(opts[o])) |
|
2470 | parentui.setconfig("web", o, str(opts[o])) | |
@@ -3072,7 +3072,8 b' table = {' | |||||
3072 | ('', 'stdio', None, _('for remote clients')), |
|
3072 | ('', 'stdio', None, _('for remote clients')), | |
3073 | ('t', 'templates', '', _('web templates to use')), |
|
3073 | ('t', 'templates', '', _('web templates to use')), | |
3074 | ('', 'style', '', _('template style to use')), |
|
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 | _('hg serve [OPTION]...')), |
|
3077 | _('hg serve [OPTION]...')), | |
3077 | "^status|st": |
|
3078 | "^status|st": | |
3078 | (status, |
|
3079 | (status, |
@@ -53,13 +53,16 b' class _hgwebhandler(object, BaseHTTPServ' | |||||
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 |
|
|
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") | |
@@ -164,6 +167,28 b' class _hgwebhandler(object, BaseHTTPServ' | |||||
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 | |||
@@ -176,6 +201,7 b' def create_server(ui, repo):' | |||||
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 | |||
@@ -222,6 +248,19 b' def create_server(ui, repo):' | |||||
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 | |||
@@ -230,10 +269,15 b' def create_server(ui, repo):' | |||||
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), |
|
279 | return IPv6HTTPServer((address, port), handler) | |
236 | else: |
|
280 | else: | |
237 |
return MercurialHTTPServer((address, port), |
|
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]) |
General Comments 0
You need to be logged in to leave comments.
Login now