rigid 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/rigid +4 -0
- data/rigid +16 -0
- data/vendor/PyYAML-3.12.dist-info/DESCRIPTION.rst +12 -0
- data/vendor/PyYAML-3.12.dist-info/INSTALLER +1 -0
- data/vendor/PyYAML-3.12.dist-info/METADATA +35 -0
- data/vendor/PyYAML-3.12.dist-info/RECORD +42 -0
- data/vendor/PyYAML-3.12.dist-info/WHEEL +5 -0
- data/vendor/PyYAML-3.12.dist-info/metadata.json +1 -0
- data/vendor/PyYAML-3.12.dist-info/top_level.txt +2 -0
- data/vendor/_yaml.so +0 -0
- data/vendor/click/__init__.py +98 -0
- data/vendor/click/__init__.pyc +0 -0
- data/vendor/click/_bashcomplete.py +83 -0
- data/vendor/click/_bashcomplete.pyc +0 -0
- data/vendor/click/_compat.py +642 -0
- data/vendor/click/_compat.pyc +0 -0
- data/vendor/click/_termui_impl.py +547 -0
- data/vendor/click/_termui_impl.pyc +0 -0
- data/vendor/click/_textwrap.py +38 -0
- data/vendor/click/_textwrap.pyc +0 -0
- data/vendor/click/_unicodefun.py +119 -0
- data/vendor/click/_unicodefun.pyc +0 -0
- data/vendor/click/_winconsole.py +273 -0
- data/vendor/click/_winconsole.pyc +0 -0
- data/vendor/click/core.py +1738 -0
- data/vendor/click/core.pyc +0 -0
- data/vendor/click/decorators.py +304 -0
- data/vendor/click/decorators.pyc +0 -0
- data/vendor/click/exceptions.py +201 -0
- data/vendor/click/exceptions.pyc +0 -0
- data/vendor/click/formatting.py +256 -0
- data/vendor/click/formatting.pyc +0 -0
- data/vendor/click/globals.py +48 -0
- data/vendor/click/globals.pyc +0 -0
- data/vendor/click/parser.py +426 -0
- data/vendor/click/parser.pyc +0 -0
- data/vendor/click/termui.py +539 -0
- data/vendor/click/termui.pyc +0 -0
- data/vendor/click/testing.py +322 -0
- data/vendor/click/testing.pyc +0 -0
- data/vendor/click/types.py +550 -0
- data/vendor/click/types.pyc +0 -0
- data/vendor/click/utils.py +415 -0
- data/vendor/click/utils.pyc +0 -0
- data/vendor/click-6.6.dist-info/DESCRIPTION.rst +3 -0
- data/vendor/click-6.6.dist-info/INSTALLER +1 -0
- data/vendor/click-6.6.dist-info/METADATA +16 -0
- data/vendor/click-6.6.dist-info/RECORD +41 -0
- data/vendor/click-6.6.dist-info/WHEEL +6 -0
- data/vendor/click-6.6.dist-info/metadata.json +1 -0
- data/vendor/click-6.6.dist-info/top_level.txt +1 -0
- data/vendor/easy_install.py +5 -0
- data/vendor/easy_install.pyc +0 -0
- data/vendor/pip-9.0.1.dist-info/DESCRIPTION.rst +39 -0
- data/vendor/pip-9.0.1.dist-info/INSTALLER +1 -0
- data/vendor/pip-9.0.1.dist-info/METADATA +69 -0
- data/vendor/pip-9.0.1.dist-info/RECORD +501 -0
- data/vendor/pip-9.0.1.dist-info/WHEEL +6 -0
- data/vendor/pip-9.0.1.dist-info/entry_points.txt +5 -0
- data/vendor/pip-9.0.1.dist-info/metadata.json +1 -0
- data/vendor/pip-9.0.1.dist-info/top_level.txt +1 -0
- data/vendor/pkg_resources/__init__.py +3051 -0
- data/vendor/pkg_resources/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/__init__.py +0 -0
- data/vendor/pkg_resources/_vendor/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/appdirs.py +552 -0
- data/vendor/pkg_resources/_vendor/appdirs.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/__about__.py +21 -0
- data/vendor/pkg_resources/_vendor/packaging/__about__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/__init__.py +14 -0
- data/vendor/pkg_resources/_vendor/packaging/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/_compat.py +30 -0
- data/vendor/pkg_resources/_vendor/packaging/_compat.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/_structures.py +68 -0
- data/vendor/pkg_resources/_vendor/packaging/_structures.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/markers.py +287 -0
- data/vendor/pkg_resources/_vendor/packaging/markers.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/requirements.py +127 -0
- data/vendor/pkg_resources/_vendor/packaging/requirements.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/specifiers.py +774 -0
- data/vendor/pkg_resources/_vendor/packaging/specifiers.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/utils.py +14 -0
- data/vendor/pkg_resources/_vendor/packaging/utils.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/version.py +393 -0
- data/vendor/pkg_resources/_vendor/packaging/version.pyc +0 -0
- data/vendor/pkg_resources/_vendor/pyparsing.py +5696 -0
- data/vendor/pkg_resources/_vendor/pyparsing.pyc +0 -0
- data/vendor/pkg_resources/_vendor/six.py +868 -0
- data/vendor/pkg_resources/_vendor/six.pyc +0 -0
- data/vendor/pkg_resources/extern/__init__.py +73 -0
- data/vendor/pkg_resources/extern/__init__.pyc +0 -0
- data/vendor/requests/__init__.py +86 -0
- data/vendor/requests/__init__.pyc +0 -0
- data/vendor/requests/adapters.py +503 -0
- data/vendor/requests/adapters.pyc +0 -0
- data/vendor/requests/api.py +148 -0
- data/vendor/requests/api.pyc +0 -0
- data/vendor/requests/auth.py +252 -0
- data/vendor/requests/auth.pyc +0 -0
- data/vendor/requests/cacert.pem +5616 -0
- data/vendor/requests/certs.py +25 -0
- data/vendor/requests/certs.pyc +0 -0
- data/vendor/requests/compat.py +66 -0
- data/vendor/requests/compat.pyc +0 -0
- data/vendor/requests/cookies.py +540 -0
- data/vendor/requests/cookies.pyc +0 -0
- data/vendor/requests/exceptions.py +114 -0
- data/vendor/requests/exceptions.pyc +0 -0
- data/vendor/requests/hooks.py +34 -0
- data/vendor/requests/hooks.pyc +0 -0
- data/vendor/requests/models.py +873 -0
- data/vendor/requests/models.pyc +0 -0
- data/vendor/requests/packages/__init__.py +36 -0
- data/vendor/requests/packages/__init__.pyc +0 -0
- data/vendor/requests/packages/chardet/__init__.py +32 -0
- data/vendor/requests/packages/chardet/__init__.pyc +0 -0
- data/vendor/requests/packages/chardet/big5freq.py +925 -0
- data/vendor/requests/packages/chardet/big5freq.pyc +0 -0
- data/vendor/requests/packages/chardet/big5prober.py +42 -0
- data/vendor/requests/packages/chardet/big5prober.pyc +0 -0
- data/vendor/requests/packages/chardet/chardetect.py +80 -0
- data/vendor/requests/packages/chardet/chardetect.pyc +0 -0
- data/vendor/requests/packages/chardet/chardistribution.py +231 -0
- data/vendor/requests/packages/chardet/chardistribution.pyc +0 -0
- data/vendor/requests/packages/chardet/charsetgroupprober.py +106 -0
- data/vendor/requests/packages/chardet/charsetgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/charsetprober.py +62 -0
- data/vendor/requests/packages/chardet/charsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/codingstatemachine.py +61 -0
- data/vendor/requests/packages/chardet/codingstatemachine.pyc +0 -0
- data/vendor/requests/packages/chardet/compat.py +34 -0
- data/vendor/requests/packages/chardet/compat.pyc +0 -0
- data/vendor/requests/packages/chardet/constants.py +39 -0
- data/vendor/requests/packages/chardet/constants.pyc +0 -0
- data/vendor/requests/packages/chardet/cp949prober.py +44 -0
- data/vendor/requests/packages/chardet/cp949prober.pyc +0 -0
- data/vendor/requests/packages/chardet/escprober.py +86 -0
- data/vendor/requests/packages/chardet/escprober.pyc +0 -0
- data/vendor/requests/packages/chardet/escsm.py +242 -0
- data/vendor/requests/packages/chardet/escsm.pyc +0 -0
- data/vendor/requests/packages/chardet/eucjpprober.py +90 -0
- data/vendor/requests/packages/chardet/eucjpprober.pyc +0 -0
- data/vendor/requests/packages/chardet/euckrfreq.py +596 -0
- data/vendor/requests/packages/chardet/euckrfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/euckrprober.py +42 -0
- data/vendor/requests/packages/chardet/euckrprober.pyc +0 -0
- data/vendor/requests/packages/chardet/euctwfreq.py +428 -0
- data/vendor/requests/packages/chardet/euctwfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/euctwprober.py +41 -0
- data/vendor/requests/packages/chardet/euctwprober.pyc +0 -0
- data/vendor/requests/packages/chardet/gb2312freq.py +472 -0
- data/vendor/requests/packages/chardet/gb2312freq.pyc +0 -0
- data/vendor/requests/packages/chardet/gb2312prober.py +41 -0
- data/vendor/requests/packages/chardet/gb2312prober.pyc +0 -0
- data/vendor/requests/packages/chardet/hebrewprober.py +283 -0
- data/vendor/requests/packages/chardet/hebrewprober.pyc +0 -0
- data/vendor/requests/packages/chardet/jisfreq.py +569 -0
- data/vendor/requests/packages/chardet/jisfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/jpcntx.py +227 -0
- data/vendor/requests/packages/chardet/jpcntx.pyc +0 -0
- data/vendor/requests/packages/chardet/langbulgarianmodel.py +229 -0
- data/vendor/requests/packages/chardet/langbulgarianmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langcyrillicmodel.py +329 -0
- data/vendor/requests/packages/chardet/langcyrillicmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langgreekmodel.py +225 -0
- data/vendor/requests/packages/chardet/langgreekmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langhebrewmodel.py +201 -0
- data/vendor/requests/packages/chardet/langhebrewmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langhungarianmodel.py +225 -0
- data/vendor/requests/packages/chardet/langhungarianmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langthaimodel.py +200 -0
- data/vendor/requests/packages/chardet/langthaimodel.pyc +0 -0
- data/vendor/requests/packages/chardet/latin1prober.py +139 -0
- data/vendor/requests/packages/chardet/latin1prober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcharsetprober.py +86 -0
- data/vendor/requests/packages/chardet/mbcharsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcsgroupprober.py +54 -0
- data/vendor/requests/packages/chardet/mbcsgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcssm.py +572 -0
- data/vendor/requests/packages/chardet/mbcssm.pyc +0 -0
- data/vendor/requests/packages/chardet/sbcharsetprober.py +120 -0
- data/vendor/requests/packages/chardet/sbcharsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/sbcsgroupprober.py +69 -0
- data/vendor/requests/packages/chardet/sbcsgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/sjisprober.py +91 -0
- data/vendor/requests/packages/chardet/sjisprober.pyc +0 -0
- data/vendor/requests/packages/chardet/universaldetector.py +170 -0
- data/vendor/requests/packages/chardet/universaldetector.pyc +0 -0
- data/vendor/requests/packages/chardet/utf8prober.py +76 -0
- data/vendor/requests/packages/chardet/utf8prober.pyc +0 -0
- data/vendor/requests/packages/urllib3/__init__.py +96 -0
- data/vendor/requests/packages/urllib3/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/_collections.py +324 -0
- data/vendor/requests/packages/urllib3/_collections.pyc +0 -0
- data/vendor/requests/packages/urllib3/connection.py +330 -0
- data/vendor/requests/packages/urllib3/connection.pyc +0 -0
- data/vendor/requests/packages/urllib3/connectionpool.py +866 -0
- data/vendor/requests/packages/urllib3/connectionpool.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/__init__.py +0 -0
- data/vendor/requests/packages/urllib3/contrib/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/appengine.py +231 -0
- data/vendor/requests/packages/urllib3/contrib/appengine.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/ntlmpool.py +115 -0
- data/vendor/requests/packages/urllib3/contrib/ntlmpool.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/pyopenssl.py +358 -0
- data/vendor/requests/packages/urllib3/contrib/pyopenssl.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/socks.py +172 -0
- data/vendor/requests/packages/urllib3/contrib/socks.pyc +0 -0
- data/vendor/requests/packages/urllib3/exceptions.py +209 -0
- data/vendor/requests/packages/urllib3/exceptions.pyc +0 -0
- data/vendor/requests/packages/urllib3/fields.py +178 -0
- data/vendor/requests/packages/urllib3/fields.pyc +0 -0
- data/vendor/requests/packages/urllib3/filepost.py +94 -0
- data/vendor/requests/packages/urllib3/filepost.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/__init__.py +5 -0
- data/vendor/requests/packages/urllib3/packages/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ordered_dict.py +259 -0
- data/vendor/requests/packages/urllib3/packages/ordered_dict.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/six.py +868 -0
- data/vendor/requests/packages/urllib3/packages/six.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py +13 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py +105 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc +0 -0
- data/vendor/requests/packages/urllib3/poolmanager.py +367 -0
- data/vendor/requests/packages/urllib3/poolmanager.pyc +0 -0
- data/vendor/requests/packages/urllib3/request.py +151 -0
- data/vendor/requests/packages/urllib3/request.pyc +0 -0
- data/vendor/requests/packages/urllib3/response.py +530 -0
- data/vendor/requests/packages/urllib3/response.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/__init__.py +46 -0
- data/vendor/requests/packages/urllib3/util/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/connection.py +144 -0
- data/vendor/requests/packages/urllib3/util/connection.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/request.py +72 -0
- data/vendor/requests/packages/urllib3/util/request.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/response.py +74 -0
- data/vendor/requests/packages/urllib3/util/response.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/retry.py +300 -0
- data/vendor/requests/packages/urllib3/util/retry.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/ssl_.py +320 -0
- data/vendor/requests/packages/urllib3/util/ssl_.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/timeout.py +242 -0
- data/vendor/requests/packages/urllib3/util/timeout.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/url.py +217 -0
- data/vendor/requests/packages/urllib3/util/url.pyc +0 -0
- data/vendor/requests/sessions.py +712 -0
- data/vendor/requests/sessions.pyc +0 -0
- data/vendor/requests/status_codes.py +91 -0
- data/vendor/requests/status_codes.pyc +0 -0
- data/vendor/requests/structures.py +105 -0
- data/vendor/requests/structures.pyc +0 -0
- data/vendor/requests/utils.py +817 -0
- data/vendor/requests/utils.pyc +0 -0
- data/vendor/requests-2.11.1.dist-info/DESCRIPTION.rst +1294 -0
- data/vendor/requests-2.11.1.dist-info/INSTALLER +1 -0
- data/vendor/requests-2.11.1.dist-info/METADATA +1323 -0
- data/vendor/requests-2.11.1.dist-info/RECORD +170 -0
- data/vendor/requests-2.11.1.dist-info/WHEEL +6 -0
- data/vendor/requests-2.11.1.dist-info/metadata.json +1 -0
- data/vendor/requests-2.11.1.dist-info/top_level.txt +1 -0
- data/vendor/rigid/__init__.py +1 -0
- data/vendor/rigid/__init__.pyc +0 -0
- data/vendor/rigid/api.py +129 -0
- data/vendor/rigid/api.pyc +0 -0
- data/vendor/rigid/commands/__init__.py +260 -0
- data/vendor/rigid/commands/__init__.pyc +0 -0
- data/vendor/rigid/commands/deploy.py +0 -0
- data/vendor/rigid/commands/deploy.pyc +0 -0
- data/vendor/rigid/deploy.py +70 -0
- data/vendor/rigid/deploy.pyc +0 -0
- data/vendor/rigid/file_scanner.py +63 -0
- data/vendor/rigid/file_scanner.pyc +0 -0
- data/vendor/rigid/utils.py +17 -0
- data/vendor/rigid/utils.pyc +0 -0
- data/vendor/rigid-0.2.0.dist-info/DESCRIPTION.rst +3 -0
- data/vendor/rigid-0.2.0.dist-info/INSTALLER +1 -0
- data/vendor/rigid-0.2.0.dist-info/METADATA +23 -0
- data/vendor/rigid-0.2.0.dist-info/RECORD +49 -0
- data/vendor/rigid-0.2.0.dist-info/WHEEL +5 -0
- data/vendor/rigid-0.2.0.dist-info/entry_points.txt +3 -0
- data/vendor/rigid-0.2.0.dist-info/metadata.json +1 -0
- data/vendor/rigid-0.2.0.dist-info/top_level.txt +2 -0
- data/vendor/setuptools-28.8.0.dist-info/DESCRIPTION.rst +243 -0
- data/vendor/setuptools-28.8.0.dist-info/INSTALLER +1 -0
- data/vendor/setuptools-28.8.0.dist-info/METADATA +272 -0
- data/vendor/setuptools-28.8.0.dist-info/RECORD +143 -0
- data/vendor/setuptools-28.8.0.dist-info/WHEEL +6 -0
- data/vendor/setuptools-28.8.0.dist-info/dependency_links.txt +2 -0
- data/vendor/setuptools-28.8.0.dist-info/entry_points.txt +63 -0
- data/vendor/setuptools-28.8.0.dist-info/metadata.json +1 -0
- data/vendor/setuptools-28.8.0.dist-info/top_level.txt +3 -0
- data/vendor/setuptools-28.8.0.dist-info/zip-safe +1 -0
- data/vendor/tests/__init__.py +0 -0
- data/vendor/tests/__init__.pyc +0 -0
- data/vendor/tests/integration/__init__.py +0 -0
- data/vendor/tests/integration/__init__.pyc +0 -0
- data/vendor/tests/integration/test_app.py +63 -0
- data/vendor/tests/integration/test_app.pyc +0 -0
- data/vendor/tests/integration/test_apps.py +27 -0
- data/vendor/tests/integration/test_apps.pyc +0 -0
- data/vendor/tests/integration/test_deploy.py +128 -0
- data/vendor/tests/integration/test_deploy.pyc +0 -0
- data/vendor/tests/integration/test_domains.py +35 -0
- data/vendor/tests/integration/test_domains.pyc +0 -0
- data/vendor/tests/integration/test_login.py +37 -0
- data/vendor/tests/integration/test_login.pyc +0 -0
- data/vendor/tests/integration/test_promote.py +24 -0
- data/vendor/tests/integration/test_promote.pyc +0 -0
- data/vendor/tests/integration/test_token.py +33 -0
- data/vendor/tests/integration/test_token.pyc +0 -0
- data/vendor/tests/integration/test_whoami.py +24 -0
- data/vendor/tests/integration/test_whoami.pyc +0 -0
- data/vendor/tests/test_deploy.py +33 -0
- data/vendor/tests/test_deploy.pyc +0 -0
- data/vendor/tests/test_file_scanner.py +89 -0
- data/vendor/tests/test_file_scanner.pyc +0 -0
- data/vendor/tests/utils.py +78 -0
- data/vendor/tests/utils.pyc +0 -0
- data/vendor/wheel-0.30.0a0.dist-info/DESCRIPTION.rst +325 -0
- data/vendor/wheel-0.30.0a0.dist-info/INSTALLER +1 -0
- data/vendor/wheel-0.30.0a0.dist-info/LICENSE.txt +22 -0
- data/vendor/wheel-0.30.0a0.dist-info/METADATA +357 -0
- data/vendor/wheel-0.30.0a0.dist-info/RECORD +86 -0
- data/vendor/wheel-0.30.0a0.dist-info/WHEEL +6 -0
- data/vendor/wheel-0.30.0a0.dist-info/entry_points.txt +6 -0
- data/vendor/wheel-0.30.0a0.dist-info/metadata.json +1 -0
- data/vendor/wheel-0.30.0a0.dist-info/top_level.txt +1 -0
- data/vendor/yaml/__init__.py +315 -0
- data/vendor/yaml/__init__.pyc +0 -0
- data/vendor/yaml/composer.py +139 -0
- data/vendor/yaml/composer.pyc +0 -0
- data/vendor/yaml/constructor.py +675 -0
- data/vendor/yaml/constructor.pyc +0 -0
- data/vendor/yaml/cyaml.py +85 -0
- data/vendor/yaml/cyaml.pyc +0 -0
- data/vendor/yaml/dumper.py +62 -0
- data/vendor/yaml/dumper.pyc +0 -0
- data/vendor/yaml/emitter.py +1140 -0
- data/vendor/yaml/emitter.pyc +0 -0
- data/vendor/yaml/error.py +75 -0
- data/vendor/yaml/error.pyc +0 -0
- data/vendor/yaml/events.py +86 -0
- data/vendor/yaml/events.pyc +0 -0
- data/vendor/yaml/loader.py +40 -0
- data/vendor/yaml/loader.pyc +0 -0
- data/vendor/yaml/nodes.py +49 -0
- data/vendor/yaml/nodes.pyc +0 -0
- data/vendor/yaml/parser.py +589 -0
- data/vendor/yaml/parser.pyc +0 -0
- data/vendor/yaml/reader.py +190 -0
- data/vendor/yaml/reader.pyc +0 -0
- data/vendor/yaml/representer.py +486 -0
- data/vendor/yaml/representer.pyc +0 -0
- data/vendor/yaml/resolver.py +227 -0
- data/vendor/yaml/resolver.pyc +0 -0
- data/vendor/yaml/scanner.py +1453 -0
- data/vendor/yaml/scanner.pyc +0 -0
- data/vendor/yaml/serializer.py +111 -0
- data/vendor/yaml/serializer.pyc +0 -0
- data/vendor/yaml/tokens.py +104 -0
- data/vendor/yaml/tokens.pyc +0 -0
- metadata +407 -0
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
try:
|
2
|
+
# Python 3.2+
|
3
|
+
from ssl import CertificateError, match_hostname
|
4
|
+
except ImportError:
|
5
|
+
try:
|
6
|
+
# Backport of the function from a pypi module
|
7
|
+
from backports.ssl_match_hostname import CertificateError, match_hostname
|
8
|
+
except ImportError:
|
9
|
+
# Our vendored copy
|
10
|
+
from ._implementation import CertificateError, match_hostname
|
11
|
+
|
12
|
+
# Not needed, but documenting what we provide.
|
13
|
+
__all__ = ('CertificateError', 'match_hostname')
|
@@ -0,0 +1,105 @@
|
|
1
|
+
"""The match_hostname() function from Python 3.3.3, essential when using SSL."""
|
2
|
+
|
3
|
+
# Note: This file is under the PSF license as the code comes from the python
|
4
|
+
# stdlib. http://docs.python.org/3/license.html
|
5
|
+
|
6
|
+
import re
|
7
|
+
|
8
|
+
__version__ = '3.4.0.2'
|
9
|
+
|
10
|
+
class CertificateError(ValueError):
|
11
|
+
pass
|
12
|
+
|
13
|
+
|
14
|
+
def _dnsname_match(dn, hostname, max_wildcards=1):
|
15
|
+
"""Matching according to RFC 6125, section 6.4.3
|
16
|
+
|
17
|
+
http://tools.ietf.org/html/rfc6125#section-6.4.3
|
18
|
+
"""
|
19
|
+
pats = []
|
20
|
+
if not dn:
|
21
|
+
return False
|
22
|
+
|
23
|
+
# Ported from python3-syntax:
|
24
|
+
# leftmost, *remainder = dn.split(r'.')
|
25
|
+
parts = dn.split(r'.')
|
26
|
+
leftmost = parts[0]
|
27
|
+
remainder = parts[1:]
|
28
|
+
|
29
|
+
wildcards = leftmost.count('*')
|
30
|
+
if wildcards > max_wildcards:
|
31
|
+
# Issue #17980: avoid denials of service by refusing more
|
32
|
+
# than one wildcard per fragment. A survey of established
|
33
|
+
# policy among SSL implementations showed it to be a
|
34
|
+
# reasonable choice.
|
35
|
+
raise CertificateError(
|
36
|
+
"too many wildcards in certificate DNS name: " + repr(dn))
|
37
|
+
|
38
|
+
# speed up common case w/o wildcards
|
39
|
+
if not wildcards:
|
40
|
+
return dn.lower() == hostname.lower()
|
41
|
+
|
42
|
+
# RFC 6125, section 6.4.3, subitem 1.
|
43
|
+
# The client SHOULD NOT attempt to match a presented identifier in which
|
44
|
+
# the wildcard character comprises a label other than the left-most label.
|
45
|
+
if leftmost == '*':
|
46
|
+
# When '*' is a fragment by itself, it matches a non-empty dotless
|
47
|
+
# fragment.
|
48
|
+
pats.append('[^.]+')
|
49
|
+
elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
|
50
|
+
# RFC 6125, section 6.4.3, subitem 3.
|
51
|
+
# The client SHOULD NOT attempt to match a presented identifier
|
52
|
+
# where the wildcard character is embedded within an A-label or
|
53
|
+
# U-label of an internationalized domain name.
|
54
|
+
pats.append(re.escape(leftmost))
|
55
|
+
else:
|
56
|
+
# Otherwise, '*' matches any dotless string, e.g. www*
|
57
|
+
pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
|
58
|
+
|
59
|
+
# add the remaining fragments, ignore any wildcards
|
60
|
+
for frag in remainder:
|
61
|
+
pats.append(re.escape(frag))
|
62
|
+
|
63
|
+
pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
|
64
|
+
return pat.match(hostname)
|
65
|
+
|
66
|
+
|
67
|
+
def match_hostname(cert, hostname):
|
68
|
+
"""Verify that *cert* (in decoded format as returned by
|
69
|
+
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
|
70
|
+
rules are followed, but IP addresses are not accepted for *hostname*.
|
71
|
+
|
72
|
+
CertificateError is raised on failure. On success, the function
|
73
|
+
returns nothing.
|
74
|
+
"""
|
75
|
+
if not cert:
|
76
|
+
raise ValueError("empty or no certificate")
|
77
|
+
dnsnames = []
|
78
|
+
san = cert.get('subjectAltName', ())
|
79
|
+
for key, value in san:
|
80
|
+
if key == 'DNS':
|
81
|
+
if _dnsname_match(value, hostname):
|
82
|
+
return
|
83
|
+
dnsnames.append(value)
|
84
|
+
if not dnsnames:
|
85
|
+
# The subject is only checked when there is no dNSName entry
|
86
|
+
# in subjectAltName
|
87
|
+
for sub in cert.get('subject', ()):
|
88
|
+
for key, value in sub:
|
89
|
+
# XXX according to RFC 2818, the most specific Common Name
|
90
|
+
# must be used.
|
91
|
+
if key == 'commonName':
|
92
|
+
if _dnsname_match(value, hostname):
|
93
|
+
return
|
94
|
+
dnsnames.append(value)
|
95
|
+
if len(dnsnames) > 1:
|
96
|
+
raise CertificateError("hostname %r "
|
97
|
+
"doesn't match either of %s"
|
98
|
+
% (hostname, ', '.join(map(repr, dnsnames))))
|
99
|
+
elif len(dnsnames) == 1:
|
100
|
+
raise CertificateError("hostname %r "
|
101
|
+
"doesn't match %r"
|
102
|
+
% (hostname, dnsnames[0]))
|
103
|
+
else:
|
104
|
+
raise CertificateError("no appropriate commonName or "
|
105
|
+
"subjectAltName fields were found")
|
Binary file
|
@@ -0,0 +1,367 @@
|
|
1
|
+
from __future__ import absolute_import
|
2
|
+
import collections
|
3
|
+
import functools
|
4
|
+
import logging
|
5
|
+
|
6
|
+
try: # Python 3
|
7
|
+
from urllib.parse import urljoin
|
8
|
+
except ImportError:
|
9
|
+
from urlparse import urljoin
|
10
|
+
|
11
|
+
from ._collections import RecentlyUsedContainer
|
12
|
+
from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool
|
13
|
+
from .connectionpool import port_by_scheme
|
14
|
+
from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown
|
15
|
+
from .request import RequestMethods
|
16
|
+
from .util.url import parse_url
|
17
|
+
from .util.retry import Retry
|
18
|
+
|
19
|
+
|
20
|
+
__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url']
|
21
|
+
|
22
|
+
|
23
|
+
log = logging.getLogger(__name__)
|
24
|
+
|
25
|
+
SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs',
|
26
|
+
'ssl_version', 'ca_cert_dir')
|
27
|
+
|
28
|
+
# The base fields to use when determining what pool to get a connection from;
|
29
|
+
# these do not rely on the ``connection_pool_kw`` and can be determined by the
|
30
|
+
# URL and potentially the ``urllib3.connection.port_by_scheme`` dictionary.
|
31
|
+
#
|
32
|
+
# All custom key schemes should include the fields in this key at a minimum.
|
33
|
+
BasePoolKey = collections.namedtuple('BasePoolKey', ('scheme', 'host', 'port'))
|
34
|
+
|
35
|
+
# The fields to use when determining what pool to get a HTTP and HTTPS
|
36
|
+
# connection from. All additional fields must be present in the PoolManager's
|
37
|
+
# ``connection_pool_kw`` instance variable.
|
38
|
+
HTTPPoolKey = collections.namedtuple(
|
39
|
+
'HTTPPoolKey', BasePoolKey._fields + ('timeout', 'retries', 'strict',
|
40
|
+
'block', 'source_address')
|
41
|
+
)
|
42
|
+
HTTPSPoolKey = collections.namedtuple(
|
43
|
+
'HTTPSPoolKey', HTTPPoolKey._fields + SSL_KEYWORDS
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
def _default_key_normalizer(key_class, request_context):
|
48
|
+
"""
|
49
|
+
Create a pool key of type ``key_class`` for a request.
|
50
|
+
|
51
|
+
According to RFC 3986, both the scheme and host are case-insensitive.
|
52
|
+
Therefore, this function normalizes both before constructing the pool
|
53
|
+
key for an HTTPS request. If you wish to change this behaviour, provide
|
54
|
+
alternate callables to ``key_fn_by_scheme``.
|
55
|
+
|
56
|
+
:param key_class:
|
57
|
+
The class to use when constructing the key. This should be a namedtuple
|
58
|
+
with the ``scheme`` and ``host`` keys at a minimum.
|
59
|
+
|
60
|
+
:param request_context:
|
61
|
+
A dictionary-like object that contain the context for a request.
|
62
|
+
It should contain a key for each field in the :class:`HTTPPoolKey`
|
63
|
+
"""
|
64
|
+
context = {}
|
65
|
+
for key in key_class._fields:
|
66
|
+
context[key] = request_context.get(key)
|
67
|
+
context['scheme'] = context['scheme'].lower()
|
68
|
+
context['host'] = context['host'].lower()
|
69
|
+
return key_class(**context)
|
70
|
+
|
71
|
+
|
72
|
+
# A dictionary that maps a scheme to a callable that creates a pool key.
|
73
|
+
# This can be used to alter the way pool keys are constructed, if desired.
|
74
|
+
# Each PoolManager makes a copy of this dictionary so they can be configured
|
75
|
+
# globally here, or individually on the instance.
|
76
|
+
key_fn_by_scheme = {
|
77
|
+
'http': functools.partial(_default_key_normalizer, HTTPPoolKey),
|
78
|
+
'https': functools.partial(_default_key_normalizer, HTTPSPoolKey),
|
79
|
+
}
|
80
|
+
|
81
|
+
pool_classes_by_scheme = {
|
82
|
+
'http': HTTPConnectionPool,
|
83
|
+
'https': HTTPSConnectionPool,
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
class PoolManager(RequestMethods):
|
88
|
+
"""
|
89
|
+
Allows for arbitrary requests while transparently keeping track of
|
90
|
+
necessary connection pools for you.
|
91
|
+
|
92
|
+
:param num_pools:
|
93
|
+
Number of connection pools to cache before discarding the least
|
94
|
+
recently used pool.
|
95
|
+
|
96
|
+
:param headers:
|
97
|
+
Headers to include with all requests, unless other headers are given
|
98
|
+
explicitly.
|
99
|
+
|
100
|
+
:param \**connection_pool_kw:
|
101
|
+
Additional parameters are used to create fresh
|
102
|
+
:class:`urllib3.connectionpool.ConnectionPool` instances.
|
103
|
+
|
104
|
+
Example::
|
105
|
+
|
106
|
+
>>> manager = PoolManager(num_pools=2)
|
107
|
+
>>> r = manager.request('GET', 'http://google.com/')
|
108
|
+
>>> r = manager.request('GET', 'http://google.com/mail')
|
109
|
+
>>> r = manager.request('GET', 'http://yahoo.com/')
|
110
|
+
>>> len(manager.pools)
|
111
|
+
2
|
112
|
+
|
113
|
+
"""
|
114
|
+
|
115
|
+
proxy = None
|
116
|
+
|
117
|
+
def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
|
118
|
+
RequestMethods.__init__(self, headers)
|
119
|
+
self.connection_pool_kw = connection_pool_kw
|
120
|
+
self.pools = RecentlyUsedContainer(num_pools,
|
121
|
+
dispose_func=lambda p: p.close())
|
122
|
+
|
123
|
+
# Locally set the pool classes and keys so other PoolManagers can
|
124
|
+
# override them.
|
125
|
+
self.pool_classes_by_scheme = pool_classes_by_scheme
|
126
|
+
self.key_fn_by_scheme = key_fn_by_scheme.copy()
|
127
|
+
|
128
|
+
def __enter__(self):
|
129
|
+
return self
|
130
|
+
|
131
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
132
|
+
self.clear()
|
133
|
+
# Return False to re-raise any potential exceptions
|
134
|
+
return False
|
135
|
+
|
136
|
+
def _new_pool(self, scheme, host, port):
|
137
|
+
"""
|
138
|
+
Create a new :class:`ConnectionPool` based on host, port and scheme.
|
139
|
+
|
140
|
+
This method is used to actually create the connection pools handed out
|
141
|
+
by :meth:`connection_from_url` and companion methods. It is intended
|
142
|
+
to be overridden for customization.
|
143
|
+
"""
|
144
|
+
pool_cls = self.pool_classes_by_scheme[scheme]
|
145
|
+
kwargs = self.connection_pool_kw
|
146
|
+
if scheme == 'http':
|
147
|
+
kwargs = self.connection_pool_kw.copy()
|
148
|
+
for kw in SSL_KEYWORDS:
|
149
|
+
kwargs.pop(kw, None)
|
150
|
+
|
151
|
+
return pool_cls(host, port, **kwargs)
|
152
|
+
|
153
|
+
def clear(self):
|
154
|
+
"""
|
155
|
+
Empty our store of pools and direct them all to close.
|
156
|
+
|
157
|
+
This will not affect in-flight connections, but they will not be
|
158
|
+
re-used after completion.
|
159
|
+
"""
|
160
|
+
self.pools.clear()
|
161
|
+
|
162
|
+
def connection_from_host(self, host, port=None, scheme='http'):
|
163
|
+
"""
|
164
|
+
Get a :class:`ConnectionPool` based on the host, port, and scheme.
|
165
|
+
|
166
|
+
If ``port`` isn't given, it will be derived from the ``scheme`` using
|
167
|
+
``urllib3.connectionpool.port_by_scheme``.
|
168
|
+
"""
|
169
|
+
|
170
|
+
if not host:
|
171
|
+
raise LocationValueError("No host specified.")
|
172
|
+
|
173
|
+
request_context = self.connection_pool_kw.copy()
|
174
|
+
request_context['scheme'] = scheme or 'http'
|
175
|
+
if not port:
|
176
|
+
port = port_by_scheme.get(request_context['scheme'].lower(), 80)
|
177
|
+
request_context['port'] = port
|
178
|
+
request_context['host'] = host
|
179
|
+
|
180
|
+
return self.connection_from_context(request_context)
|
181
|
+
|
182
|
+
def connection_from_context(self, request_context):
|
183
|
+
"""
|
184
|
+
Get a :class:`ConnectionPool` based on the request context.
|
185
|
+
|
186
|
+
``request_context`` must at least contain the ``scheme`` key and its
|
187
|
+
value must be a key in ``key_fn_by_scheme`` instance variable.
|
188
|
+
"""
|
189
|
+
scheme = request_context['scheme'].lower()
|
190
|
+
pool_key_constructor = self.key_fn_by_scheme[scheme]
|
191
|
+
pool_key = pool_key_constructor(request_context)
|
192
|
+
|
193
|
+
return self.connection_from_pool_key(pool_key)
|
194
|
+
|
195
|
+
def connection_from_pool_key(self, pool_key):
|
196
|
+
"""
|
197
|
+
Get a :class:`ConnectionPool` based on the provided pool key.
|
198
|
+
|
199
|
+
``pool_key`` should be a namedtuple that only contains immutable
|
200
|
+
objects. At a minimum it must have the ``scheme``, ``host``, and
|
201
|
+
``port`` fields.
|
202
|
+
"""
|
203
|
+
with self.pools.lock:
|
204
|
+
# If the scheme, host, or port doesn't match existing open
|
205
|
+
# connections, open a new ConnectionPool.
|
206
|
+
pool = self.pools.get(pool_key)
|
207
|
+
if pool:
|
208
|
+
return pool
|
209
|
+
|
210
|
+
# Make a fresh ConnectionPool of the desired type
|
211
|
+
pool = self._new_pool(pool_key.scheme, pool_key.host, pool_key.port)
|
212
|
+
self.pools[pool_key] = pool
|
213
|
+
|
214
|
+
return pool
|
215
|
+
|
216
|
+
def connection_from_url(self, url):
|
217
|
+
"""
|
218
|
+
Similar to :func:`urllib3.connectionpool.connection_from_url` but
|
219
|
+
doesn't pass any additional parameters to the
|
220
|
+
:class:`urllib3.connectionpool.ConnectionPool` constructor.
|
221
|
+
|
222
|
+
Additional parameters are taken from the :class:`.PoolManager`
|
223
|
+
constructor.
|
224
|
+
"""
|
225
|
+
u = parse_url(url)
|
226
|
+
return self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
|
227
|
+
|
228
|
+
def urlopen(self, method, url, redirect=True, **kw):
|
229
|
+
"""
|
230
|
+
Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen`
|
231
|
+
with custom cross-host redirect logic and only sends the request-uri
|
232
|
+
portion of the ``url``.
|
233
|
+
|
234
|
+
The given ``url`` parameter must be absolute, such that an appropriate
|
235
|
+
:class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
|
236
|
+
"""
|
237
|
+
u = parse_url(url)
|
238
|
+
conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
|
239
|
+
|
240
|
+
kw['assert_same_host'] = False
|
241
|
+
kw['redirect'] = False
|
242
|
+
if 'headers' not in kw:
|
243
|
+
kw['headers'] = self.headers
|
244
|
+
|
245
|
+
if self.proxy is not None and u.scheme == "http":
|
246
|
+
response = conn.urlopen(method, url, **kw)
|
247
|
+
else:
|
248
|
+
response = conn.urlopen(method, u.request_uri, **kw)
|
249
|
+
|
250
|
+
redirect_location = redirect and response.get_redirect_location()
|
251
|
+
if not redirect_location:
|
252
|
+
return response
|
253
|
+
|
254
|
+
# Support relative URLs for redirecting.
|
255
|
+
redirect_location = urljoin(url, redirect_location)
|
256
|
+
|
257
|
+
# RFC 7231, Section 6.4.4
|
258
|
+
if response.status == 303:
|
259
|
+
method = 'GET'
|
260
|
+
|
261
|
+
retries = kw.get('retries')
|
262
|
+
if not isinstance(retries, Retry):
|
263
|
+
retries = Retry.from_int(retries, redirect=redirect)
|
264
|
+
|
265
|
+
try:
|
266
|
+
retries = retries.increment(method, url, response=response, _pool=conn)
|
267
|
+
except MaxRetryError:
|
268
|
+
if retries.raise_on_redirect:
|
269
|
+
raise
|
270
|
+
return response
|
271
|
+
|
272
|
+
kw['retries'] = retries
|
273
|
+
kw['redirect'] = redirect
|
274
|
+
|
275
|
+
log.info("Redirecting %s -> %s", url, redirect_location)
|
276
|
+
return self.urlopen(method, redirect_location, **kw)
|
277
|
+
|
278
|
+
|
279
|
+
class ProxyManager(PoolManager):
|
280
|
+
"""
|
281
|
+
Behaves just like :class:`PoolManager`, but sends all requests through
|
282
|
+
the defined proxy, using the CONNECT method for HTTPS URLs.
|
283
|
+
|
284
|
+
:param proxy_url:
|
285
|
+
The URL of the proxy to be used.
|
286
|
+
|
287
|
+
:param proxy_headers:
|
288
|
+
A dictionary contaning headers that will be sent to the proxy. In case
|
289
|
+
of HTTP they are being sent with each request, while in the
|
290
|
+
HTTPS/CONNECT case they are sent only once. Could be used for proxy
|
291
|
+
authentication.
|
292
|
+
|
293
|
+
Example:
|
294
|
+
>>> proxy = urllib3.ProxyManager('http://localhost:3128/')
|
295
|
+
>>> r1 = proxy.request('GET', 'http://google.com/')
|
296
|
+
>>> r2 = proxy.request('GET', 'http://httpbin.org/')
|
297
|
+
>>> len(proxy.pools)
|
298
|
+
1
|
299
|
+
>>> r3 = proxy.request('GET', 'https://httpbin.org/')
|
300
|
+
>>> r4 = proxy.request('GET', 'https://twitter.com/')
|
301
|
+
>>> len(proxy.pools)
|
302
|
+
3
|
303
|
+
|
304
|
+
"""
|
305
|
+
|
306
|
+
def __init__(self, proxy_url, num_pools=10, headers=None,
|
307
|
+
proxy_headers=None, **connection_pool_kw):
|
308
|
+
|
309
|
+
if isinstance(proxy_url, HTTPConnectionPool):
|
310
|
+
proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host,
|
311
|
+
proxy_url.port)
|
312
|
+
proxy = parse_url(proxy_url)
|
313
|
+
if not proxy.port:
|
314
|
+
port = port_by_scheme.get(proxy.scheme, 80)
|
315
|
+
proxy = proxy._replace(port=port)
|
316
|
+
|
317
|
+
if proxy.scheme not in ("http", "https"):
|
318
|
+
raise ProxySchemeUnknown(proxy.scheme)
|
319
|
+
|
320
|
+
self.proxy = proxy
|
321
|
+
self.proxy_headers = proxy_headers or {}
|
322
|
+
|
323
|
+
connection_pool_kw['_proxy'] = self.proxy
|
324
|
+
connection_pool_kw['_proxy_headers'] = self.proxy_headers
|
325
|
+
|
326
|
+
super(ProxyManager, self).__init__(
|
327
|
+
num_pools, headers, **connection_pool_kw)
|
328
|
+
|
329
|
+
def connection_from_host(self, host, port=None, scheme='http'):
|
330
|
+
if scheme == "https":
|
331
|
+
return super(ProxyManager, self).connection_from_host(
|
332
|
+
host, port, scheme)
|
333
|
+
|
334
|
+
return super(ProxyManager, self).connection_from_host(
|
335
|
+
self.proxy.host, self.proxy.port, self.proxy.scheme)
|
336
|
+
|
337
|
+
def _set_proxy_headers(self, url, headers=None):
|
338
|
+
"""
|
339
|
+
Sets headers needed by proxies: specifically, the Accept and Host
|
340
|
+
headers. Only sets headers not provided by the user.
|
341
|
+
"""
|
342
|
+
headers_ = {'Accept': '*/*'}
|
343
|
+
|
344
|
+
netloc = parse_url(url).netloc
|
345
|
+
if netloc:
|
346
|
+
headers_['Host'] = netloc
|
347
|
+
|
348
|
+
if headers:
|
349
|
+
headers_.update(headers)
|
350
|
+
return headers_
|
351
|
+
|
352
|
+
def urlopen(self, method, url, redirect=True, **kw):
|
353
|
+
"Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
|
354
|
+
u = parse_url(url)
|
355
|
+
|
356
|
+
if u.scheme == "http":
|
357
|
+
# For proxied HTTPS requests, httplib sets the necessary headers
|
358
|
+
# on the CONNECT to the proxy. For HTTP, we'll definitely
|
359
|
+
# need to set 'Host' at the very least.
|
360
|
+
headers = kw.get('headers', self.headers)
|
361
|
+
kw['headers'] = self._set_proxy_headers(url, headers)
|
362
|
+
|
363
|
+
return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
|
364
|
+
|
365
|
+
|
366
|
+
def proxy_from_url(url, **kw):
|
367
|
+
return ProxyManager(proxy_url=url, **kw)
|
Binary file
|
@@ -0,0 +1,151 @@
|
|
1
|
+
from __future__ import absolute_import
|
2
|
+
try:
|
3
|
+
from urllib.parse import urlencode
|
4
|
+
except ImportError:
|
5
|
+
from urllib import urlencode
|
6
|
+
|
7
|
+
from .filepost import encode_multipart_formdata
|
8
|
+
|
9
|
+
|
10
|
+
__all__ = ['RequestMethods']
|
11
|
+
|
12
|
+
|
13
|
+
class RequestMethods(object):
|
14
|
+
"""
|
15
|
+
Convenience mixin for classes who implement a :meth:`urlopen` method, such
|
16
|
+
as :class:`~urllib3.connectionpool.HTTPConnectionPool` and
|
17
|
+
:class:`~urllib3.poolmanager.PoolManager`.
|
18
|
+
|
19
|
+
Provides behavior for making common types of HTTP request methods and
|
20
|
+
decides which type of request field encoding to use.
|
21
|
+
|
22
|
+
Specifically,
|
23
|
+
|
24
|
+
:meth:`.request_encode_url` is for sending requests whose fields are
|
25
|
+
encoded in the URL (such as GET, HEAD, DELETE).
|
26
|
+
|
27
|
+
:meth:`.request_encode_body` is for sending requests whose fields are
|
28
|
+
encoded in the *body* of the request using multipart or www-form-urlencoded
|
29
|
+
(such as for POST, PUT, PATCH).
|
30
|
+
|
31
|
+
:meth:`.request` is for making any kind of request, it will look up the
|
32
|
+
appropriate encoding format and use one of the above two methods to make
|
33
|
+
the request.
|
34
|
+
|
35
|
+
Initializer parameters:
|
36
|
+
|
37
|
+
:param headers:
|
38
|
+
Headers to include with all requests, unless other headers are given
|
39
|
+
explicitly.
|
40
|
+
"""
|
41
|
+
|
42
|
+
_encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS'])
|
43
|
+
|
44
|
+
def __init__(self, headers=None):
|
45
|
+
self.headers = headers or {}
|
46
|
+
|
47
|
+
def urlopen(self, method, url, body=None, headers=None,
|
48
|
+
encode_multipart=True, multipart_boundary=None,
|
49
|
+
**kw): # Abstract
|
50
|
+
raise NotImplemented("Classes extending RequestMethods must implement "
|
51
|
+
"their own ``urlopen`` method.")
|
52
|
+
|
53
|
+
def request(self, method, url, fields=None, headers=None, **urlopen_kw):
|
54
|
+
"""
|
55
|
+
Make a request using :meth:`urlopen` with the appropriate encoding of
|
56
|
+
``fields`` based on the ``method`` used.
|
57
|
+
|
58
|
+
This is a convenience method that requires the least amount of manual
|
59
|
+
effort. It can be used in most situations, while still having the
|
60
|
+
option to drop down to more specific methods when necessary, such as
|
61
|
+
:meth:`request_encode_url`, :meth:`request_encode_body`,
|
62
|
+
or even the lowest level :meth:`urlopen`.
|
63
|
+
"""
|
64
|
+
method = method.upper()
|
65
|
+
|
66
|
+
if method in self._encode_url_methods:
|
67
|
+
return self.request_encode_url(method, url, fields=fields,
|
68
|
+
headers=headers,
|
69
|
+
**urlopen_kw)
|
70
|
+
else:
|
71
|
+
return self.request_encode_body(method, url, fields=fields,
|
72
|
+
headers=headers,
|
73
|
+
**urlopen_kw)
|
74
|
+
|
75
|
+
def request_encode_url(self, method, url, fields=None, headers=None,
|
76
|
+
**urlopen_kw):
|
77
|
+
"""
|
78
|
+
Make a request using :meth:`urlopen` with the ``fields`` encoded in
|
79
|
+
the url. This is useful for request methods like GET, HEAD, DELETE, etc.
|
80
|
+
"""
|
81
|
+
if headers is None:
|
82
|
+
headers = self.headers
|
83
|
+
|
84
|
+
extra_kw = {'headers': headers}
|
85
|
+
extra_kw.update(urlopen_kw)
|
86
|
+
|
87
|
+
if fields:
|
88
|
+
url += '?' + urlencode(fields)
|
89
|
+
|
90
|
+
return self.urlopen(method, url, **extra_kw)
|
91
|
+
|
92
|
+
def request_encode_body(self, method, url, fields=None, headers=None,
|
93
|
+
encode_multipart=True, multipart_boundary=None,
|
94
|
+
**urlopen_kw):
|
95
|
+
"""
|
96
|
+
Make a request using :meth:`urlopen` with the ``fields`` encoded in
|
97
|
+
the body. This is useful for request methods like POST, PUT, PATCH, etc.
|
98
|
+
|
99
|
+
When ``encode_multipart=True`` (default), then
|
100
|
+
:meth:`urllib3.filepost.encode_multipart_formdata` is used to encode
|
101
|
+
the payload with the appropriate content type. Otherwise
|
102
|
+
:meth:`urllib.urlencode` is used with the
|
103
|
+
'application/x-www-form-urlencoded' content type.
|
104
|
+
|
105
|
+
Multipart encoding must be used when posting files, and it's reasonably
|
106
|
+
safe to use it in other times too. However, it may break request
|
107
|
+
signing, such as with OAuth.
|
108
|
+
|
109
|
+
Supports an optional ``fields`` parameter of key/value strings AND
|
110
|
+
key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
|
111
|
+
the MIME type is optional. For example::
|
112
|
+
|
113
|
+
fields = {
|
114
|
+
'foo': 'bar',
|
115
|
+
'fakefile': ('foofile.txt', 'contents of foofile'),
|
116
|
+
'realfile': ('barfile.txt', open('realfile').read()),
|
117
|
+
'typedfile': ('bazfile.bin', open('bazfile').read(),
|
118
|
+
'image/jpeg'),
|
119
|
+
'nonamefile': 'contents of nonamefile field',
|
120
|
+
}
|
121
|
+
|
122
|
+
When uploading a file, providing a filename (the first parameter of the
|
123
|
+
tuple) is optional but recommended to best mimick behavior of browsers.
|
124
|
+
|
125
|
+
Note that if ``headers`` are supplied, the 'Content-Type' header will
|
126
|
+
be overwritten because it depends on the dynamic random boundary string
|
127
|
+
which is used to compose the body of the request. The random boundary
|
128
|
+
string can be explicitly set with the ``multipart_boundary`` parameter.
|
129
|
+
"""
|
130
|
+
if headers is None:
|
131
|
+
headers = self.headers
|
132
|
+
|
133
|
+
extra_kw = {'headers': {}}
|
134
|
+
|
135
|
+
if fields:
|
136
|
+
if 'body' in urlopen_kw:
|
137
|
+
raise TypeError(
|
138
|
+
"request got values for both 'fields' and 'body', can only specify one.")
|
139
|
+
|
140
|
+
if encode_multipart:
|
141
|
+
body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary)
|
142
|
+
else:
|
143
|
+
body, content_type = urlencode(fields), 'application/x-www-form-urlencoded'
|
144
|
+
|
145
|
+
extra_kw['body'] = body
|
146
|
+
extra_kw['headers'] = {'Content-Type': content_type}
|
147
|
+
|
148
|
+
extra_kw['headers'].update(headers)
|
149
|
+
extra_kw.update(urlopen_kw)
|
150
|
+
|
151
|
+
return self.urlopen(method, url, **extra_kw)
|
Binary file
|