httpie-aws-authv4 icon indicating copy to clipboard operation
httpie-aws-authv4 copied to clipboard

TypeError: object supporting the buffer API required with multipart requests

Open Envek opened this issue 4 years ago • 3 comments

First of all, thank you very much for this plugin! It works awesome, but not in the following use case:

When I'm trying to make a multipart/form-data request with http --multipart and AWS Auth, like this:

http --auth-type aws4 --auth REDACTED.execute-api.us-west-2.amazonaws.com \
     --multipart POST http://redacted.dpmain.tld/endpoint field=value file@/path/to/file

I'm getting following error:

http: error: TypeError: object supporting the buffer API required

Also this error is thrown when files are included in x-www-urlencoded requests with http --form url file@/path/to/file (in case of multipart requests it fails with any fields)

http --debug output with versions and traceback is here
HTTPie 2.3.0
Requests 2.25.1
Pygments 2.7.4
Python 3.8.2 (default, Oct 22 2020, 20:12:25) 
[GCC 5.5.0]
/home/envek/.asdf/installs/python/3.8.2/bin/python3.8
Linux 5.4.0-64-generic

<Environment {'colors': 256,
 'config': {'default_options': []},
 'config_dir': PosixPath('/home/envek/.config/httpie'),
 'devnull': <property object at 0x7f7e9cce4130>,
 'is_windows': False,
 'log_error': <function Environment.log_error at 0x7f7e9cce2820>,
 'program_name': 'http',
 'stderr': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>,
 'stderr_isatty': True,
 'stdin': <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>,
 'stdin_encoding': 'utf-8',
 'stdin_isatty': True,
 'stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>,
 'stdout_encoding': 'utf-8',
 'stdout_isatty': True}>

>>> requests.request(**{'auth': <httpie_aws_authv4.AWSAuth object at 0x7f7e9e7e52b0>,
 'data': <MultipartEncoder: <generator object MultiValueOrderedDict.items at 0x7f7e9c69c970>>,
 'headers': {'User-Agent': b'HTTPie/2.3.0', 'Content-Type': 'multipart/form-data; boundary=cb266ae3fb8a4cf89c8c9c8a40ba7f85'},
 'method': 'post',
 'params': <generator object MultiValueOrderedDict.items at 0x7f7e9c69c9e0>,
 'url': 'http://localhost:8080/fileAttachments'})


http: error: TypeError: object supporting the buffer API required

Traceback (most recent call last):
  File "/home/envek/.asdf/installs/python/3.8.2/bin/http", line 8, in <module>
    sys.exit(main())
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/httpie/__main__.py", line 11, in main
    exit_status = main()
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/httpie/core.py", line 79, in main
    exit_status = program(
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/httpie/core.py", line 196, in program
    for message in messages:
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/httpie/client.py", line 80, in collect_messages
    prepared_request = requests_session.prepare_request(request)
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/requests/sessions.py", line 456, in prepare_request
    p.prepare(
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/requests/models.py", line 320, in prepare
    self.prepare_auth(auth, url)
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/requests/models.py", line 551, in prepare_auth
    r = auth(self)
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/httpie_aws_authv4.py", line 60, in __call__
    return aws_request.__call__(r)
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/aws_requests_auth/aws_auth.py", line 76, in __call__
    aws_headers = self.get_aws_request_headers_handler(r)
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/aws_requests_auth/aws_auth.py", line 88, in get_aws_request_headers_handler
    return self.get_aws_request_headers(r=r,
  File "/home/envek/.asdf/installs/python/3.8.2/lib/python3.8/site-packages/aws_requests_auth/aws_auth.py", line 146, in get_aws_request_headers
    payload_hash = hashlib.sha256(body).hexdigest()
TypeError: object supporting the buffer API required

Envek avatar Feb 01 '21 18:02 Envek

Actually it should be fixed on aws-requests-auth side, here is the proposed fix: https://github.com/DavidMuller/aws-requests-auth/pull/60

Envek avatar Feb 02 '21 09:02 Envek

Thank you for raising this issue @Envek and following up. I'll keep an eye on the upstream issue you created to see if there is anything that needs to be done to get the fix.

aidan- avatar Feb 02 '21 10:02 aidan-

Workaround for the time being to use aws-requests-auth with the fix:

pip install git+https://github.com/Envek/aws-requests-auth@fix/multipart-requests
pip install httpie httpie-aws-authv4
http --auth-type aws4 --auth REDACTED.execute-api.us-west-2.amazonaws.com \
     --multipart POST http://example.com/test field=value

Envek avatar Feb 05 '21 15:02 Envek