Export to GitHub

salesforce-python-toolkit - issue #3

Login Uses Proxy but create() does not


Posted on Apr 19, 2010 by Swift Wombat

Confirmed that the WSDL contains only http:// urls and that HTTPS requirement is disabled in my salesforce org.

Sample code:

!/usr/bin/python

import sforce from sforce.enterprise import SforceEnterpriseClient

h = SforceEnterpriseClient('enterprise.wsdl', proxy={'http':'http://proxyhost:8080'}) lr = h.login('user','pass','token')

print lr

arraymetric = h.generateObject('CustomObjectc__c') print arraymetric result = h.create(arraymetric) print result h.logout()

Stangely enough, when using the proxy, the login() call suceeds (print of lr is clean and shows the write userID, a reasonable sessionID, etc).
However, I then try a create call it stalls, eventually giving me a traceback inducating that it couldn't reach the service via https directly (not via proxy):

File "GetAndUploadFreeSpace.py", line 22, in ? result = h.create(arraymetric) File "/usr/lib/python2.4/site-packages/sforce/enterprise.py", line 33, in create return super(SforceEnterpriseClient, self).create(xml) File "/usr/lib/python2.4/site-packages/sforce/base.py", line 361, in create return self._handleResultTyping(self._sforce.service.create(sObjects)) File "/usr/lib/python2.4/site-packages/suds/client.py", line 539, in call return client.invoke(args, kwargs) File "/usr/lib/python2.4/site-packages/suds/client.py", line 598, in invoke result = self.send(msg) File "/usr/lib/python2.4/site-packages/suds/client.py", line 623, in send reply = transport.send(request) File "/usr/lib/python2.4/site-packages/suds/transport/https.py", line 64, in send return HttpTransport.send(self, request) File "/usr/lib/python2.4/site-packages/suds/transport/http.py", line 77, in send fp = self.u2open(u2request) File "/usr/lib/python2.4/site-packages/suds/transport/http.py", line 116, in u2open return url.open(u2request) File "/usr/lib/python2.4/urllib2.py", line 358, in open response = self._open(req, data) File "/usr/lib/python2.4/urllib2.py", line 376, in _open '_open', req) File "/usr/lib/python2.4/urllib2.py", line 337, in _call_chain result = func(*args) File "/usr/lib/python2.4/urllib2.py", line 1029, in https_open return self.do_open(httplib.HTTPSConnection, req) File "/usr/lib/python2.4/urllib2.py", line 996, in do_open raise URLError(err) urllib2.URLError: <urlopen error timed out>

I wouldn't expect it to be able to hit that directly, thats why i have a proxy :). Why is is automatically switching to HTTPS on me?

Comment #1

Posted on Apr 19, 2010 by Quick Cat

Salesforce returns a new location after the login() call, and even though my internal call to the SOAP client to change it shouldn't have any effect on the proxy, I bet it's being unset. Could you try the following? In base.py, in _setEndpoint, after this line

self._location = location

could you try adding

self._sforce.set_options(proxy = {{'http':'http://proxyhost:8080'})

and see if all subsequent calls work?

If that fixes it, I'll add a quick commit, and if that is the issue, I'll file it with Suds, as that's not the correct behavior IMO.

Thanks for reporting this!

Comment #2

Posted on Apr 19, 2010 by Quick Cat

As in your comment, Google Code has stripped the closing curly brace + closing paren for some reason in this line:

self._sforce.set_options(proxy = {'http':'http://proxyhost:8080'

Comment #3

Posted on Apr 19, 2010 by Swift Wombat

That didn't actually help, but it got me to figure out the problem: I note that what salesforce is sending back for location is:

https://na7-api.salesforce.com/services/Soap/c/18.0/ORGID

Which sforceenterpriseclient then passes off the SUDS, which notes that there is no https proxy in the dictionary, and goes after it directly.

I confirmed that if I manually set the location in setEndpoint to my correct URL (override anythign you get back from salesforce, note the change from https to http):

location = 'http://na7-api.salesforce.com/services/Soap/c/18.0/ORGID' 

that it does indeed work correctly and thru the proxy.

I'm not really sure who the bug lays with then - it would seem to me that salesforce should probably send back a URL with the same protocol as that with which it was access (http), and that perhaps the Toolkit should recognize that salesforce is being stupid and munge things as needed.

Thoughts?

Comment #4

Posted on Apr 19, 2010 by Swift Wombat

If you are interested in a fix, I've attached a modified copy of base.py that implements a forceHTTP keyword arg that does a simple string replacement that fixes this issue.

Attachments

Comment #5

Posted on Apr 19, 2010 by Quick Cat

Well, the initial request is also going over HTTPS, and it works transparently with your HTTP proxy... I'm not sure why changing the location causes the requests not to proxy, but if the bug is in Suds, a hack like re-instantiating the SOAP client with the new endpoint may be necessary. I'll look into this in the next couple of days and report back.

Comment #6

Posted on Apr 19, 2010 by Quick Cat

Thanks for the fix, I'd really prefer to get this sorted though, as I don't want anyone to send their data over HTTP just to work around this issue.

Comment #7

Posted on Apr 19, 2010 by Swift Wombat

Fair enough.

Thanks for the help.

Status: New

Labels:
Type-Defect Priority-Medium