已正确设置HTTPS URL,但suds仍用HTTP,如何强制其使用HTTPS?
强制suds使用HTTPS发起请求的解决方案
问题场景
使用suds调用HTTPS协议的WSDL服务时,尽管加载WSDL的URL以https://开头,抓包却发现suds实际用HTTP发起请求,导致服务端返回HTTP 301重定向错误。
可行解决方法
1. 显式指定HTTPS服务端点
创建Client实例时,通过location参数强制指定HTTPS协议的服务地址,覆盖WSDL内部可能定义的HTTP地址:
from suds.client import Client wsdl = "https://path/to/scv?wsdl" # 强制设置HTTPS的服务端点 client = Client(wsdl, location="https://path/to/scv") # 后续业务代码保持不变 token = client.factory.create("ns1:AuthenticationToken") token.LoginName = "login" token.UserId = "userid" token.Password = "password" client.set_options(soapheaders=token) articleno = "articleno" article_list = client.factory.create("ns1:ArticlesList") article_list.Article.append(articleno) result = client.service.GetStockLevel(article_list)
注:这里把变量名list改成了article_list,避免和Python内置类型冲突
2. 自定义传输层强制HTTPS
继承suds.transport.http.HttpTransport,重写请求处理逻辑,将所有HTTP请求替换为HTTPS:
from suds.client import Client from suds.transport.http import HttpTransport from urllib.parse import urlparse class ForceHttpsTransport(HttpTransport): def u2open(self, u2request): # 检查并替换请求URL的协议为HTTPS parsed = urlparse(u2request.url) if parsed.scheme == "http": u2request.url = u2request.url.replace("http://", "https://", 1) return super().u2open(u2request) wsdl = "https://path/to/scv?wsdl" client = Client(wsdl, transport=ForceHttpsTransport()) # 后续业务代码不变 token = client.factory.create("ns1:AuthenticationToken") token.LoginName = "login" token.UserId = "userid" token.Password = "password" client.set_options(soapheaders=token) articleno = "articleno" article_list = client.factory.create("ns1:ArticlesList") article_list.Article.append(articleno) result = client.service.GetStockLevel(article_list)
3. 修改WSDL文件中的服务地址
如果WSDL文件内部定义的服务端点是HTTP协议,suds会优先使用这个地址。可以手动修改WSDL,将所有<soap:address location="http://..."/>标签里的地址替换为https://,然后加载本地修改后的WSDL:
client = Client("file:///本地路径/modified_service.wsdl")
问题根源
多数情况下,问题出在WSDL文件本身——文件内部声明的服务端点使用HTTP协议,suds默认遵循WSDL中的配置,而非加载WSDL时使用的HTTPS地址。上述方法通过强制覆盖协议或修改WSDL配置,解决请求协议不匹配的问题。
内容的提问来源于stack exchange,提问作者Bart Friederichs
相关产品推荐
相关产品推荐

