fix(foundry): URL-decode path segments in files_api #19

Closed
opened 2026-04-27 14:00:36 +00:00 by zaelgohary · 0 comments
Member

Symptom

Files uploaded with non-ASCII characters in the name (e.g. spaces) get stored on disk with their percent-encoded form, then can't be read back with the same URL.

$ curl -X PUT --data-binary @doc.bin -H "Content-Type: application/pdf" \
       --unix-socket /tmp/foundry.sock \
       "http://localhost/api/files/geomind/Hello%20World.pdf"
{"ok":true, ...}

$ ls var/hero_foundry/webdav/geomind/
'Hello%20World.pdf'        # ← literal %20 baked into filename

$ curl --unix-socket /tmp/foundry.sock \
       "http://localhost/api/files/geomind/Hello%20World.pdf"
404 Not Found              # browser/proxy auto-decodes; on-disk has %20 → mismatch

Root cause

crates/hero_foundry_server/src/http/files_api.rs:36-58 (handle_files_api) reads req.uri().path() and uses the raw segment as the literal filename. Percent-encoding is never decoded. So callers that follow the standard urlencode(filename) convention (e.g. hero_office_server::socket_dav::put_file) end up storing files with their encoded names.

Acceptance

  • PUT followed by GET on /api/files/{ctx}/{name with spaces} round-trips correctly.
  • File on disk has the decoded name (e.g. Hello World.pdf, not Hello%20World.pdf).
  • DELETE/POST (rename/copy/move) handlers also work for files with spaces in the name.
  • No regression for files with already-ASCII names (e.g. Hello.pdf).
## Symptom Files uploaded with non-ASCII characters in the name (e.g. spaces) get stored on disk with their **percent-encoded** form, then can't be read back with the same URL. ``` $ curl -X PUT --data-binary @doc.bin -H "Content-Type: application/pdf" \ --unix-socket /tmp/foundry.sock \ "http://localhost/api/files/geomind/Hello%20World.pdf" {"ok":true, ...} $ ls var/hero_foundry/webdav/geomind/ 'Hello%20World.pdf' # ← literal %20 baked into filename $ curl --unix-socket /tmp/foundry.sock \ "http://localhost/api/files/geomind/Hello%20World.pdf" 404 Not Found # browser/proxy auto-decodes; on-disk has %20 → mismatch ``` ## Root cause `crates/hero_foundry_server/src/http/files_api.rs:36-58` (`handle_files_api`) reads `req.uri().path()` and uses the raw segment as the literal filename. Percent-encoding is never decoded. So callers that follow the standard `urlencode(filename)` convention (e.g. `hero_office_server::socket_dav::put_file`) end up storing files with their encoded names. ## Acceptance - PUT followed by GET on `/api/files/{ctx}/{name with spaces}` round-trips correctly. - File on disk has the decoded name (e.g. `Hello World.pdf`, not `Hello%20World.pdf`). - DELETE/POST (rename/copy/move) handlers also work for files with spaces in the name. - No regression for files with already-ASCII names (e.g. `Hello.pdf`).
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_foundry#19
No description provided.