peerix/peerix/app.py
2021-10-17 03:04:22 +02:00

70 lines
2.1 KiB
Python

import asyncio
import contextlib
from starlette.requests import Request
from starlette.responses import Response, StreamingResponse
from starlette.applications import Starlette
from peerix.local import local
from peerix.remote import remote
from peerix.prefix import PrefixStore
@contextlib.asynccontextmanager
async def _setup_stores(local_port: int):
global l_access, r_access
async with local() as l:
l_access = PrefixStore("local/nar", l)
async with remote(l_access, local_port, "0.0.0.0") as r:
r_access = PrefixStore("remote", r)
yield
setup_store = _setup_stores(12304)
app = Starlette()
@app.on_event("startup")
async def _setup_stores_init():
await setup_store.__aenter__()
@app.on_event("shutdown")
async def _setup_stores_deinit():
await setup_store.__aexit__(None, None, None)
@app.route("/nix-cache-info")
async def cache_info(_: Request) -> Response:
ci = await l_access.cache_info()
ci = ci._replace(priority=20)
return Response(content=ci.dump())
@app.route("/{hash:str}.narinfo")
async def narinfo(req: Request) -> Response:
if req.client.host != "127.0.0.1":
return Response(content="Permission denied.", status_code=403)
ni = await r_access.narinfo(req.path_params["hash"])
if ni is None:
return Response(content="Not found", status_code=404)
return Response(content=ni.dump(), status_code=200, media_type="text/x-nix-narinfo")
@app.route("/local/{hash:str}.narinfo")
async def access_narinfo(req: Request) -> Response:
ni = await l_access.narinfo(req.path_params["hash"])
if ni is None:
return Response(content="Not found", status_code=404)
return Response(content=ni.dump(), status_code=200, media_type="text/x-nix-narinfo")
@app.route("/local/nar/{path:str}")
async def push_nar(req: Request) -> Response:
return StreamingResponse(l_access.nar(f"local/nar/{req.path_params['path']}"), media_type="text/plain")
@app.route("/remote/{path:path}")
async def pull_nar(req: Request) -> Response:
return StreamingResponse(l_access.nar(f"remote/{req.path_params['path']}"), media_type="text/plain")