##// END OF EJS Templates
Fix lots of exception-related problems....
Bryan O'Sullivan -
r1251:84cf8834 default
parent child Browse files
Show More
@@ -1,142 +1,143 b''
1 # httprepo.py - HTTP repository proxy classes for mercurial
1 # httprepo.py - HTTP repository proxy classes for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 import urllib, urllib2, urlparse, os, zlib
9 from node import *
8 from node import *
10 from remoterepo import *
9 from remoterepo import *
10 from demandload import *
11 demandload(globals(), "hg os urllib urllib2 urlparse zlib")
11
12
12 class httprepository(remoterepository):
13 class httprepository(remoterepository):
13 def __init__(self, ui, path):
14 def __init__(self, ui, path):
14 # fix missing / after hostname
15 # fix missing / after hostname
15 s = urlparse.urlsplit(path)
16 s = urlparse.urlsplit(path)
16 partial = s[2]
17 partial = s[2]
17 if not partial: partial = "/"
18 if not partial: partial = "/"
18 self.url = urlparse.urlunsplit((s[0], s[1], partial, '', ''))
19 self.url = urlparse.urlunsplit((s[0], s[1], partial, '', ''))
19 self.ui = ui
20 self.ui = ui
20 no_list = [ "localhost", "127.0.0.1" ]
21 no_list = [ "localhost", "127.0.0.1" ]
21 host = ui.config("http_proxy", "host")
22 host = ui.config("http_proxy", "host")
22 if host is None:
23 if host is None:
23 host = os.environ.get("http_proxy")
24 host = os.environ.get("http_proxy")
24 if host and host.startswith('http://'):
25 if host and host.startswith('http://'):
25 host = host[7:]
26 host = host[7:]
26 user = ui.config("http_proxy", "user")
27 user = ui.config("http_proxy", "user")
27 passwd = ui.config("http_proxy", "passwd")
28 passwd = ui.config("http_proxy", "passwd")
28 no = ui.config("http_proxy", "no")
29 no = ui.config("http_proxy", "no")
29 if no is None:
30 if no is None:
30 no = os.environ.get("no_proxy")
31 no = os.environ.get("no_proxy")
31 if no:
32 if no:
32 no_list = no_list + no.split(",")
33 no_list = no_list + no.split(",")
33
34
34 no_proxy = 0
35 no_proxy = 0
35 for h in no_list:
36 for h in no_list:
36 if (path.startswith("http://" + h + "/") or
37 if (path.startswith("http://" + h + "/") or
37 path.startswith("http://" + h + ":") or
38 path.startswith("http://" + h + ":") or
38 path == "http://" + h):
39 path == "http://" + h):
39 no_proxy = 1
40 no_proxy = 1
40
41
41 # Note: urllib2 takes proxy values from the environment and those will
42 # Note: urllib2 takes proxy values from the environment and those will
42 # take precedence
43 # take precedence
43 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
44 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
44 try:
45 try:
45 if os.environ.has_key(env):
46 if os.environ.has_key(env):
46 del os.environ[env]
47 del os.environ[env]
47 except OSError:
48 except OSError:
48 pass
49 pass
49
50
50 proxy_handler = urllib2.BaseHandler()
51 proxy_handler = urllib2.BaseHandler()
51 if host and not no_proxy:
52 if host and not no_proxy:
52 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host})
53 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host})
53
54
54 authinfo = None
55 authinfo = None
55 if user and passwd:
56 if user and passwd:
56 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
57 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
57 passmgr.add_password(None, host, user, passwd)
58 passmgr.add_password(None, host, user, passwd)
58 authinfo = urllib2.ProxyBasicAuthHandler(passmgr)
59 authinfo = urllib2.ProxyBasicAuthHandler(passmgr)
59
60
60 opener = urllib2.build_opener(proxy_handler, authinfo)
61 opener = urllib2.build_opener(proxy_handler, authinfo)
61 urllib2.install_opener(opener)
62 urllib2.install_opener(opener)
62
63
63 def dev(self):
64 def dev(self):
64 return -1
65 return -1
65
66
66 def do_cmd(self, cmd, **args):
67 def do_cmd(self, cmd, **args):
67 self.ui.debug("sending %s command\n" % cmd)
68 self.ui.debug("sending %s command\n" % cmd)
68 q = {"cmd": cmd}
69 q = {"cmd": cmd}
69 q.update(args)
70 q.update(args)
70 qs = urllib.urlencode(q)
71 qs = urllib.urlencode(q)
71 cu = "%s?%s" % (self.url, qs)
72 cu = "%s?%s" % (self.url, qs)
72 resp = urllib2.urlopen(cu)
73 resp = urllib2.urlopen(cu)
73 proto = resp.headers['content-type']
74 proto = resp.headers['content-type']
74
75
75 # accept old "text/plain" and "application/hg-changegroup" for now
76 # accept old "text/plain" and "application/hg-changegroup" for now
76 if not proto.startswith('application/mercurial') and \
77 if not proto.startswith('application/mercurial') and \
77 not proto.startswith('text/plain') and \
78 not proto.startswith('text/plain') and \
78 not proto.startswith('application/hg-changegroup'):
79 not proto.startswith('application/hg-changegroup'):
79 raise RepoError("'%s' does not appear to be an hg repository"
80 raise hg.RepoError("'%s' does not appear to be an hg repository" %
80 % self.url)
81 self.url)
81
82
82 if proto.startswith('application/mercurial'):
83 if proto.startswith('application/mercurial'):
83 version = proto[22:]
84 version = proto[22:]
84 if float(version) > 0.1:
85 if float(version) > 0.1:
85 raise RepoError("'%s' uses newer protocol %s" %
86 raise hg.RepoError("'%s' uses newer protocol %s" %
86 (self.url, version))
87 (self.url, version))
87
88
88 return resp
89 return resp
89
90
90 def heads(self):
91 def heads(self):
91 d = self.do_cmd("heads").read()
92 d = self.do_cmd("heads").read()
92 try:
93 try:
93 return map(bin, d[:-1].split(" "))
94 return map(bin, d[:-1].split(" "))
94 except:
95 except:
95 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
96 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
96 raise
97 raise
97
98
98 def branches(self, nodes):
99 def branches(self, nodes):
99 n = " ".join(map(hex, nodes))
100 n = " ".join(map(hex, nodes))
100 d = self.do_cmd("branches", nodes=n).read()
101 d = self.do_cmd("branches", nodes=n).read()
101 try:
102 try:
102 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
103 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
103 return br
104 return br
104 except:
105 except:
105 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
106 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
106 raise
107 raise
107
108
108 def between(self, pairs):
109 def between(self, pairs):
109 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
110 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
110 d = self.do_cmd("between", pairs=n).read()
111 d = self.do_cmd("between", pairs=n).read()
111 try:
112 try:
112 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
113 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
113 return p
114 return p
114 except:
115 except:
115 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
116 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
116 raise
117 raise
117
118
118 def changegroup(self, nodes):
119 def changegroup(self, nodes):
119 n = " ".join(map(hex, nodes))
120 n = " ".join(map(hex, nodes))
120 f = self.do_cmd("changegroup", roots=n)
121 f = self.do_cmd("changegroup", roots=n)
121 bytes = 0
122 bytes = 0
122
123
123 class zread:
124 class zread:
124 def __init__(self, f):
125 def __init__(self, f):
125 self.zd = zlib.decompressobj()
126 self.zd = zlib.decompressobj()
126 self.f = f
127 self.f = f
127 self.buf = ""
128 self.buf = ""
128 def read(self, l):
129 def read(self, l):
129 while l > len(self.buf):
130 while l > len(self.buf):
130 r = self.f.read(4096)
131 r = self.f.read(4096)
131 if r:
132 if r:
132 self.buf += self.zd.decompress(r)
133 self.buf += self.zd.decompress(r)
133 else:
134 else:
134 self.buf += self.zd.flush()
135 self.buf += self.zd.flush()
135 break
136 break
136 d, self.buf = self.buf[:l], self.buf[l:]
137 d, self.buf = self.buf[:l], self.buf[l:]
137 return d
138 return d
138
139
139 return zread(f)
140 return zread(f)
140
141
141 class httpsrepository(httprepository):
142 class httpsrepository(httprepository):
142 pass
143 pass
@@ -1,129 +1,130 b''
1 # sshrepo.py - ssh repository proxy class for mercurial
1 # sshrepo.py - ssh repository proxy class for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 import os, re, select
9 from node import *
8 from node import *
10 from remoterepo import *
9 from remoterepo import *
10 from demandload import *
11 demandload(globals(), "hg os re select")
11
12
12 class sshrepository(remoterepository):
13 class sshrepository(remoterepository):
13 def __init__(self, ui, path):
14 def __init__(self, ui, path):
14 self.url = path
15 self.url = path
15 self.ui = ui
16 self.ui = ui
16
17
17 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
18 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
18 if not m:
19 if not m:
19 raise RepoError("couldn't parse destination %s" % path)
20 raise hg.RepoError("couldn't parse destination %s" % path)
20
21
21 self.user = m.group(2)
22 self.user = m.group(2)
22 self.host = m.group(3)
23 self.host = m.group(3)
23 self.port = m.group(5)
24 self.port = m.group(5)
24 self.path = m.group(7) or "."
25 self.path = m.group(7) or "."
25
26
26 args = self.user and ("%s@%s" % (self.user, self.host)) or self.host
27 args = self.user and ("%s@%s" % (self.user, self.host)) or self.host
27 args = self.port and ("%s -p %s") % (args, self.port) or args
28 args = self.port and ("%s -p %s") % (args, self.port) or args
28
29
29 sshcmd = self.ui.config("ui", "ssh", "ssh")
30 sshcmd = self.ui.config("ui", "ssh", "ssh")
30 remotecmd = self.ui.config("ui", "remotecmd", "hg")
31 remotecmd = self.ui.config("ui", "remotecmd", "hg")
31 cmd = "%s %s '%s -R %s serve --stdio'"
32 cmd = "%s %s '%s -R %s serve --stdio'"
32 cmd = cmd % (sshcmd, args, remotecmd, self.path)
33 cmd = cmd % (sshcmd, args, remotecmd, self.path)
33
34
34 self.pipeo, self.pipei, self.pipee = os.popen3(cmd)
35 self.pipeo, self.pipei, self.pipee = os.popen3(cmd)
35
36
36 def readerr(self):
37 def readerr(self):
37 while 1:
38 while 1:
38 r,w,x = select.select([self.pipee], [], [], 0)
39 r,w,x = select.select([self.pipee], [], [], 0)
39 if not r: break
40 if not r: break
40 l = self.pipee.readline()
41 l = self.pipee.readline()
41 if not l: break
42 if not l: break
42 self.ui.status("remote: ", l)
43 self.ui.status("remote: ", l)
43
44
44 def __del__(self):
45 def __del__(self):
45 try:
46 try:
46 self.pipeo.close()
47 self.pipeo.close()
47 self.pipei.close()
48 self.pipei.close()
48 for l in self.pipee:
49 for l in self.pipee:
49 self.ui.status("remote: ", l)
50 self.ui.status("remote: ", l)
50 self.pipee.close()
51 self.pipee.close()
51 except:
52 except:
52 pass
53 pass
53
54
54 def dev(self):
55 def dev(self):
55 return -1
56 return -1
56
57
57 def do_cmd(self, cmd, **args):
58 def do_cmd(self, cmd, **args):
58 self.ui.debug("sending %s command\n" % cmd)
59 self.ui.debug("sending %s command\n" % cmd)
59 self.pipeo.write("%s\n" % cmd)
60 self.pipeo.write("%s\n" % cmd)
60 for k, v in args.items():
61 for k, v in args.items():
61 self.pipeo.write("%s %d\n" % (k, len(v)))
62 self.pipeo.write("%s %d\n" % (k, len(v)))
62 self.pipeo.write(v)
63 self.pipeo.write(v)
63 self.pipeo.flush()
64 self.pipeo.flush()
64
65
65 return self.pipei
66 return self.pipei
66
67
67 def call(self, cmd, **args):
68 def call(self, cmd, **args):
68 r = self.do_cmd(cmd, **args)
69 r = self.do_cmd(cmd, **args)
69 l = r.readline()
70 l = r.readline()
70 self.readerr()
71 self.readerr()
71 try:
72 try:
72 l = int(l)
73 l = int(l)
73 except:
74 except:
74 raise RepoError("unexpected response '%s'" % l)
75 raise hg.RepoError("unexpected response '%s'" % l)
75 return r.read(l)
76 return r.read(l)
76
77
77 def lock(self):
78 def lock(self):
78 self.call("lock")
79 self.call("lock")
79 return remotelock(self)
80 return remotelock(self)
80
81
81 def unlock(self):
82 def unlock(self):
82 self.call("unlock")
83 self.call("unlock")
83
84
84 def heads(self):
85 def heads(self):
85 d = self.call("heads")
86 d = self.call("heads")
86 try:
87 try:
87 return map(bin, d[:-1].split(" "))
88 return map(bin, d[:-1].split(" "))
88 except:
89 except:
89 raise RepoError("unexpected response '%s'" % (d[:400] + "..."))
90 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
90
91
91 def branches(self, nodes):
92 def branches(self, nodes):
92 n = " ".join(map(hex, nodes))
93 n = " ".join(map(hex, nodes))
93 d = self.call("branches", nodes=n)
94 d = self.call("branches", nodes=n)
94 try:
95 try:
95 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
96 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
96 return br
97 return br
97 except:
98 except:
98 raise RepoError("unexpected response '%s'" % (d[:400] + "..."))
99 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
99
100
100 def between(self, pairs):
101 def between(self, pairs):
101 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
102 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
102 d = self.call("between", pairs=n)
103 d = self.call("between", pairs=n)
103 try:
104 try:
104 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
105 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
105 return p
106 return p
106 except:
107 except:
107 raise RepoError("unexpected response '%s'" % (d[:400] + "..."))
108 raise hg.RepoError("unexpected response '%s'" % (d[:400] + "..."))
108
109
109 def changegroup(self, nodes):
110 def changegroup(self, nodes):
110 n = " ".join(map(hex, nodes))
111 n = " ".join(map(hex, nodes))
111 f = self.do_cmd("changegroup", roots=n)
112 f = self.do_cmd("changegroup", roots=n)
112 return self.pipei
113 return self.pipei
113
114
114 def addchangegroup(self, cg):
115 def addchangegroup(self, cg):
115 d = self.call("addchangegroup")
116 d = self.call("addchangegroup")
116 if d:
117 if d:
117 raise RepoError("push refused: %s", d)
118 raise hg.RepoError("push refused: %s", d)
118
119
119 while 1:
120 while 1:
120 d = cg.read(4096)
121 d = cg.read(4096)
121 if not d: break
122 if not d: break
122 self.pipeo.write(d)
123 self.pipeo.write(d)
123 self.readerr()
124 self.readerr()
124
125
125 self.pipeo.flush()
126 self.pipeo.flush()
126
127
127 self.readerr()
128 self.readerr()
128 l = int(self.pipei.readline())
129 l = int(self.pipei.readline())
129 return self.pipei.read(l) != ""
130 return self.pipei.read(l) != ""
General Comments 0
You need to be logged in to leave comments. Login now