| import random | |
| from fastapi import Request, HTTPException | |
| from fastapi.responses import StreamingResponse, Response | |
| from starlette.background import BackgroundTask | |
| from utils.Client import Client | |
| from utils.config import chatgpt_base_url_list, proxy_url_list, enable_gateway | |
| headers_reject_list = [ | |
| "x-real-ip", | |
| "x-forwarded-for", | |
| "x-forwarded-proto", | |
| "x-forwarded-port", | |
| "x-forwarded-host", | |
| "x-forwarded-server", | |
| "cf-warp-tag-id", | |
| "cf-visitor", | |
| "cf-ray", | |
| "cf-connecting-ip", | |
| "cf-ipcountry", | |
| "cdn-loop", | |
| "remote-host", | |
| "x-frame-options", | |
| "x-xss-protection", | |
| "x-content-type-options", | |
| "content-security-policy", | |
| "host", | |
| "cookie", | |
| "connection", | |
| "content-length", | |
| "content-encoding", | |
| "x-middleware-prefetch", | |
| "x-nextjs-data", | |
| "purpose", | |
| "x-forwarded-uri", | |
| "x-forwarded-path", | |
| "x-forwarded-method", | |
| "x-forwarded-protocol", | |
| "x-forwarded-scheme", | |
| "cf-request-id", | |
| "cf-worker", | |
| "cf-access-client-id", | |
| "cf-access-client-device-type", | |
| "cf-access-client-device-model", | |
| "cf-access-client-device-name", | |
| "cf-access-client-device-brand", | |
| "x-middleware-prefetch", | |
| "x-forwarded-for", | |
| "x-forwarded-host", | |
| "x-forwarded-proto", | |
| "x-forwarded-server", | |
| "x-real-ip", | |
| "x-forwarded-port", | |
| "cf-connecting-ip", | |
| "cf-ipcountry", | |
| "cf-ray", | |
| "cf-visitor", | |
| ] | |
| async def chatgpt_reverse_proxy(request: Request, path: str): | |
| if not enable_gateway: | |
| raise HTTPException(status_code=404, detail="Gateway is disabled") | |
| try: | |
| origin_host = request.url.netloc | |
| if ":" in origin_host: | |
| petrol = "http" | |
| else: | |
| petrol = "https" | |
| if path.startswith("v1/"): | |
| base_url = "https://ab.chatgpt.com" | |
| else: | |
| base_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com" | |
| if "/assets" in path: | |
| base_url = "https://cdn.oaistatic.com" | |
| params = dict(request.query_params) | |
| headers = { | |
| key: value for key, value in request.headers.items() | |
| if (key.lower() not in ["host", "origin", "referer", "user-agent", | |
| "authorization"] and key.lower() not in headers_reject_list) | |
| } | |
| request_cookies = dict(request.cookies) | |
| headers.update({ | |
| "accept-Language": "en-US,en;q=0.9", | |
| "host": base_url.replace("https://", "").replace("http://", ""), | |
| "origin": base_url, | |
| "referer": f"{base_url}/", | |
| "sec-ch-ua": '"Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"', | |
| "sec-ch-ua-mobile": "?0", | |
| "sec-ch-ua-platform": "\"Windows\"", | |
| "sec-fetch-dest": "empty", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-site": "same-origin", | |
| "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0" | |
| }) | |
| if request.headers.get('Authorization'): | |
| headers['Authorization'] = request.headers['Authorization'] | |
| if headers.get("Content-Type") == "application/json": | |
| data = await request.json() | |
| else: | |
| data = await request.body() | |
| client = Client(proxy=random.choice(proxy_url_list) if proxy_url_list else None) | |
| try: | |
| background = BackgroundTask(client.close) | |
| r = await client.request(request.method, f"{base_url}/{path}", params=params, headers=headers, | |
| cookies=request_cookies, data=data, stream=True, allow_redirects=False) | |
| if r.status_code == 304: | |
| return Response(status_code=304, background=background) | |
| elif r.status_code == 307: | |
| if "oai-dm=1" not in r.headers.get("Location"): | |
| return Response(status_code=307, headers={ | |
| "Location": r.headers.get("Location").replace("chat.openai.com", origin_host) | |
| .replace("chatgpt.com", origin_host) | |
| .replace("https", petrol)}, background=background) | |
| else: | |
| return Response(status_code=307, headers={"Location": r.headers.get("Location")}, | |
| background=background) | |
| elif r.status_code == 302: | |
| return Response(status_code=302, | |
| headers={"Location": r.headers.get("Location").replace("chatgpt.com", origin_host) | |
| .replace("chat.openai.com", origin_host) | |
| .replace("ab.chatgpt.com", origin_host) | |
| .replace("cdn.oaistatic.com", origin_host) | |
| .replace("https", petrol)}, background=background) | |
| elif 'stream' in r.headers.get("content-type", ""): | |
| return StreamingResponse(r.aiter_content(), media_type=r.headers.get("content-type", ""), | |
| background=background) | |
| else: | |
| if "/conversation" in path or "/register-websocket" in path: | |
| response = Response(content=(await r.atext()), media_type=r.headers.get("content-type"), | |
| status_code=r.status_code, background=background) | |
| else: | |
| content = ((await r.atext()).replace("chatgpt.com", origin_host) | |
| .replace("chat.openai.com", origin_host) | |
| .replace("ab.chatgpt.com", origin_host) | |
| .replace("cdn.oaistatic.com", origin_host) | |
| .replace("https", petrol)) | |
| rheaders = dict(r.headers) | |
| cache_control = rheaders.get("cache-control", "") | |
| content_type = rheaders.get("content-type", "") | |
| rheaders = { | |
| "cache-control": cache_control, | |
| "content-type": content_type | |
| } | |
| response = Response(content=content, headers=rheaders, | |
| status_code=r.status_code, background=background) | |
| for cookie_name in r.cookies: | |
| if cookie_name in request_cookies: | |
| continue | |
| for cookie_domain in [".chatgpt.com"]: | |
| cookie_value = r.cookies.get(name=cookie_name, domain=cookie_domain) | |
| if cookie_name.startswith("__"): | |
| response.set_cookie(key=cookie_name, value=cookie_value, secure=True, httponly=True) | |
| else: | |
| response.set_cookie(key=cookie_name, value=cookie_value) | |
| return response | |
| except Exception: | |
| await client.close() | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |