Commit beba56ae authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

RAPI client: Add support for Python 2.6



The httplib module used by urllib2 requires its sockets to have a
makefile() method to provide a file-like interface (or rather
file-in-Python-like) to the socket. PyOpenSSL doesn't implement
makefile() as the semantics require files to call dup(2) on the
underlying file descriptors, something not easily done on SSL sockets.

Python up to and including 2.5 have a class to simulate makefile(),
httplib.FakeSocket. With the addition of SSL support in Python 2.6, this
class was deprecated and no longer functions.

This patch adds a new, simpler wrapper class which is used in Python 2.6
and above only. It's good enough for this use.

There are general problems in these generic wrapper classes--none of
them handles SSL I/O properly. They break, for example, when the server
requests a renegotiation. This will need more work.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 70c81511
......@@ -24,6 +24,7 @@
# No Ganeti-specific modules should be imported. The RAPI client is supposed to
# be standalone.
import sys
import httplib
import urllib2
import logging
......@@ -198,6 +199,10 @@ class _HTTPSConnectionOpenSSL(httplib.HTTPSConnection):
"""HTTPS Connection handler that verifies the SSL certificate.
"""
# Python before version 2.6 had its own httplib.FakeSocket wrapper for
# sockets
_SUPPORT_FAKESOCKET = (sys.hexversion < 0x2060000)
def __init__(self, *args, **kwargs):
"""Initializes this class.
......@@ -236,7 +241,35 @@ class _HTTPSConnectionOpenSSL(httplib.HTTPSConnection):
ssl = OpenSSL.SSL.Connection(ctx, sock)
ssl.connect((self.host, self.port))
if self._SUPPORT_FAKESOCKET:
self.sock = httplib.FakeSocket(sock, ssl)
else:
self.sock = _SslSocketWrapper(ssl)
class _SslSocketWrapper(object):
def __init__(self, sock):
"""Initializes this class.
"""
self._sock = sock
def __getattr__(self, name):
"""Forward everything to underlying socket.
"""
return getattr(self._sock, name)
def makefile(self, mode, bufsize):
"""Fake makefile method.
makefile() on normal file descriptors uses dup2(2), which doesn't work with
SSL sockets and therefore is not implemented by pyOpenSSL. This fake method
works with the httplib module, but might not work for other modules.
"""
# pylint: disable-msg=W0212
return socket._fileobject(self._sock, mode, bufsize)
class _HTTPSHandler(urllib2.HTTPSHandler):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment