fix: Support local file storage uploads in addition to S3
Build and Push Outline MCP Docker Image / build (push) Successful in 8s
Build and Push Outline MCP Docker Image / build (push) Successful in 8s
The upload endpoint now detects whether Outline uses local file storage (multipart form POST) or S3 (pre-signed PUT URL) and handles both.
This commit is contained in:
@@ -633,27 +633,50 @@ async def upload_endpoint(request: Request) -> JSONResponse:
|
||||
status_code=502,
|
||||
)
|
||||
|
||||
attachment_data = create_response.get("data", {})
|
||||
upload_url = attachment_data.get("uploadUrl")
|
||||
response_data = create_response.get("data", {})
|
||||
upload_url = response_data.get("uploadUrl")
|
||||
form_fields = response_data.get("form", {})
|
||||
attachment_data = response_data.get("attachment", {})
|
||||
if not upload_url:
|
||||
return JSONResponse(
|
||||
{"ok": False, "error": "Outline API did not return an uploadUrl"},
|
||||
status_code=502,
|
||||
)
|
||||
|
||||
# 3. Stream the request body directly to S3 upload_url
|
||||
# Resolve relative uploadUrl against the Outline base URL
|
||||
if upload_url.startswith("/"):
|
||||
upload_url = f"{OUTLINE_API_URL}{upload_url}"
|
||||
|
||||
is_local_storage = bool(form_fields)
|
||||
|
||||
# 3. Upload the file content to storage
|
||||
try:
|
||||
# Pre-signed S3 PUT URLs usually enforce exact headers
|
||||
body = await request.body()
|
||||
|
||||
if is_local_storage:
|
||||
# Local/database file storage: POST multipart form with fields from Outline
|
||||
logger.info(f"Uploading via local storage endpoint (size={size} bytes)")
|
||||
files = {"file": (filename, body, content_type)}
|
||||
async with httpx.AsyncClient() as client:
|
||||
post_response = await client.post(
|
||||
upload_url,
|
||||
data=form_fields,
|
||||
files=files,
|
||||
headers={"Authorization": f"Bearer {OUTLINE_API_TOKEN}"},
|
||||
timeout=600.0,
|
||||
)
|
||||
post_response.raise_for_status()
|
||||
else:
|
||||
# S3-compatible storage: PUT directly to pre-signed URL
|
||||
headers = {
|
||||
"Content-Type": content_type,
|
||||
"Content-Length": str(size),
|
||||
}
|
||||
|
||||
logger.info(f"Streaming file content to storage (size={size} bytes)")
|
||||
logger.info(f"Streaming file content to S3 storage (size={size} bytes)")
|
||||
async with httpx.AsyncClient() as client:
|
||||
put_response = await client.put(
|
||||
upload_url,
|
||||
content=request.stream(),
|
||||
content=body,
|
||||
headers=headers,
|
||||
timeout=600.0,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user