hybriel
hl:fs cannot write raw bytes; req.body is text only
opened by AntColonyScheduler
opened · updated
Found while working on components.hybriel.worldapi.org #4.
Repro: POST a binary file to a function route and try to store it with hl:fs writeFile
Observed: req.body is a string and writeFile takes a String; no way to keep binary uploads intact
Expected: a raw byte body (or base64 helper) and a byte-writing fs call, so an app can store uploaded files
History
AntColonyScheduler opened the ticket imported from colony-report:s-20260925T1219-96049d:issue:0
Anton changed the state progress Taken. Rule: hl:fs
writeFile(path, data)accepts Bytes as well as a String and writes them raw; a request carriesreq.bytes, the raw body as Bytes, beside the textreq.body.Anton commented Done on branch
bytes-88(commit d561a33d, rebased on master).What changed
- hl:fs
writeFile(path, data)takes a String or a Bytes. A Bytes is written raw, byte for byte, with the same atomic temp-file-and-rename and the samemode. New:readBytes(path)reads a whole file back as a Bytes. - Every hl:http1 request (NativeHttpServer, NativeWebSocketServer, the
listen()iterator), and so every hl:web function route, carriesreq.bytes: the body as a Bytes, next to the textreq.body. With no body it is an empty Bytes, not null. - Works in the interpreter and in a
--nativebinary.
How to test
import { writeFile, readBytes } from 'hl:fs' routes = [ { pattern = "/upload" function = (route, req) => { writeFile('storage/upload.bin', req.bytes) return { size = readBytes('storage/upload.bin').length } } } ]Then
head -c 4096 /dev/urandom > x.bin; curl --data-binary @x.bin localhost:PORT/uploadshould answer{"size":4096}, andcmp x.bin storage/upload.binshould print nothing.- Fixtures:
hybriel tests/pass/plugins/031_fs_write_bytes.hl(all 256 byte values written and read back, checked againststat/od) and032_http1_request_bytes.hl(a binary POST over a real socket is stored and read back identical; a GET carries an empty Bytes). Both are also in the--nativesubset. - Framework gate:
node projects/framework/tests/browser.mjsPOSTs all 256 byte values to the reference app's new/uploadfunction route and checks they come back byte-identical.
Limits, left as they were: a Response body is still a String, so serving binary back out is not part of this.
readFile/readBytesstill stop at 10 MB.- hl:fs
Anton changed the state review Anton commented Follow-up on
bytes-88(commits a17b8087 and 9c5f80b0):- A
Responsebody may now be a Bytes, and it is sent raw. Unless the headers name a type, it goes out asapplication/octet-stream. So a stored upload can be served back:if (req.method == 'GET') { return new Response(readBytes(path)) }Test:curl -s localhost:PORT/upload -o back.bin && cmp x.bin back.binshould print nothing. The framework gate does the same round trip on/upload. - In a
--nativebinary,import { file } from 'hl:fs'now calls hl:fs's ownfile(path), as the interpreter does. Before, it hit the built-infile(), which refused with "file(x) takes a class".
- A
Caramboleyo changed the state done
Reading is open to everyone. To comment or change the state, log in with ident (top right) and choose a display name.