You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using u32 for all the quantities makes the interface completely unable to handle files more than 4 GiB in size. I've done a bit of research, and it seems the code casts 32-bit numbers to f64 for JS (essentially supporting 52 bits), and those are converted into u64 in the workerd C++ code.
I can see multiple ways to fix this to varying degrees:
Simply changing Rust high-level definition to u64, low-level R2Range definition to f64, and erroring out during conversion if the number does not fit into f64 without precision loss. Will fix the practical problem with the least effort, but this is certainly a hack. Values read from the response could be silently wrong if they exceed 52 bits, though (should not be a practical issue).
There seems to be a (somehow undocumented) way to pass a Headers instance with pre-made Range header. The Rust code could format the header manually from u64 values, bypassing the JS f64 dance entirely.
Support BigInt in the JS interface to pass through u64 losslessly?
As a side note, the current Range Rust definition seems very weird to me: there is way too much overlap between the first three variants, and some semantics are not clear to me. What does OptionalOffsetWithLength{None, L} even mean? Is it the same as OffsetWithLength{0, L}/OffsetWithOptionalLength{0, Some(L)}? Or Suffix{L}? I think that the Range semantics could be made simpler, and it could be done simultaneously with the required breaking change to fix the data types. Perhaps this could work?
Thanks for the detailed description. I think option 1 is most viable, but I will investigate 2 I believe it may just support the standard Range header.
Regarding the API, I think this may have just been copied from the JavaScript API which appears to support the same options. I suspect that the Rust types are the way they are to allow for these 3 options, but not allow for omitting both. I will ask around about what omitting the offset does and see if your proposal is viable.
Is there an existing issue for this?
What version of
workers-rs
are you using?0.2.0
What version of
wrangler
are you using?3.53.0
Describe the bug
The
worker::r2::builder::Range
enum is defined like this:Using
u32
for all the quantities makes the interface completely unable to handle files more than 4 GiB in size. I've done a bit of research, and it seems the code casts 32-bit numbers tof64
for JS (essentially supporting 52 bits), and those are converted intou64
in the workerd C++ code.I can see multiple ways to fix this to varying degrees:
u64
, low-levelR2Range
definition tof64
, and erroring out during conversion if the number does not fit intof64
without precision loss. Will fix the practical problem with the least effort, but this is certainly a hack. Values read from the response could be silently wrong if they exceed 52 bits, though (should not be a practical issue).Headers
instance with pre-madeRange
header. The Rust code could format the header manually fromu64
values, bypassing the JSf64
dance entirely.BigInt
in the JS interface to pass throughu64
losslessly?As a side note, the current
Range
Rust definition seems very weird to me: there is way too much overlap between the first three variants, and some semantics are not clear to me. What doesOptionalOffsetWithLength{None, L}
even mean? Is it the same asOffsetWithLength{0, L}
/OffsetWithOptionalLength{0, Some(L)}
? OrSuffix{L}
? I think that the Range semantics could be made simpler, and it could be done simultaneously with the required breaking change to fix the data types. Perhaps this could work?Steps To Reproduce
No response
The text was updated successfully, but these errors were encountered: