THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
6.2KB

  1. #include "cache.h"
  2. #include "repository.h"
  3. #include "config.h"
  4. #include "pkt-line.h"
  5. #include "version.h"
  6. #include "argv-array.h"
  7. #include "ls-refs.h"
  8. #include "serve.h"
  9. #include "upload-pack.h"
  10. static int always_advertise(struct repository *r,
  11. struct strbuf *value)
  12. {
  13. return 1;
  14. }
  15. static int agent_advertise(struct repository *r,
  16. struct strbuf *value)
  17. {
  18. if (value)
  19. strbuf_addstr(value, git_user_agent_sanitized());
  20. return 1;
  21. }
  22. struct protocol_capability {
  23. /*
  24. * The name of the capability. The server uses this name when
  25. * advertising this capability, and the client uses this name to
  26. * specify this capability.
  27. */
  28. const char *name;
  29. /*
  30. * Function queried to see if a capability should be advertised.
  31. * Optionally a value can be specified by adding it to 'value'.
  32. * If a value is added to 'value', the server will advertise this
  33. * capability as "<name>=<value>" instead of "<name>".
  34. */
  35. int (*advertise)(struct repository *r, struct strbuf *value);
  36. /*
  37. * Function called when a client requests the capability as a command.
  38. * The function will be provided the capabilities requested via 'keys'
  39. * as well as a struct packet_reader 'request' which the command should
  40. * use to read the command specific part of the request. Every command
  41. * MUST read until a flush packet is seen before sending a response.
  42. *
  43. * This field should be NULL for capabilities which are not commands.
  44. */
  45. int (*command)(struct repository *r,
  46. struct argv_array *keys,
  47. struct packet_reader *request);
  48. };
  49. static struct protocol_capability capabilities[] = {
  50. { "agent", agent_advertise, NULL },
  51. { "ls-refs", always_advertise, ls_refs },
  52. { "fetch", upload_pack_advertise, upload_pack_v2 },
  53. { "server-option", always_advertise, NULL },
  54. };
  55. static void advertise_capabilities(void)
  56. {
  57. struct strbuf capability = STRBUF_INIT;
  58. struct strbuf value = STRBUF_INIT;
  59. int i;
  60. for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
  61. struct protocol_capability *c = &capabilities[i];
  62. if (c->advertise(the_repository, &value)) {
  63. strbuf_addstr(&capability, c->name);
  64. if (value.len) {
  65. strbuf_addch(&capability, '=');
  66. strbuf_addbuf(&capability, &value);
  67. }
  68. strbuf_addch(&capability, '\n');
  69. packet_write(1, capability.buf, capability.len);
  70. }
  71. strbuf_reset(&capability);
  72. strbuf_reset(&value);
  73. }
  74. packet_flush(1);
  75. strbuf_release(&capability);
  76. strbuf_release(&value);
  77. }
  78. static struct protocol_capability *get_capability(const char *key)
  79. {
  80. int i;
  81. if (!key)
  82. return NULL;
  83. for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
  84. struct protocol_capability *c = &capabilities[i];
  85. const char *out;
  86. if (skip_prefix(key, c->name, &out) && (!*out || *out == '='))
  87. return c;
  88. }
  89. return NULL;
  90. }
  91. static int is_valid_capability(const char *key)
  92. {
  93. const struct protocol_capability *c = get_capability(key);
  94. return c && c->advertise(the_repository, NULL);
  95. }
  96. static int is_command(const char *key, struct protocol_capability **command)
  97. {
  98. const char *out;
  99. if (skip_prefix(key, "command=", &out)) {
  100. struct protocol_capability *cmd = get_capability(out);
  101. if (*command)
  102. die("command '%s' requested after already requesting command '%s'",
  103. out, (*command)->name);
  104. if (!cmd || !cmd->advertise(the_repository, NULL) || !cmd->command)
  105. die("invalid command '%s'", out);
  106. *command = cmd;
  107. return 1;
  108. }
  109. return 0;
  110. }
  111. int has_capability(const struct argv_array *keys, const char *capability,
  112. const char **value)
  113. {
  114. int i;
  115. for (i = 0; i < keys->argc; i++) {
  116. const char *out;
  117. if (skip_prefix(keys->argv[i], capability, &out) &&
  118. (!*out || *out == '=')) {
  119. if (value) {
  120. if (*out == '=')
  121. out++;
  122. *value = out;
  123. }
  124. return 1;
  125. }
  126. }
  127. return 0;
  128. }
  129. enum request_state {
  130. PROCESS_REQUEST_KEYS,
  131. PROCESS_REQUEST_DONE,
  132. };
  133. static int process_request(void)
  134. {
  135. enum request_state state = PROCESS_REQUEST_KEYS;
  136. struct packet_reader reader;
  137. struct argv_array keys = ARGV_ARRAY_INIT;
  138. struct protocol_capability *command = NULL;
  139. packet_reader_init(&reader, 0, NULL, 0,
  140. PACKET_READ_CHOMP_NEWLINE |
  141. PACKET_READ_GENTLE_ON_EOF |
  142. PACKET_READ_DIE_ON_ERR_PACKET);
  143. /*
  144. * Check to see if the client closed their end before sending another
  145. * request. If so we can terminate the connection.
  146. */
  147. if (packet_reader_peek(&reader) == PACKET_READ_EOF)
  148. return 1;
  149. reader.options &= ~PACKET_READ_GENTLE_ON_EOF;
  150. while (state != PROCESS_REQUEST_DONE) {
  151. switch (packet_reader_peek(&reader)) {
  152. case PACKET_READ_EOF:
  153. BUG("Should have already died when seeing EOF");
  154. case PACKET_READ_NORMAL:
  155. /* collect request; a sequence of keys and values */
  156. if (is_command(reader.line, &command) ||
  157. is_valid_capability(reader.line))
  158. argv_array_push(&keys, reader.line);
  159. else
  160. die("unknown capability '%s'", reader.line);
  161. /* Consume the peeked line */
  162. packet_reader_read(&reader);
  163. break;
  164. case PACKET_READ_FLUSH:
  165. /*
  166. * If no command and no keys were given then the client
  167. * wanted to terminate the connection.
  168. */
  169. if (!keys.argc)
  170. return 1;
  171. /*
  172. * The flush packet isn't consume here like it is in
  173. * the other parts of this switch statement. This is
  174. * so that the command can read the flush packet and
  175. * see the end of the request in the same way it would
  176. * if command specific arguments were provided after a
  177. * delim packet.
  178. */
  179. state = PROCESS_REQUEST_DONE;
  180. break;
  181. case PACKET_READ_DELIM:
  182. /* Consume the peeked line */
  183. packet_reader_read(&reader);
  184. state = PROCESS_REQUEST_DONE;
  185. break;
  186. }
  187. }
  188. if (!command)
  189. die("no command requested");
  190. command->command(the_repository, &keys, &reader);
  191. argv_array_clear(&keys);
  192. return 0;
  193. }
  194. /* Main serve loop for protocol version 2 */
  195. void serve(struct serve_options *options)
  196. {
  197. if (options->advertise_capabilities || !options->stateless_rpc) {
  198. /* serve by default supports v2 */
  199. packet_write_fmt(1, "version 2\n");
  200. advertise_capabilities();
  201. /*
  202. * If only the list of capabilities was requested exit
  203. * immediately after advertising capabilities
  204. */
  205. if (options->advertise_capabilities)
  206. return;
  207. }
  208. /*
  209. * If stateless-rpc was requested then exit after
  210. * a single request/response exchange
  211. */
  212. if (options->stateless_rpc) {
  213. process_request();
  214. } else {
  215. for (;;)
  216. if (process_request())
  217. break;
  218. }
  219. }