diff options
Diffstat (limited to 'http-backend.c')
-rw-r--r-- | http-backend.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/http-backend.c b/http-backend.c index e7c0eea..1ed1e29 100644 --- a/http-backend.c +++ b/http-backend.c @@ -1,5 +1,9 @@ -#include "cache.h" +#include "git-compat-util.h" #include "config.h" +#include "environment.h" +#include "git-zlib.h" +#include "hex.h" +#include "path.h" #include "repository.h" #include "refs.h" #include "pkt-line.h" @@ -11,8 +15,10 @@ #include "url.h" #include "strvec.h" #include "packfile.h" -#include "object-store.h" +#include "object-store-ll.h" #include "protocol.h" +#include "date.h" +#include "write-or-die.h" static const char content_type[] = "Content-Type"; static const char content_length[] = "Content-Length"; @@ -32,6 +38,7 @@ struct rpc_service { static struct rpc_service rpc_service[] = { { "upload-pack", "uploadpack", 1, 1 }, { "receive-pack", "receivepack", 0, -1 }, + { "upload-archive", "uploadarchive", 0, -1 }, }; static struct string_list *get_parameters(void) @@ -466,9 +473,7 @@ static void run_service(const char **argv, int buffer_input) struct child_process cld = CHILD_PROCESS_INIT; ssize_t req_len = get_content_length(); - if (encoding && !strcmp(encoding, "gzip")) - gzipped_request = 1; - else if (encoding && !strcmp(encoding, "x-gzip")) + if (encoding && (!strcmp(encoding, "gzip") || !strcmp(encoding, "x-gzip"))) gzipped_request = 1; if (!user || !*user) @@ -477,12 +482,12 @@ static void run_service(const char **argv, int buffer_input) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) - strvec_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user); + strvec_pushf(&cld.env, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) - strvec_pushf(&cld.env_array, + strvec_pushf(&cld.env, "GIT_COMMITTER_EMAIL=%s@http.%s", user, host); - cld.argv = argv; + strvec_pushv(&cld.args, argv); if (buffer_input || gzipped_request || req_len >= 0) cld.in = -1; cld.git_cmd = 1; @@ -506,7 +511,7 @@ static void run_service(const char **argv, int buffer_input) } static int show_text_ref(const char *name, const struct object_id *oid, - int flag, void *cb_data) + int flag UNUSED, void *cb_data) { const char *name_nons = strip_namespace(name); struct strbuf *buf = cb_data; @@ -525,7 +530,7 @@ static int show_text_ref(const char *name, const struct object_id *oid, return 0; } -static void get_info_refs(struct strbuf *hdr, char *arg) +static void get_info_refs(struct strbuf *hdr, char *arg UNUSED) { const char *service_name = get_parameter("service"); struct strbuf buf = STRBUF_INIT; @@ -554,7 +559,7 @@ static void get_info_refs(struct strbuf *hdr, char *arg) } else { select_getanyfile(hdr); - for_each_namespaced_ref(show_text_ref, &buf); + for_each_namespaced_ref(NULL, show_text_ref, &buf); send_strbuf(hdr, "text/plain", &buf); } strbuf_release(&buf); @@ -579,7 +584,7 @@ static int show_head_ref(const char *refname, const struct object_id *oid, return 0; } -static void get_head(struct strbuf *hdr, char *arg) +static void get_head(struct strbuf *hdr, char *arg UNUSED) { struct strbuf buf = STRBUF_INIT; @@ -589,7 +594,7 @@ static void get_head(struct strbuf *hdr, char *arg) strbuf_release(&buf); } -static void get_info_packs(struct strbuf *hdr, char *arg) +static void get_info_packs(struct strbuf *hdr, char *arg UNUSED) { size_t objdirlen = strlen(get_object_directory()); struct strbuf buf = STRBUF_INIT; @@ -635,10 +640,15 @@ static void check_content_type(struct strbuf *hdr, const char *accepted_type) static void service_rpc(struct strbuf *hdr, char *service_name) { - const char *argv[] = {NULL, "--stateless-rpc", ".", NULL}; + struct strvec argv = STRVEC_INIT; struct rpc_service *svc = select_service(hdr, service_name); struct strbuf buf = STRBUF_INIT; + strvec_push(&argv, svc->name); + if (strcmp(service_name, "git-upload-archive")) + strvec_push(&argv, "--stateless-rpc"); + strvec_push(&argv, "."); + strbuf_reset(&buf); strbuf_addf(&buf, "application/x-git-%s-request", svc->name); check_content_type(hdr, buf.buf); @@ -651,9 +661,9 @@ static void service_rpc(struct strbuf *hdr, char *service_name) end_headers(hdr); - argv[0] = svc->name; - run_service(argv, svc->buffer_input); + run_service(argv.v, svc->buffer_input); strbuf_release(&buf); + strvec_clear(&argv); } static int dead; @@ -661,8 +671,9 @@ static NORETURN void die_webcgi(const char *err, va_list params) { if (dead <= 1) { struct strbuf hdr = STRBUF_INIT; + report_fn die_message_fn = get_die_message_routine(); - vreportf("fatal: ", err, params); + die_message_fn(err, params); http_status(&hdr, 500, "Internal Server Error"); hdr_nocache(&hdr); @@ -718,6 +729,7 @@ static struct service_cmd { {"GET", "/objects/pack/pack-[0-9a-f]{64}\\.idx$", get_idx_file}, {"POST", "/git-upload-pack$", service_rpc}, + {"POST", "/git-upload-archive$", service_rpc}, {"POST", "/git-receive-pack$", service_rpc} }; @@ -736,7 +748,7 @@ static int bad_request(struct strbuf *hdr, const struct service_cmd *c) return 0; } -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { char *method = getenv("REQUEST_METHOD"); const char *proto_header; @@ -759,10 +771,14 @@ int cmd_main(int argc, const char **argv) struct service_cmd *c = &services[i]; regex_t re; regmatch_t out[1]; + int ret; if (regcomp(&re, c->pattern, REG_EXTENDED)) die("Bogus regex in service table: %s", c->pattern); - if (!regexec(&re, dir, 1, out, 0)) { + ret = regexec(&re, dir, 1, out, 0); + regfree(&re); + + if (!ret) { size_t n; if (strcmp(method, c->method)) @@ -774,7 +790,6 @@ int cmd_main(int argc, const char **argv) dir[out[0].rm_so] = 0; break; } - regfree(&re); } if (!cmd) @@ -786,6 +801,7 @@ int cmd_main(int argc, const char **argv) if (!getenv("GIT_HTTP_EXPORT_ALL") && access("git-daemon-export-ok", F_OK) ) not_found(&hdr, "Repository not exported: '%s'", dir); + free(dir); http_config(); max_request_buffer = git_env_ulong("GIT_HTTP_MAX_REQUEST_BUFFER", @@ -795,5 +811,6 @@ int cmd_main(int argc, const char **argv) setenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0); cmd->imp(&hdr, cmd_arg); + free(cmd_arg); return 0; } |