|
| 1 | +import asyncio |
1 | 2 | import ctypes
|
| 3 | +import json |
2 | 4 | import os
|
3 | 5 | from platform import machine
|
4 | 6 | from sys import platform
|
5 | 7 |
|
| 8 | +from .exceptions import TLSClientException |
| 9 | + |
6 | 10 | if platform == 'darwin':
|
7 | 11 | file_ext = '-arm64.dylib' if machine() == "arm64" else '-x86.dylib'
|
8 | 12 | elif platform in ('win32', 'cygwin'):
|
|
19 | 23 | binary_filepath = os.path.join(root_dir, 'dependencies', f'tls-client{file_ext}')
|
20 | 24 | library = ctypes.cdll.LoadLibrary(binary_filepath)
|
21 | 25 |
|
22 |
| -# extract the exposed request function from the shared package |
23 |
| -request = library.request |
24 |
| -request.argtypes = [ctypes.c_char_p] |
25 |
| -request.restype = ctypes.c_char_p |
| 26 | +# Extract methods from the shared library |
| 27 | +_freeMemory = library.freeMemory |
| 28 | +_freeMemory.argtypes = [ctypes.c_char_p] |
| 29 | +_freeMemory.restype = ctypes.c_char_p |
| 30 | + |
| 31 | +_request = library.request |
| 32 | +_request.argtypes = [ctypes.c_char_p] |
| 33 | +_request.restype = ctypes.c_char_p |
| 34 | + |
| 35 | +_destroySession = library.destroySession |
| 36 | +_destroySession.argtypes = [ctypes.c_char_p] |
| 37 | +_destroySession.restype = ctypes.c_char_p |
| 38 | + |
| 39 | +_getCookiesFromSession = library.getCookiesFromSession |
| 40 | +_getCookiesFromSession.argtypes = [ctypes.c_char_p] |
| 41 | +_getCookiesFromSession.restype = ctypes.c_char_p |
| 42 | + |
| 43 | +_addCookiesToSession = library.addCookiesToSession |
| 44 | +_addCookiesToSession.argtypes = [ctypes.c_char_p] |
| 45 | +_addCookiesToSession.restype = ctypes.c_char_p |
| 46 | + |
| 47 | + |
| 48 | +async def free_memory(response_id: str): |
| 49 | + await asyncio.to_thread(_freeMemory, response_id.encode('utf-8')) |
| 50 | + |
| 51 | + |
| 52 | +async def request(payload: dict) -> dict: |
| 53 | + response = await asyncio.to_thread( |
| 54 | + _request, |
| 55 | + json.dumps(payload).encode('utf-8') |
| 56 | + ) |
| 57 | + response_bytes = ctypes.string_at(response) |
| 58 | + response_string = response_bytes.decode('utf-8') |
| 59 | + response_object = json.loads(response_string) |
| 60 | + |
| 61 | + await free_memory(response_object["id"]) |
| 62 | + |
| 63 | + if response_object["status"] == 0: |
| 64 | + raise TLSClientException(response_object["body"]) |
| 65 | + |
| 66 | + return response_object |
| 67 | + |
| 68 | + |
| 69 | +async def destroy_session(session_id: str) -> dict: |
| 70 | + destroy_session_response = await asyncio.to_thread( |
| 71 | + _destroySession, |
| 72 | + json.dumps({"sessionId": session_id}).encode('utf-8') |
| 73 | + ) |
| 74 | + destroy_session_response_bytes = ctypes.string_at(destroy_session_response) |
| 75 | + destroy_session_response_string = destroy_session_response_bytes.decode('utf-8') |
| 76 | + destroy_session_response_object = json.loads(destroy_session_response_string) |
| 77 | + await free_memory(destroy_session_response_object['id']) |
| 78 | + return destroy_session_response_object |
| 79 | + |
| 80 | + |
| 81 | +async def get_cookies_from_session(session_id: str, url: str) -> dict: |
| 82 | + cookies_response = await asyncio.to_thread( |
| 83 | + _getCookiesFromSession, |
| 84 | + json.dumps({"sessionId": session_id, "url": url}).encode('utf-8') |
| 85 | + ) |
| 86 | + # we dereference the pointer to a byte array |
| 87 | + cookies_response_bytes = ctypes.string_at(cookies_response) |
| 88 | + # convert our byte array to a string (tls client returns json) |
| 89 | + cookies_response_string = cookies_response_bytes.decode('utf-8') |
| 90 | + # convert response string to json |
| 91 | + cookies_response_object = json.loads(cookies_response_string) |
| 92 | + return cookies_response_object |
26 | 93 |
|
27 |
| -freeMemory = library.freeMemory |
28 |
| -freeMemory.argtypes = [ctypes.c_char_p] |
29 |
| -freeMemory.restype = ctypes.c_char_p |
30 | 94 |
|
31 |
| -destroySession = library.destroySession |
32 |
| -destroySession.argtypes = [ctypes.c_char_p] |
33 |
| -destroySession.restype = ctypes.c_char_p |
| 95 | +async def add_cookies_to_session(session_id, cookies: list[dict], url: str) -> dict: |
| 96 | + add_cookies_to_session_response = await asyncio.to_thread( |
| 97 | + _addCookiesToSession, |
| 98 | + json.dumps({"cookies": cookies, "sessionId": session_id, "url": url}).encode('utf-8') |
| 99 | + ) |
| 100 | + add_cookies_bytes = ctypes.string_at(add_cookies_to_session_response) |
| 101 | + add_cookies_string = add_cookies_bytes.decode('utf-8') |
| 102 | + add_cookies_object = json.loads(add_cookies_string) |
| 103 | + return add_cookies_object |
0 commit comments