diff --git a/qingstor/sdk/config.py b/qingstor/sdk/config.py index 2ffc625..5a670a0 100644 --- a/qingstor/sdk/config.py +++ b/qingstor/sdk/config.py @@ -33,6 +33,7 @@ '# Valid levels are "debug", "info", "warn", "error", and "fatal".\n' 'log_level: "warn"\n' 'enable_virtual_host_style: false\n' + 'enable_dual_stack: false\n' 'zone: ""\n' ) diff --git a/qingstor/sdk/request.py b/qingstor/sdk/request.py index 3dd9e5f..25e66db 100644 --- a/qingstor/sdk/request.py +++ b/qingstor/sdk/request.py @@ -23,6 +23,8 @@ from .build import Builder from .utils.helper import url_quote +import requests.packages.urllib3.util.connection as urllib3_cn +import socket class Request: @@ -34,6 +36,9 @@ def __init__(self, config, operation): self.secret_access_key = config.secret_access_key self.logger = logging.getLogger("qingstor-sdk") self.enable_virtual_host_style = config.enable_virtual_host_style + urllib3_cn.allowed_gai_family = rewrite_allowed_gai_family( + config.enable_dual_stack, self.req.headers["Host"] + ) def __repr__(self): return "" % self.req.method @@ -176,3 +181,29 @@ def is_sub_resource(self, key): "replication", "append", "position", "cname" ] return key in keys_map + + +def has_ipv6(host): + """ Returns True if the system resolves host to an IPv6 address by default. """ + resolves_to_ipv6 = False + try: + for res in socket.getaddrinfo(host, None, socket.AF_UNSPEC): + af, _, _, _, _ = res + if af == socket.AF_INET6: + resolves_to_ipv6 = True + except socket.gaierror: + pass + return resolves_to_ipv6 + + +def rewrite_allowed_gai_family(use_ipv6, host): + """ This function is designed to control the choice of address family. """ + def allowed_gai_family(): + family = socket.AF_INET + if has_ipv6(host): + if use_ipv6: + family = socket.AF_INET6 + else: + family = socket.AF_UNSPEC + return family + return allowed_gai_family