rigid 0.2.0 → 0.2.1

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 (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