Skip to content

Instantly share code, notes, and snippets.

@sboily
Created October 28, 2022 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sboily/6fe5c656130dc703b7e86a8d2a863ddb to your computer and use it in GitHub Desktop.
Save sboily/6fe5c656130dc703b7e86a8d2a863ddb to your computer and use it in GitHub Desktop.
List call from rtpengine python asyncio
#!/usr/bin/env python3
import aiohttp
import asyncio
import bencodepy
import random
async def main():
headers = {'content-type': 'application/x-rtpengine-ng'}
async with aiohttp.ClientSession(headers=headers) as session:
cookie = f"0_{random.randint(1000, 9999)}_1"
bdata = bencodepy.encode({'command': 'list'}).decode('utf-8')
data = f"{cookie} {bdata}"
async with session.post('http://xxx.xxx.xxx.xxx:xxx/ng', data=data) as response:
result = await response.text()
result = result.split(" ", 1)
r = bencodepy.decode(result[1])
print(r)
asyncio.run(main())
@vlad-korniiaka-idt
Copy link

vlad-korniiaka-idt commented Feb 17, 2023

Hello! Thank you for sharing this script, I faced with the issue while decoding the result string.
Here is the result of the request (example):
['0_9355_1', 'd5:callsl36:d38851c7-cf98-4cf8-9e6f-d0ab13877a7ee6:result2:oke']
And the line 17:
r = bencodepy.decode(result[1])
returns error:
bencodepy.exceptions.DecodingError: 'Invalid token character (d) at position 0.'

So, I encoded to bytes the result string:
result_bytes = result[1].encode('utf-8')

After that, bencodepy.decode function was able to decode.

Please see my changes:
https://gist.github.com/kt351b/44e7e82fa4f700b62f79a42217b6cda7#file-rtpengine_calls-py-L17

@sboily
Copy link
Author

sboily commented Feb 17, 2023

Hello, i'm not sure to understand why you want to encode the result in utf8 before the decoding of the result. That's probably the reason of the failure of the bencode decoder.

@vlad-korniiaka-idt
Copy link

vlad-korniiaka-idt commented Feb 17, 2023

Because if I run your script, I get this error:
Traceback (most recent call last):
File "/home/user/./rtpengine.py", line 20, in
asyncio.run(main())
File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/user/./rtpengine.py", line 17, in main
r = bencodepy.decode(result[1])
File "/usr/local/lib/python3.9/dist-packages/bencodepy/decoder.py", line 100, in decode
return decoder.decode()
File "/usr/local/lib/python3.9/dist-packages/bencodepy/decoder.py", line 55, in decode
return self.__wrap_with_tuple()
File "/usr/local/lib/python3.9/dist-packages/bencodepy/decoder.py", line 63, in __wrap_with_tuple
l.append(self.__parse())
File "/usr/local/lib/python3.9/dist-packages/bencodepy/decoder.py", line 49, in __parse
raise bencodepy.DecodingError(
bencodepy.exceptions.DecodingError: 'Invalid token character (d) at position 0.'

To fix this error, I did:
result_bytes = result[1].encode('utf-8')
r = bencodepy.decode(result_bytes)

@sboily
Copy link
Author

sboily commented Feb 17, 2023

I just make test with the same script.

~/dev/rtpengine-ws ❯ python3 main.py
{b'calls': [], b'result': b'ok'}
~/dev/rtpengine-ws ❯ python3 main.py
{b'calls': [b'0_3147657363@192.168.50.92'], b'result': b'ok'}

Maybe there is a different configuration?

@sboily
Copy link
Author

sboily commented Feb 17, 2023

rtpengine:~# apt show rtpengine
Package: rtpengine
Version: 11.0.1.7-1~bpo11+1

@sboily
Copy link
Author

sboily commented Feb 17, 2023

My rtpengine.conf

[rtpengine]
table = 0
interface = int/10.41.0.19;ext/172.16.42.20!xxx.xxx.xxx.xxx
listen-ng = 10.41.0.19:12221
listen-http = 10.41.0.19:8000
timeout = 60
silent-timeout = 3600
tos = 184
port-min = 50000
port-max = 51000
enable-jb = true

@sboily
Copy link
Author

sboily commented Feb 17, 2023

I'm using the URL of the listen-http for the connexion.

@vlad-korniiaka-idt
Copy link

vlad-korniiaka-idt commented Feb 17, 2023

Thanks for your reply!
When I do request to the localhost (I ran this script on rtpengine instance):

        async with session.post('http://localhost:9999/ng', data=data) as response:
            result = await response.text()
            result = result.split(" ", 1)
            print(result)
            print(type(result))
            print(result[1])
            print(type(result[1]))
            r = bencodepy.decode(result[1])
            print(r)

at line 17, I got this
print(result):
['0_5679_1',__ 'd5:callsl36:d38851c7-cf98-4cf8-9e6f-d0ab13877a7ee6:result2:oke']
print(type(result)):
<class 'list'>
print(result[1]):
d5:callsl36:d38851c7-cf98-4cf8-9e6f-d0ab13877a7ee6:result2:oke
print(type(result[1])):
<class 'str'>

and then that error that was posted above at the command bencodepy.decode(result[1])

**rtpengine --version**
Version: 10.1.1.4+0~mr10.1.1.4

**cat /etc/issue**
Debian GNU/Linux 11 \n \l

**cat /etc/rtpengine/rtpengine.conf** 
[rtpengine]
table = 0
interface = external/10.199.240.16!xxx.xxx.xxx.xxx;external_ice:1/10.199.240.16!xxx.xxx.xxx.xxx;external_ice:1/10.199.240.16;external_ice:1/SOME_IP_V6;external_v6/SOME_IP_V6
listen-ng = 10.199.240.16:9997
listen-udp = 10.199.240.16:9996
listen-cli = 127.0.0.1:9998
listen-http = 9999
timeout = 60
silent-timeout = 3600
tos = 184
port-min = 10000
port-max = 20000
log-stderr = false
log-level = 5
log-facility = local1

I hope it could be useful for someone who will use your script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment