yaocaigen / httplib2

Automatically exported from code.google.com/p/httplib2
0 stars 0 forks source link

IPv6 link local ssl connection fails #254

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Connect to a server using IPv6 link local SSL.
2. Passed the cacert.pem, client.pem, and key.pem.
3. Connections using IPv6 global and IPv4 address work fine

Instead of getting a successful connection a socket error is returned.
  File "/home/jbegin/ws/test/pyvolt/lib/httplib2/__init__.py", line 1470, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "/home/jbegin/ws/test/pyvolt/lib/httplib2/__init__.py", line 1217, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/home/jbegin/ws/test/pyvolt/lib/httplib2/__init__.py", line 1190, in _conn_request
    conn.connect()
  File "/home/jbegin/ws/test/pyvolt/lib/httplib2/__init__.py", line 943, in connect
    raise socket.error, msg
socket.error: [Errno 22] Invalid argument

Using httpli2 version 0.7.2

I was able to fix the issue by changing the sock.connect call under connect to 
for SSL to use the sockaddr instead of passing just the tuple of the host and 
the port.  SSL connections for IPv4, IPv6 global, and IPv6 link local all work 
fine now.  IPv6 link local needs a scopeid of 2 and that value is captured in 
the sockaddr variable.  My fix below:

    def connect(self):
        "Connect to a host on a given (SSL) port."

        msg = "getaddrinfo returns an empty list"
        for family, socktype, proto, canonname, sockaddr in socket.getaddrinfo(
            self.host, self.port, 0, socket.SOCK_STREAM):
            try:
                if self.proxy_info and self.proxy_info.isgood():
                    sock = socks.socksocket(family, socktype, proto)
                    sock.setproxy(*self.proxy_info.astuple())
                else:
                    sock = socket.socket(family, socktype, proto)
                    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

                if has_timeout(self.timeout):
                    sock.settimeout(self.timeout)
                #sock.connect((self.host, self.port))
                sock.connect(sockaddr)
                self.sock =_ssl_wrap_socket(

Original issue reported on code.google.com by jebeginm...@gmail.com on 29 Mar 2013 at 5:37