对接某为云总是报错{"message":"API not found","request_id":"---------"}
问题分析
调用了很多接口,使用域名访问的就会报此错误,使用IP直接访问的就没问题。所以怀疑是域名处理部分有问题,并且域名中有大写字母,更加重怀疑是某云的API网关区分host大小写导致。
解决问题
咱是对接方,只能咱们改。
项目中最后都会调用requests库进行最终的http调用,因此我们跟踪源码调试,发现有几个地方会讲url转换为小写。
-
requests/packages/urllib3/poolmanager.py
文件def _default_key_normalizer(key_class, request_context): """ Create a pool key of type ``key_class`` for a request. ... """ context = {} for key in key_class._fields: context[key] = request_context.get(key) context['scheme'] = context['scheme'].lower() # 将此处转小写删掉 #context['host'] = context['host'].lower() return key_class(**context)
-
requests/packages/urllib3/util/url.py
文件class Url(namedtuple('Url', url_attrs)): """ Datastructure for representing an HTTP URL. Used as a return value for :func:`parse_url`. Both the scheme and host are normalized as they are both case-insensitive according to RFC 3986. """ __slots__ = () def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, query=None, fragment=None): if path and not path.startswith('/'): path = '/' + path if scheme: scheme = scheme.lower() # 将此处转小写删掉 #if host: # host = host.lower() return super(Url, cls).__new__(cls, scheme, auth, host, port, path, query, fragment)
-
requests/models.py
文件class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): ... def prepare_url(self, url, params): ... try: # 将uts46参数改为False #host = idna.encode(host, uts46=True).decode('utf-8') host = idna.encode(host, uts46=False).decode('utf-8') except (UnicodeError, idna.IDNAError): if not unicode_is_ascii(host) or host.startswith(u'*'): raise InvalidURL('URL has an invalid label.') ...