7

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

这在 OS X 10.7(python 2.7)和 ubuntu 12.04 上的 suds 0.3.9 上进行了测试。

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

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

我用代理尝试了各种方法——删除 http://,使用 IP,使用 FQDN。我已经逐步浏览了 pdb 中的代码,并看到它设置了代理选项。我也尝试过在没有代理的情况下实例化客户端,然后将其设置为: ws.set_options(proxy={'http':'http://localhost:8888'})

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

谢谢!

4

5 回答 5

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())
于 2012-09-15T00:40:46.103 回答
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)
于 2012-09-13T21:05:24.617 回答
4

我实际上能够通过做两件事让它工作:

  • 确保代理字典中httphttps.
  • set_options使用创建客户端后设置代理。

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

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

于 2016-02-08T19:38:01.887 回答
2

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

直接工作。

于 2015-02-23T03:28:23.293 回答
0

对于通过 HTTPS 尝试cji 解决方案的任何人,您实际上需要保留一个处理程序以进行基本身份验证。我也在使用 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)]
于 2020-11-23T18:27:34.867 回答