Skip to content

feat(rack): bind remaining Rack::Utils (secure_compare/clean_path_info/valid_path?/select_best_encoding/forwarded_values) - #126

Merged
tannevaled merged 1 commit into
mainfrom
feat/rack-utils-remaining
Jul 3, 2026
Merged

tannevaled merged 1 commit into
mainfrom
feat/rack-utils-remaining

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Summary

PR #125 bound most of Rack::Utils but skipped five methods on the premise that go-ruby-rack/rack did not export them. That was a stale-pin artifact: rack's utils.go on main exports all five as Go funcs. This PR bumps the rack pin so they resolve and binds them, dispatching through the existing value-mapping helpers.

Ruby method Go func Semantics
secure_compare(a, b) SecureCompare constant-time equality, returns bool
clean_path_info(path) CleanPathInfo traversal-safe PATH_INFO normalise
valid_path?(path) ValidPath valid UTF-8 and NUL-free, bool
select_best_encoding(available, accept_encoding) SelectBestEncoding MRI arg order — server list first, pre-parsed [name, quality] accept list second; nil when nothing acceptable
forwarded_values(header) ForwardedValues RFC 7239; symbol-keyed Hash in header order, nil on a falsy/disallowed header

forwarded_values ordering

ForwardedValues returns an unordered map[string][]string, which alone cannot reproduce MRI's header-appearance key order. The binding reconstructs that order with rackForwardedOrder (mirrors the Go tokeniser, names only) before building the symbol-keyed Hash, so the output is byte-identical to MRI ({for: [...], proto: [...]}).

Verification

Byte-for-byte diff of a snippet exercising all five, run through the rbgo binary vs MRI 4.0.5 + rack 3.2.6 — identical, including reordered / quoted / IPv6 / duplicate-key / empty-header Forwarded cases and the select_best_encoding */identity/tie/nil arms.

select_best_encoding arg order confirmed against real rack 3.2.6: select_best_encoding(%w[gzip identity], [["gzip",1.0],["identity",0.5]]) #=> "gzip".

Empty/no-param Forwarded headers return {} (not nil) in rack 3.2.6, and the Go func matches — verified against MRI.

  • GOWORK=off go build ./... && go vet ./... && go test ./... green
  • webapp conformance green
  • 100% coverage on rack.go and rack_helpers.go

🤖 Generated with Claude Code

…o/valid_path?/select_best_encoding/forwarded_values)

Bind the five Rack::Utils methods PR #125 skipped. They are exported by
github.com/go-ruby-rack/rack's utils.go (SecureCompare, CleanPathInfo,
ValidPath, SelectBestEncoding, ForwardedValues); bump the rack pin so they
resolve, then dispatch through the existing value-mapping helpers:

- secure_compare(a, b)              -> SecureCompare      (constant-time bool)
- clean_path_info(path)             -> CleanPathInfo      (traversal-safe)
- valid_path?(path)                 -> ValidPath          (bool)
- select_best_encoding(avail, acc)  -> SelectBestEncoding (MRI arg order:
    available list first, pre-parsed [name, quality] accept list second;
    nil when nothing acceptable)
- forwarded_values(header)          -> ForwardedValues    (RFC 7239; symbol
    keys in header order, nil on a falsy/disallowed header)

ForwardedValues returns an unordered map[string][]string, so the binding
reconstructs MRI's header-appearance key order with rackForwardedOrder
(mirrors the Go tokeniser, names only) before materialising the symbol-keyed
Hash. New helpers rackFloat / rackQValues / rackForwardedArg carry the value
mapping.

Verified byte-identical to MRI 4.0.5 + rack 3.2.6 through the rbgo binary for
all five (including reordered / quoted / IPv6 / duplicate-key / empty-header
Forwarded cases). 100% coverage on rack.go and rack_helpers.go.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 691a655 into main Jul 3, 2026
9 checks passed
@tannevaled
tannevaled deleted the feat/rack-utils-remaining branch July 3, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant