summaryrefslogtreecommitdiff
path: root/serve.c
diff options
context:
space:
mode:
Diffstat (limited to 'serve.c')
-rw-r--r--serve.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/serve.c b/serve.c
index f11c0e07c4..1817edc7f5 100644
--- a/serve.c
+++ b/serve.c
@@ -9,7 +9,7 @@
#include "serve.h"
#include "upload-pack.h"
-static int advertise_sid;
+static int advertise_sid = -1;
static int always_advertise(struct repository *r,
struct strbuf *value)
@@ -35,6 +35,9 @@ static int object_format_advertise(struct repository *r,
static int session_id_advertise(struct repository *r, struct strbuf *value)
{
+ if (advertise_sid == -1 &&
+ git_config_get_bool("transfer.advertisesid", &advertise_sid))
+ advertise_sid = 0;
if (!advertise_sid)
return 0;
if (value)
@@ -60,34 +63,58 @@ struct protocol_capability {
/*
* Function called when a client requests the capability as a command.
- * The function will be provided the capabilities requested via 'keys'
- * as well as a struct packet_reader 'request' which the command should
+ * Will be provided a struct packet_reader 'request' which it should
* use to read the command specific part of the request. Every command
* MUST read until a flush packet is seen before sending a response.
*
* This field should be NULL for capabilities which are not commands.
*/
- int (*command)(struct repository *r,
- struct strvec *keys,
- struct packet_reader *request);
+ int (*command)(struct repository *r, struct packet_reader *request);
};
static struct protocol_capability capabilities[] = {
- { "agent", agent_advertise, NULL },
- { "ls-refs", ls_refs_advertise, ls_refs },
- { "fetch", upload_pack_advertise, upload_pack_v2 },
- { "server-option", always_advertise, NULL },
- { "object-format", object_format_advertise, NULL },
- { "session-id", session_id_advertise, NULL },
- { "object-info", always_advertise, cap_object_info },
+ {
+ .name = "agent",
+ .advertise = agent_advertise,
+ },
+ {
+ .name = "ls-refs",
+ .advertise = ls_refs_advertise,
+ .command = ls_refs,
+ },
+ {
+ .name = "fetch",
+ .advertise = upload_pack_advertise,
+ .command = upload_pack_v2,
+ },
+ {
+ .name = "server-option",
+ .advertise = always_advertise,
+ },
+ {
+ .name = "object-format",
+ .advertise = object_format_advertise,
+ },
+ {
+ .name = "session-id",
+ .advertise = session_id_advertise,
+ },
+ {
+ .name = "object-info",
+ .advertise = always_advertise,
+ .command = cap_object_info,
+ },
};
-static void advertise_capabilities(void)
+void protocol_v2_advertise_capabilities(void)
{
struct strbuf capability = STRBUF_INIT;
struct strbuf value = STRBUF_INIT;
int i;
+ /* serve by default supports v2 */
+ packet_write_fmt(1, "version 2\n");
+
for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
struct protocol_capability *c = &capabilities[i];
@@ -156,8 +183,8 @@ static int is_command(const char *key, struct protocol_capability **command)
return 0;
}
-int has_capability(const struct strvec *keys, const char *capability,
- const char **value)
+static int has_capability(const struct strvec *keys, const char *capability,
+ const char **value)
{
int i;
for (i = 0; i < keys->nr; i++) {
@@ -270,35 +297,22 @@ static int process_request(void)
if (has_capability(&keys, "session-id", &client_sid))
trace2_data_string("transfer", NULL, "client-sid", client_sid);
- command->command(the_repository, &keys, &reader);
+ command->command(the_repository, &reader);
strvec_clear(&keys);
return 0;
}
-/* Main serve loop for protocol version 2 */
-void serve(struct serve_options *options)
+void protocol_v2_serve_loop(int stateless_rpc)
{
- git_config_get_bool("transfer.advertisesid", &advertise_sid);
-
- if (options->advertise_capabilities || !options->stateless_rpc) {
- /* serve by default supports v2 */
- packet_write_fmt(1, "version 2\n");
-
- advertise_capabilities();
- /*
- * If only the list of capabilities was requested exit
- * immediately after advertising capabilities
- */
- if (options->advertise_capabilities)
- return;
- }
+ if (!stateless_rpc)
+ protocol_v2_advertise_capabilities();
/*
* If stateless-rpc was requested then exit after
* a single request/response exchange
*/
- if (options->stateless_rpc) {
+ if (stateless_rpc) {
process_request();
} else {
for (;;)