X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=curlwrapper.py;h=cf132b79ad1ad17a72e3d110415f0fa19171bd84;hb=d3a3b2d3ea98e72183d1cb5497c38badaa0c5863;hp=ce273a304968ec9683ab3f75ced80641a9a5c8e8;hpb=191f762aee7f7412e3d3b3840de914b9326aa888;p=nodemanager.git diff --git a/curlwrapper.py b/curlwrapper.py index ce273a3..cf132b7 100644 --- a/curlwrapper.py +++ b/curlwrapper.py @@ -1,16 +1,64 @@ -from subprocess import PIPE, Popen - - -class CurlException(Exception): pass - -def retrieve(url, postdata=None): - options = ('/usr/bin/curl', '--cacert', '/usr/boot/cacert.pem') - if postdata: options += ('--data', '@-') - p = Popen(options + (url,), stdin=PIPE, stdout=PIPE, stderr=PIPE) - if postdata: p.stdin.write(postdata) - p.stdin.close() - data = p.stdout.read() - err = p.stderr.read() - rc = p.wait() - if rc != 0: raise CurlException(err) - else: return data +import os +import xmlrpclib +import urllib +import pycurl +from cStringIO import StringIO + +import logger + +# a pycurl-based replacement for the previous version that relied on forking curl + +def retrieve(url, cacert=None, postdata=None, timeout=90): + curl= pycurl.Curl() + curl.setopt(pycurl.URL,url) + + # reproduce --fail from the previous version + curl.setopt(pycurl.FAILONERROR,1) + # don't want curl sending any signals + curl.setopt(pycurl.NOSIGNAL, 1) + + # do not follow location when attempting to download a file + # curl.setopt(pycurl.FOLLOWLOCATION, 0) + + # store result on the fly + buffer=StringIO() + curl.setopt(pycurl.WRITEFUNCTION,buffer.write) + + # set timeout + if timeout: + curl.setopt(pycurl.CONNECTTIMEOUT, timeout) + curl.setopt(pycurl.TIMEOUT, timeout) + + # set cacert + if cacert: + curl.setopt(pycurl.CAINFO, cacert) + curl.setopt(pycurl.SSL_VERIFYPEER, 2) + else: + curl.setopt(pycurl.SSL_VERIFYPEER, 0) + + # set postdata + if postdata: + if isinstance(postdata,dict): + postfields = urllib.urlencode(postdata) + else: + postfields=postdata + curl.setopt(pycurl.POSTFIELDS, postfields) + + # go + try: + curl.perform() + + errcode = curl.getinfo(pycurl.HTTP_CODE) + curl.close() + + # check the code, return 1 if successfull + if errcode == 60: + raise xmlrpclib.ProtocolError (url,errcode, "SSL certificate validation failed", postdata) + elif errcode != 200: + raise xmlrpclib.ProtocolError (url,errcode, "http error %d"%errcode, postdata) + + except pycurl.error, err: + errno, errstr = err + raise xmlrpclib.ProtocolError(url, errno, "curl error %d: '%s'\n" %(errno,errstr),postdata ) + + return buffer.getvalue()