Force requests to use IPv4 / IPv6

后端 未结 6 913
走了就别回头了
走了就别回头了 2020-12-01 14:58

How to force the requests library to use a specific internet protocol version for a get request? Or can this be achieved better with another method in Python? I

6条回答
  •  悲哀的现实
    2020-12-01 15:14

    I've written a runtime patch for requests+urllib3+socket that allows passing the required address family optionally and on a per-request basis.

    Unlike other solutions there is no monkeypatching involved, rather you replace your imports of requests with the patched file and it present a request-compatible interface with all exposed classes subclassed and patched and all “simple API” function reimplemented. The only noticeable difference should be the fact that there is an extra family parameter exposed that you can use to restrict the address family used during name resolution to socket.AF_INET or socket.AF_INET6. A somewhat complicated (but mostly just LoC intensive) series of strategic method overrides is then used to pass this value all the way down to the bottom layers of urllib3 where it will be used in an alternate implementation of the socket.create_connection function call.

    TL;DR usage looks like this:

    import socket
    
    from . import requests_wrapper as requests  # Use this load the patch
    
    
    # This will work (if IPv6 connectivity is available) …
    requests.get("http://ip6only.me/", family=socket.AF_INET6)
    # … but this won't
    requests.get("http://ip6only.me/", family=socket.AF_INET)
    
    # This one will fail as well
    requests.get("http://127.0.0.1/", family=socket.AF_INET6)
    
    # This one will work if you have IPv4 available
    requests.get("http://ip6.me/", family=socket.AF_INET)
    
    # This one will work on both IPv4 and IPv6 (the default)
    requests.get("http://ip6.me/", family=socket.AF_UNSPEC)
    

    Full link to the patch library (~350 LoC): https://gitlab.com/snippets/1900824

提交回复
热议问题