static void get_info_refs(char *arg) { const char *service_name = get_parameter("service"); struct strbuf buf = STRBUF_INIT; hdr_nocache(); if (service_name) { const char *argv[] = {NULL /* service name */, "--stateless-rpc", "--advertise-refs", ".", NULL}; struct rpc_service *svc = select_service(service_name); strbuf_addf(&buf, "application/x-git-%s-advertisement", svc->name); hdr_str(content_type, buf.buf); end_headers(); packet_write(1, "# service=git-%s\n", svc->name); packet_flush(1); argv[0] = svc->name; run_service(argv); } else { select_getanyfile(); for_each_namespaced_ref(show_text_ref, &buf); send_strbuf("text/plain", &buf); } strbuf_release(&buf); }
static void send_strbuf(const char *type, struct strbuf *buf) { hdr_int(content_length, buf->len); hdr_str(content_type, type); end_headers(); write_or_die(1, buf->buf, buf->len); }
static void send_local_file(const char *the_type, const char *name) { const char *p = git_path("%s", name); size_t buf_alloc = 8192; char *buf = xmalloc(buf_alloc); int fd; struct stat sb; fd = open(p, O_RDONLY); if (fd < 0) not_found("Cannot open '%s': %s", p, strerror(errno)); if (fstat(fd, &sb) < 0) die_errno("Cannot stat '%s'", p); hdr_int(content_length, sb.st_size); hdr_str(content_type, the_type); hdr_date(last_modified, sb.st_mtime); end_headers(); for (;;) { ssize_t n = xread(fd, buf, buf_alloc); if (n < 0) die_errno("Cannot read '%s'", p); if (!n) break; write_or_die(1, buf, n); } close(fd); free(buf); }
static void hdr_cache_forever(void) { unsigned long now = time(NULL); hdr_date("Date", now); hdr_date("Expires", now + 31536000); hdr_str("Cache-Control", "public, max-age=31536000"); }
static void hdr_cache_forever(struct strbuf *hdr) { unsigned long now = time(NULL); hdr_date(hdr, "Date", now); hdr_date(hdr, "Expires", now + 31536000); hdr_str(hdr, "Cache-Control", "public, max-age=31536000"); }
static int bad_request(struct strbuf *hdr, const struct service_cmd *c) { const char *proto = getenv("SERVER_PROTOCOL"); if (proto && !strcmp(proto, "HTTP/1.1")) { http_status(hdr, 405, "Method Not Allowed"); hdr_str(hdr, "Allow", !strcmp(c->method, "GET") ? "GET, HEAD" : c->method); } else http_status(hdr, 400, "Bad Request"); hdr_nocache(hdr); end_headers(hdr); return 0; }
static void service_rpc(char *service_name) { const char *argv[] = {NULL, "--stateless-rpc", ".", NULL}; struct rpc_service *svc = select_service(service_name); struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); strbuf_addf(&buf, "application/x-git-%s-request", svc->name); check_content_type(buf.buf); hdr_nocache(); strbuf_reset(&buf); strbuf_addf(&buf, "application/x-git-%s-result", svc->name); hdr_str(content_type, buf.buf); end_headers(); argv[0] = svc->name; run_service(argv); strbuf_release(&buf); }
static void hdr_nocache(void) { hdr_str("Expires", "Fri, 01 Jan 1980 00:00:00 GMT"); hdr_str("Pragma", "no-cache"); hdr_str("Cache-Control", "no-cache, max-age=0, must-revalidate"); }
static void hdr_date(const char *name, unsigned long when) { const char *value = show_date(when, 0, DATE_RFC2822); hdr_str(name, value); }
int main(int argc, char **argv) { char *method = getenv("REQUEST_METHOD"); char *dir; struct service_cmd *cmd = NULL; char *cmd_arg = NULL; int i; git_setup_gettext(); git_extract_argv0_path(argv[0]); set_die_routine(die_webcgi); if (!method) die("No REQUEST_METHOD from server"); if (!strcmp(method, "HEAD")) method = "GET"; dir = getdir(); for (i = 0; i < ARRAY_SIZE(services); i++) { struct service_cmd *c = &services[i]; regex_t re; regmatch_t out[1]; if (regcomp(&re, c->pattern, REG_EXTENDED)) die("Bogus regex in service table: %s", c->pattern); if (!regexec(&re, dir, 1, out, 0)) { size_t n; if (strcmp(method, c->method)) { const char *proto = getenv("SERVER_PROTOCOL"); if (proto && !strcmp(proto, "HTTP/1.1")) { http_status(405, "Method Not Allowed"); hdr_str("Allow", !strcmp(c->method, "GET") ? "GET, HEAD" : c->method); } else http_status(400, "Bad Request"); hdr_nocache(); end_headers(); return 0; } cmd = c; n = out[0].rm_eo - out[0].rm_so; cmd_arg = xmemdupz(dir + out[0].rm_so + 1, n - 1); dir[out[0].rm_so] = 0; break; } regfree(&re); } if (!cmd) not_found("Request not supported: '%s'", dir); setup_path(); if (!enter_repo(dir, 0)) not_found("Not a git repository: '%s'", dir); if (!getenv("GIT_HTTP_EXPORT_ALL") && access("git-daemon-export-ok", F_OK) ) not_found("Repository not exported: '%s'", dir); git_config(http_config, NULL); cmd->imp(cmd_arg); return 0; }
static void hdr_nocache(struct strbuf *hdr) { hdr_str(hdr, "Expires", "Fri, 01 Jan 1980 00:00:00 GMT"); hdr_str(hdr, "Pragma", "no-cache"); hdr_str(hdr, "Cache-Control", "no-cache, max-age=0, must-revalidate"); }
static void hdr_date(struct strbuf *hdr, const char *name, unsigned long when) { const char *value = show_date(when, 0, DATE_MODE(RFC2822)); hdr_str(hdr, name, value); }