diff options
Diffstat (limited to 'serve.c')
-rw-r--r-- | serve.c | 82 |
1 files changed, 48 insertions, 34 deletions
@@ -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 (;;) |