All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiang Xin <worldhello.net@gmail.com>
To: Git List <git@vger.kernel.org>,
	Junio C Hamano <gitster@pobox.com>,
	Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Cc: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Subject: [PATCH 2/2] archive: support remote archive from stateless transport
Date: Tue, 19 Sep 2023 14:41:56 +0800	[thread overview]
Message-ID: <20230919064156.13892-2-worldhello.net@gmail.com> (raw)
In-Reply-To: <20230919064156.13892-1-worldhello.net@gmail.com>

From: Jiang Xin <zhiyou.jx@alibaba-inc.com>

Even though we can establish a stateless connection, we still cannot
archive the remote repository using a stateless HTTP protocol. Try the
following steps to make it work.

 1. Add support for "git-upload-archive" service in "http-backend".

 2. Unable to access the URL ".../info/refs?service=git-upload-archive"
    to detect the protocol version, use the "git-upload-pack" service
    instead.

 3. "git-archive" does not resolve the protocol version and capabilities
    when connecting to remote-helper, so the remote-helper should not
    send them.

 4. "git-archive" may not be able to disconnect the stateless
    connection. Run "do_take_over()" to take_over the transfer for
    a graceful disconnect function.

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
---
 http-backend.c         | 15 +++++++++++++--
 remote-curl.c          | 14 +++++++++++---
 t/t5003-archive-zip.sh | 30 ++++++++++++++++++++++++++++++
 transport-helper.c     |  5 ++++-
 4 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/http-backend.c b/http-backend.c
index ff07b87e64..ed3bed965a 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -38,6 +38,7 @@ struct rpc_service {
 static struct rpc_service rpc_service[] = {
 	{ "upload-pack", "uploadpack", 1, 1 },
 	{ "receive-pack", "receivepack", 0, -1 },
+	{ "upload-archive", "uploadarchive", 0, -1 },
 };
 
 static struct string_list *get_parameters(void)
@@ -639,10 +640,19 @@ static void check_content_type(struct strbuf *hdr, const char *accepted_type)
 
 static void service_rpc(struct strbuf *hdr, char *service_name)
 {
-	const char *argv[] = {NULL, "--stateless-rpc", ".", NULL};
+	const char *argv[4];
 	struct rpc_service *svc = select_service(hdr, service_name);
 	struct strbuf buf = STRBUF_INIT;
 
+	if (!strcmp(service_name, "git-upload-archive")) {
+		argv[1] = ".";
+		argv[2] = NULL;
+	} else {
+		argv[1] = "--stateless-rpc";
+		argv[2] = ".";
+		argv[3] = NULL;
+	}
+
 	strbuf_reset(&buf);
 	strbuf_addf(&buf, "application/x-git-%s-request", svc->name);
 	check_content_type(hdr, buf.buf);
@@ -723,7 +733,8 @@ static struct service_cmd {
 	{"GET", "/objects/pack/pack-[0-9a-f]{64}\\.idx$", get_idx_file},
 
 	{"POST", "/git-upload-pack$", service_rpc},
-	{"POST", "/git-receive-pack$", service_rpc}
+	{"POST", "/git-receive-pack$", service_rpc},
+	{"POST", "/git-upload-archive$", service_rpc}
 };
 
 static int bad_request(struct strbuf *hdr, const struct service_cmd *c)
diff --git a/remote-curl.c b/remote-curl.c
index ef05752ca5..ce6cb8ac05 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -1447,8 +1447,14 @@ static int stateless_connect(const char *service_name)
 	 * establish a stateless connection, otherwise we need to tell the
 	 * client to fallback to using other transport helper functions to
 	 * complete their request.
+	 *
+	 * The "git-upload-archive" service is a read-only operation. Fallback
+	 * to use "git-upload-pack" service to discover protocol version.
 	 */
-	discover = discover_refs(service_name, 0);
+	if (!strcmp(service_name, "git-upload-archive"))
+		discover = discover_refs("git-upload-pack", 0);
+	else
+		discover = discover_refs(service_name, 0);
 	if (discover->version != protocol_v2) {
 		printf("fallback\n");
 		fflush(stdout);
@@ -1486,9 +1492,11 @@ static int stateless_connect(const char *service_name)
 
 	/*
 	 * Dump the capability listing that we got from the server earlier
-	 * during the info/refs request.
+	 * during the info/refs request. This does not work with the
+	 * "git-upload-archive" service.
 	 */
-	write_or_die(rpc.in, discover->buf, discover->len);
+	if (strcmp(service_name, "git-upload-archive"))
+		write_or_die(rpc.in, discover->buf, discover->len);
 
 	/* Until we see EOF keep sending POSTs */
 	while (1) {
diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh
index fc499cdff0..80123c1e06 100755
--- a/t/t5003-archive-zip.sh
+++ b/t/t5003-archive-zip.sh
@@ -239,4 +239,34 @@ check_zip with_untracked2
 check_added with_untracked2 untracked one/untracked
 check_added with_untracked2 untracked two/untracked
 
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success "setup for HTTP protocol" '
+	cp -R bare.git "$HTTPD_DOCUMENT_ROOT_PATH/bare.git" &&
+	git -C "$HTTPD_DOCUMENT_ROOT_PATH/bare.git" \
+		config http.uploadpack true &&
+	set_askpass user@host pass@host
+'
+
+setup_askpass_helper
+
+test_expect_success 'remote archive does not work with protocol v1' '
+	test_when_finished "rm -f d5.zip" &&
+	test_must_fail git -c protocol.version=1 archive \
+		--remote="$HTTPD_URL/auth/smart/bare.git" \
+		--output=d5.zip HEAD >actual 2>&1 &&
+	cat >expect <<-EOF &&
+	fatal: can${SQ}t connect to subservice git-upload-archive
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'archive remote http repository' '
+	test_when_finished "rm -f d5.zip" &&
+	git archive --remote="$HTTPD_URL/auth/smart/bare.git" \
+		--output=d5.zip HEAD &&
+	test_cmp_bin d.zip d5.zip
+'
+
 test_done
diff --git a/transport-helper.c b/transport-helper.c
index 2e127d24a5..91381be622 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -628,7 +628,8 @@ static int process_connect_service(struct transport *transport,
 		ret = run_connect(transport, &cmdbuf);
 	} else if (data->stateless_connect &&
 		   (get_protocol_version_config() == protocol_v2) &&
-		   !strcmp("git-upload-pack", name)) {
+		   (!strcmp("git-upload-pack", name) ||
+		    !strcmp("git-upload-archive", name))) {
 		strbuf_addf(&cmdbuf, "stateless-connect %s\n", name);
 		ret = run_connect(transport, &cmdbuf);
 		if (ret)
@@ -668,6 +669,8 @@ static int connect_helper(struct transport *transport, const char *name,
 
 	fd[0] = data->helper->out;
 	fd[1] = data->helper->in;
+
+	do_take_over(transport);
 	return 0;
 }
 
-- 
2.40.1.49.g40e13c3520.dirty


  reply	other threads:[~2023-09-19  6:42 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-19  6:41 [PATCH 1/2] transport-helper: no connection restriction in connect_helper Jiang Xin
2023-09-19  6:41 ` Jiang Xin [this message]
2023-09-19 17:18 ` Junio C Hamano
2023-09-20  0:20   ` Jiang Xin
2023-09-23 15:21   ` [PATCH v2 0/3] support remote archive from stateless transport Jiang Xin
2023-09-25 22:21     ` Junio C Hamano
2023-09-26  0:43       ` Jiang Xin
2023-09-23 15:21   ` [PATCH v2 1/3] transport-helper: no connection restriction in connect_helper Jiang Xin
2023-09-25 21:11     ` Junio C Hamano
2023-09-23 15:22   ` [PATCH v2 2/3] transport-helper: run do_take_over " Jiang Xin
2023-09-25 21:34     ` Junio C Hamano
2023-10-04 14:00       ` Jiang Xin
2023-10-04 15:21       ` [PATCH v3 0/4] support remote archive from stateless transport Jiang Xin
2023-10-04 15:21         ` [PATCH v3 1/4] transport-helper: no connection restriction in connect_helper Jiang Xin
2023-10-04 15:21         ` [PATCH v3 2/4] transport-helper: call do_take_over() in process_connect Jiang Xin
2023-10-04 18:29           ` Junio C Hamano
2023-10-04 15:21         ` [PATCH v3 3/4] transport-helper: call do_take_over() in connect_helper Jiang Xin
2023-10-04 15:21         ` [PATCH v3 4/4] archive: support remote archive from stateless transport Jiang Xin
2023-12-14 14:13         ` [PATCH v4 0/4] support remote archive via " Jiang Xin
2023-12-14 14:13           ` [PATCH v4 1/4] transport-helper: no connection restriction in connect_helper Jiang Xin
2024-01-12  7:42             ` Linus Arver
2024-01-12 21:50               ` Junio C Hamano
2024-01-16  9:04               ` Jiang Xin
2024-01-18 22:26                 ` Linus Arver
2024-01-19 10:56                   ` Jiang Xin
2024-01-20 20:25                     ` Linus Arver
2023-12-14 14:13           ` [PATCH v4 2/4] transport-helper: call do_take_over() in process_connect Jiang Xin
2023-12-14 14:13           ` [PATCH v4 3/4] transport-helper: call do_take_over() in connect_helper Jiang Xin
2024-01-12  7:56             ` Linus Arver
2024-01-16  9:41               ` Jiang Xin
2023-12-14 14:13           ` [PATCH v4 4/4] archive: support remote archive from stateless transport Jiang Xin
2024-01-12  8:12             ` Linus Arver
2024-01-16 13:39           ` [PATCH v5 0/6] support remote archive via " Jiang Xin
2024-01-16 13:39             ` [PATCH v5 1/6] transport-helper: no connection restriction in connect_helper Jiang Xin
2024-01-20 20:28               ` Linus Arver
2024-01-16 13:39             ` [PATCH v5 2/6] remote-curl: supports git-upload-archive service Jiang Xin
2024-01-20 20:30               ` Linus Arver
2024-01-16 13:39             ` [PATCH v5 3/6] transport-helper: protocol-v2 supports upload-archive Jiang Xin
2024-01-16 13:39             ` [PATCH v5 4/6] http-backend: new rpc-service for git-upload-archive Jiang Xin
2024-01-16 13:39             ` [PATCH v5 5/6] transport-helper: call do_take_over() in connect_helper Jiang Xin
2024-01-20 20:37               ` Linus Arver
2024-01-16 13:39             ` [PATCH v5 6/6] transport-helper: call do_take_over() in process_connect Jiang Xin
2024-01-20 20:43             ` [PATCH v5 0/6] support remote archive via stateless transport Linus Arver
2024-01-21  4:09               ` Jiang Xin
2024-01-21 13:15             ` [PATCH v6 " Jiang Xin
2024-01-21 13:15               ` [PATCH v6 1/6] transport-helper: no connection restriction in connect_helper Jiang Xin
2024-01-21 13:15               ` [PATCH v6 2/6] remote-curl: supports git-upload-archive service Jiang Xin
2024-01-21 13:15               ` [PATCH v6 3/6] transport-helper: protocol v2 supports upload-archive Jiang Xin
2024-01-21 13:15               ` [PATCH v6 4/6] http-backend: new rpc-service for git-upload-archive Jiang Xin
2024-01-21 13:15               ` [PATCH v6 5/6] transport-helper: call do_take_over() in connect_helper Jiang Xin
2024-01-21 13:15               ` [PATCH v6 6/6] transport-helper: call do_take_over() in process_connect Jiang Xin
2024-01-21 16:57               ` [PATCH v6 0/6] support remote archive via stateless transport Linus Arver
2024-01-22 15:54                 ` Junio C Hamano
2023-09-23 15:22   ` [PATCH v2 3/3] archive: support remote archive from " Jiang Xin
2023-09-24  6:52     ` Eric Sunshine
2023-09-24 23:39       ` Jiang Xin
2023-09-24 23:58         ` rsbecker
2023-09-25  0:15           ` Jiang Xin
2023-09-25  1:04             ` rsbecker
2023-09-24 13:41     ` Phillip Wood
2023-09-24 23:36       ` Jiang Xin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230919064156.13892-2-worldhello.net@gmail.com \
    --to=worldhello.net@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=ilari.liusvaara@elisanet.fi \
    --cc=zhiyou.jx@alibaba-inc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.