Skip to content
zit Artifact [691ea2a892]
Login

Artifact [691ea2a892]

Artifact 691ea2a892254416b55116c6b727273cb3ef712b3580d082c9ae235c323cd0fd:


zit 0.3.23

zit 0.3.23 answers an HTTP Basic challenge. A forge that gates a read answers a clone's first request with 401; the credential can now reach the wire on that first request, which is the one a private repository refuses.

No artifact, tag namespace, sync message, or on-disk repository format changed. One HTTP request header is new, sent only when a peer asks for it.

The round that could not carry the card

0.3.22 taught clone and pull to send a login card, and a private repository on a read-gating forge was still unclonable. The two halves were each correct alone. A clone cannot sign its first request, because the card's shared secret is derived from the project code and the project code is what the first reply teaches; fossil's client sends no card on that round either. And the forge refuses the first request with an HTTP 401, which the transport treated as fatal, so the round that would have carried the card never came. The server's log showed one request per clone and no credential offered, whether or not one was given.

Fossil's own server never gates a read at the HTTP layer, so the retry 0.3.22 added, which fires on a protocol-level refusal that teaches the project code, was the right answer to fossil and no answer to a forge. Fossil's client reaches a forge with --httpauth, an HTTP Basic header on every request, and that is the mechanism a first request can use.

The transport answers the challenge

When a verb holds a plaintext password, from --password, ZIT_PASSWORD, or the prompt, the transport keeps a Basic credential ready and sends nothing until asked. A 401 whose WWW-Authenticate names the Basic scheme is answered by sending the same round again with the Authorization header, and every later round carries it, as fossil's does. After the first reply teaches the project code the login card rides the later rounds as before, so a peer that admits either is served either way.

A 401 is no longer a bare status. With a challenge and no password to answer it, such as a pull on a stored login, the message says the peer wants a login and names the flags. With a credential sent and still refused, it says the peer refused the login. A 401 without a challenge says so.

A read-only account on a forge whose card secrets exist only for writers can now read with Basic, which is the case the card never covered.

Verification

Compatibility

Qualification

zig fmt --check, zig build test, e2e, smoke, muscle, git-import-e2e, git-export-e2e, dst, and cross, plus the three-runner CI battery.