lepture / authlib

The ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS,JWE,JWK,JWA,JWT included.
https://authlib.org/
BSD 3-Clause "New" or "Revised" License
4.49k stars 448 forks source link

Data loss when using httpx OAuth1 client to send files with POST requests #516

Open shc261392 opened 1 year ago

shc261392 commented 1 year ago

Describe the bug

When sending files in a POST request using httpx client, all binary data (the files) are lost.

Error Stacks

There is no error stack for this issue, since this is an issue only detectable from server-side or only when the server side returns meaningful error responses. To demonstrate the case, I've added the full steps and scripts to reproduce the issue in the next section.

To Reproduce

Scripts for issue reproduction:

  1. Main script
  2. Debug server. You can use any other tools that can act as the server to receive the request instead, this one is just attached for convenience.

Steps to reproduce:

  1. Run the debug server
  2. Run the main script. The main script includes two consecutive requests, one using the authlib requests client and one using the httpx client, so that we could compare the normal one with the corrupted one.

requests client

Received header Content-Length:  146
Received actual bytes:  146
127.0.0.1 - - [17/Dec/2022 08:39:09] "POST / HTTP/1.1" 200 -

httpx client

Received header Content-Length:  0
Received actual bytes:  0
127.0.0.1 - - [17/Dec/2022 08:39:09] "POST / HTTP/1.1" 200 -

It's obvious the binary data are lost when using httpx client.

Expected behavior

The request data should not be corrupted. httpx client should behaves like requests client when using the same inputs and configurations.

Environment:

Additional context

I've tried to fix this issue and the fix seems working. Perhaps I could submit a pull request if this issue could be verified true.

Zaczero commented 1 year ago

Setting force_include_body=True resolved the issue for me, but this looks more like a workaround.

            auth = OAuth1Auth(
                client_id=CONSUMER_KEY,
                client_secret=CONSUMER_SECRET,
                token=oauth_token,
                token_secret=oauth_token_secret,
                force_include_body=True)