Chat2API / chatgpt /reverseProxy.py
Rfym21's picture
Upload 24 files
a7df830 verified
raw
history blame
6.12 kB
import json
import random
from fastapi import Request, HTTPException
from fastapi.responses import StreamingResponse, Response
from starlette.background import BackgroundTask
from chatgpt.authorization import verify_token, get_req_token, get_ua
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 get_real_req_token(token):
req_token = get_req_token(token)
if len(req_token) == 45 or req_token.startswith("eyJhbGciOi"):
return req_token
else:
req_token = get_req_token(None, token)
return req_token
async def chatgpt_reverse_proxy(request: Request, path: str):
try:
origin_host = request.url.netloc
if request.url.is_secure:
petrol = "https"
else:
petrol = "http"
if "x-forwarded-proto" in request.headers:
petrol = request.headers["x-forwarded-proto"]
if "cf-visitor" in request.headers:
cf_visitor = json.loads(request.headers["cf-visitor"])
petrol = cf_visitor.get("scheme", petrol)
params = dict(request.query_params)
request_cookies = dict(request.cookies)
headers = {
key: value for key, value in request.headers.items()
if (key.lower() not in ["host", "origin", "referer", "priority", "oai-device-id"] and key.lower() not in headers_reject_list)
}
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"
if "file-" in path and "backend-api" not in path:
base_url = "https://files.oaiusercontent.com"
token = request.cookies.get("token")
req_token = await get_real_req_token(token)
ua = get_ua(req_token)
headers.update(ua)
headers.update({
"accept-language": "en-US,en;q=0.9",
"host": base_url.replace("https://", "").replace("http://", ""),
"origin": base_url,
"referer": f"{base_url}/"
})
token = headers.get("authorization", "").replace("Bearer ", "")
if token:
req_token = await get_real_req_token(token)
access_token = await verify_token(req_token)
headers.update({"authorization": access_token})
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 == 302:
return Response(status_code=302,
headers={"Location": r.headers.get("Location").replace("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 "/backend-api/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("cdn.oaistatic.com", origin_host)
# .replace("files.oaiusercontent.com", origin_host)
.replace("https", petrol))
rheaders = dict(r.headers)
content_type = rheaders.get("content-type", "")
cache_control = rheaders.get("cache-control", "")
expires = rheaders.get("expires", "")
rheaders = {
"cache-control": cache_control,
"content-type": content_type,
"expires": expires
}
response = Response(content=content, headers=rheaders,
status_code=r.status_code, background=background)
return response
except Exception:
await client.close()
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))