git
/
protocol.c
99 строк · 2.6 Кб
1#define USE_THE_REPOSITORY_VARIABLE2
3#include "git-compat-util.h"4#include "config.h"5#include "environment.h"6#include "protocol.h"7#include "trace2.h"8
9static enum protocol_version parse_protocol_version(const char *value)10{
11if (!strcmp(value, "0"))12return protocol_v0;13else if (!strcmp(value, "1"))14return protocol_v1;15else if (!strcmp(value, "2"))16return protocol_v2;17else18return protocol_unknown_version;19}
20
21enum protocol_version get_protocol_version_config(void)22{
23const char *value;24const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION";25const char *git_test_v;26
27if (!git_config_get_string_tmp("protocol.version", &value)) {28enum protocol_version version = parse_protocol_version(value);29
30if (version == protocol_unknown_version)31die("unknown value for config 'protocol.version': %s",32value);33
34return version;35}36
37git_test_v = getenv(git_test_k);38if (git_test_v && *git_test_v) {39enum protocol_version env = parse_protocol_version(git_test_v);40
41if (env == protocol_unknown_version)42die("unknown value for %s: %s", git_test_k, git_test_v);43return env;44}45
46return protocol_v2;47}
48
49enum protocol_version determine_protocol_version_server(void)50{
51const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT);52enum protocol_version version = protocol_v0;53
54/*55* Determine which protocol version the client has requested. Since
56* multiple 'version' keys can be sent by the client, indicating that
57* the client is okay to speak any of them, select the greatest version
58* that the client has requested. This is due to the assumption that
59* the most recent protocol version will be the most state-of-the-art.
60*/
61if (git_protocol) {62struct string_list list = STRING_LIST_INIT_DUP;63const struct string_list_item *item;64string_list_split(&list, git_protocol, ':', -1);65
66for_each_string_list_item(item, &list) {67const char *value;68enum protocol_version v;69
70if (skip_prefix(item->string, "version=", &value)) {71v = parse_protocol_version(value);72if (v > version)73version = v;74}75}76
77string_list_clear(&list, 0);78}79
80trace2_data_intmax("transfer", NULL, "negotiated-version", version);81
82return version;83}
84
85enum protocol_version determine_protocol_version_client(const char *server_response)86{
87enum protocol_version version = protocol_v0;88
89if (skip_prefix(server_response, "version ", &server_response)) {90version = parse_protocol_version(server_response);91
92if (version == protocol_unknown_version)93die("server is speaking an unknown protocol");94if (version == protocol_v0)95die("protocol error: server explicitly said version 0");96}97
98return version;99}
100