##// END OF EJS Templates
Catch HTTPException when reading from remote http repository....
Thomas Arendsen Hein -
r2015:1a09814a default
parent child Browse files
Show More
@@ -1,139 +1,142 b''
1 1 # httprepo.py - HTTP repository proxy classes for mercurial
2 2 #
3 3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from node import *
9 9 from remoterepo import *
10 10 from i18n import gettext as _
11 11 from demandload import *
12 demandload(globals(), "hg os urllib urllib2 urlparse zlib util")
12 demandload(globals(), "hg os urllib urllib2 urlparse zlib util httplib")
13 13
14 14 class httprepository(remoterepository):
15 15 def __init__(self, ui, path):
16 16 # fix missing / after hostname
17 17 s = urlparse.urlsplit(path)
18 18 partial = s[2]
19 19 if not partial: partial = "/"
20 20 self.url = urlparse.urlunsplit((s[0], s[1], partial, '', ''))
21 21 self.ui = ui
22 22 no_list = [ "localhost", "127.0.0.1" ]
23 23 host = ui.config("http_proxy", "host")
24 24 if host is None:
25 25 host = os.environ.get("http_proxy")
26 26 if host and host.startswith('http://'):
27 27 host = host[7:]
28 28 user = ui.config("http_proxy", "user")
29 29 passwd = ui.config("http_proxy", "passwd")
30 30 no = ui.config("http_proxy", "no")
31 31 if no is None:
32 32 no = os.environ.get("no_proxy")
33 33 if no:
34 34 no_list = no_list + no.split(",")
35 35
36 36 no_proxy = 0
37 37 for h in no_list:
38 38 if (path.startswith("http://" + h + "/") or
39 39 path.startswith("http://" + h + ":") or
40 40 path == "http://" + h):
41 41 no_proxy = 1
42 42
43 43 # Note: urllib2 takes proxy values from the environment and those will
44 44 # take precedence
45 45 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
46 46 try:
47 47 if os.environ.has_key(env):
48 48 del os.environ[env]
49 49 except OSError:
50 50 pass
51 51
52 52 proxy_handler = urllib2.BaseHandler()
53 53 if host and not no_proxy:
54 54 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host})
55 55
56 56 authinfo = None
57 57 if user and passwd:
58 58 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
59 59 passmgr.add_password(None, host, user, passwd)
60 60 authinfo = urllib2.ProxyBasicAuthHandler(passmgr)
61 61
62 62 opener = urllib2.build_opener(proxy_handler, authinfo)
63 63 # 1.0 here is the _protocol_ version
64 64 opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
65 65 urllib2.install_opener(opener)
66 66
67 67 def dev(self):
68 68 return -1
69 69
70 70 def lock(self):
71 71 raise util.Abort(_('operation not supported over http'))
72 72
73 73 def do_cmd(self, cmd, **args):
74 74 self.ui.debug(_("sending %s command\n") % cmd)
75 75 q = {"cmd": cmd}
76 76 q.update(args)
77 77 qs = urllib.urlencode(q)
78 78 cu = "%s?%s" % (self.url, qs)
79 79 resp = urllib2.urlopen(cu)
80 80 proto = resp.headers['content-type']
81 81
82 82 # accept old "text/plain" and "application/hg-changegroup" for now
83 83 if not proto.startswith('application/mercurial') and \
84 84 not proto.startswith('text/plain') and \
85 85 not proto.startswith('application/hg-changegroup'):
86 86 raise hg.RepoError(_("'%s' does not appear to be an hg repository") %
87 87 self.url)
88 88
89 89 if proto.startswith('application/mercurial'):
90 90 version = proto[22:]
91 91 if float(version) > 0.1:
92 92 raise hg.RepoError(_("'%s' uses newer protocol %s") %
93 93 (self.url, version))
94 94
95 95 return resp
96 96
97 97 def heads(self):
98 98 d = self.do_cmd("heads").read()
99 99 try:
100 100 return map(bin, d[:-1].split(" "))
101 101 except:
102 102 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n")
103 103 raise
104 104
105 105 def branches(self, nodes):
106 106 n = " ".join(map(hex, nodes))
107 107 d = self.do_cmd("branches", nodes=n).read()
108 108 try:
109 109 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
110 110 return br
111 111 except:
112 112 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n")
113 113 raise
114 114
115 115 def between(self, pairs):
116 116 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
117 117 d = self.do_cmd("between", pairs=n).read()
118 118 try:
119 119 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
120 120 return p
121 121 except:
122 122 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n")
123 123 raise
124 124
125 125 def changegroup(self, nodes, kind):
126 126 n = " ".join(map(hex, nodes))
127 127 f = self.do_cmd("changegroup", roots=n)
128 128 bytes = 0
129 129
130 130 def zgenerator(f):
131 131 zd = zlib.decompressobj()
132 for chnk in f:
133 yield zd.decompress(chnk)
132 try:
133 for chnk in f:
134 yield zd.decompress(chnk)
135 except httplib.HTTPException, inst:
136 raise IOError(None, _('connection ended unexpectedly'))
134 137 yield zd.flush()
135 138
136 139 return util.chunkbuffer(zgenerator(util.filechunkiter(f)))
137 140
138 141 class httpsrepository(httprepository):
139 142 pass
General Comments 0
You need to be logged in to leave comments. Login now