git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] connect: advertise OS version

From
Christian Couder <christian.couder@gmail.com>
Date
Jun 19, 2024, 12:57 UTC
Message-ID
<20240619125708.3719150-4-christian.couder@gmail.com>
In-Reply-To
<20240619125708.3719150-1-christian.couder@gmail.com>

As some issues that can happen with a Git client can be operating system specific, it can be useful for a server to know which OS a client is using. In the same way it can be useful for a client to know which OS a server is using.

Let's add OS information exchange to the protocol in the same way some git version exchange is performed.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/gitprotocol-v2.txt | 18 ++++++++++++++++++
 connect.c                        |  3 +++
 serve.c                          | 12 ++++++++++++
 t/t5555-http-smart-common.sh     |  3 +++
 t/t5701-git-serve.sh             |  3 +++
 version.c                        | 29 +++++++++++++++++++++++++++++
 version.h                        |  3 +++
 7 files changed, 71 insertions(+)
diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt
index 414bc625d5..f676b2dc7a 100644
--- a/Documentation/gitprotocol-v2.txt
+++ b/Documentation/gitprotocol-v2.txt
@@ -190,6 +190,24 @@ printable ASCII characters except space (i.e., the byte range 32 < x <
 and debugging purposes, and MUST NOT be used to programmatically assume
 the presence or absence of particular features.
 
+os-version
+~~~~~~~~~~
+
+In the same way as the `agent` capability above, the server can
+advertise the `os-version` capability with a value `X` (in the form
+`os-version=X`) to notify the client that the server is running an
+operating system that can be identified by `X`. The client may
+optionally send its own `os-version` string by including the
+`os-version` capability with a value `Y` (in the form `os-version=Y`)
+in its request to the server (but it MUST NOT do so if the server did
+not advertise the os-version capability). The `X` and `Y` strings may
+contain any printable ASCII characters except space (i.e., the byte
+range 32 < x < 127), and are typically made from the result of
+`uname -srvm`. The os-version strings are purely informative for
+statistics and debugging purposes, and MUST NOT be used to
+programmatically assume the presence or absence of particular
+features.
+
 ls-refs
 ~~~~~~~
 
diff --git a/connect.c b/connect.c
index 0d77737a53..3a48806ddc 100644
--- a/connect.c
+++ b/connect.c
@@ -489,6 +489,9 @@ static void send_capabilities(int fd_out, struct packet_reader *reader)
 	if (server_supports_v2("agent"))
 		packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
 
+	if (server_supports_v2("os-version"))
+		packet_write_fmt(fd_out, "os-version=%s", os_version_sanitized());
+
 	if (server_feature_v2("object-format", &hash_name)) {
 		int hash_algo = hash_algo_by_name(hash_name);
 		if (hash_algo == GIT_HASH_UNKNOWN)
diff --git a/serve.c b/serve.c
index aa651b73e9..77eb5ebdaa 100644
--- a/serve.c
+++ b/serve.c
@@ -29,6 +29,14 @@ static int agent_advertise(struct repository *r UNUSED,
 	return 1;
 }
 
+static int os_version_advertise(struct repository *r UNUSED,
+			   struct strbuf *value)
+{
+	if (value)
+		strbuf_addstr(value, os_version_sanitized());
+	return 1;
+}
+
 static int object_format_advertise(struct repository *r,
 				   struct strbuf *value)
 {
@@ -121,6 +129,10 @@ static struct protocol_capability capabilities[] = {
 		.name = "agent",
 		.advertise = agent_advertise,
 	},
+	{
+		.name = "os-version",
+		.advertise = os_version_advertise,
+	},
 	{
 		.name = "ls-refs",
 		.advertise = ls_refs_advertise,
diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh
index 3dcb3340a3..c67739236f 100755
--- a/t/t5555-http-smart-common.sh
+++ b/t/t5555-http-smart-common.sh
@@ -124,9 +124,12 @@ test_expect_success 'git receive-pack --advertise-refs: v1' '
 '
 
 test_expect_success 'git upload-pack --advertise-refs: v2' '
+	# Octal intervals \001-\040 and \177-\377
+	# corresponds to decimal intervals 1-32 and 127-255
 	cat >expect <<-EOF &&
 	version 2
 	agent=FAKE
+	os-version=$(uname -srvm | tr -d "\n" | tr "[\001-\040][\177-\377]" ".")
 	ls-refs=unborn
 	fetch=shallow wait-for-done
 	server-option
diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
index c48830de8f..9c9a707e6a 100755
--- a/t/t5701-git-serve.sh
+++ b/t/t5701-git-serve.sh
@@ -13,9 +13,12 @@ test_expect_success 'test capability advertisement' '
 	wrong_algo sha1:sha256
 	wrong_algo sha256:sha1
 	EOF
+	# Octal intervals \001-\040 and \177-\377
+	# corresponds to decimal intervals 1-32 and 127-255
 	cat >expect.base <<-EOF &&
 	version 2
 	agent=git/$(git version | cut -d" " -f3)
+	os-version=$(uname -srvm | tr -d "\n" | tr "[\001-\040][\177-\377]" ".")
 	ls-refs=unborn
 	fetch=shallow wait-for-done
 	server-option
diff --git a/version.c b/version.c
index 10b9fa77d1..5b20ea0d7c 100644
--- a/version.c
+++ b/version.c
@@ -61,3 +61,32 @@ int get_uname_info(struct strbuf *buf)
 		    uname_info.machine);
 	return 0;
 }
+
+const char *os_version(void)
+{
+	static const char *os = NULL;
+
+	if (!os) {
+		struct strbuf buf = STRBUF_INIT;
+
+		get_uname_info(&buf);
+		os = strbuf_detach(&buf, NULL);
+	}
+
+	return os;
+}
+
+const char *os_version_sanitized(void)
+{
+	static const char *os_sanitized = NULL;
+
+	if (!os_sanitized) {
+		struct strbuf buf = STRBUF_INIT;
+
+		strbuf_addstr(&buf, os_version());
+		strbuf_sanitize(&buf);
+		os_sanitized = strbuf_detach(&buf, NULL);
+	}
+
+	return os_sanitized;
+}
diff --git a/version.h b/version.h
index afe3dbbab7..349952c8f2 100644
--- a/version.h
+++ b/version.h
@@ -14,4 +14,7 @@ const char *git_user_agent_sanitized(void);
 */
 int get_uname_info(struct strbuf *buf);
 
+const char *os_version(void);
+const char *os_version_sanitized(void);
+
 #endif /* VERSION_H */
-- 
2.45.2.563.g6aa460b3cb
Previous: Christian CouderNext: Dragan Simic
Message 5 of 22 in “Advertise OS version”
  1. 0/3 Advertise OS versionChristian Couder, Jun 19, 2024
  2. 1/3 version: refactor strbuf_sanitize()Christian Couder, Jun 19, 2024
  3. Eric SunshineJun 19, 2024
  4. 2/3 version: refactor get_uname_info()Christian Couder, Jun 19, 2024
  5. 3/3 connect: advertise OS versionChristian Couder, Jun 19, 2024
  6. Dragan SimicJun 19, 2024
  7. Jeff KingJun 19, 2024
  8. Dragan SimicJun 19, 2024
  9. Christian CouderJun 19, 2024
  10. Dragan SimicJun 19, 2024
  11. rsbecker@nexbridge.comJun 19, 2024
  12. Jeff KingJun 19, 2024
  13. rsbecker@nexbridge.comJun 19, 2024
  14. Dragan SimicJun 19, 2024
  15. Jeff KingJun 19, 2024
  16. rsbecker@nexbridge.comJun 19, 2024
  17. brian m. carlsonJun 19, 2024
  18. Jeff KingJun 20, 2024
  19. Junio C HamanoJun 20, 2024
  20. Usman AkinyemiDec 9, 2024
  21. rsbecker@nexbridge.comDec 9, 2024
  22. Usman AkinyemiDec 10, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.