Mercurial > public > mercurial-scm > hg
annotate mercurial/httpclient/__init__.py @ 31257:11831d755b51
merge: remove uses of manifest.matches
This gets rid of the manifest.matches calls in merge.py in favor of the new api.
This is part of getting rid of manifest.matches since it is O(manifest).
author | Durham Goode <durham@fb.com> |
---|---|
date | Tue, 07 Mar 2017 18:38:20 -0800 |
parents | 456609cbd840 |
children | a53f2d4c734f |
rev | line source |
---|---|
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
1 # Copyright 2010, Google Inc. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
2 # All rights reserved. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
3 # |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
4 # Redistribution and use in source and binary forms, with or without |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
5 # modification, are permitted provided that the following conditions are |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
6 # met: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
7 # |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
8 # * Redistributions of source code must retain the above copyright |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
9 # notice, this list of conditions and the following disclaimer. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
10 # * Redistributions in binary form must reproduce the above |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
11 # copyright notice, this list of conditions and the following disclaimer |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
12 # in the documentation and/or other materials provided with the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
13 # distribution. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
14 # * Neither the name of Google Inc. nor the names of its |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
15 # contributors may be used to endorse or promote products derived from |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
16 # this software without specific prior written permission. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
17 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
29 """Improved HTTP/1.1 client library |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
30 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
31 This library contains an HTTPConnection which is similar to the one in |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
32 httplib, but has several additional features: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
33 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
34 * supports keepalives natively |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
35 * uses select() to block for incoming data |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
36 * notices when the server responds early to a request |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
37 * implements ssl inline instead of in a different class |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
38 """ |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
39 from __future__ import absolute_import |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
40 |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
41 # Many functions in this file have too many arguments. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
42 # pylint: disable=R0913 |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
43 import email |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
44 import email.message |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
45 import errno |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
46 import inspect |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
47 import logging |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
48 import select |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
49 import socket |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
50 import ssl |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
51 import sys |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
52 |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
53 try: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
54 import cStringIO as io |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
55 io.StringIO |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
56 except ImportError: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
57 import io |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
58 |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
59 try: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
60 import httplib |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
61 httplib.HTTPException |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
62 except ImportError: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
63 import http.client as httplib |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
64 |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
65 from . import ( |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
66 _readers, |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
67 ) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
68 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
69 logger = logging.getLogger(__name__) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
70 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
71 __all__ = ['HTTPConnection', 'HTTPResponse'] |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
72 |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
73 HTTP_VER_1_0 = b'HTTP/1.0' |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
74 HTTP_VER_1_1 = b'HTTP/1.1' |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
75 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
76 OUTGOING_BUFFER_SIZE = 1 << 15 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
77 INCOMING_BUFFER_SIZE = 1 << 20 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
78 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
79 HDR_ACCEPT_ENCODING = 'accept-encoding' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
80 HDR_CONNECTION_CTRL = 'connection' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
81 HDR_CONTENT_LENGTH = 'content-length' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
82 HDR_XFER_ENCODING = 'transfer-encoding' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
83 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
84 XFER_ENCODING_CHUNKED = 'chunked' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
85 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
86 CONNECTION_CLOSE = 'close' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
87 |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
88 EOL = b'\r\n' |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
89 _END_HEADERS = EOL * 2 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
90 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
91 # Based on some searching around, 1 second seems like a reasonable |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
92 # default here. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
93 TIMEOUT_ASSUME_CONTINUE = 1 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
94 TIMEOUT_DEFAULT = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
95 |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
96 if sys.version_info > (3, 0): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
97 _unicode = str |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
98 else: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
99 _unicode = unicode |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
100 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
101 def _ensurebytes(data): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
102 if not isinstance(data, (_unicode, bytes)): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
103 data = str(data) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
104 if not isinstance(data, bytes): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
105 try: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
106 return data.encode('latin-1') |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
107 except UnicodeEncodeError as err: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
108 raise UnicodeEncodeError( |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
109 err.encoding, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
110 err.object, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
111 err.start, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
112 err.end, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
113 '%r is not valid Latin-1 Use .encode("utf-8") ' |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
114 'if sending as utf-8 is desired.' % ( |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
115 data[err.start:err.end],)) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
116 return data |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
117 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
118 class _CompatMessage(email.message.Message): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
119 """Workaround for rfc822.Message and email.message.Message API diffs.""" |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
120 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
121 @classmethod |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
122 def from_string(cls, s): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
123 if sys.version_info > (3, 0): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
124 # Python 3 can't decode headers from bytes, so we have to |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
125 # trust RFC 2616 and decode the headers as iso-8859-1 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
126 # bytes. |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
127 s = s.decode('iso-8859-1') |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
128 headers = email.message_from_string(s, _class=_CompatMessage) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
129 # Fix multi-line headers to match httplib's behavior from |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
130 # Python 2.x, since email.message.Message handles them in |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
131 # slightly different ways. |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
132 if sys.version_info < (3, 0): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
133 new = [] |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
134 for h, v in headers._headers: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
135 if '\r\n' in v: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
136 v = '\n'.join([' ' + x.lstrip() for x in v.split('\r\n')])[1:] |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
137 new.append((h, v)) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
138 headers._headers = new |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
139 return headers |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
140 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
141 def getheaders(self, key): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
142 return self.get_all(key) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
143 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
144 def getheader(self, key, default=None): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
145 return self.get(key, failobj=default) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
146 |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
147 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
148 class HTTPResponse(object): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
149 """Response from an HTTP server. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
150 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
151 The response will continue to load as available. If you need the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
152 complete response before continuing, check the .complete() method. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
153 """ |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
154 def __init__(self, sock, timeout, method): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
155 self.sock = sock |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
156 self.method = method |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
157 self.raw_response = b'' |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
158 self._headers_len = 0 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
159 self.headers = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
160 self.will_close = False |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
161 self.status_line = b'' |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
162 self.status = None |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
163 self.continued = False |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
164 self.http_version = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
165 self.reason = None |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
166 self._reader = None |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
167 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
168 self._read_location = 0 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
169 self._eol = EOL |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
170 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
171 self._timeout = timeout |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
172 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
173 @property |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
174 def _end_headers(self): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
175 return self._eol * 2 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
176 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
177 def complete(self): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
178 """Returns true if this response is completely loaded. |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
179 |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
180 Note that if this is a connection where complete means the |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
181 socket is closed, this will nearly always return False, even |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
182 in cases where all the data has actually been loaded. |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
183 """ |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
184 if self._reader: |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
185 return self._reader.done() |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
186 |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
187 def _close(self): |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
188 if self._reader is not None: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
189 # We're a friend of the reader class here. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
190 # pylint: disable=W0212 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
191 self._reader._close() |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
192 |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
193 def getheader(self, header, default=None): |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
194 return self.headers.getheader(header, default=default) |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
195 |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
196 def getheaders(self): |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
197 if sys.version_info < (3, 0): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
198 return [(k.lower(), v) for k, v in self.headers.items()] |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
199 # Starting in Python 3, headers aren't lowercased before being |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
200 # returned here. |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
201 return self.headers.items() |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
202 |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
203 def readline(self): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
204 """Read a single line from the response body. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
205 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
206 This may block until either a line ending is found or the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
207 response is complete. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
208 """ |
19038 | 209 blocks = [] |
210 while True: | |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
211 self._reader.readto(b'\n', blocks) |
19038 | 212 |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
213 if blocks and blocks[-1][-1:] == b'\n' or self.complete(): |
19038 | 214 break |
215 | |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
216 self._select() |
19038 | 217 |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
218 return b''.join(blocks) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
219 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
220 def read(self, length=None): |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
221 """Read data from the response body.""" |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
222 # if length is None, unbounded read |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
223 while (not self.complete() # never select on a finished read |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
224 and (not length # unbounded, so we wait for complete() |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
225 or length > self._reader.available_data)): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
226 self._select() |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
227 if not length: |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
228 length = self._reader.available_data |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
229 r = self._reader.read(length) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
230 if self.complete() and self.will_close: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
231 self.sock.close() |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
232 return r |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
233 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
234 def _select(self): |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
235 r, unused_write, unused_err = select.select( |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
236 [self.sock], [], [], self._timeout) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
237 if not r: |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
238 # socket was not readable. If the response is not |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
239 # complete, raise a timeout. |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
240 if not self.complete(): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
241 logger.info('timed out with timeout of %s', self._timeout) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
242 raise HTTPTimeoutException('timeout reading data') |
14341
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
243 try: |
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
244 data = self.sock.recv(INCOMING_BUFFER_SIZE) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
245 except ssl.SSLError as e: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
246 if e.args[0] != ssl.SSL_ERROR_WANT_READ: |
14341
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
247 raise |
17428
72803c8edaa4
avoid using abbreviations that look like spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
17424
diff
changeset
|
248 logger.debug('SSL_ERROR_WANT_READ in _select, should retry later') |
14341
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
249 return True |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
250 logger.debug('response read %d data during _select', len(data)) |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
251 # If the socket was readable and no data was read, that means |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
252 # the socket was closed. Inform the reader (if any) so it can |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
253 # raise an exception if this is an invalid situation. |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
254 if not data: |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
255 if self._reader: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
256 # We're a friend of the reader class here. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
257 # pylint: disable=W0212 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
258 self._reader._close() |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
259 return False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
260 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
261 self._load_response(data) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
262 return True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
263 |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
264 # This method gets replaced by _load later, which confuses pylint. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
265 def _load_response(self, data): # pylint: disable=E0202 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
266 # Being here implies we're not at the end of the headers yet, |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
267 # since at the end of this method if headers were completely |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
268 # loaded we replace this method with the load() method of the |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
269 # reader we created. |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
270 self.raw_response += data |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
271 # This is a bogus server with bad line endings |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
272 if self._eol not in self.raw_response: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
273 for bad_eol in (b'\n', b'\r'): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
274 if (bad_eol in self.raw_response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
275 # verify that bad_eol is not the end of the incoming data |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
276 # as this could be a response line that just got |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
277 # split between \r and \n. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
278 and (self.raw_response.index(bad_eol) < |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
279 (len(self.raw_response) - 1))): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
280 logger.info('bogus line endings detected, ' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
281 'using %r for EOL', bad_eol) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
282 self._eol = bad_eol |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
283 break |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
284 # exit early if not at end of headers |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
285 if self._end_headers not in self.raw_response or self.headers: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
286 return |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
287 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
288 # handle 100-continue response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
289 hdrs, body = self.raw_response.split(self._end_headers, 1) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
290 unused_http_ver, status = hdrs.split(b' ', 1) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
291 if status.startswith(b'100'): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
292 self.raw_response = body |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
293 self.continued = True |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
294 logger.debug('continue seen, setting body to %r', body) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
295 return |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
296 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
297 # arriving here means we should parse response headers |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
298 # as all headers have arrived completely |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
299 hdrs, body = self.raw_response.split(self._end_headers, 1) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
300 del self.raw_response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
301 if self._eol in hdrs: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
302 self.status_line, hdrs = hdrs.split(self._eol, 1) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
303 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
304 self.status_line = hdrs |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
305 hdrs = b'' |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
306 # TODO HTTP < 1.0 support |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
307 (self.http_version, self.status, |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
308 self.reason) = self.status_line.split(b' ', 2) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
309 self.status = int(self.status) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
310 if self._eol != EOL: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
311 hdrs = hdrs.replace(self._eol, b'\r\n') |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
312 headers = _CompatMessage.from_string(hdrs) |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
313 content_len = None |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
314 if HDR_CONTENT_LENGTH in headers: |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
315 content_len = int(headers[HDR_CONTENT_LENGTH]) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
316 if self.http_version == HTTP_VER_1_0: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
317 self.will_close = True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
318 elif HDR_CONNECTION_CTRL in headers: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
319 self.will_close = ( |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
320 headers[HDR_CONNECTION_CTRL].lower() == CONNECTION_CLOSE) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
321 if (HDR_XFER_ENCODING in headers |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
322 and headers[HDR_XFER_ENCODING].lower() == XFER_ENCODING_CHUNKED): |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
323 self._reader = _readers.ChunkedReader(self._eol) |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
324 logger.debug('using a chunked reader') |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
325 else: |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
326 # HEAD responses are forbidden from returning a body, and |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
327 # it's implausible for a CONNECT response to use |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
328 # close-is-end logic for an OK response. |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
329 if (self.method == b'HEAD' or |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
330 (self.method == b'CONNECT' and content_len is None)): |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
331 content_len = 0 |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
332 if content_len is not None: |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
333 logger.debug('using a content-length reader with length %d', |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
334 content_len) |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
335 self._reader = _readers.ContentLengthReader(content_len) |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
336 else: |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
337 # Response body had no length specified and is not |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
338 # chunked, so the end of the body will only be |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
339 # identifiable by the termination of the socket by the |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
340 # server. My interpretation of the spec means that we |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
341 # are correct in hitting this case if |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
342 # transfer-encoding, content-length, and |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
343 # connection-control were left unspecified. |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
344 self._reader = _readers.CloseIsEndReader() |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
345 logger.debug('using a close-is-end reader') |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
346 self.will_close = True |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
347 |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
348 if body: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
349 # We're a friend of the reader class here. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
350 # pylint: disable=W0212 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
351 self._reader._load(body) |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
352 logger.debug('headers complete') |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
353 self.headers = headers |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
354 # We're a friend of the reader class here. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
355 # pylint: disable=W0212 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
356 self._load_response = self._reader._load |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
357 |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
358 def _foldheaders(headers): |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
359 """Given some headers, rework them so we can safely overwrite values. |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
360 |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
361 >>> _foldheaders({'Accept-Encoding': 'wat'}) |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
362 {'accept-encoding': ('Accept-Encoding', 'wat')} |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
363 """ |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
364 return dict((k.lower(), (k, v)) for k, v in headers.items()) |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
365 |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
366 try: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
367 inspect.signature |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
368 def _handlesarg(func, arg): |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
369 """ Try to determine if func accepts arg |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
370 |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
371 If it takes arg, return True |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
372 If it happens to take **args, then it could do anything: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
373 * It could throw a different TypeError, just for fun |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
374 * It could throw an ArgumentError or anything else |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
375 * It could choose not to throw an Exception at all |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
376 ... return 'unknown' |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
377 |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
378 Otherwise, return False |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
379 """ |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
380 params = inspect.signature(func).parameters |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
381 if arg in params: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
382 return True |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
383 for p in params: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
384 if params[p].kind == inspect._ParameterKind.VAR_KEYWORD: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
385 return 'unknown' |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
386 return False |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
387 except AttributeError: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
388 def _handlesarg(func, arg): |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
389 """ Try to determine if func accepts arg |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
390 |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
391 If it takes arg, return True |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
392 If it happens to take **args, then it could do anything: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
393 * It could throw a different TypeError, just for fun |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
394 * It could throw an ArgumentError or anything else |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
395 * It could choose not to throw an Exception at all |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
396 ... return 'unknown' |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
397 |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
398 Otherwise, return False |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
399 """ |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
400 spec = inspect.getargspec(func) |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
401 if arg in spec.args: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
402 return True |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
403 if spec.keywords: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
404 return 'unknown' |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
405 return False |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
406 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
407 class HTTPConnection(object): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
408 """Connection to a single http server. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
409 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
410 Supports 100-continue and keepalives natively. Uses select() for |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
411 non-blocking socket operations. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
412 """ |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
413 http_version = HTTP_VER_1_1 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
414 response_class = HTTPResponse |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
415 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
416 def __init__(self, host, port=None, use_ssl=None, ssl_validator=None, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
417 timeout=TIMEOUT_DEFAULT, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
418 continue_timeout=TIMEOUT_ASSUME_CONTINUE, |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
419 proxy_hostport=None, proxy_headers=None, |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
420 ssl_wrap_socket=None, **ssl_opts): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
421 """Create a new HTTPConnection. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
422 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
423 Args: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
424 host: The host to which we'll connect. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
425 port: Optional. The port over which we'll connect. Default 80 for |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
426 non-ssl, 443 for ssl. |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
16774
diff
changeset
|
427 use_ssl: Optional. Whether to use ssl. Defaults to False if port is |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
428 not 443, true if port is 443. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
429 ssl_validator: a function(socket) to validate the ssl cert |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
430 timeout: Optional. Connection timeout, default is TIMEOUT_DEFAULT. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
431 continue_timeout: Optional. Timeout for waiting on an expected |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
432 "100 Continue" response. Default is TIMEOUT_ASSUME_CONTINUE. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
433 proxy_hostport: Optional. Tuple of (host, port) to use as an http |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
434 proxy for the connection. Default is to not use a proxy. |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
435 proxy_headers: Optional dict of header keys and values to send to |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
436 a proxy when using CONNECT. For compatibility with |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
437 httplib, the Proxy-Authorization header may be |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
438 specified in headers for request(), which will clobber |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
439 any such header specified here if specified. Providing |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
440 this option and not proxy_hostport will raise an |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
441 ValueError. |
19807
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
442 ssl_wrap_socket: Optional function to use for wrapping |
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
443 sockets. If unspecified, the one from the ssl module will |
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
444 be used if available, or something that's compatible with |
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
445 it if on a Python older than 2.6. |
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
446 |
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
447 Any extra keyword arguments to this function will be provided |
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
448 to the ssl_wrap_socket method. If no ssl |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
449 """ |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
450 host = _ensurebytes(host) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
451 if port is None and host.count(b':') == 1 or b']:' in host: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
452 host, port = host.rsplit(b':', 1) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
453 port = int(port) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
454 if b'[' in host: |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
455 host = host[1:-1] |
19807
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
456 if ssl_wrap_socket is not None: |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
457 _wrap_socket = ssl_wrap_socket |
19807
c48df403caae
httpclient: import 4bb625347d4a to provide SSL wrapper injection
Augie Fackler <raf@durin42.com>
parents:
19620
diff
changeset
|
458 else: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
459 _wrap_socket = ssl.wrap_socket |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
460 call_wrap_socket = None |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
461 handlesubar = _handlesarg(_wrap_socket, 'server_hostname') |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
462 if handlesubar is True: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
463 # supports server_hostname |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
464 call_wrap_socket = _wrap_socket |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
465 handlesnobar = _handlesarg(_wrap_socket, 'serverhostname') |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
466 if handlesnobar is True and handlesubar is not True: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
467 # supports serverhostname |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
468 def call_wrap_socket(sock, server_hostname=None, **ssl_opts): |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
469 return _wrap_socket(sock, serverhostname=server_hostname, |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
470 **ssl_opts) |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
471 if handlesubar is False and handlesnobar is False: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
472 # does not support either |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
473 def call_wrap_socket(sock, server_hostname=None, **ssl_opts): |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
474 return _wrap_socket(sock, **ssl_opts) |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
475 if call_wrap_socket is None: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
476 # we assume it takes **args |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
477 def call_wrap_socket(sock, **ssl_opts): |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
478 if 'server_hostname' in ssl_opts: |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
479 ssl_opts['serverhostname'] = ssl_opts['server_hostname'] |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
480 return _wrap_socket(sock, **ssl_opts) |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
481 self._ssl_wrap_socket = call_wrap_socket |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
482 if use_ssl is None and port is None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
483 use_ssl = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
484 port = 80 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
485 elif use_ssl is None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
486 use_ssl = (port == 443) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
487 elif port is None: |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
488 port = (use_ssl and 443 or 80) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
489 self.port = port |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
490 self.ssl = use_ssl |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
491 self.ssl_opts = ssl_opts |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
492 self._ssl_validator = ssl_validator |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
493 self.host = host |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
494 self.sock = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
495 self._current_response = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
496 self._current_response_taken = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
497 if proxy_hostport is None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
498 self._proxy_host = self._proxy_port = None |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
499 if proxy_headers: |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
500 raise ValueError( |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
501 'proxy_headers may not be specified unless ' |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
502 'proxy_hostport is also specified.') |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
503 else: |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
504 self._proxy_headers = {} |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
505 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
506 self._proxy_host, self._proxy_port = proxy_hostport |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
507 self._proxy_headers = _foldheaders(proxy_headers or {}) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
508 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
509 self.timeout = timeout |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
510 self.continue_timeout = continue_timeout |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
511 |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
512 def _connect(self, proxy_headers): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
513 """Connect to the host and port specified in __init__.""" |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
514 if self.sock: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
515 return |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
516 if self._proxy_host is not None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
517 logger.info('Connecting to http proxy %s:%s', |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
518 self._proxy_host, self._proxy_port) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
519 sock = socket.create_connection((self._proxy_host, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
520 self._proxy_port)) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
521 if self.ssl: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
522 data = self._buildheaders(b'CONNECT', b'%s:%d' % (self.host, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
523 self.port), |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
524 proxy_headers, HTTP_VER_1_0) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
525 sock.send(data) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
526 sock.setblocking(0) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
527 r = self.response_class(sock, self.timeout, b'CONNECT') |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
528 timeout_exc = HTTPTimeoutException( |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
529 'Timed out waiting for CONNECT response from proxy') |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
530 while not r.complete(): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
531 try: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
532 # We're a friend of the response class, so let |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
533 # us use the private attribute. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
534 # pylint: disable=W0212 |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
535 if not r._select(): |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
536 if not r.complete(): |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
537 raise timeout_exc |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
538 except HTTPTimeoutException: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
539 # This raise/except pattern looks goofy, but |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
540 # _select can raise the timeout as well as the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
541 # loop body. I wish it wasn't this convoluted, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
542 # but I don't have a better solution |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
543 # immediately handy. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
544 raise timeout_exc |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
545 if r.status != 200: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
546 raise HTTPProxyConnectFailedException( |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
547 'Proxy connection failed: %d %s' % (r.status, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
548 r.read())) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
549 logger.info('CONNECT (for SSL) to %s:%s via proxy succeeded.', |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
550 self.host, self.port) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
551 else: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
552 sock = socket.create_connection((self.host, self.port)) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
553 if self.ssl: |
16774
69af967b6d6f
httpclient: update to c5abd358e543 of httpplus
Augie Fackler <raf@durin42.com>
parents:
16643
diff
changeset
|
554 # This is the default, but in the case of proxied SSL |
69af967b6d6f
httpclient: update to c5abd358e543 of httpplus
Augie Fackler <raf@durin42.com>
parents:
16643
diff
changeset
|
555 # requests the proxy logic above will have cleared |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
16774
diff
changeset
|
556 # blocking mode, so re-enable it just to be safe. |
16774
69af967b6d6f
httpclient: update to c5abd358e543 of httpplus
Augie Fackler <raf@durin42.com>
parents:
16643
diff
changeset
|
557 sock.setblocking(1) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
558 logger.debug('wrapping socket for ssl with options %r', |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
559 self.ssl_opts) |
29131
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
560 sock = self._ssl_wrap_socket(sock, server_hostname=self.host, |
8a66eda46c98
httpclient: update to upstream revision 2995635573d2
Augie Fackler <augie@google.com>
parents:
28997
diff
changeset
|
561 **self.ssl_opts) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
562 if self._ssl_validator: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
563 self._ssl_validator(sock) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
564 sock.setblocking(0) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
565 self.sock = sock |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
566 |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
567 def _buildheaders(self, method, path, headers, http_ver): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
568 if self.ssl and self.port == 443 or self.port == 80: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
569 # default port for protocol, so leave it out |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
570 hdrhost = self.host |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
571 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
572 # include nonstandard port in header |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
573 if b':' in self.host: # must be IPv6 |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
574 hdrhost = b'[%s]:%d' % (self.host, self.port) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
575 else: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
576 hdrhost = b'%s:%d' % (self.host, self.port) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
577 if self._proxy_host and not self.ssl: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
578 # When talking to a regular http proxy we must send the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
579 # full URI, but in all other cases we must not (although |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
580 # technically RFC 2616 says servers must accept our |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
581 # request if we screw up, experimentally few do that |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
582 # correctly.) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
583 assert path[0:1] == b'/', 'path must start with a /' |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
584 path = b'http://%s%s' % (hdrhost, path) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
585 outgoing = [b'%s %s %s%s' % (method, path, http_ver, EOL)] |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
586 headers[b'host'] = (b'Host', hdrhost) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
587 headers[HDR_ACCEPT_ENCODING] = (HDR_ACCEPT_ENCODING, 'identity') |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
588 for hdr, val in sorted((_ensurebytes(h), _ensurebytes(v)) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
589 for h, v in headers.values()): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
590 outgoing.append(b'%s: %s%s' % (hdr, val, EOL)) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
591 outgoing.append(EOL) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
592 return b''.join(outgoing) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
593 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
594 def close(self): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
595 """Close the connection to the server. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
596 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
597 This is a no-op if the connection is already closed. The |
17536 | 598 connection may automatically close if requested by the server |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
599 or required by the nature of a response. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
600 """ |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
601 if self.sock is None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
602 return |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
603 self.sock.close() |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
604 self.sock = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
605 logger.info('closed connection to %s on %s', self.host, self.port) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
606 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
607 def busy(self): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
608 """Returns True if this connection object is currently in use. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
609 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
610 If a response is still pending, this will return True, even if |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
611 the request has finished sending. In the future, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
612 HTTPConnection may transparently juggle multiple connections |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
613 to the server, in which case this will be useful to detect if |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
614 any of those connections is ready for use. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
615 """ |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
616 cr = self._current_response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
617 if cr is not None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
618 if self._current_response_taken: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
619 if cr.will_close: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
620 self.sock = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
621 self._current_response = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
622 return False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
623 elif cr.complete(): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
624 self._current_response = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
625 return False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
626 return True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
627 return False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
628 |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
629 def _reconnect(self, where, pheaders): |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
630 logger.info('reconnecting during %s', where) |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
631 self.close() |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
632 self._connect(pheaders) |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
633 |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
634 def request(self, method, path, body=None, headers={}, |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
635 expect_continue=False): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
636 """Send a request to the server. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
637 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
638 For increased flexibility, this does not return the response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
639 object. Future versions of HTTPConnection that juggle multiple |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
640 sockets will be able to send (for example) 5 requests all at |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
641 once, and then let the requests arrive as data is |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
642 available. Use the `getresponse()` method to retrieve the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
643 response. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
644 """ |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
645 method = _ensurebytes(method) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
646 path = _ensurebytes(path) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
647 if self.busy(): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
648 raise httplib.CannotSendRequest( |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
649 'Can not send another request before ' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
650 'current response is read!') |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
651 self._current_response_taken = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
652 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
653 logger.info('sending %s request for %s to %s on port %s', |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
654 method, path, self.host, self.port) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
655 |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
656 hdrs = _foldheaders(headers) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
657 # Figure out headers that have to be computed from the request |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
658 # body. |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
659 chunked = False |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
660 if body and HDR_CONTENT_LENGTH not in hdrs: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
661 if getattr(body, '__len__', False): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
662 hdrs[HDR_CONTENT_LENGTH] = (HDR_CONTENT_LENGTH, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
663 b'%d' % len(body)) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
664 elif getattr(body, 'read', False): |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
665 hdrs[HDR_XFER_ENCODING] = (HDR_XFER_ENCODING, |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
666 XFER_ENCODING_CHUNKED) |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
667 chunked = True |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
668 else: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
669 raise BadRequestData('body has no __len__() nor read()') |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
670 # Figure out expect-continue header |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
671 if hdrs.get('expect', ('', ''))[1].lower() == b'100-continue': |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
672 expect_continue = True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
673 elif expect_continue: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
674 hdrs['expect'] = (b'Expect', b'100-Continue') |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
675 # httplib compatibility: if the user specified a |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
676 # proxy-authorization header, that's actually intended for a |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
677 # proxy CONNECT action, not the real request, but only if |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
678 # we're going to use a proxy. |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
679 pheaders = dict(self._proxy_headers) |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
680 if self._proxy_host and self.ssl: |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
681 pa = hdrs.pop('proxy-authorization', None) |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
682 if pa is not None: |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
683 pheaders['proxy-authorization'] = pa |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
684 # Build header data |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
685 outgoing_headers = self._buildheaders( |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
686 method, path, hdrs, self.http_version) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
687 |
19620
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
688 # If we're reusing the underlying socket, there are some |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
689 # conditions where we'll want to retry, so make a note of the |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
690 # state of self.sock |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
691 fresh_socket = self.sock is None |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
692 self._connect(pheaders) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
693 response = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
694 first = True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
695 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
696 while ((outgoing_headers or body) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
697 and not (response and response.complete())): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
698 select_timeout = self.timeout |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
699 out = outgoing_headers or body |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
700 blocking_on_continue = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
701 if expect_continue and not outgoing_headers and not ( |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
702 response and (response.headers or response.continued)): |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
703 logger.info( |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
704 'waiting up to %s seconds for' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
705 ' continue response from server', |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
706 self.continue_timeout) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
707 select_timeout = self.continue_timeout |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
708 blocking_on_continue = True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
709 out = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
710 if out: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
711 w = [self.sock] |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
712 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
713 w = [] |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
714 r, w, x = select.select([self.sock], w, [], select_timeout) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
715 # if we were expecting a 100 continue and it's been long |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
716 # enough, just go ahead and assume it's ok. This is the |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
717 # recommended behavior from the RFC. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
718 if r == w == x == []: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
719 if blocking_on_continue: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
720 expect_continue = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
721 logger.info('no response to continue expectation from ' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
722 'server, optimistically sending request body') |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
723 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
724 raise HTTPTimeoutException('timeout sending data') |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
725 was_first = first |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
726 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
727 # incoming data |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
728 if r: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
729 try: |
14341
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
730 try: |
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
731 data = r[0].recv(INCOMING_BUFFER_SIZE) |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
732 except ssl.SSLError as e: |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
733 if e.args[0] != ssl.SSL_ERROR_WANT_READ: |
14341
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
734 raise |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
735 logger.debug('SSL_ERROR_WANT_READ while sending ' |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
736 'data, retrying...') |
14341
5c3de67e7402
httpclient: import revision b8c3511a8cae from py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14293
diff
changeset
|
737 continue |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
738 if not data: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
739 logger.info('socket appears closed in read') |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
740 self.sock = None |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
741 self._current_response = None |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
742 if response is not None: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
743 # We're a friend of the response class, so let |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
744 # us use the private attribute. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
745 # pylint: disable=W0212 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
746 response._close() |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
747 # This if/elif ladder is a bit subtle, |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
748 # comments in each branch should help. |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
749 if response is not None and response.complete(): |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
750 # Server responded completely and then |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
751 # closed the socket. We should just shut |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
752 # things down and let the caller get their |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
753 # response. |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
754 logger.info('Got an early response, ' |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
755 'aborting remaining request.') |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
756 break |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
757 elif was_first and response is None: |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
758 # Most likely a keepalive that got killed |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
759 # on the server's end. Commonly happens |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
760 # after getting a really large response |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
761 # from the server. |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
762 logger.info( |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
763 'Connection appeared closed in read on first' |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
764 ' request loop iteration, will retry.') |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
765 self._reconnect('read', pheaders) |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
766 continue |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
767 else: |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
768 # We didn't just send the first data hunk, |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
769 # and either have a partial response or no |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
770 # response at all. There's really nothing |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
771 # meaningful we can do here. |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
772 raise HTTPStateError( |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
773 'Connection appears closed after ' |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
774 'some request data was written, but the ' |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
775 'response was missing or incomplete!') |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
776 logger.debug('read %d bytes in request()', len(data)) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
777 if response is None: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
778 response = self.response_class( |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
779 r[0], self.timeout, method) |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
780 # We're a friend of the response class, so let us |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
781 # use the private attribute. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
782 # pylint: disable=W0212 |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
783 response._load_response(data) |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
784 # Jump to the next select() call so we load more |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
785 # data if the server is still sending us content. |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
786 continue |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24306
diff
changeset
|
787 except socket.error as e: |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
788 if e[0] != errno.EPIPE and not was_first: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
789 raise |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
790 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
791 # outgoing data |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
792 if w and out: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
793 try: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
794 if getattr(out, 'read', False): |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
795 # pylint guesses the type of out incorrectly here |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
796 # pylint: disable=E1103 |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
797 data = out.read(OUTGOING_BUFFER_SIZE) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
798 if not data: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
799 continue |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
800 if len(data) < OUTGOING_BUFFER_SIZE: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
801 if chunked: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
802 body = b'0' + EOL + EOL |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
803 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
804 body = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
805 if chunked: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
806 # This encode is okay because we know |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
807 # hex() is building us only 0-9 and a-f |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
808 # digits. |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
809 asciilen = hex(len(data))[2:].encode('ascii') |
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
810 out = asciilen + EOL + data + EOL |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
811 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
812 out = data |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
813 amt = w[0].send(out) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24306
diff
changeset
|
814 except socket.error as e: |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
815 if e[0] == ssl.SSL_ERROR_WANT_WRITE and self.ssl: |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
816 # This means that SSL hasn't flushed its buffer into |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
817 # the socket yet. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
818 # TODO: find a way to block on ssl flushing its buffer |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
819 # similar to selecting on a raw socket. |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
820 continue |
19489
42fcb2f7787d
httpclient: update to revision 9517a2b56fe9 of httpplus (issue3905)
Augie Fackler <raf@durin42.com>
parents:
19182
diff
changeset
|
821 if e[0] == errno.EWOULDBLOCK or e[0] == errno.EAGAIN: |
42fcb2f7787d
httpclient: update to revision 9517a2b56fe9 of httpplus (issue3905)
Augie Fackler <raf@durin42.com>
parents:
19182
diff
changeset
|
822 continue |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
823 elif (e[0] not in (errno.ECONNRESET, errno.EPIPE) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
824 and not first): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
825 raise |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
826 self._reconnect('write', pheaders) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
827 amt = self.sock.send(out) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
828 logger.debug('sent %d', amt) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
829 first = False |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
830 if out is body: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
831 body = out[amt:] |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
832 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
833 outgoing_headers = out[amt:] |
29442
456609cbd840
httpclient: update to 54868ef054d2 of httpplus
Augie Fackler <raf@durin42.com>
parents:
29131
diff
changeset
|
834 # End of request-sending loop. |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
835 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
836 # close if the server response said to or responded before eating |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
837 # the whole request |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
838 if response is None: |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
839 response = self.response_class(self.sock, self.timeout, method) |
19620
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
840 if not fresh_socket: |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
841 if not response._select(): |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
842 # This means the response failed to get any response |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
843 # data at all, and in all probability the socket was |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
844 # closed before the server even saw our request. Try |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
845 # the request again on a fresh socket. |
27601
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
846 logger.debug('response._select() failed during request().' |
1ad9da968a2e
httpclient: update to 938f2107d6e2 of httpplus
Augie Fackler <augie@google.com>
parents:
25660
diff
changeset
|
847 ' Assuming request needs to be retried.') |
19620
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
848 self.sock = None |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
849 # Call this method explicitly to re-try the |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
850 # request. We don't use self.request() because |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
851 # some tools (notably Mercurial) expect to be able |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
852 # to subclass and redefine request(), and they |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
853 # don't have the same argspec as we do. |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
854 # |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
855 # TODO restructure sending of requests to avoid |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
856 # this recursion |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
857 return HTTPConnection.request( |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
858 self, method, path, body=body, headers=headers, |
d4a0055af149
httpclient: import 0d1b0a8bc549 to fix bug involving late-arriving RST after a response
Augie Fackler <raf@durin42.com>
parents:
19489
diff
changeset
|
859 expect_continue=expect_continue) |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
860 data_left = bool(outgoing_headers or body) |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
861 if data_left: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
862 logger.info('stopped sending request early, ' |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
863 'will close the socket to be safe.') |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
864 response.will_close = True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
865 if response.will_close: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
866 # The socket will be closed by the response, so we disown |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
867 # the socket |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
868 self.sock = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
869 self._current_response = response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
870 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
871 def getresponse(self): |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
872 """Returns the response to the most recent request.""" |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
873 if self._current_response is None: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
874 raise httplib.ResponseNotReady() |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
875 r = self._current_response |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
876 while r.headers is None: |
19182
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
877 # We're a friend of the response class, so let us use the |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
878 # private attribute. |
fae47ecaa952
httpclient: upgrade to fe8c09e4db64 of httpplus
Augie Fackler <raf@durin42.com>
parents:
19038
diff
changeset
|
879 # pylint: disable=W0212 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
880 if not r._select() and not r.complete(): |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
881 raise _readers.HTTPRemoteClosedError() |
14293
9adbb5ef0964
httpclient: import f4c380237fd5 to fix keepalive not working
Augie Fackler <durin42@gmail.com>
parents:
14243
diff
changeset
|
882 if r.will_close: |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
883 self.sock = None |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
884 self._current_response = None |
14293
9adbb5ef0964
httpclient: import f4c380237fd5 to fix keepalive not working
Augie Fackler <durin42@gmail.com>
parents:
14243
diff
changeset
|
885 elif r.complete(): |
9adbb5ef0964
httpclient: import f4c380237fd5 to fix keepalive not working
Augie Fackler <durin42@gmail.com>
parents:
14243
diff
changeset
|
886 self._current_response = None |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
887 else: |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
888 self._current_response_taken = True |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
889 return r |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
890 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
891 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
892 class HTTPTimeoutException(httplib.HTTPException): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
893 """A timeout occurred while waiting on the server.""" |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
894 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
895 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
896 class BadRequestData(httplib.HTTPException): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
897 """Request body object has neither __len__ nor read.""" |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
898 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
899 |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
900 class HTTPProxyConnectFailedException(httplib.HTTPException): |
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
901 """Connecting to the HTTP proxy failed.""" |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
902 |
15218
c81dce8a7bb6
httpclient: update to 07d8c356f4d1 of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14376
diff
changeset
|
903 |
14376
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
904 class HTTPStateError(httplib.HTTPException): |
a75e0f4ba0ab
httpclient: import revision fc731618702a of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14341
diff
changeset
|
905 """Invalid internal state encountered.""" |
15218
c81dce8a7bb6
httpclient: update to 07d8c356f4d1 of py-nonblocking-http
Augie Fackler <durin42@gmail.com>
parents:
14376
diff
changeset
|
906 |
16643
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
907 # Forward this exception type from _readers since it needs to be part |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
908 # of the public API. |
24dbef11f477
httpclient: update to revision 892730fe7f46 of httpplus
Augie Fackler <raf@durin42.com>
parents:
15218
diff
changeset
|
909 HTTPRemoteClosedError = _readers.HTTPRemoteClosedError |
14243
861f28212398
Import new http library as mercurial.httpclient.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
910 # no-check-code |