5 from cStringIO import StringIO
9 # a pycurl-based replacement for the previous version that relied on forking curl
13 def retrieve(url, cacert=None, postdata=None, timeout=90):
15 curl.setopt(pycurl.URL,url)
16 if debug: logger.verbose('curlwrapper: new instance %r -> %s'%(curl,url))
18 # reproduce --fail from the previous version
19 curl.setopt(pycurl.FAILONERROR,1)
20 # don't want curl sending any signals
21 curl.setopt(pycurl.NOSIGNAL, 1)
23 # do not follow location when attempting to download a file
24 # curl.setopt(pycurl.FOLLOWLOCATION, 0)
26 # store result on the fly
28 curl.setopt(pycurl.WRITEFUNCTION,buffer.write)
32 curl.setopt(pycurl.CONNECTTIMEOUT, timeout)
33 curl.setopt(pycurl.TIMEOUT, timeout)
34 if debug: logger.verbose('curlwrapper: timeout set to %r'%timeout)
38 curl.setopt(pycurl.CAINFO, cacert)
39 curl.setopt(pycurl.SSL_VERIFYPEER, 2)
40 if debug: logger.verbose('curlwrapper: using cacert %s'%cacert)
42 curl.setopt(pycurl.SSL_VERIFYPEER, 0)
46 if isinstance(postdata,dict):
47 postfields = urllib.urlencode(postdata)
48 if debug: logger.verbose('curlwrapper: using encoded postfields %s'%postfields)
51 if debug: logger.verbose('curlwrapper: using raw postfields %s'%postfields)
52 curl.setopt(pycurl.POSTFIELDS, postfields)
57 errcode = curl.getinfo(pycurl.HTTP_CODE)
59 if debug: logger.verbose('curlwrapper: closing pycurl object')
62 # check the code, return 1 if successfull
64 raise xmlrpclib.ProtocolError (url,errcode, "SSL certificate validation failed", postdata)
66 raise xmlrpclib.ProtocolError (url,errcode, "http error %d"%errcode, postdata)
68 except pycurl.error, err:
70 raise xmlrpclib.ProtocolError(url, errno, "curl error %d: '%s'\n" %(errno,curl.errstr()),postdata )
72 return buffer.getvalue()