aws / aws/aws-xray-sdk-python

Requests `Session.request` assumes url to be `str`

Open
#329 1 comment 0 reactions 1 assignee Claimed by @NathanielRN View on GitHub
Dominant language
Python
Stars
338
Forks
147
PR merge metrics
No merged PRs in 30d

Description

https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/ext/requests/patch.py#L23
Implicitly assumes the `url` to be str.
In the case where you have `bytes` as the url (allowed by requests in stubs https://github.com/python/typeshed/blob/master/stubs/requests/requests/sessions.pyi#L88 and works fine in runtime. The official docs however don't specify a specific type https://github.com/psf/requests/blob/79f60274f7e461b8fd2f579e741f748438d7eadb/requests/sessions.py#L465) the variable goes through the following path leading to an `TypeError` when sampling is enabled.

https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/ext/util.py#L131
Returns parsed url with `type(url.hostname) -> bytes`.

https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/core/recorder.py#L425
Passed without any changes to `report_subsegment`.
https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/core/recorder.py#L276
And from there passed to `begin_subsegment` unchanged. Here types declared in docstrings are not followed.

https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/core/models/subsegment.py#L81
Then the name passes to `Subsegment` if sampling is enabled.

https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/core/models/entity.py#L30
`super().__init__` is called and we end up in `Entity.__init__` with the unchanged `name` with type `bytes`.

https://github.com/aws/aws-xray-sdk-python/blob/f5f9c470b189bb34f31a1d0a28f497741132b7d2/aws_xray_sdk/core/models/entity.py#L38
Then at this line we're iterating over the items in the bytes (`type(c) -> int`) and checking if those are included in an `str` and we get a `TypeError`.

```
File "/var/task/aws_xray_sdk/ext/requests/patch.py", line 27, in _xray_traced_requests
return xray_recorder.record_subsegment(
File "/var/task/aws_xray_sdk/core/recorder.py", line 428, in record_subsegment
subsegment = self.begin_subsegment(name, namespace)
File "/var/task/aws_xray_sdk/core/recorder.py", line 300, in begin_subsegment
subsegment = Subsegment(name, namespace, segment)
File "/var/task/aws_xray_sdk/core/models/subsegment.py", line 98, in __init__
super(Subsegment, self).__init__(name)
File "/var/task/aws_xray_sdk/core/models/entity.py", line 38, in __init__
self.name = ''.join([c for c in name if c not in _common_invalid_name_characters])
File "/var/task/aws_xray_sdk/core/models/entity.py", line 38, in
self.name = ''.join([c for c in name if c not in _common_invalid_name_characters])
TypeError: 'in ' requires string as left operand, not int
```

The best fix is probably to sanitize the hostname once getting that off from `urlparse` and convert it to an `str`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.