Add content negotiation for /users and /objects endpoints
- /users/{username}: Redirects to /ui/user/{username} for browsers (Accept: text/html)
- /objects/{hash}: Redirects to /ui/asset/{name} for browsers
- APIs still get JSON (application/activity+json) as before
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
24
server.py
24
server.py
@@ -1383,10 +1383,19 @@ async def webfinger(resource: str):
|
||||
|
||||
@app.get("/users/{username}")
|
||||
async def get_actor(username: str, request: Request):
|
||||
"""Get actor profile for any registered user."""
|
||||
"""Get actor profile for any registered user. Content negotiation: HTML for browsers, JSON for APIs."""
|
||||
if not user_exists(username):
|
||||
raise HTTPException(404, f"Unknown user: {username}")
|
||||
|
||||
# Check Accept header for content negotiation
|
||||
accept = request.headers.get("accept", "")
|
||||
wants_html = "text/html" in accept and "application/json" not in accept and "application/activity+json" not in accept
|
||||
|
||||
if wants_html:
|
||||
# Redirect to UI page for browsers
|
||||
from fastapi.responses import RedirectResponse
|
||||
return RedirectResponse(url=f"/ui/user/{username}", status_code=303)
|
||||
|
||||
actor = load_actor(username)
|
||||
|
||||
# Add ActivityPub context
|
||||
@@ -1774,13 +1783,22 @@ async def get_activities():
|
||||
|
||||
|
||||
@app.get("/objects/{content_hash}")
|
||||
async def get_object(content_hash: str):
|
||||
"""Get object by content hash."""
|
||||
async def get_object(content_hash: str, request: Request):
|
||||
"""Get object by content hash. Content negotiation: HTML for browsers, JSON for APIs."""
|
||||
registry = load_registry()
|
||||
|
||||
# Find asset by hash
|
||||
for name, asset in registry.get("assets", {}).items():
|
||||
if asset.get("content_hash") == content_hash:
|
||||
# Check Accept header for content negotiation
|
||||
accept = request.headers.get("accept", "")
|
||||
wants_html = "text/html" in accept and "application/json" not in accept and "application/activity+json" not in accept
|
||||
|
||||
if wants_html:
|
||||
# Redirect to UI page for browsers
|
||||
from fastapi.responses import RedirectResponse
|
||||
return RedirectResponse(url=f"/ui/asset/{name}", status_code=303)
|
||||
|
||||
owner = asset.get("owner", "unknown")
|
||||
return JSONResponse(
|
||||
content={
|
||||
|
||||
Reference in New Issue
Block a user