Mercurial > hg
annotate mercurial/httpconnection.py @ 36637:e8c361316803
py3: silence the final IOError by closing stdout/err slightly early
Fixes the following test failure:
$ hg status >/dev/full
abort: No space left on device
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' ...
OSError: [Errno 28] No space left on device
[120]
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Fri, 02 Mar 2018 22:35:20 -0500 |
parents | 23d12524a202 |
children | 6b1eb4c610b4 |
rev | line source |
---|---|
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
1 # httpconnection.py - urllib2 handler for new http support |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
2 # |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br> |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
6 # Copyright 2011 Google, Inc. |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
7 # |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
8 # This software may be used and distributed according to the terms of the |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
9 # GNU General Public License version 2 or any later version. |
27521
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
10 |
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
11 from __future__ import absolute_import |
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
12 |
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
13 import os |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
14 |
27521
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
15 from .i18n import _ |
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
16 from . import ( |
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
17 util, |
b1adf32b0605
httpconnection: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26347
diff
changeset
|
18 ) |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
19 |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28526
diff
changeset
|
20 urlerr = util.urlerr |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28526
diff
changeset
|
21 urlreq = util.urlreq |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28526
diff
changeset
|
22 |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
23 # moved here from url.py to avoid a cycle |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
24 class httpsendfile(object): |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
25 """This is a wrapper around the objects returned by python's "open". |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
26 |
15152
94b200a11cf7
http: handle push of bundles > 2 GB again (issue3017)
Mads Kiilerich <mads@kiilerich.com>
parents:
15025
diff
changeset
|
27 Its purpose is to send file-like objects via HTTP. |
94b200a11cf7
http: handle push of bundles > 2 GB again (issue3017)
Mads Kiilerich <mads@kiilerich.com>
parents:
15025
diff
changeset
|
28 It do however not define a __len__ attribute because the length |
94b200a11cf7
http: handle push of bundles > 2 GB again (issue3017)
Mads Kiilerich <mads@kiilerich.com>
parents:
15025
diff
changeset
|
29 might be more than Py_ssize_t can handle. |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
30 """ |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
31 |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
32 def __init__(self, ui, *args, **kwargs): |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
33 self.ui = ui |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
34 self._data = open(*args, **kwargs) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
35 self.seek = self._data.seek |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
36 self.close = self._data.close |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
37 self.write = self._data.write |
15152
94b200a11cf7
http: handle push of bundles > 2 GB again (issue3017)
Mads Kiilerich <mads@kiilerich.com>
parents:
15025
diff
changeset
|
38 self.length = os.fstat(self._data.fileno()).st_size |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
39 self._pos = 0 |
15791
a814f8fcc65a
Use explicit integer division
Martin Geisler <mg@aragost.com>
parents:
15288
diff
changeset
|
40 self._total = self.length // 1024 * 2 |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
41 |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
42 def read(self, *args, **kwargs): |
31488
766364caae14
httpconnection: make sure to clear progress of httpsendfile at EOF
Yuya Nishihara <yuya@tcha.org>
parents:
31300
diff
changeset
|
43 ret = self._data.read(*args, **kwargs) |
766364caae14
httpconnection: make sure to clear progress of httpsendfile at EOF
Yuya Nishihara <yuya@tcha.org>
parents:
31300
diff
changeset
|
44 if not ret: |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
45 self.ui.progress(_('sending'), None) |
31488
766364caae14
httpconnection: make sure to clear progress of httpsendfile at EOF
Yuya Nishihara <yuya@tcha.org>
parents:
31300
diff
changeset
|
46 return ret |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
47 self._pos += len(ret) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
48 # We pass double the max for total because we currently have |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
49 # to send the bundle twice in the case of a server that |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
50 # requires authentication. Since we can't know until we try |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
51 # once whether authentication will be required, just lie to |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
52 # the user and maybe the push succeeds suddenly at 50%. |
15791
a814f8fcc65a
Use explicit integer division
Martin Geisler <mg@aragost.com>
parents:
15288
diff
changeset
|
53 self.ui.progress(_('sending'), self._pos // 1024, |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
54 unit=_('kb'), total=self._total) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
55 return ret |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
56 |
30142
3dcaf1c4e90d
largefiles: use context for file closing
Mads Kiilerich <madski@unity3d.com>
parents:
29250
diff
changeset
|
57 def __enter__(self): |
3dcaf1c4e90d
largefiles: use context for file closing
Mads Kiilerich <madski@unity3d.com>
parents:
29250
diff
changeset
|
58 return self |
3dcaf1c4e90d
largefiles: use context for file closing
Mads Kiilerich <madski@unity3d.com>
parents:
29250
diff
changeset
|
59 |
3dcaf1c4e90d
largefiles: use context for file closing
Mads Kiilerich <madski@unity3d.com>
parents:
29250
diff
changeset
|
60 def __exit__(self, exc_type, exc_val, exc_tb): |
3dcaf1c4e90d
largefiles: use context for file closing
Mads Kiilerich <madski@unity3d.com>
parents:
29250
diff
changeset
|
61 self.close() |
3dcaf1c4e90d
largefiles: use context for file closing
Mads Kiilerich <madski@unity3d.com>
parents:
29250
diff
changeset
|
62 |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
63 # moved here from url.py to avoid a cycle |
15025
0593e8f81c71
http: pass user to readauthforuri() (fix 4a43e23b8c55)
Patrick Mezard <pmezard@gmail.com>
parents:
15005
diff
changeset
|
64 def readauthforuri(ui, uri, user): |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
65 # Read configuration |
31300
0c8a042b193d
httpconnection: rename config to groups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31299
diff
changeset
|
66 groups = {} |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
67 for key, val in ui.configitems('auth'): |
31935
566cb89050b7
httpconnection: allow a global auth.cookiefile config entry
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31488
diff
changeset
|
68 if key in ('cookiefile',): |
566cb89050b7
httpconnection: allow a global auth.cookiefile config entry
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31488
diff
changeset
|
69 continue |
566cb89050b7
httpconnection: allow a global auth.cookiefile config entry
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31488
diff
changeset
|
70 |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
71 if '.' not in key: |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
72 ui.warn(_("ignoring invalid [auth] key '%s'\n") % key) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
73 continue |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
74 group, setting = key.rsplit('.', 1) |
31300
0c8a042b193d
httpconnection: rename config to groups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31299
diff
changeset
|
75 gdict = groups.setdefault(group, {}) |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
76 if setting in ('username', 'cert', 'key'): |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
77 val = util.expandpath(val) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
78 gdict[setting] = val |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
79 |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
80 # Find the best match |
25206
18a032704f0a
httpconnection: drop Python 2.4 specify hack
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
19809
diff
changeset
|
81 scheme, hostpath = uri.split('://', 1) |
15005
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
82 bestuser = None |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
83 bestlen = 0 |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
84 bestauth = None |
31300
0c8a042b193d
httpconnection: rename config to groups
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31299
diff
changeset
|
85 for group, auth in groups.iteritems(): |
15005
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
86 if user and user != auth.get('username', user): |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
87 # If a username was set in the URI, the entry username |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
88 # must either match it or be unset |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
89 continue |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
90 prefix = auth.get('prefix') |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
91 if not prefix: |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
92 continue |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
93 p = prefix.split('://', 1) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
94 if len(p) > 1: |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
95 schemes, prefix = [p[0]], p[1] |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
96 else: |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
97 schemes = (auth.get('schemes') or 'https').split() |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
98 if (prefix == '*' or hostpath.startswith(prefix)) and \ |
15005
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
99 (len(prefix) > bestlen or (len(prefix) == bestlen and \ |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
100 not bestuser and 'username' in auth)) \ |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
101 and scheme in schemes: |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
102 bestlen = len(prefix) |
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
103 bestauth = group, auth |
15005
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
104 bestuser = auth.get('username') |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
105 if user and not bestuser: |
4a43e23b8c55
hgweb: do not ignore [auth] if url has a username (issue2822)
Patrick Mezard <pmezard@gmail.com>
parents:
14430
diff
changeset
|
106 auth['username'] = user |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
107 return bestauth |