Skip to content

Commit

Permalink
Do not hang when deciding not to compress a file upload
Browse files Browse the repository at this point in the history
This command would hang forever:

```console
$ echo test > test.txt
$ http -x httpbin.org/post @test.txt
```

HTTPie would read the file, compress it, then discard the compressed
data because it's larger than the original. This made `request.body`
an exhausted file handle, which `requests` doesn't seem to like.
  • Loading branch information
blyxxyz committed Jan 22, 2025
1 parent 5b604c3 commit 26a3903
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 1 deletion.
3 changes: 3 additions & 0 deletions httpie/uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ def compress_request(
body_bytes = request.body.encode()
elif hasattr(request.body, 'read'):
body_bytes = request.body.read()
# The body is consumed now, so if we don't end up compressing we should
# use the bytes we just read
request.body = body_bytes
else:
body_bytes = request.body
deflated_data = deflater.compress(body_bytes)
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def patharg(path):
JSON_FILE_PATH = FIXTURES_ROOT / 'test.json'
JSON_WITH_DUPE_KEYS_FILE_PATH = FIXTURES_ROOT / 'test_with_dupe_keys.json'
BIN_FILE_PATH = FIXTURES_ROOT / 'test.bin'
TINY_FILE_PATH = FIXTURES_ROOT / 'test_tiny.txt'

XML_FILES_PATH = FIXTURES_ROOT / 'xmldata'
XML_FILES_VALID = list((XML_FILES_PATH / 'valid').glob('*_raw.xml'))
Expand All @@ -39,6 +40,7 @@ def patharg(path):
FILE_PATH_ARG = patharg(FILE_PATH)
BIN_FILE_PATH_ARG = patharg(BIN_FILE_PATH)
JSON_FILE_PATH_ARG = patharg(JSON_FILE_PATH)
TINY_FILE_PATH_ARG = patharg(TINY_FILE_PATH)

# Strip because we don't want new lines in the data so that we can
# easily count occurrences also when embedded in JSON (where the new
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/test_tiny.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
15 changes: 14 additions & 1 deletion tests/test_compress.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import base64
import zlib

from .fixtures import FILE_PATH, FILE_CONTENT
from .fixtures import FILE_PATH, FILE_CONTENT, TINY_FILE_PATH_ARG
from httpie.status import ExitStatus
from .utils import StdinBytesIO, http, HTTP_OK, MockEnvironment

Expand Down Expand Up @@ -138,3 +138,16 @@ def test_compress_file(httpbin_both):
'multipart/form-data; boundary=')
assert r.json['files'] == {}
assert FILE_CONTENT not in r


def test_compress_skip_negative_ratio_file_upload(httpbin):
"""Reading the upload body but not compressing it doesn't cause a hang."""
r = http(
'--compress',
'PUT',
httpbin + '/put',
f'@{TINY_FILE_PATH_ARG}',
)
assert HTTP_OK in r
assert 'Content-Encoding' not in r.json['headers']
assert r.json['data'] == 'test\n'

0 comments on commit 26a3903

Please sign in to comment.