Rfym21 commited on
Commit
a7df830
·
verified ·
1 Parent(s): 7be0b4f

Upload 24 files

Browse files
app.py CHANGED
@@ -7,3 +7,4 @@ log_config["formatters"]["default"]["fmt"] = default_format
7
  log_config["formatters"]["access"]["fmt"] = access_format
8
 
9
  uvicorn.run("chat2api:app", host="0.0.0.0", port=5005)
 
 
7
  log_config["formatters"]["access"]["fmt"] = access_format
8
 
9
  uvicorn.run("chat2api:app", host="0.0.0.0", port=5005)
10
+ # uvicorn.run("chat2api:app", host="0.0.0.0", port=5005, ssl_keyfile="key.pem", ssl_certfile="cert.pem")
chat2api.py CHANGED
@@ -131,19 +131,33 @@ async def error_tokens():
131
  return {"status": "success", "error_tokens": error_tokens_list}
132
 
133
 
 
 
 
 
 
 
 
 
 
 
 
134
  if enable_gateway:
135
  @app.get("/", response_class=HTMLResponse)
136
- async def chatgpt(request: Request):
137
- seed_token = request.query_params.get("seed")
138
- if not seed_token:
139
- seed_token = request.cookies.get("seed_token")
140
- if not seed_token:
141
- seed_token = str(int(time.time()))
142
- req_token = get_req_token(seed_token)
143
- seed_token = await verify_token(req_token)
144
-
145
- response = templates.TemplateResponse("chatgpt.html", {"request": request, "access_token": seed_token})
146
- response.set_cookie("seed_token", value=seed_token)
 
 
 
147
  return response
148
 
149
 
@@ -205,8 +219,13 @@ if enable_gateway:
205
  }
206
 
207
 
208
- banned_paths = ["backend-api/accounts/logout_all", "backend-api/accounts/deactivate",
209
- "backend-api/user_system_messages"]
 
 
 
 
 
210
  redirect_paths = ["auth/logout"]
211
  chatgpt_paths = ["c/"]
212
 
@@ -215,7 +234,7 @@ if enable_gateway:
215
  async def reverse_proxy(request: Request, path: str):
216
  for chatgpt_path in chatgpt_paths:
217
  if chatgpt_path in path:
218
- return await chatgpt(request)
219
 
220
  for banned_path in banned_paths:
221
  if banned_path in path:
@@ -224,7 +243,9 @@ if enable_gateway:
224
  for redirect_path in redirect_paths:
225
  if redirect_path in path:
226
  redirect_url = str(request.base_url)
227
- return RedirectResponse(url=f"{redirect_url}?seed={int(time.time())}", status_code=302)
 
 
228
 
229
  return await chatgpt_reverse_proxy(request, path)
230
  else:
 
131
  return {"status": "success", "error_tokens": error_tokens_list}
132
 
133
 
134
+ @app.get(f"/{api_prefix}/tokens/add/{{token}}" if api_prefix else "/tokens/add/{token}")
135
+ async def add_token(token: str):
136
+ if token.strip() and not token.startswith("#"):
137
+ globals.token_list.append(token.strip())
138
+ with open("data/token.txt", "a", encoding="utf-8") as f:
139
+ f.write(token.strip() + "\n")
140
+ logger.info(f"Token count: {len(globals.token_list)}, Error token count: {len(globals.error_token_list)}")
141
+ tokens_count = len(set(globals.token_list) - set(globals.error_token_list))
142
+ return {"status": "success", "tokens_count": tokens_count}
143
+
144
+
145
  if enable_gateway:
146
  @app.get("/", response_class=HTMLResponse)
147
+ async def chatgpt_html(request: Request):
148
+ token = request.query_params.get("token")
149
+ if not token:
150
+ token = request.cookies.get("token")
151
+ if not token:
152
+ return await login_html(request)
153
+
154
+ response = templates.TemplateResponse("chatgpt.html", {"request": request, "token": token})
155
+ response.set_cookie("token", value=token)
156
+ return response
157
+
158
+ @app.get("/login", response_class=HTMLResponse)
159
+ async def login_html(request: Request):
160
+ response = templates.TemplateResponse("login.html", {"request": request})
161
  return response
162
 
163
 
 
219
  }
220
 
221
 
222
+ banned_paths = [
223
+ "backend-api/accounts/logout_all",
224
+ "backend-api/accounts/deactivate",
225
+ "backend-api/user_system_messages",
226
+ "backend-api/memories",
227
+ "backend-api/settings/clear_account_user_memory"
228
+ ]
229
  redirect_paths = ["auth/logout"]
230
  chatgpt_paths = ["c/"]
231
 
 
234
  async def reverse_proxy(request: Request, path: str):
235
  for chatgpt_path in chatgpt_paths:
236
  if chatgpt_path in path:
237
+ return await chatgpt_html(request)
238
 
239
  for banned_path in banned_paths:
240
  if banned_path in path:
 
243
  for redirect_path in redirect_paths:
244
  if redirect_path in path:
245
  redirect_url = str(request.base_url)
246
+ response = RedirectResponse(url=f"{redirect_url}", status_code=302)
247
+ response.delete_cookie("token")
248
+ return response
249
 
250
  return await chatgpt_reverse_proxy(request, path)
251
  else:
chatgpt/ChatService.py CHANGED
@@ -37,7 +37,7 @@ class ChatService:
37
  self.req_token = get_req_token(origin_token)
38
  self.ua = get_ua(self.req_token)
39
  self.user_agent = self.ua.get(
40
- "User-Agent",
41
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
42
  )
43
  self.chat_token = "gAAAAAB"
@@ -95,22 +95,22 @@ class ChatService:
95
  self.chat_request = None
96
 
97
  self.base_headers = {
98
- 'Accept': '*/*',
99
- 'Accept-Encoding': 'gzip, deflate, br, zstd',
100
- 'Accept-Language': 'en-US,en;q=0.9',
101
- 'Content-Type': 'application/json',
102
- 'Oai-Device-Id': self.oai_device_id,
103
- 'Oai-Language': 'en-US',
104
- 'Origin': self.host_url,
105
- 'Priority': 'u=1, i',
106
- 'Referer': f'{self.host_url}/',
107
- 'Sec-Ch-Ua': self.ua.get("Sec-Ch-Ua", '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"'),
108
- 'Sec-Ch-Ua-Mobile': self.ua.get("Sec-Ch-Ua-Mobile", "?0"),
109
- 'Sec-Ch-Ua-Platform': self.ua.get("Sec-Ch-Ua-Platform", '"Windows"'),
110
- 'Sec-Fetch-Dest': 'empty',
111
- 'Sec-Fetch-Mode': 'cors',
112
- 'Sec-Fetch-Site': 'same-origin',
113
- 'User-Agent': self.user_agent,
114
  }
115
  if self.access_token:
116
  self.base_url = self.host_url + "/backend-api"
@@ -281,22 +281,22 @@ class ChatService:
281
  self.chat_headers = self.base_headers.copy()
282
  self.chat_headers.update(
283
  {
284
- 'Accept': 'text/event-stream',
285
- 'Openai-Sentinel-Chat-Requirements-Token': self.chat_token,
286
- 'Openai-Sentinel-Proof-Token': self.proof_token,
287
  }
288
  )
289
  if self.ark0se_token:
290
- self.chat_headers['Openai-Sentinel-Ark' + 'ose-Token'] = self.ark0se_token
291
 
292
  if self.turnstile_token:
293
- self.chat_headers['Openai-Sentinel-Turnstile-Token'] = self.turnstile_token
294
 
295
  if conversation_only:
296
- self.chat_headers.pop('Openai-Sentinel-Chat-Requirements-Token', None)
297
- self.chat_headers.pop('Openai-Sentinel-Proof-Token', None)
298
- self.chat_headers.pop('Openai-Sentinel-Ark' + 'ose-Token', None)
299
- self.chat_headers.pop('Openai-Sentinel-Turnstile-Token', None)
300
 
301
  if "gpt-4-gizmo" in self.origin_model:
302
  gizmo_id = self.origin_model.split("gpt-4-gizmo-")[-1]
@@ -429,10 +429,10 @@ class ChatService:
429
  headers = self.base_headers.copy()
430
  headers.update(
431
  {
432
- 'Accept': 'application/json, text/plain, */*',
433
- 'Content-Type': mime_type,
434
- 'X-Ms-Blob-Type': 'BlockBlob',
435
- 'X-Ms-Version': '2020-04-08',
436
  }
437
  )
438
  headers.pop('Authorization', None)
 
37
  self.req_token = get_req_token(origin_token)
38
  self.ua = get_ua(self.req_token)
39
  self.user_agent = self.ua.get(
40
+ "user-agent",
41
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
42
  )
43
  self.chat_token = "gAAAAAB"
 
95
  self.chat_request = None
96
 
97
  self.base_headers = {
98
+ 'accept': '*/*',
99
+ 'accept-encoding': 'gzip, deflate, br, zstd',
100
+ 'accept-language': 'en-US,en;q=0.9',
101
+ 'content-type': 'application/json',
102
+ 'oai-device-id': self.oai_device_id,
103
+ 'oai-language': 'en-US',
104
+ 'origin': self.host_url,
105
+ 'priority': 'u=1, i',
106
+ 'referer': f'{self.host_url}/',
107
+ 'sec-ch-ua': self.ua.get("sec-ch-ua", '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"'),
108
+ 'sec-ch-ua-mobile': self.ua.get("sec-ch-ua-mobile", "?0"),
109
+ 'sec-ch-ua-platform': self.ua.get("sec-ch-ua-platform", '"Windows"'),
110
+ 'sec-fetch-dest': 'empty',
111
+ 'sec-fetch-mode': 'cors',
112
+ 'sec-fetch-site': 'same-origin',
113
+ 'user-agent': self.user_agent
114
  }
115
  if self.access_token:
116
  self.base_url = self.host_url + "/backend-api"
 
281
  self.chat_headers = self.base_headers.copy()
282
  self.chat_headers.update(
283
  {
284
+ 'accept': 'text/event-stream',
285
+ 'openai-sentinel-chat-requirements-token': self.chat_token,
286
+ 'openai-sentinel-proof-token': self.proof_token,
287
  }
288
  )
289
  if self.ark0se_token:
290
+ self.chat_headers['openai-sentinel-ark' + 'ose-token'] = self.ark0se_token
291
 
292
  if self.turnstile_token:
293
+ self.chat_headers['openai-sentinel-turnstile-token'] = self.turnstile_token
294
 
295
  if conversation_only:
296
+ self.chat_headers.pop('openai-sentinel-chat-requirements-token', None)
297
+ self.chat_headers.pop('openai-sentinel-proof-token', None)
298
+ self.chat_headers.pop('openai-sentinel-ark' + 'ose-token', None)
299
+ self.chat_headers.pop('openai-sentinel-turnstile-token', None)
300
 
301
  if "gpt-4-gizmo" in self.origin_model:
302
  gizmo_id = self.origin_model.split("gpt-4-gizmo-")[-1]
 
429
  headers = self.base_headers.copy()
430
  headers.update(
431
  {
432
+ 'accept': 'application/json, text/plain, */*',
433
+ 'content-type': mime_type,
434
+ 'x-ms-blob-type': 'BlockBlob',
435
+ 'x-ms-version': '2020-04-08',
436
  }
437
  )
438
  headers.pop('Authorization', None)
chatgpt/authorization.py CHANGED
@@ -1,4 +1,5 @@
1
  import asyncio
 
2
  import os
3
  import random
4
 
@@ -40,16 +41,30 @@ def get_req_token(req_token, seed=None):
40
 
41
  def get_ua(req_token):
42
  user_agent = globals.user_agent_map.get(req_token, "")
43
- # token为空,免登录用户,则随机生成ua
44
  if not user_agent:
45
- ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
46
- return {
47
- "User-Agent": ua.text,
48
- "Sec-Ch-Ua-Platform": ua.platform,
49
- "Sec-Ch-Ua": ua.ch.brands,
50
- "Sec-Ch-Ua-Mobile": ua.ch.mobile,
51
- "impersonate": random.choice(globals.impersonate_list),
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  else:
54
  return user_agent
55
 
 
1
  import asyncio
2
+ import json
3
  import os
4
  import random
5
 
 
41
 
42
  def get_ua(req_token):
43
  user_agent = globals.user_agent_map.get(req_token, "")
44
+ user_agent = {k.lower(): v for k, v in user_agent.items()}
45
  if not user_agent:
46
+ if not req_token:
47
+ ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
48
+ return {
49
+ "user-agent": ua.text,
50
+ "sec-ch-ua-platform": ua.platform,
51
+ "sec-ch-ua": ua.ch.brands,
52
+ "sec-ch-ua-mobile": ua.ch.mobile,
53
+ "impersonate": random.choice(globals.impersonate_list),
54
+ }
55
+ else:
56
+ ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
57
+ user_agent = {
58
+ "user-agent": ua.text,
59
+ "sec-ch-ua-platform": ua.platform,
60
+ "sec-ch-ua": ua.ch.brands,
61
+ "sec-ch-ua-mobile": ua.ch.mobile,
62
+ "impersonate": random.choice(globals.impersonate_list),
63
+ }
64
+ globals.user_agent_map[req_token] = user_agent
65
+ with open(globals.USER_AGENTS_FILE, "a", encoding="utf-8") as f:
66
+ f.write(json.dumps({req_token: user_agent}, indent=4))
67
+ return user_agent
68
  else:
69
  return user_agent
70
 
chatgpt/globals.py CHANGED
@@ -78,10 +78,10 @@ if os.path.exists(USER_AGENTS_FILE):
78
  for token in new_tokens:
79
  ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
80
  ua_dict = {
81
- "User-Agent": ua.text,
82
- "Sec-Ch-Ua-Platform": ua.platform,
83
- "Sec-Ch-Ua": ua.ch.brands,
84
- "Sec-Ch-Ua-Mobile": ua.ch.mobile,
85
  "impersonate": random.choice(impersonate_list),
86
  }
87
  user_agent_map[token] = ua_dict
@@ -91,10 +91,10 @@ else:
91
  for token in token_list:
92
  ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
93
  ua_dict = {
94
- "User-Agent": ua.text,
95
- "Sec-Ch-Ua-Platform": ua.platform,
96
- "Sec-Ch-Ua": ua.ch.brands,
97
- "Sec-Ch-Ua-Mobile": ua.ch.mobile,
98
  "impersonate": random.choice(impersonate_list),
99
  }
100
  user_agent_map[token] = ua_dict
 
78
  for token in new_tokens:
79
  ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
80
  ua_dict = {
81
+ "user-agent": ua.text,
82
+ "sec-ch-ua-platform": ua.platform,
83
+ "sec-ch-ua": ua.ch.brands,
84
+ "sec-ch-ua-mobile": ua.ch.mobile,
85
  "impersonate": random.choice(impersonate_list),
86
  }
87
  user_agent_map[token] = ua_dict
 
91
  for token in token_list:
92
  ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
93
  ua_dict = {
94
+ "user-agent": ua.text,
95
+ "sec-ch-ua-platform": ua.platform,
96
+ "sec-ch-ua": ua.ch.brands,
97
+ "sec-ch-ua-mobile": ua.ch.mobile,
98
  "impersonate": random.choice(impersonate_list),
99
  }
100
  user_agent_map[token] = ua_dict
chatgpt/reverseProxy.py CHANGED
@@ -5,7 +5,7 @@ from fastapi import Request, HTTPException
5
  from fastapi.responses import StreamingResponse, Response
6
  from starlette.background import BackgroundTask
7
 
8
- from chatgpt.authorization import verify_token, get_req_token
9
  from utils.Client import Client
10
  from utils.config import chatgpt_base_url_list, proxy_url_list, enable_gateway
11
 
@@ -61,6 +61,15 @@ headers_reject_list = [
61
  ]
62
 
63
 
 
 
 
 
 
 
 
 
 
64
  async def chatgpt_reverse_proxy(request: Request, path: str):
65
  try:
66
  origin_host = request.url.netloc
@@ -79,7 +88,7 @@ async def chatgpt_reverse_proxy(request: Request, path: str):
79
 
80
  headers = {
81
  key: value for key, value in request.headers.items()
82
- if (key.lower() not in ["host", "origin", "referer"] and key.lower() not in headers_reject_list)
83
  }
84
 
85
  base_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
@@ -88,31 +97,23 @@ async def chatgpt_reverse_proxy(request: Request, path: str):
88
  if "file-" in path and "backend-api" not in path:
89
  base_url = "https://files.oaiusercontent.com"
90
 
91
- # req_token = request.cookies.get("req_token")
92
- # ua = get_ua(req_token)
93
- # headers.update(ua)
 
 
94
  headers.update({
95
  "accept-language": "en-US,en;q=0.9",
96
  "host": base_url.replace("https://", "").replace("http://", ""),
97
  "origin": base_url,
98
- "referer": f"{base_url}/",
99
- "sec-fetch-dest": "empty",
100
- "sec-fetch-mode": "cors",
101
- "sec-fetch-site": "same-origin",
102
  })
103
 
104
- seed_token = headers.get("authorization", "").replace("Bearer ", "")
105
- if seed_token:
106
- req_token = get_req_token(seed_token)
107
  access_token = await verify_token(req_token)
108
- if access_token.startswith("eyJhbGciOi"):
109
- headers.update({"authorization": access_token})
110
- else:
111
- req_token = get_req_token(None, seed_token)
112
- access_token = await verify_token(req_token)
113
- headers.update({"authorization": access_token})
114
- else:
115
- headers.pop("authorization", None)
116
 
117
  data = await request.body()
118
 
 
5
  from fastapi.responses import StreamingResponse, Response
6
  from starlette.background import BackgroundTask
7
 
8
+ from chatgpt.authorization import verify_token, get_req_token, get_ua
9
  from utils.Client import Client
10
  from utils.config import chatgpt_base_url_list, proxy_url_list, enable_gateway
11
 
 
61
  ]
62
 
63
 
64
+ async def get_real_req_token(token):
65
+ req_token = get_req_token(token)
66
+ if len(req_token) == 45 or req_token.startswith("eyJhbGciOi"):
67
+ return req_token
68
+ else:
69
+ req_token = get_req_token(None, token)
70
+ return req_token
71
+
72
+
73
  async def chatgpt_reverse_proxy(request: Request, path: str):
74
  try:
75
  origin_host = request.url.netloc
 
88
 
89
  headers = {
90
  key: value for key, value in request.headers.items()
91
+ if (key.lower() not in ["host", "origin", "referer", "priority", "oai-device-id"] and key.lower() not in headers_reject_list)
92
  }
93
 
94
  base_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
 
97
  if "file-" in path and "backend-api" not in path:
98
  base_url = "https://files.oaiusercontent.com"
99
 
100
+ token = request.cookies.get("token")
101
+ req_token = await get_real_req_token(token)
102
+ ua = get_ua(req_token)
103
+ headers.update(ua)
104
+
105
  headers.update({
106
  "accept-language": "en-US,en;q=0.9",
107
  "host": base_url.replace("https://", "").replace("http://", ""),
108
  "origin": base_url,
109
+ "referer": f"{base_url}/"
 
 
 
110
  })
111
 
112
+ token = headers.get("authorization", "").replace("Bearer ", "")
113
+ if token:
114
+ req_token = await get_real_req_token(token)
115
  access_token = await verify_token(req_token)
116
+ headers.update({"authorization": access_token})
 
 
 
 
 
 
 
117
 
118
  data = await request.body()
119
 
templates/chatgpt.html CHANGED
The diff for this file is too large to render. See raw diff
 
utils/config.py CHANGED
@@ -52,7 +52,7 @@ proxy_url_list = proxy_url.split(',') if proxy_url else []
52
  user_agents_list = ast.literal_eval(user_agents)
53
 
54
  logger.info("-" * 60)
55
- logger.info("Chat2Api 1.5.6 | https://github.com/lanqian528/chat2api")
56
  logger.info("-" * 60)
57
  logger.info("Environment variables:")
58
  logger.info("API_PREFIX: " + str(api_prefix))
 
52
  user_agents_list = ast.literal_eval(user_agents)
53
 
54
  logger.info("-" * 60)
55
+ logger.info("Chat2Api 1.5.10 | https://github.com/lanqian528/chat2api")
56
  logger.info("-" * 60)
57
  logger.info("Environment variables:")
58
  logger.info("API_PREFIX: " + str(api_prefix))