Update main.py
Browse files
main.py
CHANGED
|
@@ -17,10 +17,11 @@ logging.basicConfig(
|
|
| 17 |
)
|
| 18 |
logger = logging.getLogger(__name__)
|
| 19 |
|
| 20 |
-
# ---
|
|
|
|
|
|
|
| 21 |
TARGET_HOST = os.getenv("TARGET_HOST", "https://console.gmicloud.ai")
|
| 22 |
-
|
| 23 |
-
logger.info(f"Proxying requests to host: {TARGET_HOST} with path prefix: {TARGET_PATH_PREFIX}")
|
| 24 |
|
| 25 |
# --- Retry Logic Configuration ---
|
| 26 |
MAX_RETRIES = int(os.getenv("MAX_RETRIES", "5"))
|
|
@@ -43,11 +44,7 @@ def generate_random_ip():
|
|
| 43 |
# --- HTTPX Client Lifecycle Management ---
|
| 44 |
@asynccontextmanager
|
| 45 |
async def lifespan(app: FastAPI):
|
| 46 |
-
"""
|
| 47 |
-
Manages the lifecycle of the HTTPX client.
|
| 48 |
-
The client is created on startup and closed gracefully on shutdown.
|
| 49 |
-
"""
|
| 50 |
-
# *** THE FIX IS HERE: Removed http2=True to avoid dependency error ***
|
| 51 |
async with httpx.AsyncClient(base_url=TARGET_HOST, timeout=None) as client:
|
| 52 |
logger.info(f"HTTPX client created for target: {TARGET_HOST}")
|
| 53 |
app.state.http_client = client
|
|
@@ -67,21 +64,20 @@ async def health_check():
|
|
| 67 |
return JSONResponse({
|
| 68 |
"status": "ok",
|
| 69 |
"target_host": TARGET_HOST,
|
| 70 |
-
"target_path_prefix": TARGET_PATH_PREFIX
|
| 71 |
})
|
| 72 |
|
| 73 |
|
| 74 |
@app.api_route("/{full_path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])
|
| 75 |
-
async def reverse_proxy_handler(request: Request
|
| 76 |
"""
|
| 77 |
-
A catch-all reverse proxy that forwards requests to the target
|
| 78 |
-
|
| 79 |
"""
|
| 80 |
start_time = time.monotonic()
|
| 81 |
client: httpx.AsyncClient = request.app.state.http_client
|
| 82 |
|
| 83 |
-
|
| 84 |
-
url = httpx.URL(path=
|
| 85 |
|
| 86 |
request_headers = dict(request.headers)
|
| 87 |
request_headers.pop("host", None)
|
|
@@ -105,7 +101,8 @@ async def reverse_proxy_handler(request: Request, full_path: str):
|
|
| 105 |
content=request_body,
|
| 106 |
)
|
| 107 |
|
| 108 |
-
|
|
|
|
| 109 |
|
| 110 |
resp = await client.send(req, stream=True)
|
| 111 |
|
|
|
|
| 17 |
)
|
| 18 |
logger = logging.getLogger(__name__)
|
| 19 |
|
| 20 |
+
# --- Simplified Target Configuration ---
|
| 21 |
+
# The proxy will now forward the request path exactly as it receives it.
|
| 22 |
+
# We only need to define the target host.
|
| 23 |
TARGET_HOST = os.getenv("TARGET_HOST", "https://console.gmicloud.ai")
|
| 24 |
+
logger.info(f"Proxying all request paths to host: {TARGET_HOST}")
|
|
|
|
| 25 |
|
| 26 |
# --- Retry Logic Configuration ---
|
| 27 |
MAX_RETRIES = int(os.getenv("MAX_RETRIES", "5"))
|
|
|
|
| 44 |
# --- HTTPX Client Lifecycle Management ---
|
| 45 |
@asynccontextmanager
|
| 46 |
async def lifespan(app: FastAPI):
|
| 47 |
+
"""Manages the lifecycle of the HTTPX client."""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
async with httpx.AsyncClient(base_url=TARGET_HOST, timeout=None) as client:
|
| 49 |
logger.info(f"HTTPX client created for target: {TARGET_HOST}")
|
| 50 |
app.state.http_client = client
|
|
|
|
| 64 |
return JSONResponse({
|
| 65 |
"status": "ok",
|
| 66 |
"target_host": TARGET_HOST,
|
|
|
|
| 67 |
})
|
| 68 |
|
| 69 |
|
| 70 |
@app.api_route("/{full_path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])
|
| 71 |
+
async def reverse_proxy_handler(request: Request):
|
| 72 |
"""
|
| 73 |
+
A catch-all reverse proxy that forwards requests to the target host.
|
| 74 |
+
It forwards the path and query parameters exactly as received.
|
| 75 |
"""
|
| 76 |
start_time = time.monotonic()
|
| 77 |
client: httpx.AsyncClient = request.app.state.http_client
|
| 78 |
|
| 79 |
+
# --- THE CORE FIX: Forward the path as-is, without adding any prefix ---
|
| 80 |
+
url = httpx.URL(path=request.url.path, query=request.url.query.encode("utf-8"))
|
| 81 |
|
| 82 |
request_headers = dict(request.headers)
|
| 83 |
request_headers.pop("host", None)
|
|
|
|
| 101 |
content=request_body,
|
| 102 |
)
|
| 103 |
|
| 104 |
+
# Use debug level for this log as it can be very noisy
|
| 105 |
+
logger.debug(f"Attempt {attempt + 1}/{MAX_RETRIES} -> {req.method} {req.url}")
|
| 106 |
|
| 107 |
resp = await client.send(req, stream=True)
|
| 108 |
|