Mercurial > hg
annotate mercurial/httppeer.py @ 37139:aa55c5354b8f
alias: reject non-ascii characters in user help/doc strings
Since command doc/help texts are passed to i18n.gettext(), they must be
ASCII. Otherwise, UnicodeError would be raised.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Wed, 28 Mar 2018 22:04:45 +0900 |
parents | 8e89c2bec1f7 |
children | 39f7d4ee8bcd |
rev | line source |
---|---|
17192
1ac628cd7113
peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
15246
diff
changeset
|
1 # httppeer.py - HTTP repository proxy classes for mercurial |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
2 # |
2859 | 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
5 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8206
diff
changeset
|
6 # This software may be used and distributed according to the terms of the |
10263 | 7 # GNU General Public License version 2 or any later version. |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
8 |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
9 from __future__ import absolute_import |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
10 |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
11 import errno |
33821
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
12 import io |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 import os |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 import socket |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
15 import struct |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
16 import tempfile |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
17 |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 from .i18n import _ |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
19 from . import ( |
28666
ae53ecc47414
bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
28530
diff
changeset
|
20 bundle2, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 error, |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 httpconnection, |
30924
48dea083f66d
py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30763
diff
changeset
|
23 pycompat, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
24 statichttprepo, |
36959
43815d87c6aa
httppeer: alias url as urlmod
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36835
diff
changeset
|
25 url as urlmod, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
26 util, |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
27 wireproto, |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
28 ) |
4678
a814a5b11fff
Work around urllib2 digest auth bug with Python < 2.5
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4633
diff
changeset
|
29 |
29455
0c741fd6158a
py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29241
diff
changeset
|
30 httplib = util.httplib |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
31 urlerr = util.urlerr |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
32 urlreq = util.urlreq |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
33 |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
34 def encodevalueinheaders(value, header, limit): |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
35 """Encode a string value into multiple HTTP headers. |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
36 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
37 ``value`` will be encoded into 1 or more HTTP headers with the names |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
38 ``header-<N>`` where ``<N>`` is an integer starting at 1. Each header |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
39 name + value will be at most ``limit`` bytes long. |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
40 |
34732
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
41 Returns an iterable of 2-tuples consisting of header names and |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
42 values as native strings. |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
43 """ |
34732
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
44 # HTTP Headers are ASCII. Python 3 requires them to be unicodes, |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
45 # not bytes. This function always takes bytes in as arguments. |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
46 fmt = pycompat.strurl(header) + r'-%s' |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
47 # Note: it is *NOT* a bug that the last bit here is a bytestring |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
48 # and not a unicode: we're just getting the encoded length anyway, |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
49 # and using an r-string to make it portable between Python 2 and 3 |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
50 # doesn't work because then the \r is a literal backslash-r |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
51 # instead of a carriage return. |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
52 valuelen = limit - len(fmt % r'000') - len(': \r\n') |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
53 result = [] |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
54 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
55 n = 0 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
56 for i in xrange(0, len(value), valuelen): |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
57 n += 1 |
34732
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
58 result.append((fmt % str(n), pycompat.strurl(value[i:i + valuelen]))) |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
59 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
60 return result |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
61 |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
62 def _wraphttpresponse(resp): |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
63 """Wrap an HTTPResponse with common error handlers. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
64 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
65 This ensures that any I/O from any consumer raises the appropriate |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
66 error and messaging. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
67 """ |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
68 origread = resp.read |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
69 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
70 class readerproxy(resp.__class__): |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
71 def read(self, size=None): |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
72 try: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
73 return origread(size) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
74 except httplib.IncompleteRead as e: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
75 # e.expected is an integer if length known or None otherwise. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
76 if e.expected: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
77 msg = _('HTTP request error (incomplete response; ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
78 'expected %d bytes got %d)') % (e.expected, |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
79 len(e.partial)) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
80 else: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
81 msg = _('HTTP request error (incomplete response)') |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
82 |
32023
a29580905771
error: rename RichIOError to PeerTransportError
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32022
diff
changeset
|
83 raise error.PeerTransportError( |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
84 msg, |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
85 hint=_('this may be an intermittent network failure; ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
86 'if the error persists, consider contacting the ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
87 'network or server operator')) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
88 except httplib.HTTPException as e: |
32023
a29580905771
error: rename RichIOError to PeerTransportError
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32022
diff
changeset
|
89 raise error.PeerTransportError( |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
90 _('HTTP request error (%s)') % e, |
32086
b59a292d0a53
httppeer: unify hint message for PeerTransportError
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32023
diff
changeset
|
91 hint=_('this may be an intermittent network failure; ' |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
92 'if the error persists, consider contacting the ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
93 'network or server operator')) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
94 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
95 resp.__class__ = readerproxy |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
96 |
33821
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
97 class _multifile(object): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
98 def __init__(self, *fileobjs): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
99 for f in fileobjs: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
100 if not util.safehasattr(f, 'length'): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
101 raise ValueError( |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
102 '_multifile only supports file objects that ' |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
103 'have a length but this one does not:', type(f), f) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
104 self._fileobjs = fileobjs |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
105 self._index = 0 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
106 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
107 @property |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
108 def length(self): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
109 return sum(f.length for f in self._fileobjs) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
110 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
111 def read(self, amt=None): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
112 if amt <= 0: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
113 return ''.join(f.read() for f in self._fileobjs) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
114 parts = [] |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
115 while amt and self._index < len(self._fileobjs): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
116 parts.append(self._fileobjs[self._index].read(amt)) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
117 got = len(parts[-1]) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
118 if got < amt: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
119 self._index += 1 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
120 amt -= got |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
121 return ''.join(parts) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
122 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
123 def seek(self, offset, whence=os.SEEK_SET): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
124 if whence != os.SEEK_SET: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
125 raise NotImplementedError( |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
126 '_multifile does not support anything other' |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
127 ' than os.SEEK_SET for whence on seek()') |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
128 if offset != 0: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
129 raise NotImplementedError( |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
130 '_multifile only supports seeking to start, but that ' |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
131 'could be fixed if you need it') |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
132 for f in self._fileobjs: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
133 f.seek(0) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
134 self._index = 0 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
135 |
33806
dedab036215d
wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33805
diff
changeset
|
136 class httppeer(wireproto.wirepeer): |
37006
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
137 def __init__(self, ui, path, url, opener): |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
138 self._ui = ui |
33705
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33704
diff
changeset
|
139 self._path = path |
37006
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
140 self._url = url |
33705
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33704
diff
changeset
|
141 self._caps = None |
37006
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
142 self._urlopener = opener |
36961
586891c561dc
httppeer: consolidate _requestbuilder assignments and document
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36959
diff
changeset
|
143 # This is an its own attribute to facilitate extensions overriding |
586891c561dc
httppeer: consolidate _requestbuilder assignments and document
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36959
diff
changeset
|
144 # the default type. |
586891c561dc
httppeer: consolidate _requestbuilder assignments and document
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36959
diff
changeset
|
145 self._requestbuilder = urlreq.request |
4516
96d8a56d4ef9
Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4369
diff
changeset
|
146 |
7752
998fc8f62539
close sockets on httprepository deletion (issue1487)
Steve Borho <steve@borho.org>
parents:
7641
diff
changeset
|
147 def __del__(self): |
37006
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
148 for h in self._urlopener.handlers: |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
149 h.close() |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
150 getattr(h, "close_all", lambda: None)() |
7752
998fc8f62539
close sockets on httprepository deletion (issue1487)
Steve Borho <steve@borho.org>
parents:
7641
diff
changeset
|
151 |
35697
5a7906ed78d4
httppeer: move url opening in its own method
Boris Feld <boris.feld@octobus.net>
parents:
35359
diff
changeset
|
152 def _openurl(self, req): |
35698
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
153 if (self._ui.debugflag |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
154 and self._ui.configbool('devel', 'debug.peer-request')): |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
155 dbg = self._ui.debug |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
156 line = 'devel-peer-request: %s\n' |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
157 dbg(line % '%s %s' % (req.get_method(), req.get_full_url())) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
158 hgargssize = None |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
159 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
160 for header, value in sorted(req.header_items()): |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
161 if header.startswith('X-hgarg-'): |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
162 if hgargssize is None: |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
163 hgargssize = 0 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
164 hgargssize += len(value) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
165 else: |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
166 dbg(line % ' %s %s' % (header, value)) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
167 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
168 if hgargssize is not None: |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
169 dbg(line % ' %d bytes of commands arguments in headers' |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
170 % hgargssize) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
171 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
172 if req.has_data(): |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
173 data = req.get_data() |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
174 length = getattr(data, 'length', None) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
175 if length is None: |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
176 length = len(data) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
177 dbg(line % ' %d bytes of data' % length) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
178 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
179 start = util.timer() |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
180 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
181 ret = self._urlopener.open(req) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
182 if self._ui.configbool('devel', 'debug.peer-request'): |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
183 dbg(line % ' finished in %.4f seconds (%s)' |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
184 % (util.timer() - start, ret.code)) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
185 return ret |
35697
5a7906ed78d4
httppeer: move url opening in its own method
Boris Feld <boris.feld@octobus.net>
parents:
35359
diff
changeset
|
186 |
33805
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
187 # Begin of _basepeer interface. |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
188 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
189 @util.propertycache |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
190 def ui(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
191 return self._ui |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
192 |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
193 def url(self): |
33705
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33704
diff
changeset
|
194 return self._path |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
195 |
33805
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
196 def local(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
197 return None |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
198 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
199 def peer(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
200 return self |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
201 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
202 def canpush(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
203 return True |
2442
c660691fb45d
http: query server for capabilities
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2439
diff
changeset
|
204 |
33805
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
205 def close(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
206 pass |
13603
395a84f78736
httprepo: use caps instead of between for compat check
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13555
diff
changeset
|
207 |
33805
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
208 # End of _basepeer interface. |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
209 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
210 # Begin of _basewirepeer interface. |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
211 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
212 def capabilities(self): |
36219
a463f375f021
httppeer: remove redundant code to fetch capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36218
diff
changeset
|
213 # self._fetchcaps() should have been called as part of peer |
a463f375f021
httppeer: remove redundant code to fetch capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36218
diff
changeset
|
214 # handshake. So self._caps should always be set. |
a463f375f021
httppeer: remove redundant code to fetch capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36218
diff
changeset
|
215 assert self._caps is not None |
33705
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33704
diff
changeset
|
216 return self._caps |
2442
c660691fb45d
http: query server for capabilities
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2439
diff
changeset
|
217 |
33805
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
218 # End of _basewirepeer interface. |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
219 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
220 # look up capabilities only when needed |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
221 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
222 def _fetchcaps(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
223 self._caps = set(self._call('capabilities').split()) |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33705
diff
changeset
|
224 |
30464
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
225 def _callstream(self, cmd, _compressible=False, **args): |
35359
98bc4c43f570
py3: handle keyword arguments correctly in httppeer.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
35197
diff
changeset
|
226 args = pycompat.byteskwargs(args) |
13006
ea68947ad0ce
httprepo: remove is-comparison with string literal
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12969
diff
changeset
|
227 if cmd == 'pushkey': |
12969
6bd9778ae749
pushkey: force HTTP POST on push and add tests (issue2489)
Matt Mackall <mpm@selenic.com>
parents:
12062
diff
changeset
|
228 args['data'] = '' |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
229 data = args.pop('data', None) |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
230 headers = args.pop('headers', {}) |
14245
13d44e4235f8
httprepo: send 100-continue on POSTs if using http2
Augie Fackler <durin42@gmail.com>
parents:
14244
diff
changeset
|
231 |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
8563
diff
changeset
|
232 self.ui.debug("sending %s command\n" % cmd) |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
14076
diff
changeset
|
233 q = [('cmd', cmd)] |
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
14076
diff
changeset
|
234 headersize = 0 |
30564
07bcd1bf6151
httppeer: assign Vary request header last
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30484
diff
changeset
|
235 varyheaders = [] |
28530
fd2acc5046f6
http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents:
28486
diff
changeset
|
236 # Important: don't use self.capable() here or else you end up |
fd2acc5046f6
http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents:
28486
diff
changeset
|
237 # with infinite recursion when trying to look up capabilities |
fd2acc5046f6
http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler <augie@google.com>
parents:
28486
diff
changeset
|
238 # for the first time. |
33705
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33704
diff
changeset
|
239 postargsok = self._caps is not None and 'httppostargs' in self._caps |
36218
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
240 |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
241 # Send arguments via POST. |
33821
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
242 if postargsok and args: |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
243 strargs = urlreq.urlencode(sorted(args.items())) |
33821
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
244 if not data: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
245 data = strargs |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
246 else: |
35197
bfd072c52e03
py3: use bytes in place of basestring
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34732
diff
changeset
|
247 if isinstance(data, bytes): |
33821
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
248 i = io.BytesIO(data) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
249 i.length = len(data) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
250 data = i |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
251 argsio = io.BytesIO(strargs) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
252 argsio.length = len(strargs) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33806
diff
changeset
|
253 data = _multifile(argsio, data) |
34701
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
254 headers[r'X-HgArgs-Post'] = len(strargs) |
36218
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
255 elif args: |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
256 # Calling self.capable() can infinite loop if we are calling |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
257 # "capabilities". But that command should never accept wire |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
258 # protocol arguments. So this should never happen. |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
259 assert cmd != 'capabilities' |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
260 httpheader = self.capable('httpheader') |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
261 if httpheader: |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
262 headersize = int(httpheader.split(',', 1)[0]) |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
263 |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
264 # Send arguments via HTTP headers. |
28485
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
265 if headersize > 0: |
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
266 # The headers can typically carry more data than the URL. |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
267 encargs = urlreq.urlencode(sorted(args.items())) |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
268 for header, value in encodevalueinheaders(encargs, 'X-HgArg', |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
269 headersize): |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30564
diff
changeset
|
270 headers[header] = value |
28486
50314dc3ae4e
httppeer: compute header names only once
Augie Fackler <augie@google.com>
parents:
28485
diff
changeset
|
271 varyheaders.append(header) |
36218
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
272 # Send arguments via query string (Mercurial <1.9). |
28485
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
273 else: |
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
274 q += sorted(args.items()) |
36218
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35884
diff
changeset
|
275 |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
276 qs = '?%s' % urlreq.urlencode(q) |
3562
88b4755fa48f
httprepo: record the url after a request, makes pull + redirect works
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3445
diff
changeset
|
277 cu = "%s%s" % (self._url, qs) |
28484
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
278 size = 0 |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
279 if util.safehasattr(data, 'length'): |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
280 size = data.length |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
281 elif data is not None: |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
282 size = len(data) |
34701
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
283 if data is not None and r'Content-Type' not in headers: |
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
284 headers[r'Content-Type'] = r'application/mercurial-0.1' |
30564
07bcd1bf6151
httppeer: assign Vary request header last
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30484
diff
changeset
|
285 |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
286 # Tell the server we accept application/mercurial-0.2 and multiple |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
287 # compression formats if the server is capable of emitting those |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
288 # payloads. |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
289 protoparams = [] |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
290 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
291 mediatypes = set() |
33705
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33704
diff
changeset
|
292 if self._caps is not None: |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
293 mt = self.capable('httpmediatype') |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
294 if mt: |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
295 protoparams.append('0.1') |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
296 mediatypes = set(mt.split(',')) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
297 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
298 if '0.2tx' in mediatypes: |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
299 protoparams.append('0.2') |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
300 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
301 if '0.2tx' in mediatypes and self.capable('compression'): |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
302 # We /could/ compare supported compression formats and prune |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
303 # non-mutually supported or error if nothing is mutually supported. |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
304 # For now, send the full list to the server and have it error. |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
305 comps = [e.wireprotosupport().name for e in |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
306 util.compengines.supportedwireengines(util.CLIENTROLE)] |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
307 protoparams.append('comp=%s' % ','.join(comps)) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
308 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
309 if protoparams: |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
310 protoheaders = encodevalueinheaders(' '.join(protoparams), |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
311 'X-HgProto', |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
312 headersize or 1024) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
313 for header, value in protoheaders: |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
314 headers[header] = value |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
315 varyheaders.append(header) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
316 |
32022
e5d7f99a3063
httppeer: don't send empty Vary request header
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32003
diff
changeset
|
317 if varyheaders: |
34701
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
318 headers[r'Vary'] = r','.join(varyheaders) |
32022
e5d7f99a3063
httppeer: don't send empty Vary request header
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32003
diff
changeset
|
319 |
34699
375c8debe336
httppeer: pass url to urllib as native str, not bytes
Augie Fackler <augie@google.com>
parents:
34486
diff
changeset
|
320 req = self._requestbuilder(pycompat.strurl(cu), data, headers) |
30564
07bcd1bf6151
httppeer: assign Vary request header last
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30484
diff
changeset
|
321 |
10491
d7e582cab6b6
http: len(x) fails if it doesn't fit into an int, use __len__() instead
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10282
diff
changeset
|
322 if data is not None: |
36270
2d513ab7ce94
httppeer: use %d to format int
Augie Fackler <augie@google.com>
parents:
36220
diff
changeset
|
323 self.ui.debug("sending %d bytes\n" % size) |
36297
a59ff82154b8
httppeer: headers are native strings
Augie Fackler <augie@google.com>
parents:
36270
diff
changeset
|
324 req.add_unredirected_header(r'Content-Length', r'%d' % size) |
2294
ce67fa312f61
Catch urllib's HTTPException and give a meaningful error message to the user.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2281
diff
changeset
|
325 try: |
35697
5a7906ed78d4
httppeer: move url opening in its own method
Boris Feld <boris.feld@octobus.net>
parents:
35359
diff
changeset
|
326 resp = self._openurl(req) |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
327 except urlerr.httperror as inst: |
2467
4e78dc71d946
http client: better work with authorization errors, broken sockets.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2465
diff
changeset
|
328 if inst.code == 401: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25954
diff
changeset
|
329 raise error.Abort(_('authorization failed')) |
2467
4e78dc71d946
http client: better work with authorization errors, broken sockets.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2465
diff
changeset
|
330 raise |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25500
diff
changeset
|
331 except httplib.HTTPException as inst: |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
8563
diff
changeset
|
332 self.ui.debug('http error while sending %s command\n' % cmd) |
8206
cce63ef1045b
ui: print_exc() -> traceback()
Matt Mackall <mpm@selenic.com>
parents:
8150
diff
changeset
|
333 self.ui.traceback() |
2336
f77edcffb837
http: print better error if exception happens.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2294
diff
changeset
|
334 raise IOError(None, inst) |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
335 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
336 # Insert error handlers for common I/O failures. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
337 _wraphttpresponse(resp) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30924
diff
changeset
|
338 |
3562
88b4755fa48f
httprepo: record the url after a request, makes pull + redirect works
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3445
diff
changeset
|
339 # record the url we got redirected to |
34724
9c3dcaf648ef
httppeer: convert request url back to bytes before inspecting it
Augie Fackler <augie@google.com>
parents:
34701
diff
changeset
|
340 resp_url = pycompat.bytesurl(resp.geturl()) |
3570
c141d07198b9
Inform the user about the new URL when being redirected via http.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3569
diff
changeset
|
341 if resp_url.endswith(qs): |
c141d07198b9
Inform the user about the new URL when being redirected via http.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3569
diff
changeset
|
342 resp_url = resp_url[:-len(qs)] |
9881
54b518fc6671
httprepo: suppress the `real URL is...' message in safe, common cases.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
9878
diff
changeset
|
343 if self._url.rstrip('/') != resp_url.rstrip('/'): |
14504
c59968e8b579
httprepo: send URL redirection notices to stderr (issue2828)
Matt Mackall <mpm@selenic.com>
parents:
14503
diff
changeset
|
344 if not self.ui.quiet: |
c59968e8b579
httprepo: send URL redirection notices to stderr (issue2828)
Matt Mackall <mpm@selenic.com>
parents:
14503
diff
changeset
|
345 self.ui.warn(_('real URL is %s\n') % resp_url) |
10208
37c4ce51a12d
httprepo: always store the response url (issue1968)
Steve Borho <steve@borho.org>
parents:
9881
diff
changeset
|
346 self._url = resp_url |
2435
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
347 try: |
34725
a288712d86d5
httppeer: extract content-type from headers using native str
Augie Fackler <augie@google.com>
parents:
34724
diff
changeset
|
348 proto = pycompat.bytesurl(resp.getheader(r'content-type', r'')) |
2435
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
349 except AttributeError: |
34725
a288712d86d5
httppeer: extract content-type from headers using native str
Augie Fackler <augie@google.com>
parents:
34724
diff
changeset
|
350 proto = pycompat.bytesurl(resp.headers.get(r'content-type', r'')) |
752 | 351 |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14060
diff
changeset
|
352 safeurl = util.hidepassword(self._url) |
15017
f4522df38c65
wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents:
14999
diff
changeset
|
353 if proto.startswith('application/hg-error'): |
f4522df38c65
wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents:
14999
diff
changeset
|
354 raise error.OutOfBandError(resp.read()) |
753 | 355 # accept old "text/plain" and "application/hg-changegroup" for now |
4633
ff7253a0d1da
Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4516
diff
changeset
|
356 if not (proto.startswith('application/mercurial-') or |
18737
56f8522c3591
httppeer: improve protocol check
Matt Mackall <mpm@selenic.com>
parents:
17221
diff
changeset
|
357 (proto.startswith('text/plain') |
56f8522c3591
httppeer: improve protocol check
Matt Mackall <mpm@selenic.com>
parents:
17221
diff
changeset
|
358 and not resp.headers.get('content-length')) or |
4633
ff7253a0d1da
Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4516
diff
changeset
|
359 proto.startswith('application/hg-changegroup')): |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14060
diff
changeset
|
360 self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu)) |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
361 raise error.RepoError( |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
362 _("'%s' does not appear to be an hg repository:\n" |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
363 "---%%<--- (%s)\n%s\n---%%<---\n") |
18738
b376e8f91c16
httppeer: avoid large dumps when we don't see an hgweb repo
Matt Mackall <mpm@selenic.com>
parents:
18737
diff
changeset
|
364 % (safeurl, proto or 'no content-type', resp.read(1024))) |
752 | 365 |
4012
d1e31d7f7d44
fix handling of multiple Content-type headers
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3703
diff
changeset
|
366 if proto.startswith('application/mercurial-'): |
d1e31d7f7d44
fix handling of multiple Content-type headers
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3703
diff
changeset
|
367 try: |
4356
aed9e6dceb85
Avoid float rounding errors when checking http protocol version.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4226
diff
changeset
|
368 version = proto.split('-', 1)[1] |
aed9e6dceb85
Avoid float rounding errors when checking http protocol version.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4226
diff
changeset
|
369 version_info = tuple([int(n) for n in version.split('.')]) |
4012
d1e31d7f7d44
fix handling of multiple Content-type headers
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3703
diff
changeset
|
370 except ValueError: |
7637 | 371 raise error.RepoError(_("'%s' sent a broken Content-Type " |
8053
976170068286
hide passwords in httprepo error messages
Steve Borho <steve@borho.org>
parents:
7752
diff
changeset
|
372 "header (%s)") % (safeurl, proto)) |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
373 |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
374 # TODO consider switching to a decompression reader that uses |
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
375 # generators. |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
376 if version_info == (0, 1): |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
377 if _compressible: |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
378 return util.compengines['zlib'].decompressorreader(resp) |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
379 return resp |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
380 elif version_info == (0, 2): |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
381 # application/mercurial-0.2 always identifies the compression |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
382 # engine in the payload header. |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
383 elen = struct.unpack('B', resp.read(1))[0] |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
384 ename = resp.read(elen) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
385 engine = util.compengines.forwiretype(ename) |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
386 return engine.decompressorreader(resp) |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
387 else: |
7637 | 388 raise error.RepoError(_("'%s' uses newer protocol %s") % |
8053
976170068286
hide passwords in httprepo error messages
Steve Borho <steve@borho.org>
parents:
7752
diff
changeset
|
389 (safeurl, version)) |
753 | 390 |
30464
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
391 if _compressible: |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
392 return util.compengines['zlib'].decompressorreader(resp) |
30464
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
393 |
752 | 394 return resp |
60 | 395 |
11589
e8d22fe2ddab
protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents:
11588
diff
changeset
|
396 def _call(self, cmd, **args): |
e8d22fe2ddab
protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents:
11588
diff
changeset
|
397 fp = self._callstream(cmd, **args) |
2435
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
398 try: |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
399 return fp.read() |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
400 finally: |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
401 # if using keepalive, allow connection to be reused |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
402 fp.close() |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
403 |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
404 def _callpush(self, cmd, cg, **args): |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
405 # have to stream bundle to a temp file because we do not have |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
406 # http 1.1 chunked transfer. |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
407 |
3662
f4dc02d7fb71
unduplicate bundle writing code from httprepo
Matt Mackall <mpm@selenic.com>
parents:
3661
diff
changeset
|
408 types = self.capable('unbundle') |
3703
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
409 try: |
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
410 types = types.split(',') |
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
411 except AttributeError: |
14060
aaa9a5989405
bundle: more comments about the different header types, remove useless if
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
13819
diff
changeset
|
412 # servers older than d1b16a746db6 will send 'unbundle' as a |
aaa9a5989405
bundle: more comments about the different header types, remove useless if
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
13819
diff
changeset
|
413 # boolean capability. They only support headerless/uncompressed |
aaa9a5989405
bundle: more comments about the different header types, remove useless if
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
13819
diff
changeset
|
414 # bundles. |
3703
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
415 types = [""] |
14060
aaa9a5989405
bundle: more comments about the different header types, remove useless if
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
13819
diff
changeset
|
416 for x in types: |
28666
ae53ecc47414
bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
28530
diff
changeset
|
417 if x in bundle2.bundletypes: |
14060
aaa9a5989405
bundle: more comments about the different header types, remove useless if
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
13819
diff
changeset
|
418 type = x |
aaa9a5989405
bundle: more comments about the different header types, remove useless if
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
13819
diff
changeset
|
419 break |
3613
cbf352b9a3cd
Client support for hgweb unbundle with versions.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3609
diff
changeset
|
420 |
28666
ae53ecc47414
bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
28530
diff
changeset
|
421 tempname = bundle2.writebundle(self.ui, cg, None, type) |
14244
e7525a555a64
url: use new http support if requested by the user
Augie Fackler <durin42@gmail.com>
parents:
14149
diff
changeset
|
422 fp = httpconnection.httpsendfile(self.ui, tempname, "rb") |
36297
a59ff82154b8
httppeer: headers are native strings
Augie Fackler <augie@google.com>
parents:
36270
diff
changeset
|
423 headers = {r'Content-Type': r'application/mercurial-0.1'} |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
424 |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
425 try: |
25085
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
426 r = self._call(cmd, data=fp, headers=headers, **args) |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
427 vals = r.split('\n', 1) |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
428 if len(vals) < 2: |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
429 raise error.ResponseError(_("unexpected response:"), r) |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
430 return vals |
36430
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36426
diff
changeset
|
431 except urlerr.httperror: |
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36426
diff
changeset
|
432 # Catch and re-raise these so we don't try and treat them |
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36426
diff
changeset
|
433 # like generic socket errors. They lack any values in |
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36426
diff
changeset
|
434 # .args on Python 3 which breaks our socket.error block. |
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36426
diff
changeset
|
435 raise |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25500
diff
changeset
|
436 except socket.error as err: |
25085
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
437 if err.args[0] in (errno.ECONNRESET, errno.EPIPE): |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25954
diff
changeset
|
438 raise error.Abort(_('push failed: %s') % err.args[1]) |
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25954
diff
changeset
|
439 raise error.Abort(err.args[1]) |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
440 finally: |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
441 fp.close() |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
442 os.unlink(tempname) |
2439
e8c4f3d3df8c
extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2435
diff
changeset
|
443 |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
444 def _calltwowaystream(self, cmd, fp, **args): |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
445 fh = None |
23086
cde6904f1992
httppeer: close the temporary bundle file after two-way streaming it
Matt Harbison <matt_harbison@yahoo.com>
parents:
21188
diff
changeset
|
446 fp_ = None |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
447 filename = None |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
448 try: |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
449 # dump bundle to disk |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
450 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg") |
36835
5bc7ff103081
py3: use r'' instead of sysstr('') to get around code transformer
Yuya Nishihara <yuya@tcha.org>
parents:
36430
diff
changeset
|
451 fh = os.fdopen(fd, r"wb") |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
452 d = fp.read(4096) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
453 while d: |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
454 fh.write(d) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
455 d = fp.read(4096) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
456 fh.close() |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
457 # start http push |
23086
cde6904f1992
httppeer: close the temporary bundle file after two-way streaming it
Matt Harbison <matt_harbison@yahoo.com>
parents:
21188
diff
changeset
|
458 fp_ = httpconnection.httpsendfile(self.ui, filename, "rb") |
36297
a59ff82154b8
httppeer: headers are native strings
Augie Fackler <augie@google.com>
parents:
36270
diff
changeset
|
459 headers = {r'Content-Type': r'application/mercurial-0.1'} |
23086
cde6904f1992
httppeer: close the temporary bundle file after two-way streaming it
Matt Harbison <matt_harbison@yahoo.com>
parents:
21188
diff
changeset
|
460 return self._callstream(cmd, data=fp_, headers=headers, **args) |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
461 finally: |
23086
cde6904f1992
httppeer: close the temporary bundle file after two-way streaming it
Matt Harbison <matt_harbison@yahoo.com>
parents:
21188
diff
changeset
|
462 if fp_ is not None: |
cde6904f1992
httppeer: close the temporary bundle file after two-way streaming it
Matt Harbison <matt_harbison@yahoo.com>
parents:
21188
diff
changeset
|
463 fp_.close() |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
464 if fh is not None: |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
465 fh.close() |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
466 os.unlink(filename) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
467 |
20905
167047ba3cfa
wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
18742
diff
changeset
|
468 def _callcompressable(self, cmd, **args): |
30464
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
469 return self._callstream(cmd, _compressible=True, **args) |
11370 | 470 |
21188
d36440d84328
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa
Mads Kiilerich <madski@unity3d.com>
parents:
21074
diff
changeset
|
471 def _abort(self, exception): |
d36440d84328
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa
Mads Kiilerich <madski@unity3d.com>
parents:
21074
diff
changeset
|
472 raise exception |
d36440d84328
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa
Mads Kiilerich <madski@unity3d.com>
parents:
21074
diff
changeset
|
473 |
37006
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
474 def makepeer(ui, path): |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
475 u = util.url(path) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
476 if u.query or u.fragment: |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
477 raise error.Abort(_('unsupported URL component: "%s"') % |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
478 (u.query or u.fragment)) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
479 |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
480 # urllib cannot handle URLs with embedded user or passwd. |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
481 url, authinfo = u.authinfo() |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
482 ui.debug('using %s\n' % url) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
483 |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
484 opener = urlmod.opener(ui, authinfo) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
485 |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
486 return httppeer(ui, path, url, opener) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
487 |
2740
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
488 def instance(ui, path, create): |
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
489 if create: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25954
diff
changeset
|
490 raise error.Abort(_('cannot create new http repository')) |
7211 | 491 try: |
36959
43815d87c6aa
httppeer: alias url as urlmod
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36835
diff
changeset
|
492 if path.startswith('https:') and not urlmod.has_https: |
36220
874209855f5c
httppeer: remove httpspeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36219
diff
changeset
|
493 raise error.Abort(_('Python support for SSL and HTTPS ' |
874209855f5c
httppeer: remove httpspeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36219
diff
changeset
|
494 'is not installed')) |
35884
197d10e157ce
httppeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35698
diff
changeset
|
495 |
37006
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36961
diff
changeset
|
496 inst = makepeer(ui, path) |
35884
197d10e157ce
httppeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35698
diff
changeset
|
497 inst._fetchcaps() |
197d10e157ce
httppeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35698
diff
changeset
|
498 |
7211 | 499 return inst |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25500
diff
changeset
|
500 except error.RepoError as httpexception: |
14148
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
501 try: |
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
502 r = statichttprepo.instance(ui, "static-" + path, create) |
29241
269f7ea08983
httppeer: make a message translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28883
diff
changeset
|
503 ui.note(_('(falling back to static-http)\n')) |
14148
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
504 return r |
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
505 except error.RepoError: |
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
506 raise httpexception # use the original http RepoError instead |