Line | Count | Source (jump to first uncovered line) |
1 | | #define USE_THE_REPOSITORY_VARIABLE |
2 | | |
3 | | #include "git-compat-util.h" |
4 | | #include "config.h" |
5 | | #include "environment.h" |
6 | | #include "protocol.h" |
7 | | #include "trace2.h" |
8 | | |
9 | | static enum protocol_version parse_protocol_version(const char *value) |
10 | 0 | { |
11 | 0 | if (!strcmp(value, "0")) |
12 | 0 | return protocol_v0; |
13 | 0 | else if (!strcmp(value, "1")) |
14 | 0 | return protocol_v1; |
15 | 0 | else if (!strcmp(value, "2")) |
16 | 0 | return protocol_v2; |
17 | 0 | else |
18 | 0 | return protocol_unknown_version; |
19 | 0 | } |
20 | | |
21 | | enum protocol_version get_protocol_version_config(void) |
22 | 0 | { |
23 | 0 | const char *value; |
24 | 0 | const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION"; |
25 | 0 | const char *git_test_v; |
26 | |
|
27 | 0 | if (!git_config_get_string_tmp("protocol.version", &value)) { |
28 | 0 | enum protocol_version version = parse_protocol_version(value); |
29 | |
|
30 | 0 | if (version == protocol_unknown_version) |
31 | 0 | die("unknown value for config 'protocol.version': %s", |
32 | 0 | value); |
33 | | |
34 | 0 | return version; |
35 | 0 | } |
36 | | |
37 | 0 | git_test_v = getenv(git_test_k); |
38 | 0 | if (git_test_v && *git_test_v) { |
39 | 0 | enum protocol_version env = parse_protocol_version(git_test_v); |
40 | |
|
41 | 0 | if (env == protocol_unknown_version) |
42 | 0 | die("unknown value for %s: %s", git_test_k, git_test_v); |
43 | 0 | return env; |
44 | 0 | } |
45 | | |
46 | 0 | return protocol_v2; |
47 | 0 | } |
48 | | |
49 | | enum protocol_version determine_protocol_version_server(void) |
50 | 0 | { |
51 | 0 | const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT); |
52 | 0 | enum 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 | | */ |
61 | 0 | if (git_protocol) { |
62 | 0 | struct string_list list = STRING_LIST_INIT_DUP; |
63 | 0 | const struct string_list_item *item; |
64 | 0 | string_list_split(&list, git_protocol, ':', -1); |
65 | |
|
66 | 0 | for_each_string_list_item(item, &list) { |
67 | 0 | const char *value; |
68 | 0 | enum protocol_version v; |
69 | |
|
70 | 0 | if (skip_prefix(item->string, "version=", &value)) { |
71 | 0 | v = parse_protocol_version(value); |
72 | 0 | if (v > version) |
73 | 0 | version = v; |
74 | 0 | } |
75 | 0 | } |
76 | |
|
77 | 0 | string_list_clear(&list, 0); |
78 | 0 | } |
79 | |
|
80 | 0 | trace2_data_intmax("transfer", NULL, "negotiated-version", version); |
81 | |
|
82 | 0 | return version; |
83 | 0 | } |
84 | | |
85 | | enum protocol_version determine_protocol_version_client(const char *server_response) |
86 | 0 | { |
87 | 0 | enum protocol_version version = protocol_v0; |
88 | |
|
89 | 0 | if (skip_prefix(server_response, "version ", &server_response)) { |
90 | 0 | version = parse_protocol_version(server_response); |
91 | |
|
92 | 0 | if (version == protocol_unknown_version) |
93 | 0 | die("server is speaking an unknown protocol"); |
94 | 0 | if (version == protocol_v0) |
95 | 0 | die("protocol error: server explicitly said version 0"); |
96 | 0 | } |
97 | | |
98 | 0 | return version; |
99 | 0 | } |