From: Junio C Hamano Date: Fri, 20 Sep 2013 19:30:54 +0000 (-0700) Subject: Merge branch 'bc/http-backend-allow-405' X-Git-Tag: v1.8.5-rc0~98 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/26e53f8ac02a5929e4b614010afaa9787f567698?ds=inline;hp=-c Merge branch 'bc/http-backend-allow-405' When the webserver responds with "405 Method Not Allowed", it should tell the client what methods are allowed with the "Allow" header. * bc/http-backend-allow-405: http-backend: provide Allow header for 405 --- 26e53f8ac02a5929e4b614010afaa9787f567698 diff --combined http-backend.c index 0324417297,5102d974aa..8c464bd805 --- a/http-backend.c +++ b/http-backend.c @@@ -70,7 -70,7 +70,7 @@@ static void format_write(int fd, const if (n >= sizeof(buffer)) die("protocol error: impossibly long line"); - safe_write(fd, buffer, n); + write_or_die(fd, buffer, n); } static void http_status(unsigned code, const char *msg) @@@ -111,7 -111,7 +111,7 @@@ static void hdr_cache_forever(void static void end_headers(void) { - safe_write(1, "\r\n", 2); + write_or_die(1, "\r\n", 2); } __attribute__((format (printf, 1, 2))) @@@ -157,7 -157,7 +157,7 @@@ static void send_strbuf(const char *typ hdr_int(content_length, buf->len); hdr_str(content_type, type); end_headers(); - safe_write(1, buf->buf, buf->len); + write_or_die(1, buf->buf, buf->len); } static void send_local_file(const char *the_type, const char *name) @@@ -185,7 -185,7 +185,7 @@@ die_errno("Cannot read '%s'", p); if (!n) break; - safe_write(1, buf, n); + write_or_die(1, buf, n); } close(fd); free(buf); @@@ -361,19 -361,17 +361,19 @@@ static void run_service(const char **ar static int show_text_ref(const char *name, const unsigned char *sha1, int flag, void *cb_data) { + const char *name_nons = strip_namespace(name); struct strbuf *buf = cb_data; struct object *o = parse_object(sha1); if (!o) return 0; - strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name); + strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name_nons); if (o->type == OBJ_TAG) { o = deref_tag(o, name, 0); if (!o) return 0; - strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), name); + strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), + name_nons); } return 0; } @@@ -404,40 -402,12 +404,40 @@@ static void get_info_refs(char *arg } else { select_getanyfile(); - for_each_ref(show_text_ref, &buf); + for_each_namespaced_ref(show_text_ref, &buf); send_strbuf("text/plain", &buf); } strbuf_release(&buf); } +static int show_head_ref(const char *refname, const unsigned char *sha1, + int flag, void *cb_data) +{ + struct strbuf *buf = cb_data; + + if (flag & REF_ISSYMREF) { + unsigned char unused[20]; + const char *target = resolve_ref_unsafe(refname, unused, 1, NULL); + const char *target_nons = strip_namespace(target); + + strbuf_addf(buf, "ref: %s\n", target_nons); + } else { + strbuf_addf(buf, "%s\n", sha1_to_hex(sha1)); + } + + return 0; +} + +static void get_head(char *arg) +{ + struct strbuf buf = STRBUF_INIT; + + select_getanyfile(); + head_ref_namespaced(show_head_ref, &buf); + send_strbuf("text/plain", &buf); + strbuf_release(&buf); +} + static void get_info_packs(char *arg) { size_t objdirlen = strlen(get_object_directory()); @@@ -550,7 -520,7 +550,7 @@@ static struct service_cmd const char *pattern; void (*imp)(char *); } services[] = { - {"GET", "/HEAD$", get_text_file}, + {"GET", "/HEAD$", get_head}, {"GET", "/info/refs$", get_info_refs}, {"GET", "/objects/info/alternates$", get_text_file}, {"GET", "/objects/info/http-alternates$", get_text_file}, @@@ -594,9 -564,11 +594,11 @@@ int main(int argc, char **argv if (strcmp(method, c->method)) { const char *proto = getenv("SERVER_PROTOCOL"); - if (proto && !strcmp(proto, "HTTP/1.1")) + if (proto && !strcmp(proto, "HTTP/1.1")) { http_status(405, "Method Not Allowed"); - else + hdr_str("Allow", !strcmp(c->method, "GET") ? + "GET, HEAD" : c->method); + } else http_status(400, "Bad Request"); hdr_nocache(); end_headers();