Skip to content

Commit 5dafcbd

Browse files
fix(utils): correct Content-Length for io.StringIO bodies (#6917)
- Add special handling for io.StringIO in super_len() function - Calculate byte length by encoding StringIO content as UTF-8 - Preserve stream position to avoid surprising users - Fixes incorrect Content-Length header when StringIO contains multi-byte UTF-8 characters
1 parent da9113c commit 5dafcbd

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

src/requests/utils.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,24 @@ def super_len(o):
140140
# of latin-1 (iso-8859-1) like http.client.
141141
o = o.encode("utf-8")
142142

143+
# Special case: io.StringIO bodies
144+
# StringIO.tell() returns characters, not bytes; UTF-8 encoding may
145+
# expand the payload. We calculate the true byte length without
146+
# mutating the stream position. This mirrors the logic already
147+
# applied to plain `str` bodies (see above) and maintains backwards
148+
# compatibility for callers.
149+
# Fixes: https://github.com/psf/requests/issues/6917
150+
if isinstance(o, io.StringIO):
151+
# Cache current cursor, read content, restore cursor
152+
current_pos = o.tell()
153+
try:
154+
o.seek(0)
155+
content = o.read()
156+
total_length = len(content.encode("utf-8"))
157+
finally:
158+
o.seek(current_pos)
159+
return max(0, total_length - (len(content[:current_pos].encode("utf-8")) if current_pos > 0 else 0))
160+
143161
if hasattr(o, "__len__"):
144162
total_length = len(o)
145163

0 commit comments

Comments
 (0)