lib/gitea: fix the fetch-pack-over-HTTP hang — native parse fast path

The sx-forge native-loop blocker: clone! of the live giles/rose-ash
never returned over gitea/http-app. Root cause was NOT the transport —
pack-line-parse ran every pack line through the interpreted spec parser
(~6.6KB/s on the CEK machine; a full-repo pack = hours), and a non-hex
byte in a pkt length header parsed negative (index-of -1), walking the
scan index backwards forever.

- gitea/parse-obj: use the host reader (open-input-string + read,
  ~3700x faster, value-identical) when the host provides it; hosts
  without string ports keep sx-parse. Feature-detected at load.
- pkt-sections-loop: (< n 4) guard — malformed lengths error instead
  of hanging.
- push-cmd!: haves = every advertised remote ref held locally, so a
  NEW branch pushes only its delta, not the whole repo closure.
- tests/wire.sx: malformed-len errors, truncated-pkt clamps, parse-obj
  = sx-parse equivalence (blob/commit + cid). 83/83.
- tests/wire-http.sh + wire-http-client.sx: end-to-end over REAL
  http-listen/http-request on :8943 — ls-remote/clone/push-new-branch/
  fresh-clone-verify/delete. The coverage gap that hid all this.

Proven vs the live forge (in sx-gitea-1): full 4468-file clone in 77s
(was: hang), commit, push heads/sx-smoke-test ok, branch advertised on
sx.sx-web.org. Conformance 620/620.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 00:30:59 +00:00
parent 72e461cf2c
commit 8ed44f7770
6 changed files with 257 additions and 23 deletions

View File

@@ -488,3 +488,34 @@
{})
:error)
404)
(gitea-wire-test
"pkt-sections malformed len errors"
(guard (e (true "errored")) (gitea/pkt-sections "zzzzzzzz"))
"errored")
(gitea-wire-test
"pkt-sections truncated pkt clamps"
(guard (e (true "errored")) (gitea/pkt-sections "0009hi"))
(list (list "hi")))
(define gw-po-blob (serialize (git/blob "hello \"quoted\" \n multiline")))
(define
gw-po-commit
(serialize (git/commit "sx1:tree" (list "sx1:p1" "sx1:p2") {:message "m" :author "a" :time 42})))
(gitea-wire-test
"parse-obj blob = sx-parse"
(gitea/parse-obj gw-po-blob)
(first (sx-parse gw-po-blob)))
(gitea-wire-test
"parse-obj commit = sx-parse"
(gitea/parse-obj gw-po-commit)
(first (sx-parse gw-po-commit)))
(gitea-wire-test
"parse-obj cid stable"
(git/cid (gitea/parse-obj gw-po-commit))
(git/cid (first (sx-parse gw-po-commit))))