Mercurial > public > mercurial-scm > hg
comparison contrib/phabricator.py @ 34064:8b659b7388c0
phabricator: add a config to use curl for communication
Not sure why, but I got `phabsend` hang on work network pretty frequently.
The traceback indicates it hangs at `_sslobj.do_handshake()`:
File "mercurial/sslutil.py", line 404, in wrapsocket
sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
File "/usr/lib/python2.7/ssl.py", line 363, in wrap_socket
_context=self)
File "/usr/lib/python2.7/ssl.py", line 611, in __init__
self.do_handshake()
File "/usr/lib/python2.7/ssl.py", line 840, in do_handshake
self._sslobj.do_handshake()
I had tried adding `timeout` in various places but they seem not effective.
It seems easier to just allow shelling out to `curl` with retry and timeout
flags.
This could also be helpful for people with an older Python installed without
modern security (SNI).
Differential Revision: https://phab.mercurial-scm.org/D605
author | Jun Wu <quark@fb.com> |
---|---|
date | Fri, 01 Sep 2017 12:13:17 -0700 |
parents | 941c33cfde81 |
children | a0d33f4ddff9 |
comparison
equal
deleted
inserted
replaced
34063:941c33cfde81 | 34064:8b659b7388c0 |
---|---|
26 | 26 |
27 # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its | 27 # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its |
28 # callsign is "FOO". | 28 # callsign is "FOO". |
29 callsign = FOO | 29 callsign = FOO |
30 | 30 |
31 # curl command to use. If not set (default), use builtin HTTP library to | |
32 # communicate. If set, use the specified curl command. This could be useful | |
33 # if you need to specify advanced options that is not easily supported by | |
34 # the internal library. | |
35 curlcmd = curl --connect-timeout 2 --retry 3 --silent | |
31 """ | 36 """ |
32 | 37 |
33 from __future__ import absolute_import | 38 from __future__ import absolute_import |
34 | 39 |
35 import itertools | 40 import itertools |
106 | 111 |
107 def callconduit(repo, name, params): | 112 def callconduit(repo, name, params): |
108 """call Conduit API, params is a dict. return json.loads result, or None""" | 113 """call Conduit API, params is a dict. return json.loads result, or None""" |
109 host, token = readurltoken(repo) | 114 host, token = readurltoken(repo) |
110 url, authinfo = util.url('/'.join([host, 'api', name])).authinfo() | 115 url, authinfo = util.url('/'.join([host, 'api', name])).authinfo() |
111 urlopener = urlmod.opener(repo.ui, authinfo) | |
112 repo.ui.debug('Conduit Call: %s %s\n' % (url, params)) | 116 repo.ui.debug('Conduit Call: %s %s\n' % (url, params)) |
113 params = params.copy() | 117 params = params.copy() |
114 params['api.token'] = token | 118 params['api.token'] = token |
115 request = util.urlreq.request(url, data=urlencodenested(params)) | 119 data = urlencodenested(params) |
116 body = urlopener.open(request).read() | 120 curlcmd = repo.ui.config('phabricator', 'curlcmd') |
121 if curlcmd: | |
122 sin, sout = util.popen2('%s -d @- %s' % (curlcmd, util.shellquote(url))) | |
123 sin.write(data) | |
124 sin.close() | |
125 body = sout.read() | |
126 else: | |
127 urlopener = urlmod.opener(repo.ui, authinfo) | |
128 request = util.urlreq.request(url, data=data) | |
129 body = urlopener.open(request).read() | |
117 repo.ui.debug('Conduit Response: %s\n' % body) | 130 repo.ui.debug('Conduit Response: %s\n' % body) |
118 parsed = json.loads(body) | 131 parsed = json.loads(body) |
119 if parsed.get(r'error_code'): | 132 if parsed.get(r'error_code'): |
120 msg = (_('Conduit Error (%s): %s') | 133 msg = (_('Conduit Error (%s): %s') |
121 % (parsed[r'error_code'], parsed[r'error_info'])) | 134 % (parsed[r'error_code'], parsed[r'error_info'])) |