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