annotate upmana/mercurial/url.py @ 121:496dbf12a6cb alpha

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