Repository navigation
feat(rack): complete Rack::Utils surface (nested query / q-values / cookies / status table) - #125
Merged
Merged
Conversation
…tus table
The go-ruby-rack binding already exposed escape/unescape/parse_query/
build_query and Rack::Request/Response. This completes the Rack::Utils
pure-compute surface over the same authoritative library:
- parse_nested_query(qs, sep = nil) — nested Hash/Array params
- build_nested_query(value, prefix = nil) — via a new insertion-ordered
rackToGoNested converter (a sub-hash maps to *rack.Params so Ruby Hash
order survives, which buildNested requires)
- q_values / best_q_match — Accept-header quality negotiation
- parse_cookies_header(header) and parse_cookies(env) (reads HTTP_COOKIE)
- HTTP_STATUS_CODES constant (code -> reason phrase, ascending)
Also fixes status_code: it now maps a Symbol through
rack.SymbolToStatusCode (:not_found -> 404, obsolete aliases too, raising
ArgumentError on an unknown symbol) instead of blindly coercing the
argument to an int.
Verified byte-identical to MRI 4.0.5 + rack 3.2.6 for every method
(executed through rbgo, not just parsed). rack.go / rack_helpers.go stay
at 100% coverage; go build / vet / test ./... and the webapp conformance
suite are green.
Not bound (absent from go-ruby-rack/rack, flagged as an upstream-lib
follow-up rather than reinvented host-side): secure_compare,
clean_path_info, valid_path?, select_best_encoding, forwarded_values.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tannevaled
added a commit
that referenced
this pull request
Jul 3, 2026
…o/valid_path?/select_best_encoding/forwarded_values) (#126) 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
go-ruby-rackwas already bound into rbgo (PR #104):Rack::Request,Rack::Response, and a first slice ofRack::Utils(
escape/unescape/escape_html/escape_path/parse_query/build_query).This PR extends the existing binding rather than reinventing it, completing
the
Rack::Utilspure-compute surface over the same authoritative library.What's added to
Rack::Utilsparse_nested_query(qs, sep = nil)— nested Hash/Array paramsbuild_nested_query(value, prefix = nil)— backed by a new insertion-orderedrackToGoNestedconverter (a sub-hash maps to*rack.Params, so Ruby Hashorder survives —
buildNestedrecognises*Params, notmap[string]any)q_values(header)/best_q_match(header, available)— Accept-header qualitynegotiation (
best_q_matchreturnsnilon no match, like MRI)parse_cookies_header(header)andparse_cookies(env)(readsHTTP_COOKIE)HTTP_STATUS_CODESconstant (code → reason phrase, ascending order)Fixed
Rack::Utils.status_codepreviously coerced its argument straight to an int, sostatus_code(:not_found)wrongly returned500. It now routes a Symbol throughrack.SymbolToStatusCode(:not_found→ 404, obsolete aliases like:unprocessable_entity→ 422 too) and raisesArgumentErroron an unknownsymbol, while Integer/String still coerce to int.
Value mapping
Reuses the existing helpers (
rackParamsToHash/rackFromGorecurse through*rack.Params→ ordered Hash,[]any→ Array,nil→ nil). AddsrackToGoNested(ordered nested conversion forbuild_nested_query),rackStrArray(availablelist forbest_q_match), andrackCookieHeader(pull
HTTP_COOKIEout of an env Hash).Verification
Executed through rbgo (not just parsed) and diffed byte-for-byte against
MRI 4.0.5 + rack 3.2.6 across nested queries, arrays, cookies, q-values,
status codes and the constant table — identical on every case.
rack.go/rack_helpers.gostay at 100% coverage;go build ./...,go vet ./...,go test ./...and the webapp conformance suite are green.Scoped out (upstream-lib follow-up)
Absent from
go-ruby-rack/rack, so flagged for the owning library rather thanhand-rolled here (keeps the authoritative impl + oracle tests in one place):
secure_compare,clean_path_info,valid_path?,select_best_encoding,forwarded_values.🤖 Generated with Claude Code