from aiohttp import web, ClientSession, ClientTimeout PIXIV_BACKEND = "http://127.0.0.1:9007" BILIBILI_BACKEND = "http://127.0.0.1:9006" DUFE_BACKEND = "http://127.0.0.1:9005" JM_BACKEND = "http://127.0.0.1:9004" async def handle_pixiv(request): pid = request.query.get("id", "") if not pid: return web.json_response({"error": "missing id parameter"}, status=400) target = f"{PIXIV_BACKEND}/{pid}" return await proxy(request, target) async def handle_bilibili(request): qs = request.query_string target = f"{BILIBILI_BACKEND}/bilibili/get_video" if qs: target += "?" + qs return await proxy(request, target) async def handle_dufe_sign_in(request): # ginkgo_sign_in.service(127.0.0.1:9005),端点 /dufe/ginkgostu_sign_in,支持 GET|POST target = f"{DUFE_BACKEND}/dufe/ginkgostu_sign_in" if request.query_string: target += "?" + request.query_string return await proxy_forward(request, target) async def handle_jm(request): qs = request.query_string target = f"{JM_BACKEND}/jm/get_comic" if qs: target += "?" + qs return await proxy(request, target) async def proxy(request, target): timeout = ClientTimeout(total=300) async with ClientSession(timeout=timeout) as session: try: async with session.get(target) as resp: body = await resp.read() headers = {} for key in ("Content-Type", "Content-Disposition", "Cache-Control"): if key in resp.headers: headers[key] = resp.headers[key] return web.Response( body=body, status=resp.status, headers=headers, ) except Exception as e: return web.json_response( {"error": "backend unreachable", "detail": str(e)}, status=502 ) async def proxy_forward(request, target): # 保留请求方法与请求体的转发,供需要 POST 的后端使用(dufe 签到码查询) timeout = ClientTimeout(total=300) data = None fwd_headers = {} if request.method not in ("GET", "HEAD"): data = await request.read() ctype = request.headers.get("Content-Type") if ctype: fwd_headers["Content-Type"] = ctype async with ClientSession(timeout=timeout) as session: try: async with session.request( request.method, target, data=data, headers=fwd_headers ) as resp: body = await resp.read() headers = {} for key in ("Content-Type", "Content-Disposition", "Cache-Control"): if key in resp.headers: headers[key] = resp.headers[key] return web.Response( body=body, status=resp.status, headers=headers, ) except Exception as e: return web.json_response( {"error": "backend unreachable", "detail": str(e)}, status=502 ) async def handle_root(request): raise web.HTTPFound("https://rrrosmontis.icu/articles/index.html?id=00003") app = web.Application() app.router.add_get("/", handle_root) app.router.add_get("/pixiv/get_image", handle_pixiv) app.router.add_get("/bilibili/get_video", handle_bilibili) app.router.add_get("/dufe/ginkgostu_sign_in", handle_dufe_sign_in) app.router.add_post("/dufe/ginkgostu_sign_in", handle_dufe_sign_in) app.router.add_get("/jm/get_comic", handle_jm) if __name__ == "__main__": web.run_app(app, host="127.0.0.1", port=9008)