Artifact b70834be84f48af0471bffbf15b5096cd65c6bc1e7c3f24a7f69ec6cfc9c0be4:
- File
internal/xfer/login_cookie_test.go
— part of check-in
[6963b0a9dc]
at
2026-10-12 23:10:13
on branch main
— fix(sync): exchange server-version and gate SHA3 content by peer release (#303) (#358)
fossil's page_xfer answers a client-version that carries DATE and TIME with pragma server-version, and both sides record the peer's release; send_file, send_compressed_file and send_unversioned_file then append "error Fossil version 2.0 or later required." in place of SHA3-named content for a peer older than 2.0, with a server treating a client that announced no release as one (sections 7.6, 9.1). The server sent no server-version and neither side kept or gated on the peer's release.
The server gates gimme, clone and uvgimme; the client gates its answer to a gimme. Because a server-version from a current release turns fossil's client to logging in through the x-f-l-c cookie (section 6.5), the HTTP server now reads that cookie: xfer.DecodeRequest puts its login card first with the nonce bound to the whole body, as page_xfer does. Without it a real fossil client's later rounds arrived as nobody. That moves sync.6.5.server-cookie-login, marked for #304, here. (user: [email protected], size: 1218) [annotate] [blame] [check-ins using]
package xfer import ( "testing" "github.com/danmestas/go-libfossil/internal/hash" ) // TestDecodeRequestLoginCookie pins ยง6.5: a login card carried in the // x-f-l-c cookie is put first, with its nonce bound to the whole body, and a // cookie that is not a login card is ignored. func TestDecodeRequestLoginCookie(t *testing.T) { body := []byte("pull sc pc\n# trailing comment\n") nonce := hash.SHA1(body) msg, err := DecodeRequest(body, ContentTypeUncompressed, "login+alice+"+nonce+"+sig") if err != nil { t.Fatalf("DecodeRequest: %v", err) } lc, ok := msg.Cards[0].(*LoginCard) if !ok { t.Fatalf("first card is %T, want the cookie's login card", msg.Cards[0]) } if lc.User != "alice" || lc.Signature != "sig" || !lc.NonceCoversTail() { t.Fatalf("cookie login = %+v, covers body %v", lc, lc.NonceCoversTail()) } notLogins := []string{"", "alice+" + nonce + "+sig", "login+alice+" + nonce, "%zz"} for _, cookie := range notLogins { msg, err := DecodeRequest(body, ContentTypeUncompressed, cookie) if err != nil { t.Fatalf("DecodeRequest(cookie %q): %v", cookie, err) } if _, ok := msg.Cards[0].(*LoginCard); ok { t.Errorf("cookie %q was taken as a login card", cookie) } } }