Suds无视代理设置

时间:2012-09-13 20:51:39

标签: python salesforce suds

我正在尝试使用salesforce-python-toolkit对Salesforce API进行Web服务调用,但是我无法让客户端通过代理。由于工具包是基于suds的,我尝试使用suds本身来看看我是否可以让它尊重那里的代理设置,但它也没有用。

在OS X 10.7(python 2.7)和ubuntu 12.04上测试了泡沫0.3.9。

我做的一个示例请求最终没有通过代理(只是在本地运行的burp或charles代理):

import suds
ws = suds.client.Client('file://sandbox.xml',proxy={'http':'http://localhost:8888'})
ws.service.login('user','pass')

我已尝试使用代理进行各种操作 - 使用FQDN删除http://,使用IP。我已经逐步完成了pdb中的代码并看到它设置了代理选项。我也尝试在没有代理的情况下实例化客户端,然后设置它:     ws.set_options(代理= { 'HTTP': '的http://本地主机:8888'})

suds不再使用代理吗?我没有看到它直接在http://jortel.fedorapeople.org/suds/doc/suds.options.Options-class.html列出,但我确实在传输中看到了它。我是否需要通过运输设置不同的方式?当我走进pdb时,它确实看起来像是在使用传输,但我不确定如何。

谢谢!

5 个答案:

答案 0 :(得分:14)

我在freenode上进入了#suds,Xelnor / rbarrois提供了一个很好的答案!显然,suds中的自定义映射会覆盖urllib2使用系统配置环境变量的行为。此解决方案现在依赖于相应地设置http_proxy / https_proxy / no_proxy环境变量。

我希望这可以帮助其他人遇到代理和suds(或其他使用suds的库)的问题。 https://gist.github.com/3721801

from suds.transport.http import HttpTransport as SudsHttpTransport 


class WellBehavedHttpTransport(SudsHttpTransport): 
    """HttpTransport which properly obeys the ``*_proxy`` environment variables.""" 

    def u2handlers(self): 
        """Return a list of specific handlers to add. 

        The urllib2 logic regarding ``build_opener(*handlers)`` is: 

        - It has a list of default handlers to use 

        - If a subclass or an instance of one of those default handlers is given 
            in ``*handlers``, it overrides the default one. 

        Suds uses a custom {'protocol': 'proxy'} mapping in self.proxy, and adds 
        a ProxyHandler(self.proxy) to that list of handlers. 
        This overrides the default behaviour of urllib2, which would otherwise 
        use the system configuration (environment variables on Linux, System 
        Configuration on Mac OS, ...) to determine which proxies to use for 
        the current protocol, and when not to use a proxy (no_proxy). 

        Thus, passing an empty list will use the default ProxyHandler which 
        behaves correctly. 
        """ 
        return []

client = suds.client.Client(my_wsdl, transport=WellBehavedHttpTransport())

答案 1 :(得分:4)

我认为你可以使用如下所示的urllib2开启器。

import suds
t = suds.transport.http.HttpTransport()
proxy = urllib2.ProxyHandler({'http': 'http://localhost:8888'})
opener = urllib2.build_opener(proxy)
t.urlopener = opener
ws = suds.client.Client('file://sandbox.xml', transport=t)

答案 2 :(得分:3)

我实际上可以通过做两件事来实现它:

  • 确保http以及https的代理字典中有密钥。
  • 在创建客户端后使用set_options设置代理。

所以,我的相关代码如下所示:

self.suds_client = suds.client.Client(wsdl) self.suds_client.set_options(proxy={'http': 'http://localhost:8888', 'https': 'http://localhost:8888'})

答案 3 :(得分:2)

我使用Suds有多个问题,即使我的代理配置正确我也无法连接到端点wsdl。在花费大量时间尝试制定解决方法后,我决定给一次soap2py - https://code.google.com/p/pysimplesoap/wiki/SoapClient

直接蝙蝠。

答案 4 :(得分:0)

对于通过HTTPS尝试cji's solution的任何人,您实际上都需要保留基本身份验证的处理程序之一。我也在使用python3.7,因此urllib2已替换为urllib.request

from suds.transport.https import HttpAuthenticated as SudsHttpsTransport
from urllib.request import HTTPBasicAuthHandler

class WellBehavedHttpsTransport(SudsHttpsTransport):
    """ HttpsTransport which properly obeys the ``*_proxy`` environment variables."""

    def u2handlers(self):
        """ Return a list of specific handlers to add.

        The urllib2 logic regarding ``build_opener(*handlers)`` is:

        - It has a list of default handlers to use

        - If a subclass or an instance of one of those default handlers is given
            in ``*handlers``, it overrides the default one.

        Suds uses a custom {'protocol': 'proxy'} mapping in self.proxy, and adds
        a ProxyHandler(self.proxy) to that list of handlers.
        This overrides the default behaviour of urllib2, which would otherwise
        use the system configuration (environment variables on Linux, System
        Configuration on Mac OS, ...) to determine which proxies to use for
        the current protocol, and when not to use a proxy (no_proxy).

        Thus, passing an empty list (asides from the BasicAuthHandler) 
        will use the default ProxyHandler which behaves correctly.
        """
        return [HTTPBasicAuthHandler(self.pm)]