From 6ddf771c9f753cf052d9eb2965000021f8ecd26c Mon Sep 17 00:00:00 2001 From: lethliel Date: Thu, 13 Dec 2018 14:53:34 +0100 Subject: [PATCH] [python3] make oscssl.py python3 ready. * works also with python2 --- osc/oscssl.py | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/osc/oscssl.py b/osc/oscssl.py index 186c98db..0e7401b2 100644 --- a/osc/oscssl.py +++ b/osc/oscssl.py @@ -5,9 +5,8 @@ from __future__ import print_function -import M2Crypto.httpslib from M2Crypto.SSL.Checker import SSLVerificationError -from M2Crypto import m2, SSL +from M2Crypto import m2, SSL, httpslib import M2Crypto.m2urllib2 import socket import sys @@ -185,22 +184,28 @@ class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler): # "do_open()" and "https_open()" so that we just need to override # the small "https_open()" method...) def https_open(self, req): - host = req.get_host() + # https://docs.python.org/3.3/library/urllib.request.html#urllib.request.Request.get_host + try: # up to python-3.2 + host = req.get_host() + except AttributeError: # from python-3.3 + host = req.host if not host: - raise M2Crypto.m2urllib2.URLError('no host given: ' + req.get_full_url()) + raise M2Crypto.m2urllib2.URLError('no host given') # Our change: Check to see if we're using a proxy. # Then create an appropriate ssl-aware connection. full_url = req.get_full_url() target_host = urlparse(full_url)[1] - if (target_host != host): - h = myProxyHTTPSConnection(host = host, appname = self.appname, ssl_context = self.ctx) - # M2Crypto.ProxyHTTPSConnection.putrequest expects a fullurl - selector = full_url + if target_host != host: + request_uri = urldefrag(full_url)[0] + h = httpslib.ProxyHTTPSConnection(host=host, ssl_context=self.ctx) else: - h = myHTTPSConnection(host = host, appname = self.appname, ssl_context = self.ctx) - selector = req.get_selector() + try: # up to python-3.2 + request_uri = req.get_selector() + except AttributeError: # from python-3.3 + request_uri = req.selector + h = httpslib.HTTPSConnection(host=host, ssl_context=self.ctx) # End our change h.set_debuglevel(self._debuglevel) @@ -214,10 +219,9 @@ class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler): # request. headers["Connection"] = "close" try: - h.request(req.get_method(), selector, req.data, headers) + h.request(req.get_method(), request_uri, req.data, headers) r = h.getresponse() - except socket.error as err: # XXX what error? - err.filename = full_url + except socket.error as err: # XXX what error? raise M2Crypto.m2urllib2.URLError(err) # Pick apart the HTTPResponse object to get the addinfourl @@ -227,18 +231,26 @@ class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler): # for Windows. That adapter calls recv(), so delegate recv() # to read(). This weird wrapping allows the returned object to # have readline() and readlines() methods. - - # XXX It might be better to extract the read buffering code - # out of socket._fileobject() and into a base class. - r.recv = r.read - fp = socket._fileobject(r) + if (sys.version_info < (3, 0)): + fp = socket._fileobject(r, close=True) + else: + r._decref_socketios = lambda: None + r.ssl = h.sock.ssl + r._timeout = -1.0 + # hack to bypass python3 bug with 0 buffer size and + # http/client.py readinto method for response class + if r.length is not None and r.length == 0: + r.readinto = lambda b: 0 + r.recv_into = r.readinto + fp = socket.SocketIO(r, 'rb') resp = addinfourl(fp, r.msg, req.get_full_url()) resp.code = r.status resp.msg = r.reason return resp + class myHTTPSConnection(M2Crypto.httpslib.HTTPSConnection): def __init__(self, *args, **kwargs): self.appname = kwargs.pop('appname', 'generic')