Skip to content
Snippets Groups Projects
Commit 809bc174 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 c1a25b88
No related branches found
No related tags found
No related merge requests found
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
# No Ganeti-specific modules should be imported. The RAPI client is supposed to # No Ganeti-specific modules should be imported. The RAPI client is supposed to
# be standalone. # be standalone.
import sys
import httplib import httplib
import urllib2 import urllib2
import logging import logging
...@@ -198,6 +199,10 @@ class _HTTPSConnectionOpenSSL(httplib.HTTPSConnection): ...@@ -198,6 +199,10 @@ class _HTTPSConnectionOpenSSL(httplib.HTTPSConnection):
"""HTTPS Connection handler that verifies the SSL certificate. """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): def __init__(self, *args, **kwargs):
"""Initializes this class. """Initializes this class.
...@@ -236,7 +241,35 @@ class _HTTPSConnectionOpenSSL(httplib.HTTPSConnection): ...@@ -236,7 +241,35 @@ class _HTTPSConnectionOpenSSL(httplib.HTTPSConnection):
ssl = OpenSSL.SSL.Connection(ctx, sock) ssl = OpenSSL.SSL.Connection(ctx, sock)
ssl.connect((self.host, self.port)) ssl.connect((self.host, self.port))
self.sock = httplib.FakeSocket(sock, ssl) 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): class _HTTPSHandler(urllib2.HTTPSHandler):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment