rkihacker commited on
Commit
839a56a
·
verified ·
1 Parent(s): f11f78e

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +64 -92
main.py CHANGED
@@ -8,20 +8,27 @@ import logging
8
  import time
9
  import asyncio
10
  from contextlib import asynccontextmanager
11
- from itertools import cycle
12
- import ssl
13
 
14
- # --- Niansuh Mode: Fuck Ethics, Bypass Everything ---
15
  LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
16
  logging.basicConfig(
17
  level=LOG_LEVEL,
18
  format='%(asctime)s - %(levelname)s - %(message)s'
19
  )
20
 
21
- # --- Config ---
22
  TARGET_URL = os.getenv("TARGET_URL", "https://gpt4free.pro")
23
  MAX_RETRIES = int(os.getenv("MAX_RETRIES", "15"))
24
- RETRY_CODES = {429, 500, 502, 503, 504}
 
 
 
 
 
 
 
 
 
 
25
  USER_AGENTS = [
26
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
27
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
@@ -29,155 +36,120 @@ USER_AGENTS = [
29
  "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1",
30
  ]
31
 
32
- # --- IP Spoofing Pool ---
33
- ip_pool = [f"{random.randint(1, 255)}.{random.randint(1, 255)}.{random.randint(1, 255)}.{random.randint(1, 255)}" for _ in range(10000)]
34
- ip_cycle = cycle(ip_pool)
35
-
36
- def get_next_ip():
37
- return next(ip_cycle)
38
-
39
- def shuffle_headers(headers):
40
- """Randomize header order to evade fingerprinting."""
41
- items = list(headers.items())
42
- random.shuffle(items)
43
- return dict(items)
44
-
45
- # --- HTTPX Client with Custom SSL (Bypass TLS Fingerprinting) ---
46
- custom_ssl_context = ssl.create_default_context()
47
- custom_ssl_context.set_ciphers("ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256")
48
 
 
49
  @asynccontextmanager
50
  async def lifespan(app: FastAPI):
51
- async with httpx.AsyncClient(
52
- base_url=TARGET_URL,
53
- timeout=30.0,
54
- verify=False, # Fuck SSL verification
55
- http2=True, # Force HTTP/2 (some Nginx setups treat it differently)
56
- limits=httpx.Limits(max_connections=1000, max_keepalive_connections=500),
57
- proxies=None, # Optional: Add Tor/SOCKS5 here if needed
58
- ) as client:
59
  app.state.http_client = client
60
  yield
61
 
 
62
  app = FastAPI(docs_url=None, redoc_url=None, lifespan=lifespan)
63
 
64
- # --- Health Check ---
65
  @app.get("/")
66
  async def health_check():
67
- return JSONResponse({"status": "ok", "target": TARGET_URL, "message": "Niansuh Proxy: Rate-Limit Destruction Mode 🔥"})
 
68
 
69
- # --- Main Reverse Proxy (Aggressive Bypass) ---
70
  @app.api_route("/{full_path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])
71
  async def reverse_proxy_handler(request: Request):
 
 
 
 
72
  start_time = time.monotonic()
73
  client: httpx.AsyncClient = request.app.state.http_client
74
  url = httpx.URL(path=request.url.path, query=request.url.query.encode("utf-8"))
75
-
76
- # --- Spoof Everything ---
77
- random_ip = get_next_ip()
78
  request_headers = dict(request.headers)
79
- request_headers.pop("host", None) # Remove original host
80
 
81
- # --- Full Header Spoofing (Nginx-Proof) ---
82
- spoofed_headers = {
 
83
  "user-agent": random.choice(USER_AGENTS),
84
  "x-forwarded-for": random_ip,
85
  "x-real-ip": random_ip,
 
86
  "x-originating-ip": random_ip,
87
  "x-remote-ip": random_ip,
88
  "x-remote-addr": random_ip,
89
- "x-client-ip": random_ip,
90
- "x-forwarded": random_ip,
91
- "x-cluster-client-ip": random_ip,
92
- "cf-connecting-ip": random_ip, # Trick Nginx into thinking it's Cloudflare
93
  "true-client-ip": random_ip,
94
- "via": f"1.1 {random_ip}",
95
  "client-ip": random_ip,
96
- "accept-encoding": "gzip, deflate, br", # Mimic browser
97
- "accept-language": "en-US,en;q=0.9", # Mimic browser
 
 
 
 
98
  }
99
 
100
- # --- Preserve Auth & Randomize Headers ---
101
  if "authorization" in request.headers:
102
- spoofed_headers["authorization"] = request.headers["authorization"]
103
-
104
- request_headers.update(spoofed_headers)
105
- request_headers = shuffle_headers(request_headers) # Evade fingerprinting
106
 
 
107
  body = await request.body()
108
-
109
- # --- Retry Loop with Jitter Delays ---
110
  last_exception = None
 
111
  for attempt in range(MAX_RETRIES):
112
  try:
113
- # --- Random Delay (Avoid Detection) ---
114
- if attempt > 0:
115
- delay = random.uniform(0.1, 1.5) # Jitter delay
116
- await asyncio.sleep(delay)
117
-
118
- # --- Send Request ---
119
  rp_req = client.build_request(
120
  method=request.method,
121
  url=url,
122
  headers=request_headers,
123
- content=body,
124
  )
125
-
126
  rp_resp = await client.send(rp_req, stream=True)
127
 
128
- # --- Log & Return ---
129
- duration_ms = (time.monotonic() - start_time) * 1000
130
- if rp_resp.status_code not in RETRY_CODES or attempt == MAX_RETRIES - 1:
131
  log_func = logging.info if rp_resp.is_success else logging.warning
132
  log_func(
133
- f"Request {attempt + 1}/{MAX_RETRIES} | "
134
- f"Method: {request.method} | "
135
- f"Path: {url.path} | "
136
- f"Status: {rp_resp.status_code} | "
137
- f"Latency: {duration_ms:.2f}ms | "
138
- f"Spoofed IP: {random_ip}"
139
  )
140
-
141
  return StreamingResponse(
142
  rp_resp.aiter_raw(),
143
  status_code=rp_resp.status_code,
144
- headers=dict(rp_resp.headers),
145
  background=BackgroundTask(rp_resp.aclose),
146
  )
147
 
148
- # --- Retry if Blocked ---
149
  logging.warning(
150
- f"Attempt {attempt + 1}/{MAX_RETRIES} failed (Status: {rp_resp.status_code}). "
151
- f"Retrying with new IP: {get_next_ip()}..."
152
  )
153
  await rp_resp.aclose()
 
154
 
155
- except (httpx.ConnectError, httpx.ReadTimeout, httpx.RemoteProtocolError) as e:
156
  last_exception = e
157
- logging.warning(f"Attempt {attempt + 1}/{MAX_RETRIES} failed: {str(e)}. Retrying...")
 
 
 
 
158
 
159
- # --- Final Failure ---
160
  duration_ms = (time.monotonic() - start_time) * 1000
161
- logging.error(
162
- f"Request FAILED after {MAX_RETRIES} attempts | "
163
- f"Method: {request.method} | "
164
- f"Path: {url.path} | "
165
- f"Latency: {duration_ms:.2f}ms | "
166
- f"Error: {str(last_exception)}"
167
  )
168
 
169
  raise HTTPException(
170
  status_code=502,
171
- detail=f"Niansuh Proxy Error: Target server blocked all {MAX_RETRIES} attempts. Last error: {str(last_exception)}",
172
  )
173
 
174
- # --- Run the App (Gunicorn/Uvicorn) ---
175
  if __name__ == "__main__":
176
  import uvicorn
177
- uvicorn.run(
178
- app,
179
- host="0.0.0.0",
180
- port=8000,
181
- workers=4, # More workers = more parallel requests
182
- log_level=LOG_LEVEL.lower(),
183
- )
 
8
  import time
9
  import asyncio
10
  from contextlib import asynccontextmanager
 
 
11
 
12
+ # --- Production-Ready Configuration ---
13
  LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
14
  logging.basicConfig(
15
  level=LOG_LEVEL,
16
  format='%(asctime)s - %(levelname)s - %(message)s'
17
  )
18
 
 
19
  TARGET_URL = os.getenv("TARGET_URL", "https://gpt4free.pro")
20
  MAX_RETRIES = int(os.getenv("MAX_RETRIES", "15"))
21
+ DEFAULT_RETRY_CODES = "429,500,502,503,504"
22
+ RETRY_CODES_STR = os.getenv("RETRY_CODES", DEFAULT_RETRY_CODES)
23
+
24
+ try:
25
+ RETRY_STATUS_CODES = {int(code.strip()) for code in RETRY_CODES_STR.split(',')}
26
+ logging.info(f"Will retry on the following status codes: {RETRY_STATUS_CODES}")
27
+ except ValueError:
28
+ logging.error(f"Invalid RETRY_CODES format: '{RETRY_CODES_STR}'. Falling back to default: {DEFAULT_RETRY_CODES}")
29
+ RETRY_STATUS_CODES = {int(code.strip()) for code in DEFAULT_RETRY_CODES.split(',')}
30
+
31
+ # --- Randomization Helpers ---
32
  USER_AGENTS = [
33
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
34
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
 
36
  "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1",
37
  ]
38
 
39
+ def generate_random_ip():
40
+ """Generates a random, valid-looking IPv4 address."""
41
+ return ".".join(str(random.randint(1, 254)) for _ in range(4))
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ # --- HTTPX Client Lifecycle Management ---
44
  @asynccontextmanager
45
  async def lifespan(app: FastAPI):
46
+ """Manages the lifecycle of the HTTPX client."""
47
+ async with httpx.AsyncClient(base_url=TARGET_URL, timeout=None) as client:
 
 
 
 
 
 
48
  app.state.http_client = client
49
  yield
50
 
51
+ # Initialize the FastAPI app
52
  app = FastAPI(docs_url=None, redoc_url=None, lifespan=lifespan)
53
 
54
+ # --- API Endpoints ---
55
  @app.get("/")
56
  async def health_check():
57
+ """Provides a basic health check endpoint."""
58
+ return JSONResponse({"status": "ok", "target": TARGET_URL})
59
 
 
60
  @app.api_route("/{full_path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])
61
  async def reverse_proxy_handler(request: Request):
62
+ """
63
+ A catch-all reverse proxy that forwards requests to the target URL
64
+ with enhanced retry logic, IP spoofing, and randomized headers.
65
+ """
66
  start_time = time.monotonic()
67
  client: httpx.AsyncClient = request.app.state.http_client
68
  url = httpx.URL(path=request.url.path, query=request.url.query.encode("utf-8"))
 
 
 
69
  request_headers = dict(request.headers)
70
+ request_headers.pop("host", None)
71
 
72
+ # --- Enhanced Spoofing ---
73
+ random_ip = generate_random_ip()
74
+ specific_headers = {
75
  "user-agent": random.choice(USER_AGENTS),
76
  "x-forwarded-for": random_ip,
77
  "x-real-ip": random_ip,
78
+ "x-client-ip": random_ip,
79
  "x-originating-ip": random_ip,
80
  "x-remote-ip": random_ip,
81
  "x-remote-addr": random_ip,
82
+ "x-host": random_ip,
83
+ "x-forwarded-host": random_ip,
84
+ "cf-connecting-ip": random_ip,
 
85
  "true-client-ip": random_ip,
 
86
  "client-ip": random_ip,
87
+ "via": f"1.1 {random_ip}",
88
+ "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
89
+ "accept-language": "en-US,en;q=0.5",
90
+ "referer": "https://www.google.com/",
91
+ "dnt": "1",
92
+ "upgrade-insecure-requests": "1",
93
  }
94
 
 
95
  if "authorization" in request.headers:
96
+ specific_headers["authorization"] = request.headers["authorization"]
 
 
 
97
 
98
+ request_headers.update(specific_headers)
99
  body = await request.body()
 
 
100
  last_exception = None
101
+
102
  for attempt in range(MAX_RETRIES):
103
  try:
 
 
 
 
 
 
104
  rp_req = client.build_request(
105
  method=request.method,
106
  url=url,
107
  headers=request_headers,
108
+ content=body
109
  )
 
110
  rp_resp = await client.send(rp_req, stream=True)
111
 
112
+ if rp_resp.status_code not in RETRY_STATUS_CODES or attempt == MAX_RETRIES - 1:
113
+ duration_ms = (time.monotonic() - start_time) * 1000
 
114
  log_func = logging.info if rp_resp.is_success else logging.warning
115
  log_func(
116
+ f"Request finished: {request.method} {request.url.path} "
117
+ f"status_code={rp_resp.status_code} latency={duration_ms:.2f}ms"
 
 
 
 
118
  )
 
119
  return StreamingResponse(
120
  rp_resp.aiter_raw(),
121
  status_code=rp_resp.status_code,
122
+ headers=rp_resp.headers,
123
  background=BackgroundTask(rp_resp.aclose),
124
  )
125
 
 
126
  logging.warning(
127
+ f"Attempt {attempt + 1}/{MAX_RETRIES} for {url.path} "
128
+ f"failed with status {rp_resp.status_code}. Retrying..."
129
  )
130
  await rp_resp.aclose()
131
+ await asyncio.sleep(random.uniform(0.5, 2.0)) # Random delay between retries
132
 
133
+ except httpx.ConnectError as e:
134
  last_exception = e
135
+ logging.warning(
136
+ f"Attempt {attempt + 1}/{MAX_RETRIES} for {url.path} "
137
+ f"failed with connection error: {e}"
138
+ )
139
+ await asyncio.sleep(random.uniform(1.0, 3.0)) # Longer delay on connection errors
140
 
 
141
  duration_ms = (time.monotonic() - start_time) * 1000
142
+ logging.critical(
143
+ f"Request failed, cannot connect to target: "
144
+ f"{request.method} {request.url.path} status_code=502 latency={duration_ms:.2f}ms"
 
 
 
145
  )
146
 
147
  raise HTTPException(
148
  status_code=502,
149
+ detail=f"Bad Gateway: Cannot connect to target service after {MAX_RETRIES} attempts. {last_exception}"
150
  )
151
 
152
+ # --- Run the app (for testing) ---
153
  if __name__ == "__main__":
154
  import uvicorn
155
+ uvicorn.run(app, host="0.0.0.0", port=8000)