Skip to content

Commit

Permalink
Fix Content-Length for unicode file contents with multipart (#1537)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchristie authored Mar 25, 2021
1 parent 68cf1ff commit c75ddc2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
8 changes: 2 additions & 6 deletions httpx/_multipart.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ def render_headers(self) -> bytes:

def render_data(self) -> bytes:
if not hasattr(self, "_data"):
self._data = (
self.value
if isinstance(self.value, bytes)
else self.value.encode("utf-8")
)
self._data = to_bytes(self.value)

return self._data

Expand Down Expand Up @@ -88,7 +84,7 @@ def get_length(self) -> int:
headers = self.render_headers()

if isinstance(self.file, (str, bytes)):
return len(headers) + len(self.file)
return len(headers) + len(to_bytes(self.file))

# Let's do our best not to read `file` into memory.
try:
Expand Down
23 changes: 23 additions & 0 deletions tests/test_multipart.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ def test_multipart_encode(tmp_path: typing.Any) -> None:
assert content == b"".join(stream)


def test_multipart_encode_unicode_file_contents() -> None:
files = {"file": ("name.txt", "<únicode string>")}

with mock.patch("os.urandom", return_value=os.urandom(16)):
boundary = os.urandom(16).hex()

headers, stream = encode_request(files=files)
assert isinstance(stream, typing.Iterable)

content = (
'--{0}\r\nContent-Disposition: form-data; name="file";'
' filename="name.txt"\r\n'
"Content-Type: text/plain\r\n\r\n<únicode string>\r\n"
"--{0}--\r\n"
"".format(boundary).encode("utf-8")
)
assert headers == {
"Content-Type": f"multipart/form-data; boundary={boundary}",
"Content-Length": str(len(content)),
}
assert content == b"".join(stream)


def test_multipart_encode_files_allows_filenames_as_none() -> None:
files = {"file": (None, io.BytesIO(b"<file content>"))}
with mock.patch("os.urandom", return_value=os.urandom(16)):
Expand Down

0 comments on commit c75ddc2

Please sign in to comment.