Bugs: Content-Length not updated by reused urllib.request.Request / has_header() case-sensitive
Johannes Kleese
j.kleese at arcor.de
Mon Nov 12 10:52:27 EST 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