rigid 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (229) hide show
  1. checksums.yaml +4 -4
  2. data/vendor/click/__init__.pyc +0 -0
  3. data/vendor/click/_bashcomplete.pyc +0 -0
  4. data/vendor/click/_compat.pyc +0 -0
  5. data/vendor/click/_termui_impl.pyc +0 -0
  6. data/vendor/click/_textwrap.pyc +0 -0
  7. data/vendor/click/_unicodefun.pyc +0 -0
  8. data/vendor/click/_winconsole.pyc +0 -0
  9. data/vendor/click/core.pyc +0 -0
  10. data/vendor/click/decorators.pyc +0 -0
  11. data/vendor/click/exceptions.pyc +0 -0
  12. data/vendor/click/formatting.pyc +0 -0
  13. data/vendor/click/globals.pyc +0 -0
  14. data/vendor/click/parser.pyc +0 -0
  15. data/vendor/click/termui.pyc +0 -0
  16. data/vendor/click/testing.pyc +0 -0
  17. data/vendor/click/types.pyc +0 -0
  18. data/vendor/click/utils.pyc +0 -0
  19. data/vendor/easy_install.pyc +0 -0
  20. data/vendor/pkg_resources/__init__.pyc +0 -0
  21. data/vendor/pkg_resources/_vendor/__init__.pyc +0 -0
  22. data/vendor/pkg_resources/_vendor/appdirs.pyc +0 -0
  23. data/vendor/pkg_resources/_vendor/packaging/__about__.pyc +0 -0
  24. data/vendor/pkg_resources/_vendor/packaging/__init__.pyc +0 -0
  25. data/vendor/pkg_resources/_vendor/packaging/_compat.pyc +0 -0
  26. data/vendor/pkg_resources/_vendor/packaging/_structures.pyc +0 -0
  27. data/vendor/pkg_resources/_vendor/packaging/markers.pyc +0 -0
  28. data/vendor/pkg_resources/_vendor/packaging/requirements.pyc +0 -0
  29. data/vendor/pkg_resources/_vendor/packaging/specifiers.pyc +0 -0
  30. data/vendor/pkg_resources/_vendor/packaging/utils.pyc +0 -0
  31. data/vendor/pkg_resources/_vendor/packaging/version.pyc +0 -0
  32. data/vendor/pkg_resources/_vendor/pyparsing.pyc +0 -0
  33. data/vendor/pkg_resources/_vendor/six.pyc +0 -0
  34. data/vendor/pkg_resources/extern/__init__.pyc +0 -0
  35. data/vendor/{requests-2.11.1.dist-info/METADATA → requests-2.12.1.dist-info/DESCRIPTION.rst} +51 -30
  36. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/INSTALLER +0 -0
  37. data/vendor/{requests-2.11.1.dist-info/DESCRIPTION.rst → requests-2.12.1.dist-info/METADATA} +80 -1
  38. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/RECORD +61 -41
  39. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/WHEEL +1 -1
  40. data/vendor/requests-2.12.1.dist-info/metadata.json +1 -0
  41. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/top_level.txt +0 -0
  42. data/vendor/requests/__init__.py +2 -2
  43. data/vendor/requests/__init__.pyc +0 -0
  44. data/vendor/requests/_internal_utils.py +27 -0
  45. data/vendor/requests/_internal_utils.pyc +0 -0
  46. data/vendor/requests/adapters.py +1 -1
  47. data/vendor/requests/adapters.pyc +0 -0
  48. data/vendor/requests/api.py +3 -1
  49. data/vendor/requests/api.pyc +0 -0
  50. data/vendor/requests/auth.py +2 -1
  51. data/vendor/requests/auth.pyc +0 -0
  52. data/vendor/requests/cacert.pem +448 -375
  53. data/vendor/requests/certs.pyc +0 -0
  54. data/vendor/requests/compat.py +2 -0
  55. data/vendor/requests/compat.pyc +0 -0
  56. data/vendor/requests/cookies.py +3 -1
  57. data/vendor/requests/cookies.pyc +0 -0
  58. data/vendor/requests/exceptions.py +2 -0
  59. data/vendor/requests/exceptions.pyc +0 -0
  60. data/vendor/requests/hooks.pyc +0 -0
  61. data/vendor/requests/models.py +53 -29
  62. data/vendor/requests/models.pyc +0 -0
  63. data/vendor/requests/packages/__init__.py +6 -0
  64. data/vendor/requests/packages/__init__.pyc +0 -0
  65. data/vendor/requests/packages/chardet/__init__.pyc +0 -0
  66. data/vendor/requests/packages/chardet/big5freq.pyc +0 -0
  67. data/vendor/requests/packages/chardet/big5prober.pyc +0 -0
  68. data/vendor/requests/packages/chardet/chardetect.pyc +0 -0
  69. data/vendor/requests/packages/chardet/chardistribution.pyc +0 -0
  70. data/vendor/requests/packages/chardet/charsetgroupprober.pyc +0 -0
  71. data/vendor/requests/packages/chardet/charsetprober.pyc +0 -0
  72. data/vendor/requests/packages/chardet/codingstatemachine.pyc +0 -0
  73. data/vendor/requests/packages/chardet/compat.pyc +0 -0
  74. data/vendor/requests/packages/chardet/constants.pyc +0 -0
  75. data/vendor/requests/packages/chardet/cp949prober.pyc +0 -0
  76. data/vendor/requests/packages/chardet/escprober.pyc +0 -0
  77. data/vendor/requests/packages/chardet/escsm.pyc +0 -0
  78. data/vendor/requests/packages/chardet/eucjpprober.pyc +0 -0
  79. data/vendor/requests/packages/chardet/euckrfreq.pyc +0 -0
  80. data/vendor/requests/packages/chardet/euckrprober.pyc +0 -0
  81. data/vendor/requests/packages/chardet/euctwfreq.pyc +0 -0
  82. data/vendor/requests/packages/chardet/euctwprober.pyc +0 -0
  83. data/vendor/requests/packages/chardet/gb2312freq.pyc +0 -0
  84. data/vendor/requests/packages/chardet/gb2312prober.pyc +0 -0
  85. data/vendor/requests/packages/chardet/hebrewprober.pyc +0 -0
  86. data/vendor/requests/packages/chardet/jisfreq.pyc +0 -0
  87. data/vendor/requests/packages/chardet/jpcntx.pyc +0 -0
  88. data/vendor/requests/packages/chardet/langbulgarianmodel.pyc +0 -0
  89. data/vendor/requests/packages/chardet/langcyrillicmodel.pyc +0 -0
  90. data/vendor/requests/packages/chardet/langgreekmodel.pyc +0 -0
  91. data/vendor/requests/packages/chardet/langhebrewmodel.pyc +0 -0
  92. data/vendor/requests/packages/chardet/langhungarianmodel.pyc +0 -0
  93. data/vendor/requests/packages/chardet/langthaimodel.pyc +0 -0
  94. data/vendor/requests/packages/chardet/latin1prober.pyc +0 -0
  95. data/vendor/requests/packages/chardet/mbcharsetprober.pyc +0 -0
  96. data/vendor/requests/packages/chardet/mbcsgroupprober.pyc +0 -0
  97. data/vendor/requests/packages/chardet/mbcssm.pyc +0 -0
  98. data/vendor/requests/packages/chardet/sbcharsetprober.pyc +0 -0
  99. data/vendor/requests/packages/chardet/sbcsgroupprober.pyc +0 -0
  100. data/vendor/requests/packages/chardet/sjisprober.pyc +0 -0
  101. data/vendor/requests/packages/chardet/universaldetector.pyc +0 -0
  102. data/vendor/requests/packages/chardet/utf8prober.pyc +0 -0
  103. data/vendor/requests/packages/idna/__init__.py +1 -0
  104. data/vendor/requests/packages/idna/__init__.pyc +0 -0
  105. data/vendor/requests/packages/idna/codec.py +118 -0
  106. data/vendor/requests/packages/idna/codec.pyc +0 -0
  107. data/vendor/requests/packages/idna/compat.py +12 -0
  108. data/vendor/requests/packages/idna/compat.pyc +0 -0
  109. data/vendor/requests/packages/idna/core.py +387 -0
  110. data/vendor/requests/packages/idna/core.pyc +0 -0
  111. data/vendor/requests/packages/idna/idnadata.py +1584 -0
  112. data/vendor/requests/packages/idna/idnadata.pyc +0 -0
  113. data/vendor/requests/packages/idna/intranges.py +46 -0
  114. data/vendor/requests/packages/idna/intranges.pyc +0 -0
  115. data/vendor/requests/packages/idna/uts46data.py +7267 -0
  116. data/vendor/requests/packages/idna/uts46data.pyc +0 -0
  117. data/vendor/requests/packages/urllib3/__init__.py +2 -1
  118. data/vendor/requests/packages/urllib3/__init__.pyc +0 -0
  119. data/vendor/requests/packages/urllib3/_collections.pyc +0 -0
  120. data/vendor/requests/packages/urllib3/connection.py +62 -26
  121. data/vendor/requests/packages/urllib3/connection.pyc +0 -0
  122. data/vendor/requests/packages/urllib3/connectionpool.py +25 -20
  123. data/vendor/requests/packages/urllib3/connectionpool.pyc +0 -0
  124. data/vendor/requests/packages/urllib3/contrib/__init__.pyc +0 -0
  125. data/vendor/requests/packages/urllib3/contrib/appengine.py +87 -22
  126. data/vendor/requests/packages/urllib3/contrib/appengine.pyc +0 -0
  127. data/vendor/requests/packages/urllib3/contrib/ntlmpool.py +2 -5
  128. data/vendor/requests/packages/urllib3/contrib/ntlmpool.pyc +0 -0
  129. data/vendor/requests/packages/urllib3/contrib/pyopenssl.py +191 -118
  130. data/vendor/requests/packages/urllib3/contrib/pyopenssl.pyc +0 -0
  131. data/vendor/requests/packages/urllib3/contrib/socks.py +11 -5
  132. data/vendor/requests/packages/urllib3/contrib/socks.pyc +0 -0
  133. data/vendor/requests/packages/urllib3/exceptions.py +32 -0
  134. data/vendor/requests/packages/urllib3/exceptions.pyc +0 -0
  135. data/vendor/requests/packages/urllib3/fields.py +1 -1
  136. data/vendor/requests/packages/urllib3/fields.pyc +0 -0
  137. data/vendor/requests/packages/urllib3/filepost.py +1 -1
  138. data/vendor/requests/packages/urllib3/filepost.pyc +0 -0
  139. data/vendor/requests/packages/urllib3/packages/__init__.pyc +0 -0
  140. data/vendor/requests/packages/urllib3/packages/backports/__init__.py +0 -0
  141. data/vendor/requests/packages/urllib3/packages/backports/__init__.pyc +0 -0
  142. data/vendor/requests/packages/urllib3/packages/backports/makefile.py +53 -0
  143. data/vendor/requests/packages/urllib3/packages/backports/makefile.pyc +0 -0
  144. data/vendor/requests/packages/urllib3/packages/ordered_dict.pyc +0 -0
  145. data/vendor/requests/packages/urllib3/packages/six.pyc +0 -0
  146. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py +7 -1
  147. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc +0 -0
  148. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py +55 -3
  149. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc +0 -0
  150. data/vendor/requests/packages/urllib3/poolmanager.py +2 -6
  151. data/vendor/requests/packages/urllib3/poolmanager.pyc +0 -0
  152. data/vendor/requests/packages/urllib3/request.py +1 -4
  153. data/vendor/requests/packages/urllib3/request.pyc +0 -0
  154. data/vendor/requests/packages/urllib3/response.py +94 -6
  155. data/vendor/requests/packages/urllib3/response.pyc +0 -0
  156. data/vendor/requests/packages/urllib3/util/__init__.pyc +0 -0
  157. data/vendor/requests/packages/urllib3/util/connection.py +1 -0
  158. data/vendor/requests/packages/urllib3/util/connection.pyc +0 -0
  159. data/vendor/requests/packages/urllib3/util/request.pyc +0 -0
  160. data/vendor/requests/packages/urllib3/util/response.py +7 -0
  161. data/vendor/requests/packages/urllib3/util/response.pyc +0 -0
  162. data/vendor/requests/packages/urllib3/util/retry.py +93 -17
  163. data/vendor/requests/packages/urllib3/util/retry.pyc +0 -0
  164. data/vendor/requests/packages/urllib3/util/ssl_.py +28 -12
  165. data/vendor/requests/packages/urllib3/util/ssl_.pyc +0 -0
  166. data/vendor/requests/packages/urllib3/util/timeout.py +9 -6
  167. data/vendor/requests/packages/urllib3/util/timeout.pyc +0 -0
  168. data/vendor/requests/packages/urllib3/util/url.py +14 -5
  169. data/vendor/requests/packages/urllib3/util/url.pyc +0 -0
  170. data/vendor/requests/sessions.py +18 -5
  171. data/vendor/requests/sessions.pyc +0 -0
  172. data/vendor/requests/status_codes.pyc +0 -0
  173. data/vendor/requests/structures.pyc +0 -0
  174. data/vendor/requests/utils.py +42 -32
  175. data/vendor/requests/utils.pyc +0 -0
  176. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/DESCRIPTION.rst +0 -0
  177. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/INSTALLER +0 -0
  178. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/METADATA +2 -2
  179. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/RECORD +18 -18
  180. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/WHEEL +0 -0
  181. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/entry_points.txt +0 -0
  182. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/metadata.json +1 -1
  183. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/top_level.txt +0 -0
  184. data/vendor/rigid/__init__.pyc +0 -0
  185. data/vendor/rigid/api.py +39 -2
  186. data/vendor/rigid/api.pyc +0 -0
  187. data/vendor/rigid/commands/__init__.py +71 -11
  188. data/vendor/rigid/commands/__init__.pyc +0 -0
  189. data/vendor/rigid/commands/deploy.pyc +0 -0
  190. data/vendor/rigid/deploy.py +1 -1
  191. data/vendor/rigid/deploy.pyc +0 -0
  192. data/vendor/rigid/file_scanner.py +1 -1
  193. data/vendor/rigid/file_scanner.pyc +0 -0
  194. data/vendor/rigid/utils.pyc +0 -0
  195. data/vendor/tests/__init__.pyc +0 -0
  196. data/vendor/tests/integration/__init__.pyc +0 -0
  197. data/vendor/tests/integration/test_app.py +12 -0
  198. data/vendor/tests/integration/test_app.pyc +0 -0
  199. data/vendor/tests/integration/test_apps.pyc +0 -0
  200. data/vendor/tests/integration/test_deploy.pyc +0 -0
  201. data/vendor/tests/integration/test_domains.pyc +0 -0
  202. data/vendor/tests/integration/test_login.pyc +0 -0
  203. data/vendor/tests/integration/test_promote.py +2 -2
  204. data/vendor/tests/integration/test_promote.pyc +0 -0
  205. data/vendor/tests/integration/test_token.pyc +0 -0
  206. data/vendor/tests/integration/test_whoami.pyc +0 -0
  207. data/vendor/tests/test_deploy.pyc +0 -0
  208. data/vendor/tests/test_file_scanner.pyc +0 -0
  209. data/vendor/tests/utils.py +5 -2
  210. data/vendor/tests/utils.pyc +0 -0
  211. data/vendor/yaml/__init__.pyc +0 -0
  212. data/vendor/yaml/composer.pyc +0 -0
  213. data/vendor/yaml/constructor.pyc +0 -0
  214. data/vendor/yaml/cyaml.pyc +0 -0
  215. data/vendor/yaml/dumper.pyc +0 -0
  216. data/vendor/yaml/emitter.pyc +0 -0
  217. data/vendor/yaml/error.pyc +0 -0
  218. data/vendor/yaml/events.pyc +0 -0
  219. data/vendor/yaml/loader.pyc +0 -0
  220. data/vendor/yaml/nodes.pyc +0 -0
  221. data/vendor/yaml/parser.pyc +0 -0
  222. data/vendor/yaml/reader.pyc +0 -0
  223. data/vendor/yaml/representer.pyc +0 -0
  224. data/vendor/yaml/resolver.pyc +0 -0
  225. data/vendor/yaml/scanner.pyc +0 -0
  226. data/vendor/yaml/serializer.pyc +0 -0
  227. data/vendor/yaml/tokens.pyc +0 -0
  228. metadata +37 -17
  229. data/vendor/requests-2.11.1.dist-info/metadata.json +0 -1
@@ -32,7 +32,7 @@ except ImportError:
32
32
 
33
33
  __author__ = 'Andrey Petrov (andrey.petrov@shazow.net)'
34
34
  __license__ = 'MIT'
35
- __version__ = '1.16'
35
+ __version__ = '1.19.1'
36
36
 
37
37
  __all__ = (
38
38
  'HTTPConnectionPool',
@@ -71,6 +71,7 @@ def add_stderr_logger(level=logging.DEBUG):
71
71
  logger.debug('Added a stderr logging handler to logger: %s', __name__)
72
72
  return handler
73
73
 
74
+
74
75
  # ... Clean up.
75
76
  del NullHandler
76
77
 
@@ -7,13 +7,8 @@ import socket
7
7
  from socket import error as SocketError, timeout as SocketTimeout
8
8
  import warnings
9
9
  from .packages import six
10
-
11
- try: # Python 3
12
- from http.client import HTTPConnection as _HTTPConnection
13
- from http.client import HTTPException # noqa: unused in this module
14
- except ImportError:
15
- from httplib import HTTPConnection as _HTTPConnection
16
- from httplib import HTTPException # noqa: unused in this module
10
+ from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection
11
+ from .packages.six.moves.http_client import HTTPException # noqa: F401
17
12
 
18
13
  try: # Compiled with SSL?
19
14
  import ssl
@@ -44,8 +39,9 @@ from .packages.ssl_match_hostname import match_hostname, CertificateError
44
39
  from .util.ssl_ import (
45
40
  resolve_cert_reqs,
46
41
  resolve_ssl_version,
47
- ssl_wrap_socket,
48
42
  assert_fingerprint,
43
+ create_urllib3_context,
44
+ ssl_wrap_socket
49
45
  )
50
46
 
51
47
 
@@ -174,7 +170,13 @@ class HTTPConnection(_HTTPConnection, object):
174
170
  """
175
171
  headers = HTTPHeaderDict(headers if headers is not None else {})
176
172
  skip_accept_encoding = 'accept-encoding' in headers
177
- self.putrequest(method, url, skip_accept_encoding=skip_accept_encoding)
173
+ skip_host = 'host' in headers
174
+ self.putrequest(
175
+ method,
176
+ url,
177
+ skip_accept_encoding=skip_accept_encoding,
178
+ skip_host=skip_host
179
+ )
178
180
  for header, value in headers.items():
179
181
  self.putheader(header, value)
180
182
  if 'transfer-encoding' not in headers:
@@ -203,14 +205,18 @@ class HTTPConnection(_HTTPConnection, object):
203
205
  class HTTPSConnection(HTTPConnection):
204
206
  default_port = port_by_scheme['https']
205
207
 
208
+ ssl_version = None
209
+
206
210
  def __init__(self, host, port=None, key_file=None, cert_file=None,
207
- strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, **kw):
211
+ strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
212
+ ssl_context=None, **kw):
208
213
 
209
214
  HTTPConnection.__init__(self, host, port, strict=strict,
210
215
  timeout=timeout, **kw)
211
216
 
212
217
  self.key_file = key_file
213
218
  self.cert_file = cert_file
219
+ self.ssl_context = ssl_context
214
220
 
215
221
  # Required property for Google AppEngine 1.9.0 which otherwise causes
216
222
  # HTTPS requests to go out as HTTP. (See Issue #356)
@@ -219,7 +225,19 @@ class HTTPSConnection(HTTPConnection):
219
225
  def connect(self):
220
226
  conn = self._new_conn()
221
227
  self._prepare_conn(conn)
222
- self.sock = ssl.wrap_socket(conn, self.key_file, self.cert_file)
228
+
229
+ if self.ssl_context is None:
230
+ self.ssl_context = create_urllib3_context(
231
+ ssl_version=resolve_ssl_version(None),
232
+ cert_reqs=resolve_cert_reqs(None),
233
+ )
234
+
235
+ self.sock = ssl_wrap_socket(
236
+ sock=conn,
237
+ keyfile=self.key_file,
238
+ certfile=self.cert_file,
239
+ ssl_context=self.ssl_context,
240
+ )
223
241
 
224
242
 
225
243
  class VerifiedHTTPSConnection(HTTPSConnection):
@@ -237,9 +255,18 @@ class VerifiedHTTPSConnection(HTTPSConnection):
237
255
  cert_reqs=None, ca_certs=None,
238
256
  assert_hostname=None, assert_fingerprint=None,
239
257
  ca_cert_dir=None):
240
-
241
- if (ca_certs or ca_cert_dir) and cert_reqs is None:
242
- cert_reqs = 'CERT_REQUIRED'
258
+ """
259
+ This method should only be called once, before the connection is used.
260
+ """
261
+ # If cert_reqs is not provided, we can try to guess. If the user gave
262
+ # us a cert database, we assume they want to use it: otherwise, if
263
+ # they gave us an SSL Context object we should use whatever is set for
264
+ # it.
265
+ if cert_reqs is None:
266
+ if ca_certs or ca_cert_dir:
267
+ cert_reqs = 'CERT_REQUIRED'
268
+ elif self.ssl_context is not None:
269
+ cert_reqs = self.ssl_context.verify_mode
243
270
 
244
271
  self.key_file = key_file
245
272
  self.cert_file = cert_file
@@ -253,9 +280,6 @@ class VerifiedHTTPSConnection(HTTPSConnection):
253
280
  # Add certificate verification
254
281
  conn = self._new_conn()
255
282
 
256
- resolved_cert_reqs = resolve_cert_reqs(self.cert_reqs)
257
- resolved_ssl_version = resolve_ssl_version(self.ssl_version)
258
-
259
283
  hostname = self.host
260
284
  if getattr(self, '_tunnel_host', None):
261
285
  # _tunnel_host was added in Python 2.6.3
@@ -281,17 +305,27 @@ class VerifiedHTTPSConnection(HTTPSConnection):
281
305
 
282
306
  # Wrap socket using verification with the root certs in
283
307
  # trusted_root_certs
284
- self.sock = ssl_wrap_socket(conn, self.key_file, self.cert_file,
285
- cert_reqs=resolved_cert_reqs,
286
- ca_certs=self.ca_certs,
287
- ca_cert_dir=self.ca_cert_dir,
288
- server_hostname=hostname,
289
- ssl_version=resolved_ssl_version)
308
+ if self.ssl_context is None:
309
+ self.ssl_context = create_urllib3_context(
310
+ ssl_version=resolve_ssl_version(self.ssl_version),
311
+ cert_reqs=resolve_cert_reqs(self.cert_reqs),
312
+ )
313
+
314
+ context = self.ssl_context
315
+ context.verify_mode = resolve_cert_reqs(self.cert_reqs)
316
+ self.sock = ssl_wrap_socket(
317
+ sock=conn,
318
+ keyfile=self.key_file,
319
+ certfile=self.cert_file,
320
+ ca_certs=self.ca_certs,
321
+ ca_cert_dir=self.ca_cert_dir,
322
+ server_hostname=hostname,
323
+ ssl_context=context)
290
324
 
291
325
  if self.assert_fingerprint:
292
326
  assert_fingerprint(self.sock.getpeercert(binary_form=True),
293
327
  self.assert_fingerprint)
294
- elif resolved_cert_reqs != ssl.CERT_NONE \
328
+ elif context.verify_mode != ssl.CERT_NONE \
295
329
  and self.assert_hostname is not False:
296
330
  cert = self.sock.getpeercert()
297
331
  if not cert.get('subjectAltName', ()):
@@ -304,8 +338,10 @@ class VerifiedHTTPSConnection(HTTPSConnection):
304
338
  )
305
339
  _match_hostname(cert, self.assert_hostname or hostname)
306
340
 
307
- self.is_verified = (resolved_cert_reqs == ssl.CERT_REQUIRED or
308
- self.assert_fingerprint is not None)
341
+ self.is_verified = (
342
+ context.verify_mode == ssl.CERT_REQUIRED or
343
+ self.assert_fingerprint is not None
344
+ )
309
345
 
310
346
 
311
347
  def _match_hostname(cert, asserted_hostname):
@@ -7,13 +7,6 @@ import warnings
7
7
  from socket import error as SocketError, timeout as SocketTimeout
8
8
  import socket
9
9
 
10
- try: # Python 3
11
- from queue import LifoQueue, Empty, Full
12
- except ImportError:
13
- from Queue import LifoQueue, Empty, Full
14
- # Queue is imported for side effects on MS Windows
15
- import Queue as _unused_module_Queue # noqa: unused
16
-
17
10
 
18
11
  from .exceptions import (
19
12
  ClosedPoolError,
@@ -32,6 +25,7 @@ from .exceptions import (
32
25
  )
33
26
  from .packages.ssl_match_hostname import CertificateError
34
27
  from .packages import six
28
+ from .packages.six.moves.queue import LifoQueue, Empty, Full
35
29
  from .connection import (
36
30
  port_by_scheme,
37
31
  DummyConnection,
@@ -48,6 +42,10 @@ from .util.timeout import Timeout
48
42
  from .util.url import get_host, Url
49
43
 
50
44
 
45
+ if six.PY2:
46
+ # Queue is imported for side effects on MS Windows
47
+ import Queue as _unused_module_Queue # noqa: F401
48
+
51
49
  xrange = six.moves.xrange
52
50
 
53
51
  log = logging.getLogger(__name__)
@@ -210,8 +208,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
210
208
  Return a fresh :class:`HTTPConnection`.
211
209
  """
212
210
  self.num_connections += 1
213
- log.info("Starting new HTTP connection (%d): %s",
214
- self.num_connections, self.host)
211
+ log.debug("Starting new HTTP connection (%d): %s",
212
+ self.num_connections, self.host)
215
213
 
216
214
  conn = self.ConnectionCls(host=self.host, port=self.port,
217
215
  timeout=self.timeout.connect_timeout,
@@ -246,7 +244,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
246
244
 
247
245
  # If this is a persistent connection, check if it got disconnected
248
246
  if conn and is_connection_dropped(conn):
249
- log.info("Resetting dropped connection: %s", self.host)
247
+ log.debug("Resetting dropped connection: %s", self.host)
250
248
  conn.close()
251
249
  if getattr(conn, 'auto_open', 1) == 0:
252
250
  # This is a proxied connection that has been mutated by
@@ -397,8 +395,9 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
397
395
 
398
396
  # AppEngine doesn't have a version attr.
399
397
  http_version = getattr(conn, '_http_vsn_str', 'HTTP/?')
400
- log.debug("\"%s %s %s\" %s %s", method, url, http_version,
401
- httplib_response.status, httplib_response.length)
398
+ log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port,
399
+ method, url, http_version, httplib_response.status,
400
+ httplib_response.length)
402
401
 
403
402
  try:
404
403
  assert_header_parsing(httplib_response.msg)
@@ -600,10 +599,14 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
600
599
  # mess.
601
600
  response_conn = conn if not release_conn else None
602
601
 
602
+ # Pass method to Response for length checking
603
+ response_kw['request_method'] = method
604
+
603
605
  # Import httplib's response into our own wrapper object
604
606
  response = self.ResponseCls.from_httplib(httplib_response,
605
607
  pool=self,
606
608
  connection=response_conn,
609
+ retries=retries,
607
610
  **response_kw)
608
611
 
609
612
  # Everything went great!
@@ -683,7 +686,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
683
686
  raise
684
687
  return response
685
688
 
686
- log.info("Redirecting %s -> %s", url, redirect_location)
689
+ retries.sleep_for_retry(response)
690
+ log.debug("Redirecting %s -> %s", url, redirect_location)
687
691
  return self.urlopen(
688
692
  method, redirect_location, body, headers,
689
693
  retries=retries, redirect=redirect,
@@ -692,7 +696,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
692
696
  release_conn=release_conn, **response_kw)
693
697
 
694
698
  # Check if we should retry the HTTP response.
695
- if retries.is_forced_retry(method, status_code=response.status):
699
+ has_retry_after = bool(response.getheader('Retry-After'))
700
+ if retries.is_retry(method, response.status, has_retry_after):
696
701
  try:
697
702
  retries = retries.increment(method, url, response=response, _pool=self)
698
703
  except MaxRetryError:
@@ -702,8 +707,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
702
707
  response.release_conn()
703
708
  raise
704
709
  return response
705
- retries.sleep()
706
- log.info("Forced retry: %s", url)
710
+ retries.sleep(response)
711
+ log.debug("Retry: %s", url)
707
712
  return self.urlopen(
708
713
  method, url, body, headers,
709
714
  retries=retries, redirect=redirect,
@@ -775,7 +780,6 @@ class HTTPSConnectionPool(HTTPConnectionPool):
775
780
  assert_hostname=self.assert_hostname,
776
781
  assert_fingerprint=self.assert_fingerprint)
777
782
  conn.ssl_version = self.ssl_version
778
-
779
783
  return conn
780
784
 
781
785
  def _prepare_proxy(self, conn):
@@ -801,8 +805,8 @@ class HTTPSConnectionPool(HTTPConnectionPool):
801
805
  Return a fresh :class:`httplib.HTTPSConnection`.
802
806
  """
803
807
  self.num_connections += 1
804
- log.info("Starting new HTTPS connection (%d): %s",
805
- self.num_connections, self.host)
808
+ log.debug("Starting new HTTPS connection (%d): %s",
809
+ self.num_connections, self.host)
806
810
 
807
811
  if not self.ConnectionCls or self.ConnectionCls is DummyConnection:
808
812
  raise SSLError("Can't connect to HTTPS URL because the SSL "
@@ -834,7 +838,8 @@ class HTTPSConnectionPool(HTTPConnectionPool):
834
838
  warnings.warn((
835
839
  'Unverified HTTPS request is being made. '
836
840
  'Adding certificate verification is strongly advised. See: '
837
- 'https://urllib3.readthedocs.io/en/latest/security.html'),
841
+ 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html'
842
+ '#ssl-warnings'),
838
843
  InsecureRequestWarning)
839
844
 
840
845
 
@@ -1,7 +1,48 @@
1
+ """
2
+ This module provides a pool manager that uses Google App Engine's
3
+ `URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
4
+
5
+ Example usage::
6
+
7
+ from urllib3 import PoolManager
8
+ from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox
9
+
10
+ if is_appengine_sandbox():
11
+ # AppEngineManager uses AppEngine's URLFetch API behind the scenes
12
+ http = AppEngineManager()
13
+ else:
14
+ # PoolManager uses a socket-level API behind the scenes
15
+ http = PoolManager()
16
+
17
+ r = http.request('GET', 'https://google.com/')
18
+
19
+ There are `limitations <https://cloud.google.com/appengine/docs/python/\
20
+ urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be
21
+ the best choice for your application. There are three options for using
22
+ urllib3 on Google App Engine:
23
+
24
+ 1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is
25
+ cost-effective in many circumstances as long as your usage is within the
26
+ limitations.
27
+ 2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets.
28
+ Sockets also have `limitations and restrictions
29
+ <https://cloud.google.com/appengine/docs/python/sockets/\
30
+ #limitations-and-restrictions>`_ and have a lower free quota than URLFetch.
31
+ To use sockets, be sure to specify the following in your ``app.yaml``::
32
+
33
+ env_variables:
34
+ GAE_USE_SOCKETS_HTTPLIB : 'true'
35
+
36
+ 3. If you are using `App Engine Flexible
37
+ <https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard
38
+ :class:`PoolManager` without any configuration or special environment variables.
39
+ """
40
+
1
41
  from __future__ import absolute_import
2
42
  import logging
3
43
  import os
4
44
  import warnings
45
+ from ..packages.six.moves.urllib.parse import urljoin
5
46
 
6
47
  from ..exceptions import (
7
48
  HTTPError,
@@ -41,13 +82,12 @@ class AppEngineManager(RequestMethods):
41
82
 
42
83
  This manager uses the URLFetch service directly instead of using the
43
84
  emulated httplib, and is subject to URLFetch limitations as described in
44
- the App Engine documentation here:
45
-
46
- https://cloud.google.com/appengine/docs/python/urlfetch
85
+ the App Engine documentation `here
86
+ <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
47
87
 
48
- Notably it will raise an AppEnginePlatformError if:
88
+ Notably it will raise an :class:`AppEnginePlatformError` if:
49
89
  * URLFetch is not available.
50
- * If you attempt to use this on GAEv2 (Managed VMs), as full socket
90
+ * If you attempt to use this on App Engine Flexible, as full socket
51
91
  support is available.
52
92
  * If a request size is more than 10 megabytes.
53
93
  * If a response size is more than 32 megabtyes.
@@ -56,7 +96,8 @@ class AppEngineManager(RequestMethods):
56
96
  Beyond those cases, it will raise normal urllib3 errors.
57
97
  """
58
98
 
59
- def __init__(self, headers=None, retries=None, validate_certificate=True):
99
+ def __init__(self, headers=None, retries=None, validate_certificate=True,
100
+ urlfetch_retries=True):
60
101
  if not urlfetch:
61
102
  raise AppEnginePlatformError(
62
103
  "URLFetch is not available in this environment.")
@@ -75,6 +116,7 @@ class AppEngineManager(RequestMethods):
75
116
 
76
117
  RequestMethods.__init__(self, headers)
77
118
  self.validate_certificate = validate_certificate
119
+ self.urlfetch_retries = urlfetch_retries
78
120
 
79
121
  self.retries = retries or Retry.DEFAULT
80
122
 
@@ -92,16 +134,17 @@ class AppEngineManager(RequestMethods):
92
134
  retries = self._get_retries(retries, redirect)
93
135
 
94
136
  try:
137
+ follow_redirects = (
138
+ redirect and
139
+ retries.redirect != 0 and
140
+ retries.total)
95
141
  response = urlfetch.fetch(
96
142
  url,
97
143
  payload=body,
98
144
  method=method,
99
145
  headers=headers or {},
100
146
  allow_truncated=False,
101
- follow_redirects=(
102
- redirect and
103
- retries.redirect != 0 and
104
- retries.total),
147
+ follow_redirects=self.urlfetch_retries and follow_redirects,
105
148
  deadline=self._get_absolute_timeout(timeout),
106
149
  validate_certificate=self.validate_certificate,
107
150
  )
@@ -133,19 +176,40 @@ class AppEngineManager(RequestMethods):
133
176
  "URLFetch does not support method: %s" % method, e)
134
177
 
135
178
  http_response = self._urlfetch_response_to_http_response(
136
- response, **response_kw)
137
-
138
- # Check for redirect response
139
- if (http_response.get_redirect_location() and
140
- retries.raise_on_redirect and redirect):
141
- raise MaxRetryError(self, url, "too many redirects")
179
+ response, retries=retries, **response_kw)
180
+
181
+ # Handle redirect?
182
+ redirect_location = redirect and http_response.get_redirect_location()
183
+ if redirect_location:
184
+ # Check for redirect response
185
+ if (self.urlfetch_retries and retries.raise_on_redirect):
186
+ raise MaxRetryError(self, url, "too many redirects")
187
+ else:
188
+ if http_response.status == 303:
189
+ method = 'GET'
190
+
191
+ try:
192
+ retries = retries.increment(method, url, response=http_response, _pool=self)
193
+ except MaxRetryError:
194
+ if retries.raise_on_redirect:
195
+ raise MaxRetryError(self, url, "too many redirects")
196
+ return http_response
197
+
198
+ retries.sleep_for_retry(http_response)
199
+ log.debug("Redirecting %s -> %s", url, redirect_location)
200
+ redirect_url = urljoin(url, redirect_location)
201
+ return self.urlopen(
202
+ method, redirect_url, body, headers,
203
+ retries=retries, redirect=redirect,
204
+ timeout=timeout, **response_kw)
142
205
 
143
206
  # Check if we should retry the HTTP response.
144
- if retries.is_forced_retry(method, status_code=http_response.status):
207
+ has_retry_after = bool(http_response.getheader('Retry-After'))
208
+ if retries.is_retry(method, http_response.status, has_retry_after):
145
209
  retries = retries.increment(
146
210
  method, url, response=http_response, _pool=self)
147
- log.info("Forced retry: %s", url)
148
- retries.sleep()
211
+ log.debug("Retry: %s", url)
212
+ retries.sleep(http_response)
149
213
  return self.urlopen(
150
214
  method, url,
151
215
  body=body, headers=headers,
@@ -183,12 +247,13 @@ class AppEngineManager(RequestMethods):
183
247
 
184
248
  def _get_absolute_timeout(self, timeout):
185
249
  if timeout is Timeout.DEFAULT_TIMEOUT:
186
- return 5 # 5s is the default timeout for URLFetch.
250
+ return None # Defer to URLFetch's default.
187
251
  if isinstance(timeout, Timeout):
188
- if timeout._read is not timeout._connect:
252
+ if timeout._read is not None or timeout._connect is not None:
189
253
  warnings.warn(
190
254
  "URLFetch does not support granular timeout settings, "
191
- "reverting to total timeout.", AppEnginePlatformWarning)
255
+ "reverting to total or default URLFetch timeout.",
256
+ AppEnginePlatformWarning)
192
257
  return timeout.total
193
258
  return timeout
194
259