annotate upmana/mercurial/url.py @ 247:64728b1dfa57 beta

Traipse Beta 'OpenRPG' {101130-02} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Closed) New Features: New to Map, can re-order Grid, Miniatures, and Whiteboard layer draw order New to Server GUI, can now clear log New Earthdawn Dieroller New IronClaw roller, sheet, and image New ShapeShifter PC Sheet Updates: Update to Warhammer PC Sheet. Rollers set as macros. Should work with little maintanence. Update to Browser Server window. Display rooms with ' " & cleaner Update to Server. Handles ' " & cleaner Update to Dieroller. Cleaner, more effecient expression system Update to Hidden Die plugin, allows for non standard dice rolls Update to location.py, allows for more portable references when starting Traipse Update to the Features node Fixes: Fix to InterParse that was causing an Infernal Loop with Namespace Internal Fix to XML data, removed old Minidom and switched to Element Tree Fix to Server that was causing eternal attempt to find a Server ID, in Register Rooms thread Fix to metaservers.xml file not being created Fix to Single and Double quotes in Whiteboard text Fix to Background images not showing when using the Image Server Fix to Duplicate chat names appearing Fix to Server GUI's logging output Fix to FNB.COLORFUL_TABS bug Fix to Gametree for XSLT Sheets Fix to Gametree for locating gametree files Fix to Send to Chat from Gametree Fix to Gametree, renaming and remapping operates correctly Fix to aliaslib, prevents error caused when SafeHTML is sent None
author sirebral
date Tue, 30 Nov 2010 05:00:25 -0600
parents dcf4fbe09b70
children
rev   line source
135
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
1 # url.py - HTTP handling for mercurial
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
2 #
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
3 # Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
6 #
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
7 # This software may be used and distributed according to the terms of the
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
8 # GNU General Public License version 2, incorporated herein by reference.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
9
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
10 import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
11 from i18n import _
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
12 import keepalive, util
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
13
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
14 def hidepassword(url):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
15 '''hide user credential in a url string'''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
16 scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
17 netloc = re.sub('([^:]*):([^@]*)@(.*)', r'\1:***@\3', netloc)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
18 return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
19
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
20 def removeauth(url):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
21 '''remove all authentication information from a url string'''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
22 scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
23 netloc = netloc[netloc.find('@')+1:]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
24 return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
25
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
26 def netlocsplit(netloc):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
27 '''split [user[:passwd]@]host[:port] into 4-tuple.'''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
28
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
29 a = netloc.find('@')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
30 if a == -1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
31 user, passwd = None, None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
32 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
33 userpass, netloc = netloc[:a], netloc[a+1:]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
34 c = userpass.find(':')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
35 if c == -1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
36 user, passwd = urllib.unquote(userpass), None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
37 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
38 user = urllib.unquote(userpass[:c])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
39 passwd = urllib.unquote(userpass[c+1:])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
40 c = netloc.find(':')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
41 if c == -1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
42 host, port = netloc, None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
43 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
44 host, port = netloc[:c], netloc[c+1:]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
45 return host, port, user, passwd
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
46
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
47 def netlocunsplit(host, port, user=None, passwd=None):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
48 '''turn host, port, user, passwd into [user[:passwd]@]host[:port].'''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
49 if port:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
50 hostport = host + ':' + port
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
51 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
52 hostport = host
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
53 if user:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
54 if passwd:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
55 userpass = urllib.quote(user) + ':' + urllib.quote(passwd)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
56 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
57 userpass = urllib.quote(user)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
58 return userpass + '@' + hostport
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
59 return hostport
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
60
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
61 _safe = ('abcdefghijklmnopqrstuvwxyz'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
62 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
63 '0123456789' '_.-/')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
64 _safeset = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
65 _hex = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
66 def quotepath(path):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
67 '''quote the path part of a URL
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
68
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
69 This is similar to urllib.quote, but it also tries to avoid
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
70 quoting things twice (inspired by wget):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
71
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
72 >>> quotepath('abc def')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
73 'abc%20def'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
74 >>> quotepath('abc%20def')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
75 'abc%20def'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
76 >>> quotepath('abc%20 def')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
77 'abc%20%20def'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
78 >>> quotepath('abc def%20')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
79 'abc%20def%20'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
80 >>> quotepath('abc def%2')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
81 'abc%20def%252'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
82 >>> quotepath('abc def%')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
83 'abc%20def%25'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
84 '''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
85 global _safeset, _hex
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
86 if _safeset is None:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
87 _safeset = set(_safe)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
88 _hex = set('abcdefABCDEF0123456789')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
89 l = list(path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
90 for i in xrange(len(l)):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
91 c = l[i]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
92 if c == '%' and i + 2 < len(l) and (l[i+1] in _hex and l[i+2] in _hex):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
93 pass
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
94 elif c not in _safeset:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
95 l[i] = '%%%02X' % ord(c)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
96 return ''.join(l)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
97
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
98 class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
99 def __init__(self, ui):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
100 urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
101 self.ui = ui
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
102
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
103 def find_user_password(self, realm, authuri):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
104 authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
105 self, realm, authuri)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
106 user, passwd = authinfo
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
107 if user and passwd:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
108 self._writedebug(user, passwd)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
109 return (user, passwd)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
110
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
111 if not user:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
112 auth = self.readauthtoken(authuri)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
113 if auth:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
114 user, passwd = auth.get('username'), auth.get('password')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
115 if not user or not passwd:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
116 if not self.ui.interactive():
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
117 raise util.Abort(_('http authorization required'))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
118
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
119 self.ui.write(_("http authorization required\n"))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
120 self.ui.status(_("realm: %s\n") % realm)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
121 if user:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
122 self.ui.status(_("user: %s\n") % user)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
123 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
124 user = self.ui.prompt(_("user:"), default=None)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
125
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
126 if not passwd:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
127 passwd = self.ui.getpass()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
128
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
129 self.add_password(realm, authuri, user, passwd)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
130 self._writedebug(user, passwd)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
131 return (user, passwd)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
132
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
133 def _writedebug(self, user, passwd):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
134 msg = _('http auth: user %s, password %s\n')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
135 self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set'))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
136
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
137 def readauthtoken(self, uri):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
138 # Read configuration
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
139 config = dict()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
140 for key, val in self.ui.configitems('auth'):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
141 group, setting = key.split('.', 1)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
142 gdict = config.setdefault(group, dict())
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
143 gdict[setting] = val
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
144
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
145 # Find the best match
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
146 scheme, hostpath = uri.split('://', 1)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
147 bestlen = 0
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
148 bestauth = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
149 for auth in config.itervalues():
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
150 prefix = auth.get('prefix')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
151 if not prefix: continue
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
152 p = prefix.split('://', 1)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
153 if len(p) > 1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
154 schemes, prefix = [p[0]], p[1]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
155 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
156 schemes = (auth.get('schemes') or 'https').split()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
157 if (prefix == '*' or hostpath.startswith(prefix)) and \
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
158 len(prefix) > bestlen and scheme in schemes:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
159 bestlen = len(prefix)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
160 bestauth = auth
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
161 return bestauth
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
162
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
163 class proxyhandler(urllib2.ProxyHandler):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
164 def __init__(self, ui):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
165 proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
166 # XXX proxyauthinfo = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
167
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
168 if proxyurl:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
169 # proxy can be proper url or host[:port]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
170 if not (proxyurl.startswith('http:') or
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
171 proxyurl.startswith('https:')):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
172 proxyurl = 'http://' + proxyurl + '/'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
173 snpqf = urlparse.urlsplit(proxyurl)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
174 proxyscheme, proxynetloc, proxypath, proxyquery, proxyfrag = snpqf
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
175 hpup = netlocsplit(proxynetloc)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
176
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
177 proxyhost, proxyport, proxyuser, proxypasswd = hpup
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
178 if not proxyuser:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
179 proxyuser = ui.config("http_proxy", "user")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
180 proxypasswd = ui.config("http_proxy", "passwd")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
181
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
182 # see if we should use a proxy for this url
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
183 no_list = [ "localhost", "127.0.0.1" ]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
184 no_list.extend([p.lower() for
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
185 p in ui.configlist("http_proxy", "no")])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
186 no_list.extend([p.strip().lower() for
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
187 p in os.getenv("no_proxy", '').split(',')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
188 if p.strip()])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
189 # "http_proxy.always" config is for running tests on localhost
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
190 if ui.configbool("http_proxy", "always"):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
191 self.no_list = []
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
192 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
193 self.no_list = no_list
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
194
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
195 proxyurl = urlparse.urlunsplit((
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
196 proxyscheme, netlocunsplit(proxyhost, proxyport,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
197 proxyuser, proxypasswd or ''),
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
198 proxypath, proxyquery, proxyfrag))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
199 proxies = {'http': proxyurl, 'https': proxyurl}
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
200 ui.debug(_('proxying through http://%s:%s\n') %
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
201 (proxyhost, proxyport))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
202 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
203 proxies = {}
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
204
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
205 # urllib2 takes proxy values from the environment and those
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
206 # will take precedence if found, so drop them
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
207 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
208 try:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
209 if env in os.environ:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
210 del os.environ[env]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
211 except OSError:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
212 pass
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
213
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
214 urllib2.ProxyHandler.__init__(self, proxies)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
215 self.ui = ui
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
216
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
217 def proxy_open(self, req, proxy, type_):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
218 host = req.get_host().split(':')[0]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
219 if host in self.no_list:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
220 return None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
221
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
222 # work around a bug in Python < 2.4.2
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
223 # (it leaves a "\n" at the end of Proxy-authorization headers)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
224 baseclass = req.__class__
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
225 class _request(baseclass):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
226 def add_header(self, key, val):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
227 if key.lower() == 'proxy-authorization':
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
228 val = val.strip()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
229 return baseclass.add_header(self, key, val)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
230 req.__class__ = _request
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
231
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
232 return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
233
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
234 class httpsendfile(file):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
235 def __len__(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
236 return os.fstat(self.fileno()).st_size
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
237
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
238 def _gen_sendfile(connection):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
239 def _sendfile(self, data):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
240 # send a file
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
241 if isinstance(data, httpsendfile):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
242 # if auth required, some data sent twice, so rewind here
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
243 data.seek(0)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
244 for chunk in util.filechunkiter(data):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
245 connection.send(self, chunk)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
246 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
247 connection.send(self, data)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
248 return _sendfile
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
249
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
250 has_https = hasattr(urllib2, 'HTTPSHandler')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
251 if has_https:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
252 try:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
253 # avoid using deprecated/broken FakeSocket in python 2.6
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
254 import ssl
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
255 _ssl_wrap_socket = ssl.wrap_socket
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
256 except ImportError:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
257 def _ssl_wrap_socket(sock, key_file, cert_file):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
258 ssl = socket.ssl(sock, key_file, cert_file)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
259 return httplib.FakeSocket(sock, ssl)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
260
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
261 class httpconnection(keepalive.HTTPConnection):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
262 # must be able to send big bundle as stream.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
263 send = _gen_sendfile(keepalive.HTTPConnection)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
264
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
265 def _proxytunnel(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
266 proxyheaders = dict(
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
267 [(x, self.headers[x]) for x in self.headers
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
268 if x.lower().startswith('proxy-')])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
269 self._set_hostport(self.host, self.port)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
270 self.send('CONNECT %s:%d HTTP/1.0\r\n' % (self.realhost, self.realport))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
271 for header in proxyheaders.iteritems():
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
272 self.send('%s: %s\r\n' % header)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
273 self.send('\r\n')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
274
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
275 # majority of the following code is duplicated from
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
276 # httplib.HTTPConnection as there are no adequate places to
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
277 # override functions to provide the needed functionality
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
278 res = self.response_class(self.sock,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
279 strict=self.strict,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
280 method=self._method)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
281
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
282 while True:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
283 version, status, reason = res._read_status()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
284 if status != httplib.CONTINUE:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
285 break
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
286 while True:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
287 skip = res.fp.readline().strip()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
288 if not skip:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
289 break
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
290 res.status = status
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
291 res.reason = reason.strip()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
292
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
293 if res.status == 200:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
294 while True:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
295 line = res.fp.readline()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
296 if line == '\r\n':
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
297 break
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
298 return True
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
299
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
300 if version == 'HTTP/1.0':
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
301 res.version = 10
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
302 elif version.startswith('HTTP/1.'):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
303 res.version = 11
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
304 elif version == 'HTTP/0.9':
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
305 res.version = 9
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
306 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
307 raise httplib.UnknownProtocol(version)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
308
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
309 if res.version == 9:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
310 res.length = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
311 res.chunked = 0
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
312 res.will_close = 1
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
313 res.msg = httplib.HTTPMessage(cStringIO.StringIO())
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
314 return False
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
315
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
316 res.msg = httplib.HTTPMessage(res.fp)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
317 res.msg.fp = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
318
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
319 # are we using the chunked-style of transfer encoding?
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
320 trenc = res.msg.getheader('transfer-encoding')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
321 if trenc and trenc.lower() == "chunked":
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
322 res.chunked = 1
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
323 res.chunk_left = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
324 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
325 res.chunked = 0
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
326
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
327 # will the connection close at the end of the response?
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
328 res.will_close = res._check_close()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
329
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
330 # do we have a Content-Length?
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
331 # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
332 length = res.msg.getheader('content-length')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
333 if length and not res.chunked:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
334 try:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
335 res.length = int(length)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
336 except ValueError:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
337 res.length = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
338 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
339 if res.length < 0: # ignore nonsensical negative lengths
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
340 res.length = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
341 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
342 res.length = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
343
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
344 # does the body have a fixed length? (of zero)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
345 if (status == httplib.NO_CONTENT or status == httplib.NOT_MODIFIED or
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
346 100 <= status < 200 or # 1xx codes
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
347 res._method == 'HEAD'):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
348 res.length = 0
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
349
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
350 # if the connection remains open, and we aren't using chunked, and
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
351 # a content-length was not provided, then assume that the connection
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
352 # WILL close.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
353 if (not res.will_close and
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
354 not res.chunked and
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
355 res.length is None):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
356 res.will_close = 1
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
357
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
358 self.proxyres = res
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
359
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
360 return False
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
361
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
362 def connect(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
363 if has_https and self.realhost: # use CONNECT proxy
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
364 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
365 self.sock.connect((self.host, self.port))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
366 if self._proxytunnel():
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
367 # we do not support client x509 certificates
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
368 self.sock = _ssl_wrap_socket(self.sock, None, None)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
369 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
370 keepalive.HTTPConnection.connect(self)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
371
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
372 def getresponse(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
373 proxyres = getattr(self, 'proxyres', None)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
374 if proxyres:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
375 if proxyres.will_close:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
376 self.close()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
377 self.proxyres = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
378 return proxyres
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
379 return keepalive.HTTPConnection.getresponse(self)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
380
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
381 class httphandler(keepalive.HTTPHandler):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
382 def http_open(self, req):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
383 return self.do_open(httpconnection, req)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
384
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
385 def _start_transaction(self, h, req):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
386 if req.get_selector() == req.get_full_url(): # has proxy
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
387 urlparts = urlparse.urlparse(req.get_selector())
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
388 if urlparts[0] == 'https': # only use CONNECT for HTTPS
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
389 if ':' in urlparts[1]:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
390 realhost, realport = urlparts[1].split(':')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
391 realport = int(realport)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
392 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
393 realhost = urlparts[1]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
394 realport = 443
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
395
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
396 h.realhost = realhost
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
397 h.realport = realport
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
398 h.headers = req.headers.copy()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
399 h.headers.update(self.parent.addheaders)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
400 return keepalive.HTTPHandler._start_transaction(self, h, req)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
401
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
402 h.realhost = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
403 h.realport = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
404 h.headers = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
405 return keepalive.HTTPHandler._start_transaction(self, h, req)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
406
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
407 def __del__(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
408 self.close_all()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
409
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
410 if has_https:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
411 class httpsconnection(httplib.HTTPSConnection):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
412 response_class = keepalive.HTTPResponse
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
413 # must be able to send big bundle as stream.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
414 send = _gen_sendfile(httplib.HTTPSConnection)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
415
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
416 class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
417 def __init__(self, ui):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
418 keepalive.KeepAliveHandler.__init__(self)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
419 urllib2.HTTPSHandler.__init__(self)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
420 self.ui = ui
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
421 self.pwmgr = passwordmgr(self.ui)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
422
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
423 def https_open(self, req):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
424 self.auth = self.pwmgr.readauthtoken(req.get_full_url())
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
425 return self.do_open(self._makeconnection, req)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
426
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
427 def _makeconnection(self, host, port=443, *args, **kwargs):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
428 keyfile = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
429 certfile = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
430
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
431 if args: # key_file
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
432 keyfile = args.pop(0)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
433 if args: # cert_file
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
434 certfile = args.pop(0)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
435
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
436 # if the user has specified different key/cert files in
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
437 # hgrc, we prefer these
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
438 if self.auth and 'key' in self.auth and 'cert' in self.auth:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
439 keyfile = self.auth['key']
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
440 certfile = self.auth['cert']
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
441
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
442 # let host port take precedence
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
443 if ':' in host and '[' not in host or ']:' in host:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
444 host, port = host.rsplit(':', 1)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
445 port = int(port)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
446 if '[' in host:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
447 host = host[1:-1]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
448
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
449 return httpsconnection(host, port, keyfile, certfile, *args, **kwargs)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
450
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
451 # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
452 # it doesn't know about the auth type requested. This can happen if
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
453 # somebody is using BasicAuth and types a bad password.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
454 class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
455 def http_error_auth_reqed(self, auth_header, host, req, headers):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
456 try:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
457 return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
458 self, auth_header, host, req, headers)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
459 except ValueError, inst:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
460 arg = inst.args[0]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
461 if arg.startswith("AbstractDigestAuthHandler doesn't know "):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
462 return
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
463 raise
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
464
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
465 def getauthinfo(path):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
466 scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
467 if not urlpath:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
468 urlpath = '/'
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
469 if scheme != 'file':
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
470 # XXX: why are we quoting the path again with some smart
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
471 # heuristic here? Anyway, it cannot be done with file://
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
472 # urls since path encoding is os/fs dependent (see
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
473 # urllib.pathname2url() for details).
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
474 urlpath = quotepath(urlpath)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
475 host, port, user, passwd = netlocsplit(netloc)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
476
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
477 # urllib cannot handle URLs with embedded user or passwd
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
478 url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
479 urlpath, query, frag))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
480 if user:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
481 netloc = host
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
482 if port:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
483 netloc += ':' + port
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
484 # Python < 2.4.3 uses only the netloc to search for a password
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
485 authinfo = (None, (url, netloc), user, passwd or '')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
486 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
487 authinfo = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
488 return url, authinfo
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
489
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
490 def opener(ui, authinfo=None):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
491 '''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
492 construct an opener suitable for urllib2
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
493 authinfo will be added to the password manager
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
494 '''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
495 handlers = [httphandler()]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
496 if has_https:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
497 handlers.append(httpshandler(ui))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
498
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
499 handlers.append(proxyhandler(ui))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
500
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
501 passmgr = passwordmgr(ui)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
502 if authinfo is not None:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
503 passmgr.add_password(*authinfo)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
504 user, passwd = authinfo[2:4]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
505 ui.debug(_('http auth: user %s, password %s\n') %
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
506 (user, passwd and '*' * len(passwd) or 'not set'))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
507
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
508 handlers.extend((urllib2.HTTPBasicAuthHandler(passmgr),
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
509 httpdigestauthhandler(passmgr)))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
510 opener = urllib2.build_opener(*handlers)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
511
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
512 # 1.0 here is the _protocol_ version
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
513 opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
514 opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
515 return opener
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
516
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
517 scheme_re = re.compile(r'^([a-zA-Z0-9+-.]+)://')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
518
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
519 def open(ui, url, data=None):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
520 scheme = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
521 m = scheme_re.search(url)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
522 if m:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
523 scheme = m.group(1).lower()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
524 if not scheme:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
525 path = util.normpath(os.path.abspath(url))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
526 url = 'file://' + urllib.pathname2url(path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
527 authinfo = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
528 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
529 url, authinfo = getauthinfo(url)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
530 return opener(ui, authinfo).open(url, data)