Fix byte-limited reads for Enumerator-backed request bodies - #275
Fix byte-limited reads for Enumerator-backed request bodies#275fallintoplace wants to merge 1 commit into
Conversation
6a6a07c to
9a9d079
Compare
|
Thank you so much for the careful and comprehensive work here, @fallintoplace. Your analysis of byte-oriented Since this PR was opened, I’m closing this PR only because #354 supersedes it—not because the contribution wasn’t valuable. It materially shaped the final implementation and gave us the complete contract we needed. Really appreciate the time, rigor, and care you put into this. Thank you! 🙏 |
## Summary - preserve arbitrary binary bytes when multipart request bodies yield a mix of UTF-8 and binary chunks - honor `IO#read(max_len, out_string)` byte limits, buffering, EOF, negative-length, and output-buffer semantics for Enumerator-backed bodies - retain native `IO` and `StringIO` delegation, including implicit `to_int` length conversion - update RBI/RBS contracts and add focused regression coverage This fixes openai#317 and consolidates the complete behavior needed from openai#275, openai#294, and openai#324 on the current SDK-owned `ReadIOAdapter` implementation. ## Ownership This is handwritten SDK runtime behavior introduced as an SDK-owned component in openai#345. It does not change OpenAPI inputs, Castiron facts, renderer rules, templates, or generator configuration. ## Validation - `mise exec ruby@4.0.6 -- ./scripts/test` — 531 runs, 1,736 assertions, 0 failures - `mise exec ruby@4.0.6 -- bundle exec rake lint` — RuboCop, Sorbet, and 1,211 RBS files clean - `mise exec ruby@4.0.6 -- bundle exec rake build:gem` - installed-gem adapter probe - Ruby 3.3.12 mixed-encoding compatibility probe - 1,000 randomized read sequences compared against `StringIO` - real local HTTP multipart upload with a 1 MiB binary file and UTF-8 prompt, verified byte-for-byte by SHA-256
Summary
ReadIOAdapter#read(max_len)return at mostmax_lenbytesIO#readsemanticsout_stringWhy
This adapter feeds streamed request bodies into IO consumers such as
IO.copy_stream. Returning more bytes than requested can break those consumers and corrupt multipart upload boundaries; character-oriented slicing also makes the result depend on string encoding instead of the requested byte count.Fixes #274.
Test plan
bundle exec rake TEST=test/openai/internal/util_test.rb testbundle exec rake lint