Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

application/x-www-form-urlencoded request with None body #913

Open
ericbn opened this issue Feb 26, 2025 · 0 comments
Open

application/x-www-form-urlencoded request with None body #913

ericbn opened this issue Feb 26, 2025 · 0 comments

Comments

@ericbn
Copy link

ericbn commented Feb 26, 2025

Double checking the exiting transformers defined in vcr.matchers, we see:

>>> from vcr.matchers import _checker_transformer_pairs
>>> for i, (_, transformer) in enumerate(_checker_transformer_pairs):
...     print(i)
...     try:
...             print(transformer(None))
...     except Exception as e:
...             print(e)
...
0
None
1
'NoneType' object has no attribute 'decode'
2
None
3
a bytes-like object is required, not 'NoneType'
  1. Transfer-Encoding: chunked accepts None
  2. Content-Type: application/x-www-form-urlencoded does not accept None
  3. Content-Type: application/json accepts None
  4. Content-Type: text/xml; User-Agent: xmlrpc does not accept None

I'm particularly interested in letting the Content-Type: application/x-www-form-urlencoded transformer accept None.

The twilio package does arguably unusual requests in some cases: GET with header Content-Type: application/x-www-form-urlencoded. In these cases, the body is None. See

https://github.com/twilio/twilio-python/blob/71fb731c9c6356cf08030221d74a900c935109da/twilio/rest/sync/v1/service/sync_map/sync_map_item.py#L734-L740

When trying to record these requests with vcr, it fails with 'NoneType' object has no attribute 'decode'.

If I change matchers.py as follows:

 _checker_transformer_pairs = (
     (_header_checker("chunked", header="Transfer-Encoding"), _dechunk),
     (
         _header_checker("application/x-www-form-urlencoded"),
-        lambda body: urllib.parse.parse_qs(body.decode("ascii")),
+        lambda body: None if body is None else urllib.parse.parse_qs(body.decode("ascii")),
     ),
     (_header_checker("application/json"), _transform_json),
     (lambda request: _xml_header_checker(request) and _xmlrpc_header_checker(request), xmlrpc.client.loads),
 )

then I can successfully record an interaction. For the twilio package code mentioned above, a recorded interaction will then look like:

- request:
    body: null
    headers:
      Content-Type:
      - application/x-www-form-urlencoded
    method: GET
    uri: https://sync.twilio.com/v1/Services/default/Maps/MyMap/Items?PageSize=1000
  response:
    body:
      string: '{...}'
    headers:
      Content-Type:
      - application/json; charset=utf-8
    status:
      code: 200
      message: OK

Do you agree with the proposed change? I'll be happy to submit a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant