Requests: 请求 2.11:check_header_validity 在具有整数值的标头上失败

创建于 2016-08-08  ·  23评论  ·  资料来源: psf/requests

你好,

自请求 2.11 以来,我使用应用程序请求的所有调用都已中断。 经过调试,这个版本似乎不接受带有整数值的标头,就像以前一样。

2.10:

In [1]: import requests

In [2]: requests.get('http://bing.com', headers={'Content-Length': 42})
Out[2]: <Response [200]>

2.11

In [1]: import requests

In [2]: requests.get('http://bing.com', headers={'Content-Length': 42})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\utils.py in check_header_validity(header)
    751     try:
--> 752         if not pat.match(value):
    753             raise InvalidHeader("Invalid return character or leading space in header: %s" % name)

TypeError: expected string or bytes-like object

During handling of the above exception, another exception occurred:

InvalidHeader                             Traceback (most recent call last)
<ipython-input-2-ae7ec2933e34> in <module>()
----> 1 requests.get('http://bing.com', headers={'Content-Length': 42})

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\api.py in get(url, params, **kwargs)
     68
     69     kwargs.setdefault('allow_redirects', True)
---> 70     return request('get', url, params=params, **kwargs)
     71
     72

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\api.py in request(method, url, **kwargs)
     54     # cases, and look like a memory leak in others.
     55     with sessions.Session() as session:
---> 56         return session.request(method=method, url=url, **kwargs)
     57
     58

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    455             hooks = hooks,
    456         )
--> 457         prep = self.prepare_request(req)
    458
    459         proxies = proxies or {}

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\sessions.py in prepare_request(self, request)
    388             auth=merge_setting(auth, self.auth),
    389             cookies=merged_cookies,
--> 390             hooks=merge_hooks(request.hooks, self.hooks),
    391         )
    392         return p

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\models.py in prepare(self, method, url, headers, files, data, params, auth, cookies, hooks, json)
    293         self.prepare_method(method)
    294         self.prepare_url(url, params)
--> 295         self.prepare_headers(headers)
    296         self.prepare_cookies(cookies)
    297         self.prepare_body(data, files, json)

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\models.py in prepare_headers(self, headers)
    407             for header in headers.items():
    408                 # Raise exception on invalid header value.
--> 409                 check_header_validity(header)
    410                 name, value = header
    411                 self.headers[to_native_string(name)] = value

D:\VSProjects\azure-sdk-for-python\env3.5\Lib\site-packages\requests\utils.py in check_header_validity(header)
    754     except TypeError:
    755         raise InvalidHeader("Header value %s must be of type str or bytes, "
--> 756                             "not %s" % (value, type(value)))
    757
    758

InvalidHeader: Header value 42 must be of type str or bytes, not <class 'int'>

我们在每个请求中定义了“Content-Length”。 无论如何,对语义上是整数的标头使用整数有意义不是吗?

最有用的评论

似乎是 dot-release 的突破性变化,不是吗?

所有23条评论

可悲的是,标头值的非字符串从来都不是被接受的使用请求的方式,虽然在以前的版本中允许它,但我们已经进行了不允许它的更改。 这主要是因为标头是_真的_ 字符串-字符串映射,还因为在传递给请求的事物上调用str的一般方法倾向于以意想不到的方式行为不端,让用户感到惊讶。

TL; DR 是:是的,这是故意完成的,不,我们不认为这是一个错误。

另见:#865。

似乎是 dot-release 的突破性变化,不是吗?

而且你没有在 ChangeLog 中描述这个巨大的修改:(

这不是一个重大的 API 更改——在整个文档中,API 被清楚地记录为基于字符串的。 您将它与整数一起使用而不是其预期输入的事实是代码中的错误,而不是此代码库中的错误或 API 中的更改。

在更改日志中添加有关此非破坏性更改的注释可能是个好主意。

@clarkbreyman-yammer 需要明确的是,这是一个临界案例。 您可以在 #3386 和 #3388 中看到最近的决策,但基本论点是:非字符串标头从来没有 _intended_ 工作,因此它们停止工作的事实是可以接受的。 事实上,这在过去是行不通的。

@lmazuel你是对的,这在更新日志中被遗漏了,这 100% 是我的错:这里的损坏是我们对标头值的更严格验证的偶然事件,因此我在编译时没有看到它变更日志。 如果你想制作一个更新更新日志的 PR,我欢迎。

需要明确的是,我们三个人都同意这一点。 在那里发送一个整数 _ever_ 工作的事实纯粹是运气。 它曾经根本不起作用,我们很久以前就决定它永远不会起作用。 不过,我们从来没有_强制_过任何事情。

话虽如此,将其添加为受支持的功能可能是一个好主意,并且在我的书中将是一个受欢迎的 API 更改(如果实现得很好)。 但是,在很长一段时间内,事物的现状很可能会保持不变。

在变更日志中添加了一条注释。

谢谢@kennethreitz。

好的,谢谢澄清。 我会相应地更新我的代码。
@kennethreitz如果你也能在 PyPI 中添加你的笔记,那就太棒了。

@lmazuel就可以了!

@lmazuel完成了✨🍰✨

@lmazuel ps 谢谢你的关心 :P

我修复了我的代码,其他一切都很好。 感谢您的超快响应时间!

在官方文档中没有提到重大变化。 这真的是误导。

它不被 Requests 团队视为重大更改,它被视为适合记录的库行为范围内的错误修复。

@COLDMOUNT ,您可以在自定义标题的快速入门部分的最后一段中找到此处的文档。 我们还在HISTORY.rst 中发布了

最好提供一个 str 类型的标头示例,或者如何
将 dict 类型的标题转换为 str 类型,谢谢。

2016-09-27 1:30 GMT+08:00 Nate Prewitt [email protected]

@COLDMOUNT https://github.com/COLDMOUNT ,你可以找到
文档在这里
http://docs.python-requests.org/en/master/user/quickstart/#custom -headers
在自定义标题的快速入门部分的最后一段中。 我们
还在 (HISTORY.rst)[ https://github.
com/kennethreitz/requests/blob/master/HISTORY.rst] 为 2.11.0
请求的变更日志。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/kennethreitz/requests/issues/3477#issuecomment -249638650,
或静音线程
https://github.com/notifications/unsubscribe-auth/ARIa89wU7tKL8Br2WWU6lJy8HEbNr72Vks5quAE3gaJpZM4JffFG
.

或如何将 dict 类型的标题转换为 str 类型

等等,什么? 你之前是如何发送标头的?

就像页面上的指南一样——
http://docs.python-requests.org/en/master/user/quickstart/—— “如果你
喜欢向请求添加 HTTP 标头,只需将 dict 传递给标头
参数。”但现在不再接受dict类型,str是什么
类型看起来像?

2016-09-27 17:51 GMT+08:00 Cory Benfield [email protected]

或如何将 dict 类型的标题转换为 str 类型

等等,什么? 你之前是如何发送标头的?


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/kennethreitz/requests/issues/3477#issuecomment -249819028,
或静音线程
https://github.com/notifications/unsubscribe-auth/ARIa8_ZPJmzxH2lWmpTvSJ3PvHE7jlpvks5quOcrgaJpZM4JffFG
.

@COLDMOUNT dict被_绝对_接受,我们根本没有改变。 我们改变的是该字典的键和值现在必须是字符串。 之前有可能不小心变成了其他几种类型,现在已经解决了。 文档不需要更改。

明白了,爽! 谢谢! :)

2016-09-27 18:23 GMT+08:00 Cory Benfield [email protected]

@COLDMOUNT https://github.com/COLDMOUNT dict 被_绝对_接受,
我们根本没有改变这一点。 我们改变的是键和
该 dict 的值现在必须是字符串。 以前可以为
它们偶然成为其他几种类型,现已解决。 这
文档不需要更改。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/kennethreitz/requests/issues/3477#issuecomment -249825918,
或静音线程
https://github.com/notifications/unsubscribe-auth/ARIa8z0jZ-ovBtvFWl4hTXnkk_kJXobrks5quO6ggaJpZM4JffFG
.

此页面是否有帮助?
0 / 5 - 0 等级