fix(node): skip withheld-walk when no path-scoped rule can withhold#60
fix(node): skip withheld-walk when no path-scoped rule can withhold#60beardthelion wants to merge 2 commits into
Conversation
…t-circuit Shared predicate (rules.iter().any(path_glob != "/")) both serve and replication paths will use to skip the per-blob withheld walk when no rule can withhold. Doc records the "/"-gate precondition and the validate_path_glob dependency. Adds unit tests plus a gate-aware safety invariant test.
) The serve path (git_upload_pack) ran the full per-ref withheld_blob_oids walk on every clone/fetch before falling back to a plain upload_pack, even for repos with no path-scoped rules where the walk can never withhold anything. Cost grew with #42 (per-ref git ls-tree -r). Guard both call sites on has_path_scoped_rule: the serve path skips the spawn_blocking walk entirely and serves upload_pack directly; the replication path generalizes its is_empty() short-circuit to also cover root-only rule sets. Safe because the whole-repo "/" gate runs before both sites, so a denying root rule 404s/withholds upstream and never reaches the predicate. No change to served-pack contents on the success path.
📝 WalkthroughWalkthroughAdds a new ChangesShort-circuit withheld-blob walk for non-path-scoped rules
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Public clones and fetches were paying for an authorization walk they could never benefit from. On every clone/fetch the serve path enumerated every blob path across every ref (a blocking
git ls-tree -rper ref) to compute which blobs to withhold, then threw the result away and served a normal pack whenever nothing was withheld — which is always the case for a repo with no path-scoped visibility rules, i.e. the common public repo. The cost got worse with #42, which widened the walk from heads/tags to every ref.This skips the walk entirely when no rule can withhold anything.
What changed
A shared predicate,
has_path_scoped_rule, now gates both consumers of the walk. The serve path (git_upload_pack) skips the blocking walk and serves the pack directly; the post-push replication path's existing empty-rules short-circuit is generalized to also cover root-only rule sets, so the two call sites can't drift.Why it's safe
The short-circuit is only sound because the whole-repo
/access gate already runs before both call sites: a denying root rule 404s the caller on the serve path, and suppresses announcement on the replication path, before the predicate is ever consulted. Any caller that reaches the predicate has therefore already cleared repo-level access — and with no path-scoped rule left, there is nothing to withhold. Served-pack contents are unchanged on the success path.The predicate's doc comment records this precondition explicitly, plus the dependency on
validate_path_globrejecting/**(the only non-/glob that would match every path).One intended behavioural difference, on the error path only: a corrupt public/root-only repo whose ref walk would have thrown now skips that walk and goes straight to
upload_pack, so a spurious 500 originating in the walk no longer surfaces there. This is the wasted-walk overhead going away, not a change to what content is served.Tests
/gate, an empty or root-only rule set yields an empty withheld set — pinning the invariant the skip depends on against future changes to the matching logic.gitlawb-nodesuite: 117 passing;cargo fmt --checkandcargo clippyclean.The serve/replication HTTP endpoints have no integration-test harness in this crate, so the call-site wiring is covered at the predicate level rather than via new end-to-end tests.
Closes #50.
Summary by CodeRabbit
Bug Fixes
Performance Improvements
Tests