upload_document: chunked raw-bytes path for large files #12

Open
opened 2026-04-27 07:31:37 +00:00 by zaelgohary · 0 comments
Member

Symptom

upload_document is JSON-RPC with a base64-encoded body. A 50 MB pptx becomes ~67 MB JSON, materialized fully in browser memory and again on the server. Three full copies in flight (browser → server → foundry). Gateway body-cap kicks in before WASM does.

Cause

JSON-RPC envelope is wrong shape for binary blobs above ~10 MB. Was the right call for v1 (one API surface) but doesn't scale.

Proposed fix

Add a raw-bytes upload path on hero_office_ui:

PUT /hero_office/ui/files/{ctx}/{name}
Content-Type: <mime>
<raw bytes>

hero_office_ui proxies to hero_office_server (or directly to hero_foundry) without base64. Browser picks upload_document (RPC) for files under a threshold (1-2 MB) and the raw PUT for everything else. Same code path for delete is unchanged (small payload).

Acceptance

  • New raw-PUT endpoint on hero_office_ui.
  • embed/office/src/service.rs::upload_file chooses RPC vs raw based on byte length.
  • Memory ceiling for a 100 MB upload is bounded by chunk buffer, not file size.
  • e2e: upload a 50 MB file via the Upload button, confirm it lands and the editor opens it.
## Symptom `upload_document` is JSON-RPC with a base64-encoded body. A 50 MB pptx becomes ~67 MB JSON, materialized fully in browser memory and again on the server. Three full copies in flight (browser → server → foundry). Gateway body-cap kicks in before WASM does. ## Cause JSON-RPC envelope is wrong shape for binary blobs above ~10 MB. Was the right call for v1 (one API surface) but doesn't scale. ## Proposed fix Add a raw-bytes upload path on `hero_office_ui`: ``` PUT /hero_office/ui/files/{ctx}/{name} Content-Type: <mime> <raw bytes> ``` `hero_office_ui` proxies to `hero_office_server` (or directly to hero_foundry) without base64. Browser picks `upload_document` (RPC) for files under a threshold (1-2 MB) and the raw PUT for everything else. Same code path for delete is unchanged (small payload). ## Acceptance - New raw-PUT endpoint on hero_office_ui. - `embed/office/src/service.rs::upload_file` chooses RPC vs raw based on byte length. - Memory ceiling for a 100 MB upload is bounded by chunk buffer, not file size. - e2e: upload a 50 MB file via the Upload button, confirm it lands and the editor opens it.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_office#12
No description provided.