"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
fix capabilities sent by gotsh if no refs exist
To:
gameoftrees@openbsd.org
Date:
Mon, 7 Nov 2022 21:36:13 +0100

Download raw body.

Thread
If the repository contains no references we announce capabilities via
send_zero_refs(). This function does not yet handle the repo_write case,
resulting in invalid capabilities being announced to the client.

In particular, we do not announce the 'report' capability but send reports
regardless, which results in an "unexpected message from server" error
being reported by got clone/fetch.

ok?

diff 593af7bd3baeb8314b7ef9a11fe0559a6ba9557d 5a3cf3b6bde9a6f3b33391a2229d7a6870417361
commit - 593af7bd3baeb8314b7ef9a11fe0559a6ba9557d
commit + 5a3cf3b6bde9a6f3b33391a2229d7a6870417361
blob - 85ee3e8503a054b2d587e80262d305695c1c8449
blob + b8131d3c9afbbd434818c6c64743b9be8d7edf13
--- lib/serve.c
+++ lib/serve.c
@@ -220,7 +220,7 @@ send_zero_refs(int outfd, int chattygot)
 }
 
 static const struct got_error *
-send_zero_refs(int outfd, int chattygot)
+send_zero_refs(int outfd, int client_is_reading, int chattygot)
 {
 	const struct got_error *err = NULL;
 	char buf[GOT_PKT_MAX];
@@ -237,10 +237,18 @@ send_zero_refs(int outfd, int chattygot)
 	if (len >= sizeof(buf))
 		return got_error(GOT_ERR_NO_SPACE);
 
-	err = got_gitproto_append_capabilities(&capalen, buf, len,
-	    sizeof(buf), read_capabilities, nitems(read_capabilities));
-	if (err)
-		return err;
+	if (client_is_reading) {
+		err = got_gitproto_append_capabilities(&capalen, buf, len,
+		    sizeof(buf), read_capabilities, nitems(read_capabilities));
+		if (err)
+			return err;
+	} else {
+		err = got_gitproto_append_capabilities(&capalen, buf, len,
+		    sizeof(buf), write_capabilities,
+		    nitems(write_capabilities));
+		if (err)
+			return err;
+	}
 
 	return got_pkt_writepkt(outfd, buf, len + capalen, chattygot);
 }
@@ -315,7 +323,8 @@ announce_refs(int outfd, struct imsgbuf *ibuf, int cli
 			nrefs = ireflist.nrefs;
 			have_nrefs = 1;
 			if (nrefs == 0)
-				err = send_zero_refs(outfd, chattygot);
+				err = send_zero_refs(outfd, client_is_reading,
+				    chattygot);
 			break;
 		case GOTD_IMSG_REF:
 			if (!have_nrefs || nrefs == 0) {