geventhttpclient 2.3.3__tar.gz → 2.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {geventhttpclient-2.3.3/src/geventhttpclient.egg-info → geventhttpclient-2.3.4}/PKG-INFO +4 -26
  2. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/pyproject.toml +2 -3
  3. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/__init__.py +1 -1
  4. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/url.py +69 -3
  5. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/useragent.py +1 -1
  6. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4/src/geventhttpclient.egg-info}/PKG-INFO +4 -26
  7. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_ssl.py +1 -1
  8. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_url.py +11 -2
  9. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/LICENSE-MIT +0 -0
  10. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/MANIFEST.in +0 -0
  11. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/README.md +0 -0
  12. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/ext/Python_compat.h +0 -0
  13. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/ext/_parser.c +0 -0
  14. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/llhttp/LICENSE-MIT +0 -0
  15. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/llhttp/include/llhttp.h +0 -0
  16. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/llhttp/src/api.c +0 -0
  17. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/llhttp/src/http.c +0 -0
  18. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/llhttp/src/llhttp.c +0 -0
  19. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/setup.cfg +0 -0
  20. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/setup.py +0 -0
  21. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/api.py +0 -0
  22. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/client.py +0 -0
  23. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/connectionpool.py +0 -0
  24. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/header.py +0 -0
  25. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/httplib.py +0 -0
  26. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/httplib2.py +0 -0
  27. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/requests.py +0 -0
  28. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient/response.py +0 -0
  29. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient.egg-info/SOURCES.txt +0 -0
  30. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient.egg-info/dependency_links.txt +0 -0
  31. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient.egg-info/requires.txt +0 -0
  32. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/src/geventhttpclient.egg-info/top_level.txt +0 -0
  33. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_client.py +0 -0
  34. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_headers.py +0 -0
  35. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_httplib.py +0 -0
  36. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_httplib2.py +0 -0
  37. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_keep_alive.py +0 -0
  38. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_network_failures.py +0 -0
  39. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_no_module_ssl.py +0 -0
  40. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_parser.py +0 -0
  41. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_requests.py +0 -0
  42. {geventhttpclient-2.3.3 → geventhttpclient-2.3.4}/tests/test_useragent.py +0 -0
@@ -1,31 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: geventhttpclient
3
- Version: 2.3.3
3
+ Version: 2.3.4
4
4
  Summary: HTTP client library for gevent
5
5
  Author-email: Antonin Amand <antonin.amand@gmail.com>
6
- License: This software is licensed under the MIT License.
7
-
8
- Copyright Antonin Amand <antonin.amand@gmail.com>, 2018.
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a
11
- copy of this software and associated documentation files (the
12
- "Software"), to deal in the Software without restriction, including
13
- without limitation the rights to use, copy, modify, merge, publish,
14
- distribute, sublicense, and/or sell copies of the Software, and to permit
15
- persons to whom the Software is furnished to do so, subject to the
16
- following conditions:
17
-
18
- The above copyright notice and this permission notice shall be included
19
- in all copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
24
- NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
27
- USE OR OTHER DEALINGS IN THE SOFTWARE.
28
-
6
+ License-Expression: MIT
29
7
  Project-URL: homepage, http://github.com/geventhttpclient/geventhttpclient
30
8
  Project-URL: issues, http://github.com/geventhttpclient/geventhttpclient/issues
31
9
  Project-URL: download, https://pypi.org/project/geventhttpclient/#files
@@ -33,7 +11,6 @@ Keywords: http,gevent,client
33
11
  Classifier: Development Status :: 5 - Production/Stable
34
12
  Classifier: Intended Audience :: Developers
35
13
  Classifier: Intended Audience :: Information Technology
36
- Classifier: License :: OSI Approved :: MIT License
37
14
  Classifier: Operating System :: OS Independent
38
15
  Classifier: Programming Language :: Python :: 3
39
16
  Classifier: Programming Language :: Python :: 3.9
@@ -60,6 +37,7 @@ Requires-Dist: urllib3; extra == "benchmarks"
60
37
  Requires-Dist: httplib2; extra == "benchmarks"
61
38
  Provides-Extra: examples
62
39
  Requires-Dist: oauth2; extra == "examples"
40
+ Dynamic: license-file
63
41
 
64
42
  [![GitHub Workflow CI Status](https://img.shields.io/github/actions/workflow/status/geventhttpclient/geventhttpclient/test.yml?branch=master&logo=github&style=flat)](https://github.com/geventhttpclient/geventhttpclient/actions)
65
43
  [![PyPI](https://img.shields.io/pypi/v/geventhttpclient.svg?style=flat)](https://pypi.org/project/geventhttpclient/)
@@ -5,18 +5,17 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "geventhttpclient"
8
- version = "2.3.3" # don't forget to update version __init__.py as well
8
+ version = "2.3.4" # don't forget to update version __init__.py as well
9
9
  description = "HTTP client library for gevent"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.9"
12
- license = {file = "LICENSE-MIT"}
12
+ license = "MIT"
13
13
  keywords = ["http", "gevent", "client"]
14
14
  authors = [{name = "Antonin Amand", email = "antonin.amand@gmail.com"}]
15
15
  classifiers = [
16
16
  "Development Status :: 5 - Production/Stable",
17
17
  "Intended Audience :: Developers",
18
18
  "Intended Audience :: Information Technology",
19
- "License :: OSI Approved :: MIT License",
20
19
  "Operating System :: OS Independent",
21
20
  "Programming Language :: Python :: 3",
22
21
  "Programming Language :: Python :: 3.9",
@@ -1,6 +1,6 @@
1
1
  # package
2
2
 
3
- __version__ = "2.3.3" # don't forget to update version in pyproject.toml as well
3
+ __version__ = "2.3.4" # don't forget to update version in pyproject.toml as well
4
4
 
5
5
  from geventhttpclient.api import delete, get, head, options, patch, post, put, request
6
6
  from geventhttpclient.client import HTTPClient
@@ -33,9 +33,6 @@ class URL:
33
33
  if params is not None:
34
34
  new_params = _encode_params(params)
35
35
  query = query + "&" + new_params if query else new_params
36
- if query:
37
- # get a little closer to the behaviour of requests.utils.requote_uri
38
- query = query.replace(" ", "%20")
39
36
  self._parsed = urlparse.ParseResult(scheme, netloc, path, parsed_params, query, fragment)
40
37
 
41
38
  def __str__(self):
@@ -109,6 +106,14 @@ class URL:
109
106
  parsed = urlparse.ParseResult(scheme, netloc, path, params, query, fragment)
110
107
  return type(self)(parsed)
111
108
 
109
+ @property
110
+ def quoted(self):
111
+ return requote_uri(str(self))
112
+
113
+ @property
114
+ def quoted_uri(self):
115
+ return requote_uri(self.request_uri)
116
+
112
117
 
113
118
  def _encode_params(data):
114
119
  """Encode parameters in a piece of data.
@@ -158,3 +163,64 @@ def to_key_val_list(value):
158
163
  value = value.items()
159
164
 
160
165
  return list(value)
166
+
167
+
168
+ class InvalidURL(Exception):
169
+ pass
170
+
171
+
172
+ # The following functions are taken from requests
173
+ # Copyright of the original requests project:
174
+ # :copyright: (c) 2012 by Kenneth Reitz.
175
+ # :license: Apache2, see LICENSE for more details.
176
+
177
+ # The unreserved URI characters (RFC 3986)
178
+ UNRESERVED_SET = frozenset(
179
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~"
180
+ )
181
+
182
+
183
+ def unquote_unreserved(uri):
184
+ """Un-escape any percent-escape sequences in a URI that are unreserved
185
+ characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
186
+
187
+ :rtype: str
188
+ """
189
+ parts = uri.split("%")
190
+ for i in range(1, len(parts)):
191
+ h = parts[i][0:2]
192
+ if len(h) == 2 and h.isalnum():
193
+ try:
194
+ c = chr(int(h, 16))
195
+ except ValueError:
196
+ raise InvalidURL(f"Invalid percent-escape sequence: '{h}'")
197
+
198
+ if c in UNRESERVED_SET:
199
+ parts[i] = c + parts[i][2:]
200
+ else:
201
+ parts[i] = f"%{parts[i]}"
202
+ else:
203
+ parts[i] = f"%{parts[i]}"
204
+ return "".join(parts)
205
+
206
+
207
+ def requote_uri(uri):
208
+ """Re-quote the given URI.
209
+
210
+ This function passes the given URI through an unquote/quote cycle to
211
+ ensure that it is fully and consistently quoted.
212
+
213
+ :rtype: str
214
+ """
215
+ safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
216
+ safe_without_percent = "!#$&'()*+,/:;=?@[]~"
217
+ try:
218
+ # Unquote only the unreserved characters
219
+ # Then quote only illegal characters (do not quote reserved,
220
+ # unreserved, or '%')
221
+ return urlparse.quote(unquote_unreserved(uri), safe=safe_with_percent)
222
+ except InvalidURL:
223
+ # We couldn't unquote the given URI, so let's try quoting it, but
224
+ # there may be unquoted '%'s in the URI. We need to make sure they're
225
+ # properly quoted so they do not cause issues elsewhere.
226
+ return urlparse.quote(uri, safe=safe_without_percent)
@@ -457,7 +457,7 @@ class UserAgent:
457
457
  client = self.clientpool.get_client(request.url_split)
458
458
  resp = client.request(
459
459
  request.method,
460
- request.url_split.request_uri,
460
+ request.url_split.quoted_uri,
461
461
  body=request.payload,
462
462
  headers=request.headers,
463
463
  )
@@ -1,31 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: geventhttpclient
3
- Version: 2.3.3
3
+ Version: 2.3.4
4
4
  Summary: HTTP client library for gevent
5
5
  Author-email: Antonin Amand <antonin.amand@gmail.com>
6
- License: This software is licensed under the MIT License.
7
-
8
- Copyright Antonin Amand <antonin.amand@gmail.com>, 2018.
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a
11
- copy of this software and associated documentation files (the
12
- "Software"), to deal in the Software without restriction, including
13
- without limitation the rights to use, copy, modify, merge, publish,
14
- distribute, sublicense, and/or sell copies of the Software, and to permit
15
- persons to whom the Software is furnished to do so, subject to the
16
- following conditions:
17
-
18
- The above copyright notice and this permission notice shall be included
19
- in all copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
24
- NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
27
- USE OR OTHER DEALINGS IN THE SOFTWARE.
28
-
6
+ License-Expression: MIT
29
7
  Project-URL: homepage, http://github.com/geventhttpclient/geventhttpclient
30
8
  Project-URL: issues, http://github.com/geventhttpclient/geventhttpclient/issues
31
9
  Project-URL: download, https://pypi.org/project/geventhttpclient/#files
@@ -33,7 +11,6 @@ Keywords: http,gevent,client
33
11
  Classifier: Development Status :: 5 - Production/Stable
34
12
  Classifier: Intended Audience :: Developers
35
13
  Classifier: Intended Audience :: Information Technology
36
- Classifier: License :: OSI Approved :: MIT License
37
14
  Classifier: Operating System :: OS Independent
38
15
  Classifier: Programming Language :: Python :: 3
39
16
  Classifier: Programming Language :: Python :: 3.9
@@ -60,6 +37,7 @@ Requires-Dist: urllib3; extra == "benchmarks"
60
37
  Requires-Dist: httplib2; extra == "benchmarks"
61
38
  Provides-Extra: examples
62
39
  Requires-Dist: oauth2; extra == "examples"
40
+ Dynamic: license-file
63
41
 
64
42
  [![GitHub Workflow CI Status](https://img.shields.io/github/actions/workflow/status/geventhttpclient/geventhttpclient/test.yml?branch=master&logo=github&style=flat)](https://github.com/geventhttpclient/geventhttpclient/actions)
65
43
  [![PyPI](https://img.shields.io/pypi/v/geventhttpclient.svg?style=flat)](https://pypi.org/project/geventhttpclient/)
@@ -164,7 +164,7 @@ def sni_checker_server():
164
164
  def run(sock):
165
165
  while True:
166
166
  conn, addr = sock.accept()
167
- client_hello = conn.recv(1024)
167
+ client_hello = conn.recv(4096)
168
168
  return extract_sni_from_client_hello(client_hello)
169
169
 
170
170
  def extract_sni_from_client_hello(hello_packet):
@@ -41,13 +41,22 @@ def test_params_urlencoded():
41
41
  assert url.fragment == "frag"
42
42
 
43
43
 
44
- def test_query_urlencoded():
44
+ def test_quote_spaces():
45
45
  url = URL("http://gevent.org/?foo=bar with spaces")
46
- assert url.query == "foo=bar%20with%20spaces"
46
+ assert url.quoted == "http://gevent.org/?foo=bar%20with%20spaces"
47
+ assert url.quoted_uri == "/?foo=bar%20with%20spaces"
47
48
  assert url.host == "gevent.org"
48
49
  assert url.port == 80
49
50
 
50
51
 
52
+ def test_quote_non_ascii():
53
+ url = URL("http://127.0.0.1:8000/ы")
54
+ assert url.quoted == "http://127.0.0.1:8000/%D1%8B"
55
+ assert url.quoted_uri == "/%D1%8B"
56
+ assert url.host == "127.0.0.1"
57
+ assert url.port == 8000
58
+
59
+
51
60
  def test_tuple_unpack():
52
61
  url = URL("http://gevent.org/somepath?foo=bar#frag")
53
62
  assert len(tuple(url)) == 6