diff --git a/src/python/WMCore/Services/pycurl_manager.py b/src/python/WMCore/Services/pycurl_manager.py index 94f413004e..b1433b9afd 100644 --- a/src/python/WMCore/Services/pycurl_manager.py +++ b/src/python/WMCore/Services/pycurl_manager.py @@ -67,23 +67,43 @@ def __init__(self, config=None, logger=None): self.maxredirs = config.get('maxredirs', 5) self.logger = logger if logger else logging.getLogger() + def encode_params(self, params, verb, doseq): + """ Encode request parameters for usage with the 4 verbs. + Assume params is alrady encoded if it is a string and + uses a different encoding depending on the HTTP verb + (either json.dumps or urllib.urlencode) + """ + #data is already encoded, just return it + if isinstance(params, basestring): + return params + + #data is not encoded, we need to do that + if verb in ['GET', 'HEAD']: + if params: + encoded_data = urllib.urlencode(params, doseq=doseq) + else: + return '' + else: + if params: + encoded_data = json.dumps(params) + else: + return {} + + return encoded_data + def set_opts(self, curl, url, params, headers, ckey=None, cert=None, capath=None, verbose=None, verb='GET', doseq=True, cainfo=None): """Set options for given curl object, params should be a dictionary""" - if params == None: - params = {} - if not isinstance(params, dict): - raise TypeError("pycurl parameters should be passed as dictionary") + if not (isinstance(params, dict) or isinstance(params, basestring) or params==None): + raise TypeError("pycurl parameters should be passed as dictionary or an (encoded) string") curl.setopt(pycurl.NOSIGNAL, self.nosignal) curl.setopt(pycurl.TIMEOUT, self.timeout) curl.setopt(pycurl.CONNECTTIMEOUT, self.connecttimeout) curl.setopt(pycurl.FOLLOWLOCATION, self.followlocation) curl.setopt(pycurl.MAXREDIRS, self.maxredirs) - if params: - encoded_data = urllib.urlencode(params, doseq=doseq) - else: - encoded_data = '' + encoded_data = self.encode_params(params, verb, doseq) + if verb == 'GET': if encoded_data: url = url + '?' + encoded_data @@ -95,13 +115,13 @@ def set_opts(self, curl, url, params, headers, curl.setopt(pycurl.NOBODY, True) elif verb == 'POST': curl.setopt(pycurl.POST, 1) - if params: - curl.setopt(pycurl.POSTFIELDS, json.dumps(params)) + if encoded_data: + curl.setopt(pycurl.POSTFIELDS, encoded_data) elif verb == 'DELETE' or verb == 'PUT': curl.setopt(pycurl.CUSTOMREQUEST, verb) curl.setopt(pycurl.HTTPHEADER, ['Transfer-Encoding: chunked']) - if params: - curl.setopt(pycurl.POSTFIELDS, json.dumps(params)) + if encoded_data: + curl.setopt(pycurl.POSTFIELDS, encoded_data) else: raise Exception('Unsupported HTTP method "%s"' % verb)