Files
ad/molodetz/curl_transport.py
T

62 lines
2.0 KiB
Python
Raw Normal View History

2026-10-05 09:36:20 +02:00
# retoor <retoor@molodetz.nl>
import httpx
try:
from curl_cffi import CurlHttpVersion
from curl_cffi.requests import AsyncSession
CURL_AVAILABLE = True
except ImportError:
CURL_AVAILABLE = False
IMPERSONATE_PROFILE = "chrome"
class CurlImpersonationTransport(httpx.AsyncBaseTransport):
def __init__(self, proxy=None, timeout=30.0, verify=True):
self.proxy = proxy or None
self.timeout = timeout
self.verify = verify
self._session = None
def _session_for(self):
if self._session is None:
self._session = AsyncSession(impersonate=IMPERSONATE_PROFILE, verify=self.verify)
return self._session
async def handle_async_request(self, request):
url = str(request.url)
http_version = CurlHttpVersion.V1_1 if request.url.scheme == "http" else None
headers = {
key.decode("latin-1"): value.decode("latin-1")
for key, value in request.headers.raw
if key.lower() not in (b"host", b"content-length", b"user-agent", b"accept-encoding", b"connection")
}
body = await request.aread()
kwargs = {
"headers": headers,
"data": body or None,
"timeout": self.timeout,
"allow_redirects": False,
"proxy": self.proxy,
}
if http_version is not None:
kwargs["http_version"] = http_version
response = await self._session_for().request(request.method, url, **kwargs)
response_headers = [
(key, value)
for key, value in response.headers.multi_items()
if key.lower() not in ("content-encoding", "content-length", "transfer-encoding")
]
return httpx.Response(
status_code=response.status_code,
headers=response_headers,
content=response.content,
request=request,
)
async def aclose(self):
if self._session is not None:
await self._session.close()
self._session = None