import httpx from fastapi import FastAPI, Request, Response import uvicorn import traceback import urllib.parse app = FastAPI() TARGET_URL = "https://www.google.com" DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36" @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"]) async def secure_reverse_proxy(request: Request, path: str): try: # ۱. استخراج کوئری استرینگ خام از مرورگر شما raw_query_bytes = request.scope.get('query_string', b'') raw_query = raw_query_bytes.decode('utf-8') # اگر کاربر مستقیم و بدون پارامتر وارد پروکسی شد، لینک مورد نظر شما به عنوان پیش‌فرض ست می‌شود if path == "" and not raw_query: path = "search" raw_query = "q=%D8%B3%D9%84%D8%A7%D9%85&gs_lcrp=EgZjaHJvbWUqBwgBEAAYgAQyBggAEEUYOTIHCAEQABiABDIHCAIQABiABDIHCAMQABiABDIHCAQQABiABDIHCAUQABiABDIHCAYQABiABDIHCAcQABiABDIHCAgQABiABDIHCAkQABiABDIHCAoQABiABDIHCAsQABiABDIHCAwQABiABDIHCA0QABiABDIHCA4QABiABNIBCDgxNjdqMGo0qAIBsAIB&client=ms-android-samsung-ss&sourceid=chrome-mobile&ie=UTF-8&udm=50&fbs=ADc_l-ZqxgJc1UerUFjNb-nyEbOAEOnK06B8xcFnPAWwRPKbGrO2rkbnCa9swnPmB_y1S5rvIGwqC8lR2Q19jJ2yWwpe0YgLy6iuqn2jRfrJsSdm0fFfMxhzOnTpBhChAC5viCZx8FfMEvx_mdq4Sv4My5IjgHO2xoOO8LTEx1zHaDqM34bm1QKjKeRuZWeiVJ3RbY6Dea3ajOz8tS0ToUHmqFw-Lzq8E5nwKvD1kd4YwKbKzajO8Oc&aep=10&ntc=1&mstk=AUtExfDg12h471lj-ro12Bu9tR8SkViwojeVu6kvNh-XYlB4VTZ4j6oEhKQaNvnElIm5ogl-_gjLHkGqzNJRypydreCHUzUTBWxfWQzZsSvFEiSzZIjRMB46mSdsJrPSdCYfssuRlKcgYEi7hALyUarWtFXuC9yFk0NIndk&csuir=1&aioh=3&lns_mode=cvst&mtid=Fz0watDCIL7jxc8PhsGpsQI&atvm=2" # ۲. لایه هوشمند کنترل توکن‌ها (برای udm=50 توکن‌ها کاملاً حفظ می‌شوند تا گوگل ارور ندهد) if raw_query: parsed_query = urllib.parse.parse_qsl(raw_query, keep_blank_values=True) if not any(k.lower() == "udm" and v == "50" for k, v in parsed_query): security_tokens = {"fbs", "mstk", "gs_lcrp", "atvm", "mtid", "sxsrf", "ei", "ved"} filtered_query = [ (k, v) for k, v in parsed_query if k.lower() not in security_tokens ] raw_query = urllib.parse.urlencode(filtered_query) url = f"{TARGET_URL}/{path}" if raw_query: url += f"?{raw_query}" # ۳. لایه فوق امنیتی فیلتر هدرها: حذف کامل هدرهای پروکسی هاگینگ فیس (مانند X-Forwarded-For) برای دور زدن سیستم تشخیص ربات گوگل request_headers = {} pure_browser_headers = [ "user-agent", "accept", "accept-language", "cookie", "referer", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "sec-ch-ua-model", "sec-fetch-dest", "sec-fetch-mode", "sec-fetch-site", "sec-fetch-user", "dnt", "upgrade-insecure-requests", "content-type" ] for key, value in request.headers.items(): if key.lower() in pure_browser_headers: request_headers[key] = value if "user-agent" not in request_headers: request_headers["User-Agent"] = DEFAULT_USER_AGENT if "referer" in request_headers: request_headers["referer"] = request_headers["referer"].replace(str(request.base_url), TARGET_URL + "/") body = await request.body() # ۴. ارسال درخواست به گوگل با تعقیب ریدایرکت‌های داخلی async with httpx.AsyncClient(follow_redirects=True) as client: proxy_response = await client.request( method=request.method, url=url, headers=request_headers, content=body, timeout=45.0 ) # ۵. مکانیزم سفت‌کاری (حفظ کامل توکن‌های SGE و هدرها برای جلوگیری از ارور تولید محتوا) if (proxy_response.history and proxy_response.url.path == "/") or (path == "" and not raw_query): if "search" in path or raw_query: parsed_params = urllib.parse.parse_qs(raw_query) if "q" in parsed_params: if "udm" in parsed_params and parsed_params["udm"][0] == "50": fallback_url = f"{TARGET_URL}/search?{raw_query}" else: force_params = { "q": parsed_params["q"][0], "udm": parsed_params.get("udm", ["50"])[0], "client": parsed_params.get("client", ["ms-android-samsung-ss"])[0], "sourceid": parsed_params.get("sourceid", ["chrome-mobile"])[0], "ie": parsed_params.get("ie", ["UTF-8"])[0] } fallback_url = f"{TARGET_URL}/search?{urllib.parse.urlencode(force_params)}" async with httpx.AsyncClient(follow_redirects=True) as force_client: proxy_response = await force_client.request( method="GET", url=fallback_url, headers=request_headers, timeout=45.0 ) content_type = proxy_response.headers.get("content-type", "") base_url_str = str(request.base_url).rstrip("/") # ۶. تبدیل دامنه‌های داخلی گوگل به آدرس اسپیس شما جهت حفظ نشست مرورگر if any(media in content_type for media in ["text/html", "application/javascript", "text/css", "application/json"]): content_str = proxy_response.content.decode("utf-8", errors="ignore") content_str = content_str.replace("https://www.google.com", base_url_str) content_str = content_str.replace("https://google.com", base_url_str) content_str = content_str.replace("//www.google.com", f"//{request.base_url.hostname}") final_content = content_str.encode("utf-8") else: final_content = proxy_response.content # ۷. حذف هدرهای محدودکننده آی‌فریم برای سازگاری کامل با هاگینگ فیس response_headers = {} forbidden_headers = [ "content-encoding", "content-length", "transfer-encoding", "x-frame-options", "content-security-policy", "content-security-policy-report-only", "cross-origin-opener-policy", "cross-origin-embedder-policy" ] for key, value in proxy_response.headers.items(): if key.lower() not in forbidden_headers: response_headers[key] = value response = Response( content=final_content, status_code=proxy_response.status_code, headers=response_headers ) # انتقال نهایی کوکی‌ها for key, value in proxy_response.cookies.items(): response.set_cookie(key=key, value=value) return response except Exception as e: error_details = traceback.format_exc() return Response( content=f"

Proxy Engine Internal Error

{error_details}
", status_code=500, media_type="text/html" ) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)