Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/httppeer.py @ 37547:835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Upcoming commits will move the initial ?cmd=capabilities handshake
request out of httppeer so the handshake can be performed before a
peer instance is constructed. In order to do this, we'll need to
refactor code for making HTTP requests.
The type used to construct HTTP requests is configurable. If we'll
be making HTTP requests outside of httppeer, we should be able to
use a custom request builder. So move the definition of that type
into makepeer().
Extensions can monkeypatch the function and override the argument
value.
Differential Revision: https://phab.mercurial-scm.org/D3232
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 10 Apr 2018 10:22:26 -0700 |
parents | 3a2367e6c6f2 |
children | 8e7a4435ab6d |
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 |
33842
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
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 _ |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
19 from .thirdparty import ( |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
20 cbor, |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
21 ) |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 from . import ( |
28666
ae53ecc47414
bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
28530
diff
changeset
|
23 bundle2, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
24 error, |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
25 httpconnection, |
30944
48dea083f66d
py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30763
diff
changeset
|
26 pycompat, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
27 statichttprepo, |
36965
43815d87c6aa
httppeer: alias url as urlmod
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36843
diff
changeset
|
28 url as urlmod, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
29 util, |
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
30 wireproto, |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
31 wireprotoframing, |
37545
93397c4633f6
wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37544
diff
changeset
|
32 wireprotov2server, |
25954
7bbdb78d2842
httppeer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
33 ) |
4678
a814a5b11fff
Work around urllib2 digest auth bug with Python < 2.5
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4633
diff
changeset
|
34 |
29455
0c741fd6158a
py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29241
diff
changeset
|
35 httplib = util.httplib |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
36 urlerr = util.urlerr |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
37 urlreq = util.urlreq |
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
38 |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
39 def encodevalueinheaders(value, header, limit): |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
40 """Encode a string value into multiple HTTP headers. |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
41 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
42 ``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:
30569
diff
changeset
|
43 ``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:
30569
diff
changeset
|
44 name + value will be at most ``limit`` bytes long. |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
45 |
34732
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
46 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
|
47 values as native strings. |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
48 """ |
34732
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
49 # 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
|
50 # 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
|
51 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
|
52 # 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
|
53 # 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
|
54 # 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
|
55 # 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
|
56 # instead of a carriage return. |
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
57 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:
30569
diff
changeset
|
58 result = [] |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
59 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
60 n = 0 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
61 for i in xrange(0, len(value), valuelen): |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
62 n += 1 |
34732
67e9678efd98
httppeer: always produce native str header keys and values
Augie Fackler <augie@google.com>
parents:
34725
diff
changeset
|
63 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:
30569
diff
changeset
|
64 |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
65 return result |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
66 |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
67 def _wraphttpresponse(resp): |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
68 """Wrap an HTTPResponse with common error handlers. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
69 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
70 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:
30944
diff
changeset
|
71 error and messaging. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
72 """ |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
73 origread = resp.read |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
74 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
75 class readerproxy(resp.__class__): |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
76 def read(self, size=None): |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
77 try: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
78 return origread(size) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
79 except httplib.IncompleteRead as e: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
80 # e.expected is an integer if length known or None otherwise. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
81 if e.expected: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
82 msg = _('HTTP request error (incomplete response; ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
83 'expected %d bytes got %d)') % (e.expected, |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
84 len(e.partial)) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
85 else: |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
86 msg = _('HTTP request error (incomplete response)') |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
87 |
32023
a29580905771
error: rename RichIOError to PeerTransportError
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32022
diff
changeset
|
88 raise error.PeerTransportError( |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
89 msg, |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
90 hint=_('this may be an intermittent network failure; ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
91 'if the error persists, consider contacting the ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
92 'network or server operator')) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
93 except httplib.HTTPException as e: |
32023
a29580905771
error: rename RichIOError to PeerTransportError
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32022
diff
changeset
|
94 raise error.PeerTransportError( |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
95 _('HTTP request error (%s)') % e, |
32086
b59a292d0a53
httppeer: unify hint message for PeerTransportError
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32023
diff
changeset
|
96 hint=_('this may be an intermittent network failure; ' |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
97 'if the error persists, consider contacting the ' |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
98 'network or server operator')) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
99 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
100 resp.__class__ = readerproxy |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
101 |
33842
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
102 class _multifile(object): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
103 def __init__(self, *fileobjs): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
104 for f in fileobjs: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
105 if not util.safehasattr(f, 'length'): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
106 raise ValueError( |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
107 '_multifile only supports file objects that ' |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
108 '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:
33827
diff
changeset
|
109 self._fileobjs = fileobjs |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
110 self._index = 0 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
111 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
112 @property |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
113 def length(self): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
114 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:
33827
diff
changeset
|
115 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
116 def read(self, amt=None): |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
117 if amt <= 0: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
118 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:
33827
diff
changeset
|
119 parts = [] |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
120 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:
33827
diff
changeset
|
121 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:
33827
diff
changeset
|
122 got = len(parts[-1]) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
123 if got < amt: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
124 self._index += 1 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
125 amt -= got |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
126 return ''.join(parts) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
127 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
128 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:
33827
diff
changeset
|
129 if whence != os.SEEK_SET: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
130 raise NotImplementedError( |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
131 '_multifile does not support anything other' |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
132 ' 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:
33827
diff
changeset
|
133 if offset != 0: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
134 raise NotImplementedError( |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
135 '_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:
33827
diff
changeset
|
136 '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:
33827
diff
changeset
|
137 for f in self._fileobjs: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
138 f.seek(0) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
139 self._index = 0 |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
140 |
33827
dedab036215d
wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33826
diff
changeset
|
141 class httppeer(wireproto.wirepeer): |
37547
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
142 def __init__(self, ui, path, url, opener, requestbuilder): |
37321
e826fe7a08c7
peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37320
diff
changeset
|
143 self.ui = ui |
33731
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33730
diff
changeset
|
144 self._path = path |
37009
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
145 self._url = url |
33731
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33730
diff
changeset
|
146 self._caps = None |
37009
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
147 self._urlopener = opener |
37547
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
148 self._requestbuilder = requestbuilder |
4516
96d8a56d4ef9
Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4369
diff
changeset
|
149 |
7752
998fc8f62539
close sockets on httprepository deletion (issue1487)
Steve Borho <steve@borho.org>
parents:
7641
diff
changeset
|
150 def __del__(self): |
37009
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
151 for h in self._urlopener.handlers: |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
152 h.close() |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
153 getattr(h, "close_all", lambda: None)() |
7752
998fc8f62539
close sockets on httprepository deletion (issue1487)
Steve Borho <steve@borho.org>
parents:
7641
diff
changeset
|
154 |
35697
5a7906ed78d4
httppeer: move url opening in its own method
Boris Feld <boris.feld@octobus.net>
parents:
35368
diff
changeset
|
155 def _openurl(self, req): |
37321
e826fe7a08c7
peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37320
diff
changeset
|
156 if (self.ui.debugflag |
e826fe7a08c7
peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37320
diff
changeset
|
157 and self.ui.configbool('devel', 'debug.peer-request')): |
e826fe7a08c7
peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37320
diff
changeset
|
158 dbg = self.ui.debug |
35698
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
159 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
|
160 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
|
161 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
|
162 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
163 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
|
164 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
|
165 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
|
166 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
|
167 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
|
168 else: |
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 % ' %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
|
170 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
171 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
|
172 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
|
173 % hgargssize) |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
174 |
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 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
|
176 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
|
177 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
|
178 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
|
179 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
|
180 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
|
181 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
182 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
|
183 |
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
184 ret = self._urlopener.open(req) |
37321
e826fe7a08c7
peer: make ui an attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37320
diff
changeset
|
185 if self.ui.configbool('devel', 'debug.peer-request'): |
35698
0c4b23ccf1a5
httppeer: add support for tracing all http request made by the peer
Boris Feld <boris.feld@octobus.net>
parents:
35697
diff
changeset
|
186 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
|
187 % (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
|
188 return ret |
35697
5a7906ed78d4
httppeer: move url opening in its own method
Boris Feld <boris.feld@octobus.net>
parents:
35368
diff
changeset
|
189 |
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37009
diff
changeset
|
190 # Begin of ipeerconnection interface. |
33826
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
191 |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
192 def url(self): |
33731
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33730
diff
changeset
|
193 return self._path |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2612
diff
changeset
|
194 |
33826
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
195 def local(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
196 return None |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
197 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
198 def peer(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
199 return self |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
200 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
201 def canpush(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
202 return True |
2442
c660691fb45d
http: query server for capabilities
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2439
diff
changeset
|
203 |
33826
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
204 def close(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
205 pass |
13603
395a84f78736
httprepo: use caps instead of between for compat check
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
13555
diff
changeset
|
206 |
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37009
diff
changeset
|
207 # End of ipeerconnection interface. |
33826
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
208 |
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37009
diff
changeset
|
209 # Begin of ipeercommands interface. |
33826
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
210 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
211 def capabilities(self): |
36257
a463f375f021
httppeer: remove redundant code to fetch capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36256
diff
changeset
|
212 # 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:
36256
diff
changeset
|
213 # handshake. So self._caps should always be set. |
a463f375f021
httppeer: remove redundant code to fetch capabilities
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36256
diff
changeset
|
214 assert self._caps is not None |
33731
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33730
diff
changeset
|
215 return self._caps |
2442
c660691fb45d
http: query server for capabilities
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2439
diff
changeset
|
216 |
37320
39f7d4ee8bcd
repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37009
diff
changeset
|
217 # End of ipeercommands interface. |
33826
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
218 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
219 # look up capabilities only when needed |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
220 |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
221 def _fetchcaps(self): |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
222 self._caps = set(self._call('capabilities').split()) |
f913e90f15a0
httppeer: use peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33731
diff
changeset
|
223 |
30473
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
224 def _callstream(self, cmd, _compressible=False, **args): |
35368
98bc4c43f570
py3: handle keyword arguments correctly in httppeer.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
35208
diff
changeset
|
225 args = pycompat.byteskwargs(args) |
13006
ea68947ad0ce
httprepo: remove is-comparison with string literal
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
12969
diff
changeset
|
226 if cmd == 'pushkey': |
12969
6bd9778ae749
pushkey: force HTTP POST on push and add tests (issue2489)
Matt Mackall <mpm@selenic.com>
parents:
12062
diff
changeset
|
227 args['data'] = '' |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
228 data = args.pop('data', None) |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
229 headers = args.pop('headers', {}) |
14245
13d44e4235f8
httprepo: send 100-continue on POSTs if using http2
Augie Fackler <durin42@gmail.com>
parents:
14244
diff
changeset
|
230 |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
8563
diff
changeset
|
231 self.ui.debug("sending %s command\n" % cmd) |
14093
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
14076
diff
changeset
|
232 q = [('cmd', cmd)] |
ce99d887585f
httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents:
14076
diff
changeset
|
233 headersize = 0 |
30569
07bcd1bf6151
httppeer: assign Vary request header last
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30493
diff
changeset
|
234 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
|
235 # 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
|
236 # 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
|
237 # for the first time. |
33731
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33730
diff
changeset
|
238 postargsok = self._caps is not None and 'httppostargs' in self._caps |
36256
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
239 |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
240 # Send arguments via POST. |
33842
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
241 if postargsok and args: |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
242 strargs = urlreq.urlencode(sorted(args.items())) |
33842
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
243 if not data: |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
244 data = strargs |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
245 else: |
35208
bfd072c52e03
py3: use bytes in place of basestring
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34732
diff
changeset
|
246 if isinstance(data, bytes): |
33842
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
247 i = io.BytesIO(data) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
248 i.length = len(data) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
249 data = i |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
250 argsio = io.BytesIO(strargs) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
251 argsio.length = len(strargs) |
3c91cc0c5fde
httppeer: add support for httppostargs when we're sending a file
Augie Fackler <augie@google.com>
parents:
33827
diff
changeset
|
252 data = _multifile(argsio, data) |
34701
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
253 headers[r'X-HgArgs-Post'] = len(strargs) |
36256
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
254 elif args: |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
255 # Calling self.capable() can infinite loop if we are calling |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
256 # "capabilities". But that command should never accept wire |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
257 # protocol arguments. So this should never happen. |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
258 assert cmd != 'capabilities' |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
259 httpheader = self.capable('httpheader') |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
260 if httpheader: |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
261 headersize = int(httpheader.split(',', 1)[0]) |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
262 |
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
263 # Send arguments via HTTP headers. |
28485
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
264 if headersize > 0: |
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
265 # 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
|
266 encargs = urlreq.urlencode(sorted(args.items())) |
30759
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
267 for header, value in encodevalueinheaders(encargs, 'X-HgArg', |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
268 headersize): |
3f5f0c98cd18
httppeer: extract code for HTTP header spanning
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30569
diff
changeset
|
269 headers[header] = value |
28486
50314dc3ae4e
httppeer: compute header names only once
Augie Fackler <augie@google.com>
parents:
28485
diff
changeset
|
270 varyheaders.append(header) |
36256
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
271 # 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
|
272 else: |
d3893900f6c8
httppeer: indent existing argument handling with if True
Augie Fackler <augie@google.com>
parents:
28484
diff
changeset
|
273 q += sorted(args.items()) |
36256
e4ccd7a69f77
httppeer: change logic around argument handling
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35924
diff
changeset
|
274 |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
275 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
|
276 cu = "%s%s" % (self._url, qs) |
28484
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
277 size = 0 |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
278 if util.safehasattr(data, 'length'): |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
279 size = data.length |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
280 elif data is not None: |
da6f713ab480
httppeer: move size computation later in _callstream
Augie Fackler <augie@google.com>
parents:
28483
diff
changeset
|
281 size = len(data) |
34701
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
282 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
|
283 headers[r'Content-Type'] = r'application/mercurial-0.1' |
30569
07bcd1bf6151
httppeer: assign Vary request header last
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30493
diff
changeset
|
284 |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
285 # 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
|
286 # 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
|
287 # payloads. |
37498
aacfca6f9767
wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents:
37483
diff
changeset
|
288 protoparams = {'partial-pull'} |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
289 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
290 mediatypes = set() |
33731
73fd395ee29e
httppeer: make several instance attributes internal (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33730
diff
changeset
|
291 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
|
292 mt = self.capable('httpmediatype') |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
293 if mt: |
37411
3e1688711efd
wireproto: turn client capabilities into sets, sorted on the wire
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
294 protoparams.add('0.1') |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
295 mediatypes = set(mt.split(',')) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
296 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
297 if '0.2tx' in mediatypes: |
37411
3e1688711efd
wireproto: turn client capabilities into sets, sorted on the wire
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
298 protoparams.add('0.2') |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
299 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
300 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
|
301 # 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
|
302 # 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
|
303 # 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
|
304 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
|
305 util.compengines.supportedwireengines(util.CLIENTROLE)] |
37411
3e1688711efd
wireproto: turn client capabilities into sets, sorted on the wire
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
306 protoparams.add('comp=%s' % ','.join(comps)) |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
307 |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
308 if protoparams: |
37411
3e1688711efd
wireproto: turn client capabilities into sets, sorted on the wire
Joerg Sonnenberger <joerg@bec.de>
parents:
37321
diff
changeset
|
309 protoheaders = encodevalueinheaders(' '.join(sorted(protoparams)), |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
310 'X-HgProto', |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
311 headersize or 1024) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
312 for header, value in protoheaders: |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
313 headers[header] = value |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
314 varyheaders.append(header) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
315 |
32022
e5d7f99a3063
httppeer: don't send empty Vary request header
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32003
diff
changeset
|
316 if varyheaders: |
34701
6db536bed7ec
httppeer: use native strings for headers
Augie Fackler <augie@google.com>
parents:
34699
diff
changeset
|
317 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
|
318 |
34699
375c8debe336
httppeer: pass url to urllib as native str, not bytes
Augie Fackler <augie@google.com>
parents:
34486
diff
changeset
|
319 req = self._requestbuilder(pycompat.strurl(cu), data, headers) |
30569
07bcd1bf6151
httppeer: assign Vary request header last
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30493
diff
changeset
|
320 |
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
|
321 if data is not None: |
36303
2d513ab7ce94
httppeer: use %d to format int
Augie Fackler <augie@google.com>
parents:
36258
diff
changeset
|
322 self.ui.debug("sending %d bytes\n" % size) |
36330
a59ff82154b8
httppeer: headers are native strings
Augie Fackler <augie@google.com>
parents:
36303
diff
changeset
|
323 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
|
324 try: |
35697
5a7906ed78d4
httppeer: move url opening in its own method
Boris Feld <boris.feld@octobus.net>
parents:
35368
diff
changeset
|
325 resp = self._openurl(req) |
28883
032c4c2f802a
pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents:
28666
diff
changeset
|
326 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
|
327 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
|
328 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
|
329 raise |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25500
diff
changeset
|
330 except httplib.HTTPException as inst: |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
8563
diff
changeset
|
331 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
|
332 self.ui.traceback() |
2336
f77edcffb837
http: print better error if exception happens.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2294
diff
changeset
|
333 raise IOError(None, inst) |
32002
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
334 |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
335 # Insert error handlers for common I/O failures. |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
336 _wraphttpresponse(resp) |
bf855efe5664
httppeer: wrap HTTPResponse.read() globally
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30944
diff
changeset
|
337 |
3562
88b4755fa48f
httprepo: record the url after a request, makes pull + redirect works
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3445
diff
changeset
|
338 # 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
|
339 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
|
340 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
|
341 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
|
342 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
|
343 if not self.ui.quiet: |
c59968e8b579
httprepo: send URL redirection notices to stderr (issue2828)
Matt Mackall <mpm@selenic.com>
parents:
14503
diff
changeset
|
344 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
|
345 self._url = resp_url |
2435
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
346 try: |
34725
a288712d86d5
httppeer: extract content-type from headers using native str
Augie Fackler <augie@google.com>
parents:
34724
diff
changeset
|
347 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
|
348 except AttributeError: |
34725
a288712d86d5
httppeer: extract content-type from headers using native str
Augie Fackler <augie@google.com>
parents:
34724
diff
changeset
|
349 proto = pycompat.bytesurl(resp.headers.get(r'content-type', r'')) |
752 | 350 |
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
14060
diff
changeset
|
351 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
|
352 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
|
353 raise error.OutOfBandError(resp.read()) |
753 | 354 # 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
|
355 if not (proto.startswith('application/mercurial-') or |
18737
56f8522c3591
httppeer: improve protocol check
Matt Mackall <mpm@selenic.com>
parents:
17221
diff
changeset
|
356 (proto.startswith('text/plain') |
56f8522c3591
httppeer: improve protocol check
Matt Mackall <mpm@selenic.com>
parents:
17221
diff
changeset
|
357 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
|
358 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
|
359 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
|
360 raise error.RepoError( |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
361 _("'%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
|
362 "---%%<--- (%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
|
363 % (safeurl, proto or 'no content-type', resp.read(1024))) |
752 | 364 |
4012
d1e31d7f7d44
fix handling of multiple Content-type headers
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3703
diff
changeset
|
365 if proto.startswith('application/mercurial-'): |
d1e31d7f7d44
fix handling of multiple Content-type headers
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3703
diff
changeset
|
366 try: |
4356
aed9e6dceb85
Avoid float rounding errors when checking http protocol version.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4226
diff
changeset
|
367 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
|
368 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
|
369 except ValueError: |
7637 | 370 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
|
371 "header (%s)") % (safeurl, proto)) |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
372 |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
373 # TODO consider switching to a decompression reader that uses |
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
374 # generators. |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
375 if version_info == (0, 1): |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
376 if _compressible: |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
377 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
|
378 return resp |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
379 elif version_info == (0, 2): |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
380 # 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
|
381 # engine in the payload header. |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
382 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
|
383 ename = resp.read(elen) |
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
384 engine = util.compengines.forwiretype(ename) |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
385 return engine.decompressorreader(resp) |
30763
a520aefb96f1
httppeer: advertise and support application/mercurial-0.2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30759
diff
changeset
|
386 else: |
7637 | 387 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
|
388 (safeurl, version)) |
753 | 389 |
30473
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
390 if _compressible: |
32003
84569d2b3fb7
httppeer: eliminate decompressresponse() proxy
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32002
diff
changeset
|
391 return util.compengines['zlib'].decompressorreader(resp) |
30473
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
392 |
752 | 393 return resp |
60 | 394 |
11589
e8d22fe2ddab
protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents:
11588
diff
changeset
|
395 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
|
396 fp = self._callstream(cmd, **args) |
2435
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
397 try: |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
398 return fp.read() |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
399 finally: |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
400 # if using keepalive, allow connection to be reused |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
401 fp.close() |
ff2bac730b99
http client: support persistent connections.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2337
diff
changeset
|
402 |
11592
26e0782b8380
protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents:
11591
diff
changeset
|
403 def _callpush(self, cmd, cg, **args): |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
404 # 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
|
405 # http 1.1 chunked transfer. |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
406 |
3662
f4dc02d7fb71
unduplicate bundle writing code from httprepo
Matt Mackall <mpm@selenic.com>
parents:
3661
diff
changeset
|
407 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
|
408 try: |
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
409 types = types.split(',') |
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
410 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
|
411 # 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
|
412 # 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
|
413 # bundles. |
3703
e674cae8efee
fix push over HTTP to older servers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3662
diff
changeset
|
414 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
|
415 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
|
416 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
|
417 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
|
418 break |
3613
cbf352b9a3cd
Client support for hgweb unbundle with versions.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3609
diff
changeset
|
419 |
28666
ae53ecc47414
bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
28530
diff
changeset
|
420 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
|
421 fp = httpconnection.httpsendfile(self.ui, tempname, "rb") |
36330
a59ff82154b8
httppeer: headers are native strings
Augie Fackler <augie@google.com>
parents:
36303
diff
changeset
|
422 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
|
423 |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
424 try: |
25085
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
425 r = self._call(cmd, data=fp, headers=headers, **args) |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
426 vals = r.split('\n', 1) |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
427 if len(vals) < 2: |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
428 raise error.ResponseError(_("unexpected response:"), r) |
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
429 return vals |
36460
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36456
diff
changeset
|
430 except urlerr.httperror: |
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36456
diff
changeset
|
431 # 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:
36456
diff
changeset
|
432 # like generic socket errors. They lack any values in |
efebfa9b4cab
httppeer: explicitly catch urlerr.httperror and re-raise
Augie Fackler <augie@google.com>
parents:
36456
diff
changeset
|
433 # .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:
36456
diff
changeset
|
434 raise |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25500
diff
changeset
|
435 except socket.error as err: |
25085
e05734cd7902
httppeer: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
23895
diff
changeset
|
436 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
|
437 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
|
438 raise error.Abort(err.args[1]) |
2465
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
439 finally: |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
440 fp.close() |
c91118f425d0
push over http: client support.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2447
diff
changeset
|
441 os.unlink(tempname) |
2439
e8c4f3d3df8c
extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2435
diff
changeset
|
442 |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
443 def _calltwowaystream(self, cmd, fp, **args): |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
444 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
|
445 fp_ = None |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
446 filename = None |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
447 try: |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
448 # dump bundle to disk |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
449 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg") |
36843
5bc7ff103081
py3: use r'' instead of sysstr('') to get around code transformer
Yuya Nishihara <yuya@tcha.org>
parents:
36460
diff
changeset
|
450 fh = os.fdopen(fd, r"wb") |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
451 d = fp.read(4096) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
452 while d: |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
453 fh.write(d) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
454 d = fp.read(4096) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
455 fh.close() |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
456 # 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
|
457 fp_ = httpconnection.httpsendfile(self.ui, filename, "rb") |
36330
a59ff82154b8
httppeer: headers are native strings
Augie Fackler <augie@google.com>
parents:
36303
diff
changeset
|
458 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
|
459 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
|
460 finally: |
23086
cde6904f1992
httppeer: close the temporary bundle file after two-way streaming it
Matt Harbison <matt_harbison@yahoo.com>
parents:
21188
diff
changeset
|
461 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
|
462 fp_.close() |
21074
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
463 if fh is not None: |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
464 fh.close() |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
465 os.unlink(filename) |
f8a0d82b0463
httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20905
diff
changeset
|
466 |
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
|
467 def _callcompressable(self, cmd, **args): |
30473
e16e234b9ca3
httppeer: do decompression inside _callstream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30241
diff
changeset
|
468 return self._callstream(cmd, _compressible=True, **args) |
11370 | 469 |
21188
d36440d84328
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa
Mads Kiilerich <madski@unity3d.com>
parents:
21074
diff
changeset
|
470 def _abort(self, exception): |
d36440d84328
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa
Mads Kiilerich <madski@unity3d.com>
parents:
21074
diff
changeset
|
471 raise exception |
d36440d84328
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa
Mads Kiilerich <madski@unity3d.com>
parents:
21074
diff
changeset
|
472 |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
473 # TODO implement interface for version 2 peers |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
474 class httpv2peer(object): |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
475 def __init__(self, ui, repourl, opener): |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
476 self.ui = ui |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
477 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
478 if repourl.endswith('/'): |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
479 repourl = repourl[:-1] |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
480 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
481 self.url = repourl |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
482 self._opener = opener |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
483 # This is an its own attribute to facilitate extensions overriding |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
484 # the default type. |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
485 self._requestbuilder = urlreq.request |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
486 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
487 def close(self): |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
488 pass |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
489 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
490 # TODO require to be part of a batched primitive, use futures. |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
491 def _call(self, name, **args): |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
492 """Call a wire protocol command with arguments.""" |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
493 |
37546
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
494 # Having this early has a side-effect of importing wireprotov2server, |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
495 # which has the side-effect of ensuring commands are registered. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
496 |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
497 # TODO modify user-agent to reflect v2. |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
498 headers = { |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
499 r'Accept': wireprotov2server.FRAMINGTYPE, |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
500 r'Content-Type': wireprotov2server.FRAMINGTYPE, |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
501 } |
3a2367e6c6f2
wireproto: move version 2 command handlers to wireprotov2server
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37545
diff
changeset
|
502 |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
503 # TODO permissions should come from capabilities results. |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
504 permission = wireproto.commandsv2[name].permission |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
505 if permission not in ('push', 'pull'): |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
506 raise error.ProgrammingError('unknown permission type: %s' % |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
507 permission) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
508 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
509 permission = { |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
510 'push': 'rw', |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
511 'pull': 'ro', |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
512 }[permission] |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
513 |
37545
93397c4633f6
wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37544
diff
changeset
|
514 url = '%s/api/%s/%s/%s' % (self.url, wireprotov2server.HTTPV2, |
93397c4633f6
wireproto: extract HTTP version 2 code to own module
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37544
diff
changeset
|
515 permission, name) |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
516 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
517 # TODO this should be part of a generic peer for the frame-based |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
518 # protocol. |
37543
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
519 reactor = wireprotoframing.clientreactor(hasmultiplesend=False, |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
520 buffersends=True) |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
521 |
37543
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
522 request, action, meta = reactor.callcommand(name, args) |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
523 assert action == 'noop' |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
524 |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
525 action, meta = reactor.flushcommands() |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
526 assert action == 'sendframes' |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
527 |
01361be9e2dc
wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37498
diff
changeset
|
528 body = b''.join(map(bytes, meta['framegen'])) |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
529 req = self._requestbuilder(pycompat.strurl(url), body, headers) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
530 req.add_unredirected_header(r'Content-Length', r'%d' % len(body)) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
531 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
532 # TODO unify this code with httppeer. |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
533 try: |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
534 res = self._opener.open(req) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
535 except urlerr.httperror as e: |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
536 if e.code == 401: |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
537 raise error.Abort(_('authorization failed')) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
538 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
539 raise |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
540 except httplib.HTTPException as e: |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
541 self.ui.traceback() |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
542 raise IOError(None, e) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
543 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
544 # TODO validate response type, wrap response to handle I/O errors. |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
545 # TODO more robust frame receiver. |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
546 results = [] |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
547 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
548 while True: |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
549 frame = wireprotoframing.readframe(res) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
550 if frame is None: |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
551 break |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
552 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
553 self.ui.note(_('received %r\n') % frame) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
554 |
37544
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
555 action, meta = reactor.onframerecv(frame) |
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
556 |
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
557 if action == 'responsedata': |
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
558 if meta['cbor']: |
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
559 payload = util.bytesio(meta['data']) |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
560 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
561 decoder = cbor.CBORDecoder(payload) |
37544
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
562 while payload.tell() + 1 < len(meta['data']): |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
563 results.append(decoder.decode()) |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
564 else: |
37544
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
565 results.append(meta['data']) |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
566 else: |
37544
55b5ba8d4e68
wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37543
diff
changeset
|
567 error.ProgrammingError('unhandled action: %s' % action) |
37483
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
568 |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
569 return results |
61e405fb6372
wireproto: crude support for version 2 HTTP peer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37411
diff
changeset
|
570 |
37547
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
571 def makepeer(ui, path, requestbuilder=urlreq.request): |
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
572 """Construct an appropriate HTTP peer instance. |
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
573 |
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
574 ``requestbuilder`` is the type used for constructing HTTP requests. |
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
575 It exists as an argument so extensions can override the default. |
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
576 """ |
37009
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
577 u = util.url(path) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
578 if u.query or u.fragment: |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
579 raise error.Abort(_('unsupported URL component: "%s"') % |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
580 (u.query or u.fragment)) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
581 |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
582 # urllib cannot handle URLs with embedded user or passwd. |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
583 url, authinfo = u.authinfo() |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
584 ui.debug('using %s\n' % url) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
585 |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
586 opener = urlmod.opener(ui, authinfo) |
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
587 |
37547
835ccc2a5ef1
httppeer: move requestbuilder defaults into makepeer() argument
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37546
diff
changeset
|
588 return httppeer(ui, path, url, opener, requestbuilder) |
37009
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
589 |
2740
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
590 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
|
591 if create: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25954
diff
changeset
|
592 raise error.Abort(_('cannot create new http repository')) |
7211 | 593 try: |
36965
43815d87c6aa
httppeer: alias url as urlmod
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36843
diff
changeset
|
594 if path.startswith('https:') and not urlmod.has_https: |
36258
874209855f5c
httppeer: remove httpspeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36257
diff
changeset
|
595 raise error.Abort(_('Python support for SSL and HTTPS ' |
874209855f5c
httppeer: remove httpspeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36257
diff
changeset
|
596 'is not installed')) |
35924
197d10e157ce
httppeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35698
diff
changeset
|
597 |
37009
8e89c2bec1f7
httppeer: refactor how httppeer is created (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36967
diff
changeset
|
598 inst = makepeer(ui, path) |
35924
197d10e157ce
httppeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35698
diff
changeset
|
599 inst._fetchcaps() |
197d10e157ce
httppeer: remove support for connecting to <0.9.1 servers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35698
diff
changeset
|
600 |
7211 | 601 return inst |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25500
diff
changeset
|
602 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
|
603 try: |
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
604 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
|
605 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
|
606 return r |
cc9366a3751b
httprepo: use the original exception after falling back to static-http failed
Mads Kiilerich <mads@kiilerich.com>
parents:
14094
diff
changeset
|
607 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
|
608 raise httpexception # use the original http RepoError instead |