snowflake-connector-python 4.4.0__cp314-cp314-win_amd64.whl
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.
- snowflake/connector/__init__.py +118 -0
- snowflake/connector/_query_context_cache.py +276 -0
- snowflake/connector/_sql_util.py +48 -0
- snowflake/connector/_utils.py +353 -0
- snowflake/connector/aio/README.md +88 -0
- snowflake/connector/aio/__init__.py +163 -0
- snowflake/connector/aio/_azure_storage_client.py +227 -0
- snowflake/connector/aio/_bind_upload_agent.py +69 -0
- snowflake/connector/aio/_connection.py +1216 -0
- snowflake/connector/aio/_cursor.py +1402 -0
- snowflake/connector/aio/_description.py +5 -0
- snowflake/connector/aio/_direct_file_operation_utils.py +88 -0
- snowflake/connector/aio/_file_transfer_agent.py +316 -0
- snowflake/connector/aio/_gcs_storage_client.py +360 -0
- snowflake/connector/aio/_network.py +860 -0
- snowflake/connector/aio/_ocsp_asn1crypto.py +51 -0
- snowflake/connector/aio/_ocsp_snowflake.py +608 -0
- snowflake/connector/aio/_pandas_tools.py +561 -0
- snowflake/connector/aio/_result_batch.py +442 -0
- snowflake/connector/aio/_result_set.py +309 -0
- snowflake/connector/aio/_s3_storage_client.py +460 -0
- snowflake/connector/aio/_session_manager.py +588 -0
- snowflake/connector/aio/_storage_client.py +331 -0
- snowflake/connector/aio/_telemetry.py +97 -0
- snowflake/connector/aio/_time_util.py +57 -0
- snowflake/connector/aio/_wif_util.py +324 -0
- snowflake/connector/aio/auth/__init__.py +52 -0
- snowflake/connector/aio/auth/_auth.py +406 -0
- snowflake/connector/aio/auth/_by_plugin.py +131 -0
- snowflake/connector/aio/auth/_default.py +28 -0
- snowflake/connector/aio/auth/_idtoken.py +54 -0
- snowflake/connector/aio/auth/_keypair.py +60 -0
- snowflake/connector/aio/auth/_no_auth.py +31 -0
- snowflake/connector/aio/auth/_oauth.py +27 -0
- snowflake/connector/aio/auth/_oauth_code.py +117 -0
- snowflake/connector/aio/auth/_oauth_credentials.py +100 -0
- snowflake/connector/aio/auth/_okta.py +247 -0
- snowflake/connector/aio/auth/_pat.py +27 -0
- snowflake/connector/aio/auth/_usrpwdmfa.py +30 -0
- snowflake/connector/aio/auth/_webbrowser.py +405 -0
- snowflake/connector/aio/auth/_workload_identity.py +60 -0
- snowflake/connector/arrow_context.py +211 -0
- snowflake/connector/auth/__init__.py +53 -0
- snowflake/connector/auth/_auth.py +669 -0
- snowflake/connector/auth/_http_server.py +257 -0
- snowflake/connector/auth/_oauth_base.py +472 -0
- snowflake/connector/auth/by_plugin.py +219 -0
- snowflake/connector/auth/default.py +36 -0
- snowflake/connector/auth/idtoken.py +72 -0
- snowflake/connector/auth/keypair.py +225 -0
- snowflake/connector/auth/no_auth.py +39 -0
- snowflake/connector/auth/oauth.py +49 -0
- snowflake/connector/auth/oauth_code.py +490 -0
- snowflake/connector/auth/oauth_credentials.py +71 -0
- snowflake/connector/auth/okta.py +339 -0
- snowflake/connector/auth/pat.py +40 -0
- snowflake/connector/auth/usrpwdmfa.py +69 -0
- snowflake/connector/auth/webbrowser.py +514 -0
- snowflake/connector/auth/workload_identity.py +110 -0
- snowflake/connector/azure_storage_client.py +278 -0
- snowflake/connector/backoff_policies.py +141 -0
- snowflake/connector/bind_upload_agent.py +89 -0
- snowflake/connector/cache.py +696 -0
- snowflake/connector/compat.py +127 -0
- snowflake/connector/config_manager.py +553 -0
- snowflake/connector/connection.py +2671 -0
- snowflake/connector/connection_diagnostic.py +793 -0
- snowflake/connector/constants.py +460 -0
- snowflake/connector/converter.py +809 -0
- snowflake/connector/converter_issue23517.py +87 -0
- snowflake/connector/converter_null.py +14 -0
- snowflake/connector/converter_snowsql.py +205 -0
- snowflake/connector/crl.py +919 -0
- snowflake/connector/crl_cache.py +734 -0
- snowflake/connector/cursor.py +2099 -0
- snowflake/connector/dbapi.py +53 -0
- snowflake/connector/description.py +21 -0
- snowflake/connector/direct_file_operation_utils.py +88 -0
- snowflake/connector/encryption_util.py +220 -0
- snowflake/connector/errorcode.py +94 -0
- snowflake/connector/errors.py +666 -0
- snowflake/connector/externals_utils/__init__.py +0 -0
- snowflake/connector/externals_utils/externals_setup.py +30 -0
- snowflake/connector/feature.py +4 -0
- snowflake/connector/file_compression_type.py +118 -0
- snowflake/connector/file_lock.py +72 -0
- snowflake/connector/file_transfer_agent.py +1244 -0
- snowflake/connector/file_util.py +153 -0
- snowflake/connector/gcs_storage_client.py +476 -0
- snowflake/connector/gzip_decoder.py +85 -0
- snowflake/connector/interval_util.py +26 -0
- snowflake/connector/local_storage_client.py +90 -0
- snowflake/connector/log_configuration.py +62 -0
- snowflake/connector/logging_utils/__init__.py +0 -0
- snowflake/connector/logging_utils/filters.py +72 -0
- snowflake/connector/minicore/__init__.py +0 -0
- snowflake/connector/minicore/aix_ppc64/libsf_mini_core.a +0 -0
- snowflake/connector/minicore/aix_ppc64/libsf_mini_core_static.a +0 -0
- snowflake/connector/minicore/linux_aarch64_glibc/libsf_mini_core.so +0 -0
- snowflake/connector/minicore/linux_aarch64_musl/libsf_mini_core.so +0 -0
- snowflake/connector/minicore/linux_x86_64_glibc/libsf_mini_core.so +0 -0
- snowflake/connector/minicore/linux_x86_64_musl/libsf_mini_core.so +0 -0
- snowflake/connector/minicore/macos_aarch64/libsf_mini_core.dylib +0 -0
- snowflake/connector/minicore/macos_x86_64/libsf_mini_core.dylib +0 -0
- snowflake/connector/minicore/windows_x86_64/sf_mini_core.dll +0 -0
- snowflake/connector/minicore/windows_x86_64/sf_mini_core_static.lib +0 -0
- snowflake/connector/nanoarrow_arrow_iterator.cp314-win_amd64.pyd +0 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +570 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1140 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +138 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +75 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +57 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +67 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +262 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
- snowflake/connector/network.py +1227 -0
- snowflake/connector/ocsp_asn1crypto.py +447 -0
- snowflake/connector/ocsp_snowflake.py +1939 -0
- snowflake/connector/options.py +179 -0
- snowflake/connector/os_details.py +88 -0
- snowflake/connector/pandas_tools.py +734 -0
- snowflake/connector/platform_detection.py +555 -0
- snowflake/connector/proxy.py +28 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +917 -0
- snowflake/connector/result_set.py +340 -0
- snowflake/connector/s3_storage_client.py +614 -0
- snowflake/connector/secret_detector.py +181 -0
- snowflake/connector/session_manager.py +650 -0
- snowflake/connector/sf_dirs.py +64 -0
- snowflake/connector/sfbinaryformat.py +35 -0
- snowflake/connector/sfdatetime.py +345 -0
- snowflake/connector/snow_logging.py +144 -0
- snowflake/connector/sqlstate.py +9 -0
- snowflake/connector/ssd_internal_keys.py +30 -0
- snowflake/connector/ssl_wrap_socket.py +281 -0
- snowflake/connector/storage_client.py +486 -0
- snowflake/connector/telemetry.py +254 -0
- snowflake/connector/telemetry_oob.py +544 -0
- snowflake/connector/test_util.py +30 -0
- snowflake/connector/time_util.py +159 -0
- snowflake/connector/token_cache.py +457 -0
- snowflake/connector/tool/__init__.py +0 -0
- snowflake/connector/tool/dump_certs.py +57 -0
- snowflake/connector/tool/dump_ocsp_response.py +139 -0
- snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
- snowflake/connector/tool/probe_connection.py +69 -0
- snowflake/connector/url_util.py +55 -0
- snowflake/connector/util_text.py +320 -0
- snowflake/connector/vendored/__init__.py +3 -0
- snowflake/connector/vendored/requests/LICENSE +175 -0
- snowflake/connector/vendored/requests/__init__.py +184 -0
- snowflake/connector/vendored/requests/__version__.py +14 -0
- snowflake/connector/vendored/requests/_internal_utils.py +50 -0
- snowflake/connector/vendored/requests/adapters.py +696 -0
- snowflake/connector/vendored/requests/api.py +157 -0
- snowflake/connector/vendored/requests/auth.py +314 -0
- snowflake/connector/vendored/requests/certs.py +17 -0
- snowflake/connector/vendored/requests/compat.py +106 -0
- snowflake/connector/vendored/requests/cookies.py +561 -0
- snowflake/connector/vendored/requests/exceptions.py +151 -0
- snowflake/connector/vendored/requests/help.py +134 -0
- snowflake/connector/vendored/requests/hooks.py +33 -0
- snowflake/connector/vendored/requests/models.py +1039 -0
- snowflake/connector/vendored/requests/packages.py +23 -0
- snowflake/connector/vendored/requests/sessions.py +831 -0
- snowflake/connector/vendored/requests/status_codes.py +128 -0
- snowflake/connector/vendored/requests/structures.py +99 -0
- snowflake/connector/vendored/requests/utils.py +1086 -0
- snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
- snowflake/connector/vendored/urllib3/__init__.py +211 -0
- snowflake/connector/vendored/urllib3/_base_connection.py +165 -0
- snowflake/connector/vendored/urllib3/_collections.py +487 -0
- snowflake/connector/vendored/urllib3/_request_methods.py +278 -0
- snowflake/connector/vendored/urllib3/_version.py +34 -0
- snowflake/connector/vendored/urllib3/connection.py +1108 -0
- snowflake/connector/vendored/urllib3/connectionpool.py +1178 -0
- snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/emscripten/__init__.py +17 -0
- snowflake/connector/vendored/urllib3/contrib/emscripten/connection.py +260 -0
- snowflake/connector/vendored/urllib3/contrib/emscripten/emscripten_fetch_worker.js +110 -0
- snowflake/connector/vendored/urllib3/contrib/emscripten/fetch.py +726 -0
- snowflake/connector/vendored/urllib3/contrib/emscripten/request.py +22 -0
- snowflake/connector/vendored/urllib3/contrib/emscripten/response.py +277 -0
- snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +564 -0
- snowflake/connector/vendored/urllib3/contrib/socks.py +228 -0
- snowflake/connector/vendored/urllib3/exceptions.py +335 -0
- snowflake/connector/vendored/urllib3/fields.py +341 -0
- snowflake/connector/vendored/urllib3/filepost.py +89 -0
- snowflake/connector/vendored/urllib3/http2/__init__.py +53 -0
- snowflake/connector/vendored/urllib3/http2/connection.py +356 -0
- snowflake/connector/vendored/urllib3/http2/probe.py +87 -0
- snowflake/connector/vendored/urllib3/poolmanager.py +651 -0
- snowflake/connector/vendored/urllib3/py.typed +2 -0
- snowflake/connector/vendored/urllib3/response.py +1480 -0
- snowflake/connector/vendored/urllib3/util/__init__.py +42 -0
- snowflake/connector/vendored/urllib3/util/connection.py +137 -0
- snowflake/connector/vendored/urllib3/util/proxy.py +43 -0
- snowflake/connector/vendored/urllib3/util/request.py +263 -0
- snowflake/connector/vendored/urllib3/util/response.py +101 -0
- snowflake/connector/vendored/urllib3/util/retry.py +549 -0
- snowflake/connector/vendored/urllib3/util/ssl_.py +527 -0
- snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
- snowflake/connector/vendored/urllib3/util/ssltransport.py +271 -0
- snowflake/connector/vendored/urllib3/util/timeout.py +275 -0
- snowflake/connector/vendored/urllib3/util/url.py +469 -0
- snowflake/connector/vendored/urllib3/util/util.py +42 -0
- snowflake/connector/vendored/urllib3/util/wait.py +124 -0
- snowflake/connector/version.py +3 -0
- snowflake/connector/wif_util.py +434 -0
- snowflake_connector_python-4.4.0.dist-info/DELVEWHEEL +2 -0
- snowflake_connector_python-4.4.0.dist-info/METADATA +1591 -0
- snowflake_connector_python-4.4.0.dist-info/RECORD +302 -0
- snowflake_connector_python-4.4.0.dist-info/WHEEL +5 -0
- snowflake_connector_python-4.4.0.dist-info/entry_points.txt +4 -0
- snowflake_connector_python-4.4.0.dist-info/licenses/LICENSE.txt +202 -0
- snowflake_connector_python-4.4.0.dist-info/licenses/NOTICE +8 -0
- snowflake_connector_python-4.4.0.dist-info/top_level.txt +1 -0
- snowflake_connector_python.libs/msvcp140-0f885b509a685d2bbfa652fed26b5fb3.dll +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import logging
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
from argparse import ArgumentParser, Namespace
|
|
8
|
+
from time import gmtime, strftime
|
|
9
|
+
|
|
10
|
+
from asn1crypto import ocsp as asn1crypto_ocsp
|
|
11
|
+
|
|
12
|
+
from snowflake.connector.compat import urlsplit
|
|
13
|
+
from snowflake.connector.ocsp_asn1crypto import SnowflakeOCSPAsn1Crypto as SFOCSP
|
|
14
|
+
from snowflake.connector.ocsp_snowflake import OCSPTelemetryData
|
|
15
|
+
from snowflake.connector.ssl_wrap_socket import _openssl_connect
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _parse_args() -> Namespace:
|
|
19
|
+
parser = ArgumentParser(
|
|
20
|
+
prog="dump_ocsp_response",
|
|
21
|
+
description="Dump OCSP Response for the URLs (an internal tool).",
|
|
22
|
+
)
|
|
23
|
+
parser.add_argument(
|
|
24
|
+
"-o",
|
|
25
|
+
"--output-file",
|
|
26
|
+
required=False,
|
|
27
|
+
help="Dump output file",
|
|
28
|
+
type=str,
|
|
29
|
+
default=None,
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"--log-level",
|
|
33
|
+
required=False,
|
|
34
|
+
help="Log level",
|
|
35
|
+
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
36
|
+
)
|
|
37
|
+
parser.add_argument("--log-file", required=False, help="Log file", default=None)
|
|
38
|
+
parser.add_argument("urls", nargs="+", help="URLs to dump OCSP Response for")
|
|
39
|
+
return parser.parse_args()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def main() -> None:
|
|
43
|
+
"""Internal Tool: OCSP response dumper."""
|
|
44
|
+
args = _parse_args()
|
|
45
|
+
if args.log_level:
|
|
46
|
+
if args.log_file:
|
|
47
|
+
logging.basicConfig(
|
|
48
|
+
filename=args.log_file, level=getattr(logging, args.log_level.upper())
|
|
49
|
+
)
|
|
50
|
+
else:
|
|
51
|
+
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
|
52
|
+
dump_ocsp_response(args.urls, output_filename=args.output_file)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def dump_good_status(current_time, single_response) -> None:
|
|
56
|
+
print("This Update: {}".format(single_response["this_update"].native))
|
|
57
|
+
print("Next Update: {}".format(single_response["next_update"].native))
|
|
58
|
+
this_update = (
|
|
59
|
+
single_response["this_update"].native.replace(tzinfo=None) - SFOCSP.ZERO_EPOCH
|
|
60
|
+
).total_seconds()
|
|
61
|
+
next_update = (
|
|
62
|
+
single_response["next_update"].native.replace(tzinfo=None) - SFOCSP.ZERO_EPOCH
|
|
63
|
+
).total_seconds()
|
|
64
|
+
|
|
65
|
+
tolerable_validity = SFOCSP._calculate_tolerable_validity(this_update, next_update)
|
|
66
|
+
print(
|
|
67
|
+
"Tolerable Update: {}".format(
|
|
68
|
+
strftime("%Y%m%d%H%M%SZ", gmtime(next_update + tolerable_validity))
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
if SFOCSP._is_validaity_range(current_time, this_update, next_update):
|
|
72
|
+
print("OK")
|
|
73
|
+
else:
|
|
74
|
+
print(SFOCSP._validity_error_message(current_time, this_update, next_update))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def dump_revoked_status(single_response) -> None:
|
|
78
|
+
revoked_info = single_response["cert_status"]
|
|
79
|
+
revocation_time = revoked_info.native["revocation_time"]
|
|
80
|
+
revocation_reason = revoked_info.native["revocation_reason"]
|
|
81
|
+
print(
|
|
82
|
+
"Revoked Time: {}".format(
|
|
83
|
+
revocation_time.strftime(SFOCSP.OUTPUT_TIMESTAMP_FORMAT)
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
print(f"Revoked Reason: {revocation_reason}")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def dump_ocsp_response(urls, output_filename):
|
|
90
|
+
ocsp = SFOCSP()
|
|
91
|
+
for url in urls:
|
|
92
|
+
if not url.startswith("http"):
|
|
93
|
+
url = "https://" + url
|
|
94
|
+
parsed_url = urlsplit(url)
|
|
95
|
+
hostname = parsed_url.hostname
|
|
96
|
+
port = parsed_url.port or 443
|
|
97
|
+
connection = _openssl_connect(hostname, port)
|
|
98
|
+
cert_data = ocsp.extract_certificate_chain(connection)
|
|
99
|
+
current_time = int(time.time())
|
|
100
|
+
print(f"Target URL: {url}")
|
|
101
|
+
print(
|
|
102
|
+
"Current Time: {}".format(strftime("%Y%m%d%H%M%SZ", gmtime(current_time)))
|
|
103
|
+
)
|
|
104
|
+
for issuer, subject in cert_data:
|
|
105
|
+
_, _ = ocsp.create_ocsp_request(issuer, subject)
|
|
106
|
+
_, _, _, cert_id, ocsp_response_der = ocsp.validate_by_direct_connection(
|
|
107
|
+
issuer, subject, OCSPTelemetryData()
|
|
108
|
+
)
|
|
109
|
+
ocsp_response = asn1crypto_ocsp.OCSPResponse.load(ocsp_response_der)
|
|
110
|
+
print("------------------------------------------------------------")
|
|
111
|
+
print(f"Subject Name: {subject.subject.native}")
|
|
112
|
+
print(f"Issuer Name: {issuer.subject.native}")
|
|
113
|
+
print(f"OCSP URI: {subject.ocsp_urls}")
|
|
114
|
+
print(f"CRL URI: {subject.crl_distribution_points[0].native}")
|
|
115
|
+
print(f"Issuer Name Hash: {subject.issuer.sha1}")
|
|
116
|
+
print(f"Issuer Key Hash: {issuer.public_key.sha1}")
|
|
117
|
+
print(f"Serial Number: {subject.serial_number}")
|
|
118
|
+
print("Response Status: {}".format(ocsp_response["response_status"].native))
|
|
119
|
+
basic_ocsp_response = ocsp_response.basic_ocsp_response
|
|
120
|
+
tbs_response_data = basic_ocsp_response["tbs_response_data"]
|
|
121
|
+
print("Responder ID: {}".format(tbs_response_data["responder_id"].name))
|
|
122
|
+
current_time = int(time.time())
|
|
123
|
+
for single_response in tbs_response_data["responses"]:
|
|
124
|
+
cert_status = single_response["cert_status"].name
|
|
125
|
+
if cert_status == "good":
|
|
126
|
+
dump_good_status(current_time, single_response)
|
|
127
|
+
elif cert_status == "revoked":
|
|
128
|
+
dump_revoked_status(single_response)
|
|
129
|
+
else:
|
|
130
|
+
print("Unknown")
|
|
131
|
+
print("")
|
|
132
|
+
|
|
133
|
+
if output_filename:
|
|
134
|
+
SFOCSP.OCSP_CACHE.write_ocsp_response_cache_file(ocsp, output_filename)
|
|
135
|
+
return SFOCSP.OCSP_CACHE
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
main()
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from glob import glob
|
|
8
|
+
from os import path
|
|
9
|
+
from time import gmtime, strftime, time
|
|
10
|
+
|
|
11
|
+
from asn1crypto import core, ocsp
|
|
12
|
+
from asn1crypto.x509 import Certificate
|
|
13
|
+
from OpenSSL.crypto import FILETYPE_ASN1, dump_certificate
|
|
14
|
+
|
|
15
|
+
from snowflake.connector.ocsp_asn1crypto import SnowflakeOCSPAsn1Crypto as SFOCSP
|
|
16
|
+
from snowflake.connector.ssl_wrap_socket import _openssl_connect
|
|
17
|
+
|
|
18
|
+
ZERO_EPOCH = datetime.fromtimestamp(0, timezone.utc).replace(tzinfo=None)
|
|
19
|
+
|
|
20
|
+
OCSP_CACHE_SERVER_INTERVAL = 20 * 60 * 60 # seconds
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> None:
|
|
24
|
+
"""Internal Tool: Dump OCSP response cache file."""
|
|
25
|
+
|
|
26
|
+
def help() -> None:
|
|
27
|
+
print(
|
|
28
|
+
"Dump OCSP Response cache. This tools extracts OCSP response "
|
|
29
|
+
"cache file, i.e., ~/.cache/snowflake/ocsp_response_cache. "
|
|
30
|
+
"Note the subject name shows up if the certificate exists in "
|
|
31
|
+
"the certs directory."
|
|
32
|
+
)
|
|
33
|
+
print(
|
|
34
|
+
"""
|
|
35
|
+
Usage: {} <ocsp response cache file> <hostname file> <cert file glob pattern>
|
|
36
|
+
""".format(
|
|
37
|
+
path.basename(sys.argv[0])
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
sys.exit(2)
|
|
41
|
+
|
|
42
|
+
if len(sys.argv) < 4:
|
|
43
|
+
help()
|
|
44
|
+
sys.exit(2)
|
|
45
|
+
|
|
46
|
+
ocsp_response_cache_file = sys.argv[1]
|
|
47
|
+
if not path.isfile(ocsp_response_cache_file):
|
|
48
|
+
help()
|
|
49
|
+
sys.exit(2)
|
|
50
|
+
|
|
51
|
+
hostname_file = sys.argv[2]
|
|
52
|
+
cert_glob_pattern = sys.argv[3]
|
|
53
|
+
dump_ocsp_response_cache(ocsp_response_cache_file, hostname_file, cert_glob_pattern)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def raise_old_cache_exception(current_time, created_on, name, serial_number):
|
|
57
|
+
raise Exception(
|
|
58
|
+
"ERROR: OCSP response cache is too old. created_on "
|
|
59
|
+
"should be newer than {}: "
|
|
60
|
+
"name: {}, serial_number: {}, "
|
|
61
|
+
"current_time: {}, created_on: {}".format(
|
|
62
|
+
strftime(
|
|
63
|
+
SFOCSP.OUTPUT_TIMESTAMP_FORMAT,
|
|
64
|
+
gmtime(current_time - OCSP_CACHE_SERVER_INTERVAL),
|
|
65
|
+
),
|
|
66
|
+
name,
|
|
67
|
+
serial_number,
|
|
68
|
+
strftime(SFOCSP.OUTPUT_TIMESTAMP_FORMAT, gmtime(current_time)),
|
|
69
|
+
strftime(SFOCSP.OUTPUT_TIMESTAMP_FORMAT, gmtime(created_on)),
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def raise_outdated_validity_exception(
|
|
75
|
+
current_time, name, serial_number, this_update, next_update
|
|
76
|
+
):
|
|
77
|
+
raise Exception(
|
|
78
|
+
"ERROR: OCSP response cache include "
|
|
79
|
+
"outdated data: "
|
|
80
|
+
"name: {}, serial_number: {}, "
|
|
81
|
+
"current_time: {}, this_update: {}, "
|
|
82
|
+
"next_update: {}".format(
|
|
83
|
+
name,
|
|
84
|
+
serial_number,
|
|
85
|
+
strftime(SFOCSP.OUTPUT_TIMESTAMP_FORMAT, gmtime(current_time)),
|
|
86
|
+
this_update.strftime(SFOCSP.OUTPUT_TIMESTAMP_FORMAT),
|
|
87
|
+
next_update.strftime(SFOCSP.OUTPUT_TIMESTAMP_FORMAT),
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def dump_ocsp_response_cache(
|
|
93
|
+
ocsp_response_cache_file, hostname_file, cert_glob_pattern
|
|
94
|
+
) -> None:
|
|
95
|
+
"""Dump OCSP response cache contents.
|
|
96
|
+
|
|
97
|
+
Show the subject name as well if the subject is included in the certificate files.
|
|
98
|
+
"""
|
|
99
|
+
sfocsp = SFOCSP()
|
|
100
|
+
s_to_n = _fetch_certs(hostname_file)
|
|
101
|
+
s_to_n1 = _serial_to_name(sfocsp, cert_glob_pattern)
|
|
102
|
+
s_to_n.update(s_to_n1)
|
|
103
|
+
|
|
104
|
+
SFOCSP.OCSP_CACHE.read_ocsp_response_cache_file(sfocsp, ocsp_response_cache_file)
|
|
105
|
+
|
|
106
|
+
def custom_key(k):
|
|
107
|
+
# third element is Serial Number for the subject
|
|
108
|
+
serial_number = core.Integer.load(k[2])
|
|
109
|
+
return int(serial_number.native)
|
|
110
|
+
|
|
111
|
+
output = {}
|
|
112
|
+
ocsp_validation_cache = SFOCSP.OCSP_CACHE.CACHE
|
|
113
|
+
for hkey in sorted(ocsp_validation_cache, key=custom_key):
|
|
114
|
+
json_key = sfocsp.encode_cert_id_base64(hkey)
|
|
115
|
+
|
|
116
|
+
serial_number = core.Integer.load(hkey[2]).native
|
|
117
|
+
if int(serial_number) in s_to_n:
|
|
118
|
+
name = s_to_n[int(serial_number)]
|
|
119
|
+
else:
|
|
120
|
+
name = "Unknown"
|
|
121
|
+
output[json_key] = {
|
|
122
|
+
"serial_number": format(serial_number, "d"),
|
|
123
|
+
"name": name,
|
|
124
|
+
}
|
|
125
|
+
value = ocsp_validation_cache[hkey]
|
|
126
|
+
cache = value[1]
|
|
127
|
+
ocsp_response = ocsp.OCSPResponse.load(cache)
|
|
128
|
+
basic_ocsp_response = ocsp_response.basic_ocsp_response
|
|
129
|
+
|
|
130
|
+
tbs_response_data = basic_ocsp_response["tbs_response_data"]
|
|
131
|
+
|
|
132
|
+
current_time = int(time())
|
|
133
|
+
for single_response in tbs_response_data["responses"]:
|
|
134
|
+
created_on = int(value[0])
|
|
135
|
+
produce_at = tbs_response_data["produced_at"].native
|
|
136
|
+
this_update = single_response["this_update"].native
|
|
137
|
+
next_update = single_response["next_update"].native
|
|
138
|
+
if current_time - OCSP_CACHE_SERVER_INTERVAL > created_on:
|
|
139
|
+
raise_old_cache_exception(current_time, created_on, name, serial_number)
|
|
140
|
+
|
|
141
|
+
next_update_utc = (
|
|
142
|
+
next_update.replace(tzinfo=None) - ZERO_EPOCH
|
|
143
|
+
).total_seconds()
|
|
144
|
+
this_update_utc = (
|
|
145
|
+
this_update.replace(tzinfo=None) - ZERO_EPOCH
|
|
146
|
+
).total_seconds()
|
|
147
|
+
|
|
148
|
+
if current_time > next_update_utc or current_time < this_update_utc:
|
|
149
|
+
raise_outdated_validity_exception(
|
|
150
|
+
current_time, name, serial_number, this_update, next_update
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
output[json_key]["created_on"] = strftime(
|
|
154
|
+
SFOCSP.OUTPUT_TIMESTAMP_FORMAT, gmtime(created_on)
|
|
155
|
+
)
|
|
156
|
+
output[json_key]["produce_at"] = str(produce_at)
|
|
157
|
+
output[json_key]["this_update"] = str(this_update)
|
|
158
|
+
output[json_key]["next_update"] = str(next_update)
|
|
159
|
+
print(json.dumps(output))
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _serial_to_name(sfocsp, cert_glob_pattern):
|
|
163
|
+
"""Creates a map table from serial number to name."""
|
|
164
|
+
map_serial_to_name = {}
|
|
165
|
+
for cert_file in glob(cert_glob_pattern):
|
|
166
|
+
cert_map = {}
|
|
167
|
+
sfocsp.read_cert_bundle(cert_file, cert_map)
|
|
168
|
+
cert_data = sfocsp.create_pair_issuer_subject(cert_map)
|
|
169
|
+
|
|
170
|
+
for _, subject in cert_data:
|
|
171
|
+
map_serial_to_name[subject.serial_number] = subject.subject.native
|
|
172
|
+
|
|
173
|
+
return map_serial_to_name
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _fetch_certs(hostname_file):
|
|
177
|
+
with open(hostname_file) as f:
|
|
178
|
+
hostnames = f.read().split("\n")
|
|
179
|
+
|
|
180
|
+
map_serial_to_name = {}
|
|
181
|
+
for h in hostnames:
|
|
182
|
+
if not h:
|
|
183
|
+
continue
|
|
184
|
+
connection = _openssl_connect(h, 443)
|
|
185
|
+
for cert_openssl in connection.get_peer_cert_chain():
|
|
186
|
+
cert_der = dump_certificate(FILETYPE_ASN1, cert_openssl)
|
|
187
|
+
cert = Certificate.load(cert_der)
|
|
188
|
+
map_serial_to_name[cert.serial_number] = cert.subject.native
|
|
189
|
+
|
|
190
|
+
return map_serial_to_name
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
if __name__ == "__main__":
|
|
194
|
+
main()
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from socket import gaierror, gethostbyname_ex
|
|
4
|
+
|
|
5
|
+
from asn1crypto import ocsp
|
|
6
|
+
from OpenSSL.crypto import FILETYPE_ASN1, dump_certificate
|
|
7
|
+
|
|
8
|
+
from ..compat import urlsplit
|
|
9
|
+
from ..ssl_wrap_socket import _openssl_connect
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def probe_connection(url):
|
|
13
|
+
parsed_url = urlsplit(url)
|
|
14
|
+
|
|
15
|
+
# DNS lookup
|
|
16
|
+
try:
|
|
17
|
+
actual_hostname, aliases, ips = gethostbyname_ex(parsed_url.hostname)
|
|
18
|
+
ret = {
|
|
19
|
+
"url": url,
|
|
20
|
+
"input_hostname": parsed_url.hostname,
|
|
21
|
+
"actual_hostname": actual_hostname,
|
|
22
|
+
"aliases": aliases,
|
|
23
|
+
"ips": ips,
|
|
24
|
+
}
|
|
25
|
+
except gaierror as e:
|
|
26
|
+
return {"err:": e}
|
|
27
|
+
connection = _openssl_connect(parsed_url.hostname, parsed_url.port)
|
|
28
|
+
|
|
29
|
+
# certificates
|
|
30
|
+
certificates = []
|
|
31
|
+
for cert_openssl in connection.get_peer_cert_chain():
|
|
32
|
+
cert_der = dump_certificate(FILETYPE_ASN1, cert_openssl)
|
|
33
|
+
cert = ocsp.Certificate.load(cert_der)
|
|
34
|
+
ocsp_uris = cert.ocsp_urls
|
|
35
|
+
|
|
36
|
+
if len(ocsp_uris) == 1:
|
|
37
|
+
parsed_ocsp_url = urlsplit(ocsp_uris[0])
|
|
38
|
+
|
|
39
|
+
# DNS lookup for OCSP server
|
|
40
|
+
try:
|
|
41
|
+
actual_hostname, aliases, ips = gethostbyname_ex(
|
|
42
|
+
parsed_ocsp_url.hostname
|
|
43
|
+
)
|
|
44
|
+
ocsp_status = {
|
|
45
|
+
"input_url": ocsp_uris[0],
|
|
46
|
+
"actual_hostname": actual_hostname,
|
|
47
|
+
"aliases": aliases,
|
|
48
|
+
"ips": ips,
|
|
49
|
+
}
|
|
50
|
+
except gaierror as e:
|
|
51
|
+
ocsp_status = {
|
|
52
|
+
"input_url": ocsp_uris[0],
|
|
53
|
+
"error": e,
|
|
54
|
+
}
|
|
55
|
+
else:
|
|
56
|
+
ocsp_status = {}
|
|
57
|
+
|
|
58
|
+
certificates.append(
|
|
59
|
+
{
|
|
60
|
+
"hash": cert.subject.sha1,
|
|
61
|
+
"name": cert.subject.native,
|
|
62
|
+
"issuer": cert.issuer.native,
|
|
63
|
+
"serial_number": cert.serial_number,
|
|
64
|
+
"ocsp": ocsp_status,
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
ret["certificates"] = certificates
|
|
69
|
+
return ret
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import urllib.parse
|
|
5
|
+
from logging import getLogger
|
|
6
|
+
from typing import Iterable
|
|
7
|
+
|
|
8
|
+
from .constants import _TOP_LEVEL_DOMAIN_REGEX
|
|
9
|
+
from .vendored import requests
|
|
10
|
+
|
|
11
|
+
logger = getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
URL_VALIDATOR = re.compile(
|
|
15
|
+
"^http(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z@:])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\&\\(\\)\\/\\\\\\+&%\\$#_=@:]*)?$"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def is_valid_url(url: str) -> bool:
|
|
20
|
+
"""Confirms if the provided URL is a valid HTTP/ HTTPs URL
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
url: the URL that needs to be validated
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
true/ false depending on whether the URL is valid or not
|
|
27
|
+
"""
|
|
28
|
+
return bool(URL_VALIDATOR.match(url))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def url_encode_str(target: str | None) -> str:
|
|
32
|
+
"""Converts a target string into escaped URL safe string
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
target: string to be URL encoded
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
URL encoded string
|
|
39
|
+
"""
|
|
40
|
+
if target is None:
|
|
41
|
+
logger.debug("The string to be URL encoded is None")
|
|
42
|
+
return ""
|
|
43
|
+
return urllib.parse.quote_plus(target, safe="")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def extract_top_level_domain_from_hostname(hostname: str | None = None) -> str:
|
|
47
|
+
if not hostname:
|
|
48
|
+
return "com"
|
|
49
|
+
# RFC1034 for TLD spec, and https://data.iana.org/TLD/tlds-alpha-by-domain.txt for full TLD list
|
|
50
|
+
match = re.search(_TOP_LEVEL_DOMAIN_REGEX, hostname)
|
|
51
|
+
return (match.group(0)[1:] if match else "com").lower()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def should_bypass_proxies(url: str | bytes, no_proxy: Iterable[str] | None) -> bool:
|
|
55
|
+
return requests.utils.should_bypass_proxies(url, no_proxy)
|