mirror of
https://github.com/httpie/cli.git
synced 2024-11-24 08:22:22 +02:00
Added tests for binary request data.
This commit is contained in:
parent
8905b4fc72
commit
90d34ffd0d
@ -85,7 +85,7 @@ def get_response(args, env):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
if args.debug:
|
if args.debug:
|
||||||
raise
|
raise
|
||||||
env.stderr.write(str(e.message) + '\n')
|
env.stderr.write(str(repr(e) + '\n'))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class Parser(argparse.ArgumentParser):
|
|||||||
self._parse_items(args)
|
self._parse_items(args)
|
||||||
|
|
||||||
if not env.stdin_isatty:
|
if not env.stdin_isatty:
|
||||||
self._body_from_file(args, env.stdin.read())
|
self._body_from_file(args, env.stdin)
|
||||||
|
|
||||||
if args.auth and not args.auth.has_password():
|
if args.auth and not args.auth.has_password():
|
||||||
# Stdin already read (if not a tty) so it's save to prompt.
|
# Stdin already read (if not a tty) so it's save to prompt.
|
||||||
@ -129,12 +129,16 @@ class Parser(argparse.ArgumentParser):
|
|||||||
|
|
||||||
super(Parser, self)._print_message(message, file)
|
super(Parser, self)._print_message(message, file)
|
||||||
|
|
||||||
def _body_from_file(self, args, data):
|
def _body_from_file(self, args, fd):
|
||||||
"""There can only be one source of request data."""
|
"""There can only be one source of request data.
|
||||||
|
|
||||||
|
Bytes are always read.
|
||||||
|
|
||||||
|
"""
|
||||||
if args.data:
|
if args.data:
|
||||||
self.error('Request body (from stdin or a file) and request '
|
self.error('Request body (from stdin or a file) and request '
|
||||||
'data (key=value) cannot be mixed.')
|
'data (key=value) cannot be mixed.')
|
||||||
args.data = data
|
args.data = getattr(fd, 'buffer', fd).read()
|
||||||
|
|
||||||
def _guess_method(self, args, env):
|
def _guess_method(self, args, env):
|
||||||
"""Set `args.method` if not specified to either POST or GET
|
"""Set `args.method` if not specified to either POST or GET
|
||||||
@ -201,9 +205,9 @@ class Parser(argparse.ArgumentParser):
|
|||||||
'Invalid file fields (perhaps you meant --form?): %s'
|
'Invalid file fields (perhaps you meant --form?): %s'
|
||||||
% ','.join(file_fields))
|
% ','.join(file_fields))
|
||||||
|
|
||||||
fn, data = args.files['']
|
fn, fd = args.files['']
|
||||||
args.files = {}
|
args.files = {}
|
||||||
self._body_from_file(args, data)
|
self._body_from_file(args, fd)
|
||||||
if 'Content-Type' not in args.headers:
|
if 'Content-Type' not in args.headers:
|
||||||
mime, encoding = mimetypes.guess_type(fn, strict=False)
|
mime, encoding = mimetypes.guess_type(fn, strict=False)
|
||||||
if mime:
|
if mime:
|
||||||
@ -420,8 +424,8 @@ def parse_items(items, data=None, headers=None, files=None, params=None):
|
|||||||
target = params
|
target = params
|
||||||
elif item.sep == SEP_FILES:
|
elif item.sep == SEP_FILES:
|
||||||
try:
|
try:
|
||||||
with open(os.path.expanduser(value)) as f:
|
value = (os.path.basename(value),
|
||||||
value = (os.path.basename(f.name), f.read())
|
open(os.path.expanduser(value), 'rb'))
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
'Invalid argument "%s": %s' % (item.orig, e))
|
'Invalid argument "%s": %s' % (item.orig, e))
|
||||||
|
@ -120,6 +120,10 @@ class HTTPMessage(object):
|
|||||||
|
|
||||||
# Body
|
# Body
|
||||||
if request.files:
|
if request.files:
|
||||||
|
# TODO: would be nice if we didn't need to encode the files again
|
||||||
|
for fn, fd in request.files.values():
|
||||||
|
# Rewind the files as they have already been read before.
|
||||||
|
fd.seek(0)
|
||||||
body, _ = request._encode_files(request.files)
|
body, _ = request._encode_files(request.files)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
BIN
tests/fixtures/file.bin
vendored
Normal file
BIN
tests/fixtures/file.bin
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
@ -51,10 +51,16 @@ from httpie.input import ParseError
|
|||||||
HTTPBIN_URL = os.environ.get('HTTPBIN_URL',
|
HTTPBIN_URL = os.environ.get('HTTPBIN_URL',
|
||||||
'http://httpbin.org')
|
'http://httpbin.org')
|
||||||
|
|
||||||
TEST_FILE_PATH = os.path.join(TESTS_ROOT, 'file.txt')
|
TEST_FILE_PATH = os.path.join(TESTS_ROOT, 'fixtures', 'file.txt')
|
||||||
TEST_FILE2_PATH = os.path.join(TESTS_ROOT, 'file2.txt')
|
TEST_FILE2_PATH = os.path.join(TESTS_ROOT, 'fixtures', 'file2.txt')
|
||||||
|
|
||||||
with open(TEST_FILE_PATH) as f:
|
with open(TEST_FILE_PATH) as f:
|
||||||
TEST_FILE_CONTENT = f.read().strip()
|
TEST_FILE_CONTENT = f.read().strip()
|
||||||
|
|
||||||
|
TEST_BIN_FILE_PATH = os.path.join(TESTS_ROOT, 'fixtures', 'file.bin')
|
||||||
|
with open(TEST_BIN_FILE_PATH, 'rb') as f:
|
||||||
|
TEST_BIN_FILE_CONTENT = f.read()
|
||||||
|
|
||||||
TERMINAL_COLOR_PRESENCE_CHECK = '\x1b['
|
TERMINAL_COLOR_PRESENCE_CHECK = '\x1b['
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +88,6 @@ def http(*args, **kwargs):
|
|||||||
and return a unicode response.
|
and return a unicode response.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if 'env' not in kwargs:
|
if 'env' not in kwargs:
|
||||||
# Ensure that we have terminal by default (needed for Travis).
|
# Ensure that we have terminal by default (needed for Travis).
|
||||||
kwargs['env'] = Environment(
|
kwargs['env'] = Environment(
|
||||||
@ -94,7 +99,11 @@ def http(*args, **kwargs):
|
|||||||
stdout = kwargs['env'].stdout = tempfile.TemporaryFile('w+b')
|
stdout = kwargs['env'].stdout = tempfile.TemporaryFile('w+b')
|
||||||
stderr = kwargs['env'].stderr = tempfile.TemporaryFile('w+t')
|
stderr = kwargs['env'].stderr = tempfile.TemporaryFile('w+t')
|
||||||
|
|
||||||
|
try:
|
||||||
exit_status = main(args=['--debug'] + list(args), **kwargs)
|
exit_status = main(args=['--debug'] + list(args), **kwargs)
|
||||||
|
except (Exception, SystemExit) as e:
|
||||||
|
sys.stderr.write(stderr.read())
|
||||||
|
raise
|
||||||
|
|
||||||
stdout.seek(0)
|
stdout.seek(0)
|
||||||
stderr.seek(0)
|
stderr.seek(0)
|
||||||
@ -564,7 +573,54 @@ class MultipartFormDataFileUploadTest(BaseTestCase):
|
|||||||
self.assertIn('"foo": "bar"', r)
|
self.assertIn('"foo": "bar"', r)
|
||||||
|
|
||||||
|
|
||||||
class TestBinaryResponses(BaseTestCase):
|
class BinaryRequestDataTest(BaseTestCase):
|
||||||
|
|
||||||
|
def test_binary_stdin(self):
|
||||||
|
env = Environment(
|
||||||
|
stdin=open(TEST_BIN_FILE_PATH, 'rb'),
|
||||||
|
stdin_isatty=False,
|
||||||
|
stdout_isatty=False
|
||||||
|
)
|
||||||
|
r = http(
|
||||||
|
'--print=B',
|
||||||
|
'POST',
|
||||||
|
httpbin('/post'),
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
self.assertEqual(r, TEST_BIN_FILE_CONTENT)
|
||||||
|
|
||||||
|
def test_binary_file_path(self):
|
||||||
|
env = Environment(
|
||||||
|
stdin_isatty=True,
|
||||||
|
stdout_isatty=False
|
||||||
|
)
|
||||||
|
r = http(
|
||||||
|
'--print=B',
|
||||||
|
'POST',
|
||||||
|
httpbin('/post'),
|
||||||
|
'@' + TEST_BIN_FILE_PATH,
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(r, TEST_BIN_FILE_CONTENT)
|
||||||
|
|
||||||
|
def test_binary_file_form(self):
|
||||||
|
env = Environment(
|
||||||
|
stdin_isatty=True,
|
||||||
|
stdout_isatty=False
|
||||||
|
)
|
||||||
|
r = http(
|
||||||
|
'--print=B',
|
||||||
|
'--form',
|
||||||
|
'POST',
|
||||||
|
httpbin('/post'),
|
||||||
|
'test@' + TEST_BIN_FILE_PATH,
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
self.assertIn(bytes(TEST_BIN_FILE_CONTENT), bytes(r))
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryResponseDataTest(BaseTestCase):
|
||||||
|
|
||||||
url = 'http://www.google.com/favicon.ico'
|
url = 'http://www.google.com/favicon.ico'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user