Hooshvare1 / app.py
Opera8's picture
Update app.py
9d2dc00 verified
Raw
History Blame Contribute Delete
7.81 kB
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"<h3>Proxy Engine Internal Error</h3><pre>{error_details}</pre>",
status_code=500,
media_type="text/html"
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)