Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/httprepo.py @ 1089:142b5d5ec9cc
Break apart hg.py
- move the various parts of hg.py into their own files
- create node.py to store node manipulation functions
author | mpm@selenic.com |
---|---|
date | Sat, 27 Aug 2005 14:21:25 -0700 |
parents | mercurial/hg.py@05dc7aba22eb |
children | 84cf8834efb5 |
comparison
equal
deleted
inserted
replaced
1088:39b916b1d8e4 | 1089:142b5d5ec9cc |
---|---|
1 # httprepo.py - HTTP repository proxy classes for mercurial | |
2 # | |
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms | |
6 # of the GNU General Public License, incorporated herein by reference. | |
7 | |
8 import urllib, urllib2, urlparse, os, zlib | |
9 from node import * | |
10 from remoterepo import * | |
11 | |
12 class httprepository(remoterepository): | |
13 def __init__(self, ui, path): | |
14 # fix missing / after hostname | |
15 s = urlparse.urlsplit(path) | |
16 partial = s[2] | |
17 if not partial: partial = "/" | |
18 self.url = urlparse.urlunsplit((s[0], s[1], partial, '', '')) | |
19 self.ui = ui | |
20 no_list = [ "localhost", "127.0.0.1" ] | |
21 host = ui.config("http_proxy", "host") | |
22 if host is None: | |
23 host = os.environ.get("http_proxy") | |
24 if host and host.startswith('http://'): | |
25 host = host[7:] | |
26 user = ui.config("http_proxy", "user") | |
27 passwd = ui.config("http_proxy", "passwd") | |
28 no = ui.config("http_proxy", "no") | |
29 if no is None: | |
30 no = os.environ.get("no_proxy") | |
31 if no: | |
32 no_list = no_list + no.split(",") | |
33 | |
34 no_proxy = 0 | |
35 for h in no_list: | |
36 if (path.startswith("http://" + h + "/") or | |
37 path.startswith("http://" + h + ":") or | |
38 path == "http://" + h): | |
39 no_proxy = 1 | |
40 | |
41 # Note: urllib2 takes proxy values from the environment and those will | |
42 # take precedence | |
43 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]: | |
44 try: | |
45 if os.environ.has_key(env): | |
46 del os.environ[env] | |
47 except OSError: | |
48 pass | |
49 | |
50 proxy_handler = urllib2.BaseHandler() | |
51 if host and not no_proxy: | |
52 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host}) | |
53 | |
54 authinfo = None | |
55 if user and passwd: | |
56 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() | |
57 passmgr.add_password(None, host, user, passwd) | |
58 authinfo = urllib2.ProxyBasicAuthHandler(passmgr) | |
59 | |
60 opener = urllib2.build_opener(proxy_handler, authinfo) | |
61 urllib2.install_opener(opener) | |
62 | |
63 def dev(self): | |
64 return -1 | |
65 | |
66 def do_cmd(self, cmd, **args): | |
67 self.ui.debug("sending %s command\n" % cmd) | |
68 q = {"cmd": cmd} | |
69 q.update(args) | |
70 qs = urllib.urlencode(q) | |
71 cu = "%s?%s" % (self.url, qs) | |
72 resp = urllib2.urlopen(cu) | |
73 proto = resp.headers['content-type'] | |
74 | |
75 # accept old "text/plain" and "application/hg-changegroup" for now | |
76 if not proto.startswith('application/mercurial') and \ | |
77 not proto.startswith('text/plain') and \ | |
78 not proto.startswith('application/hg-changegroup'): | |
79 raise RepoError("'%s' does not appear to be an hg repository" | |
80 % self.url) | |
81 | |
82 if proto.startswith('application/mercurial'): | |
83 version = proto[22:] | |
84 if float(version) > 0.1: | |
85 raise RepoError("'%s' uses newer protocol %s" % | |
86 (self.url, version)) | |
87 | |
88 return resp | |
89 | |
90 def heads(self): | |
91 d = self.do_cmd("heads").read() | |
92 try: | |
93 return map(bin, d[:-1].split(" ")) | |
94 except: | |
95 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
96 raise | |
97 | |
98 def branches(self, nodes): | |
99 n = " ".join(map(hex, nodes)) | |
100 d = self.do_cmd("branches", nodes=n).read() | |
101 try: | |
102 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] | |
103 return br | |
104 except: | |
105 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
106 raise | |
107 | |
108 def between(self, pairs): | |
109 n = "\n".join(["-".join(map(hex, p)) for p in pairs]) | |
110 d = self.do_cmd("between", pairs=n).read() | |
111 try: | |
112 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] | |
113 return p | |
114 except: | |
115 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
116 raise | |
117 | |
118 def changegroup(self, nodes): | |
119 n = " ".join(map(hex, nodes)) | |
120 f = self.do_cmd("changegroup", roots=n) | |
121 bytes = 0 | |
122 | |
123 class zread: | |
124 def __init__(self, f): | |
125 self.zd = zlib.decompressobj() | |
126 self.f = f | |
127 self.buf = "" | |
128 def read(self, l): | |
129 while l > len(self.buf): | |
130 r = self.f.read(4096) | |
131 if r: | |
132 self.buf += self.zd.decompress(r) | |
133 else: | |
134 self.buf += self.zd.flush() | |
135 break | |
136 d, self.buf = self.buf[:l], self.buf[l:] | |
137 return d | |
138 | |
139 return zread(f) | |
140 | |
141 class httpsrepository(httprepository): | |
142 pass |