Bugs: Content-Length not updated by reused urllib.request.Request / has_header() case-sensitive

Johannes Kleese j.kleese at arcor.de
Mon Nov 12 16:52:27 CET 2012


Hi!

(Yes, I did take a look at the issue tracker but couldn't find any
corresponding bug, and no, I don't want to open a new account just for
this one.)

--------------------------------------------------------------------

I'm reusing a single urllib.request.Request object to HTTP-POST data to
the same URL a number of times. While the data itself is sent as
expected every time, the Content-Length header is not updated after the
first request. Tested with Python 3.1.3 and Python 3.1.4.

>>> opener = urllib.request.build_opener()
>>> request = urllib.request.Request("http://example.com/", headers =
{"Content-Type": "application/x-www-form-urlencoded"})


>>> opener.open(request, "1".encode("us-ascii"))

>>> request.data
b'1'
>>> request.header_items()
[('Content-length', '1'), ('Content-type',
'application/x-www-form-urlencoded'), ('Host', 'example.com'),
('User-agent', 'Python-urllib/3.1')]


>>> opener.open(request, "123456789".encode("us-ascii"))

>>> request.data
b'123456789'
>>> request.header_items()
[('Content-length', '1'), ('Content-type',
'application/x-www-form-urlencoded'), ('Host', 'example.com'),
('User-agent', 'Python-urllib/3.1')]

Note that after the second run, Content-Length stays "1", but should be
"9", corresponding to the data b'123456789'. (Request data is not
x-www-form-urlencoded to shorten the test case. Doesn't affect the bug,
though.)




--------------------------------------------------------------------

While at it, I noticed that urllib.request.Request.has_header() and
.get_header() are case-sensitive, while HTTP headers are not (RFC 2616,
4.2). Thus the following, slightly unfortunate behaviour:

>>> request.header_items()
[('Content-length', '1'), ('Content-type',
'application/x-www-form-urlencoded'), ('Host', 'example.com'),
('User-agent', 'Python-urllib/3.1')]

>>> request.has_header("Content-Type")
False
>>> request.has_header("Content-type")
True
>>> request.get_header("Content-Type")
>>> request.get_header("Content-type")
'application/x-www-form-urlencoded'

--------------------------------------------------------------------

Thanks for taking care.



More information about the Python-list mailing list