mirror of
https://github.com/lanqian528/chat2api.git
synced 2026-06-13 21:02:46 +08:00
158 lines
6.6 KiB
Python
158 lines
6.6 KiB
Python
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"
|
|
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="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"',
|
|
"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/124.0.0.0 Safari/537.36 Edg/124.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) + "?oai-dm=1"}, 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))
|
|
response = Response(content=content, media_type=r.headers.get("content-type"),
|
|
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))
|