##// END OF EJS Templates
httpconnection: convert url to bytes in readauthforuri...
Augie Fackler -
r36669:6b1eb4c6 default
parent child Browse files
Show More
@@ -1,107 +1,109 b''
1 # httpconnection.py - urllib2 handler for new http support
1 # httpconnection.py - urllib2 handler for new http support
2 #
2 #
3 # Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
6 # Copyright 2011 Google, Inc.
6 # Copyright 2011 Google, Inc.
7 #
7 #
8 # This software may be used and distributed according to the terms of the
8 # This software may be used and distributed according to the terms of the
9 # GNU General Public License version 2 or any later version.
9 # GNU General Public License version 2 or any later version.
10
10
11 from __future__ import absolute_import
11 from __future__ import absolute_import
12
12
13 import os
13 import os
14
14
15 from .i18n import _
15 from .i18n import _
16 from . import (
16 from . import (
17 pycompat,
17 util,
18 util,
18 )
19 )
19
20
20 urlerr = util.urlerr
21 urlerr = util.urlerr
21 urlreq = util.urlreq
22 urlreq = util.urlreq
22
23
23 # moved here from url.py to avoid a cycle
24 # moved here from url.py to avoid a cycle
24 class httpsendfile(object):
25 class httpsendfile(object):
25 """This is a wrapper around the objects returned by python's "open".
26 """This is a wrapper around the objects returned by python's "open".
26
27
27 Its purpose is to send file-like objects via HTTP.
28 Its purpose is to send file-like objects via HTTP.
28 It do however not define a __len__ attribute because the length
29 It do however not define a __len__ attribute because the length
29 might be more than Py_ssize_t can handle.
30 might be more than Py_ssize_t can handle.
30 """
31 """
31
32
32 def __init__(self, ui, *args, **kwargs):
33 def __init__(self, ui, *args, **kwargs):
33 self.ui = ui
34 self.ui = ui
34 self._data = open(*args, **kwargs)
35 self._data = open(*args, **kwargs)
35 self.seek = self._data.seek
36 self.seek = self._data.seek
36 self.close = self._data.close
37 self.close = self._data.close
37 self.write = self._data.write
38 self.write = self._data.write
38 self.length = os.fstat(self._data.fileno()).st_size
39 self.length = os.fstat(self._data.fileno()).st_size
39 self._pos = 0
40 self._pos = 0
40 self._total = self.length // 1024 * 2
41 self._total = self.length // 1024 * 2
41
42
42 def read(self, *args, **kwargs):
43 def read(self, *args, **kwargs):
43 ret = self._data.read(*args, **kwargs)
44 ret = self._data.read(*args, **kwargs)
44 if not ret:
45 if not ret:
45 self.ui.progress(_('sending'), None)
46 self.ui.progress(_('sending'), None)
46 return ret
47 return ret
47 self._pos += len(ret)
48 self._pos += len(ret)
48 # We pass double the max for total because we currently have
49 # We pass double the max for total because we currently have
49 # to send the bundle twice in the case of a server that
50 # to send the bundle twice in the case of a server that
50 # requires authentication. Since we can't know until we try
51 # requires authentication. Since we can't know until we try
51 # once whether authentication will be required, just lie to
52 # once whether authentication will be required, just lie to
52 # the user and maybe the push succeeds suddenly at 50%.
53 # the user and maybe the push succeeds suddenly at 50%.
53 self.ui.progress(_('sending'), self._pos // 1024,
54 self.ui.progress(_('sending'), self._pos // 1024,
54 unit=_('kb'), total=self._total)
55 unit=_('kb'), total=self._total)
55 return ret
56 return ret
56
57
57 def __enter__(self):
58 def __enter__(self):
58 return self
59 return self
59
60
60 def __exit__(self, exc_type, exc_val, exc_tb):
61 def __exit__(self, exc_type, exc_val, exc_tb):
61 self.close()
62 self.close()
62
63
63 # moved here from url.py to avoid a cycle
64 # moved here from url.py to avoid a cycle
64 def readauthforuri(ui, uri, user):
65 def readauthforuri(ui, uri, user):
66 uri = pycompat.bytesurl(uri)
65 # Read configuration
67 # Read configuration
66 groups = {}
68 groups = {}
67 for key, val in ui.configitems('auth'):
69 for key, val in ui.configitems('auth'):
68 if key in ('cookiefile',):
70 if key in ('cookiefile',):
69 continue
71 continue
70
72
71 if '.' not in key:
73 if '.' not in key:
72 ui.warn(_("ignoring invalid [auth] key '%s'\n") % key)
74 ui.warn(_("ignoring invalid [auth] key '%s'\n") % key)
73 continue
75 continue
74 group, setting = key.rsplit('.', 1)
76 group, setting = key.rsplit('.', 1)
75 gdict = groups.setdefault(group, {})
77 gdict = groups.setdefault(group, {})
76 if setting in ('username', 'cert', 'key'):
78 if setting in ('username', 'cert', 'key'):
77 val = util.expandpath(val)
79 val = util.expandpath(val)
78 gdict[setting] = val
80 gdict[setting] = val
79
81
80 # Find the best match
82 # Find the best match
81 scheme, hostpath = uri.split('://', 1)
83 scheme, hostpath = uri.split('://', 1)
82 bestuser = None
84 bestuser = None
83 bestlen = 0
85 bestlen = 0
84 bestauth = None
86 bestauth = None
85 for group, auth in groups.iteritems():
87 for group, auth in groups.iteritems():
86 if user and user != auth.get('username', user):
88 if user and user != auth.get('username', user):
87 # If a username was set in the URI, the entry username
89 # If a username was set in the URI, the entry username
88 # must either match it or be unset
90 # must either match it or be unset
89 continue
91 continue
90 prefix = auth.get('prefix')
92 prefix = auth.get('prefix')
91 if not prefix:
93 if not prefix:
92 continue
94 continue
93 p = prefix.split('://', 1)
95 p = prefix.split('://', 1)
94 if len(p) > 1:
96 if len(p) > 1:
95 schemes, prefix = [p[0]], p[1]
97 schemes, prefix = [p[0]], p[1]
96 else:
98 else:
97 schemes = (auth.get('schemes') or 'https').split()
99 schemes = (auth.get('schemes') or 'https').split()
98 if (prefix == '*' or hostpath.startswith(prefix)) and \
100 if (prefix == '*' or hostpath.startswith(prefix)) and \
99 (len(prefix) > bestlen or (len(prefix) == bestlen and \
101 (len(prefix) > bestlen or (len(prefix) == bestlen and \
100 not bestuser and 'username' in auth)) \
102 not bestuser and 'username' in auth)) \
101 and scheme in schemes:
103 and scheme in schemes:
102 bestlen = len(prefix)
104 bestlen = len(prefix)
103 bestauth = group, auth
105 bestauth = group, auth
104 bestuser = auth.get('username')
106 bestuser = auth.get('username')
105 if user and not bestuser:
107 if user and not bestuser:
106 auth['username'] = user
108 auth['username'] = user
107 return bestauth
109 return bestauth
General Comments 0
You need to be logged in to leave comments. Login now