These services can be enabled/disabled using the per-repository
 configuration file:
 
+http.getanyfile::
+       This serves older Git clients which are unable to use the
+       upload pack service.  When enabled, clients are able to read
+       any file within the repository, including objects that are
+       no longer reachable from a branch but are still present.
+       It is enabled by default, but a repository can disable it
+       by setting this configuration item to `false`.
+
 http.uploadpack::
        This serves 'git-fetch-pack' and 'git-ls-remote' clients.
        It is enabled by default, but a repository can disable it
 
 static const char content_type[] = "Content-Type";
 static const char content_length[] = "Content-Length";
 static const char last_modified[] = "Last-Modified";
+static int getanyfile = 1;
 
 static struct string_list *query_params;
 
        exit(0);
 }
 
+static void select_getanyfile(void)
+{
+       if (!getanyfile)
+               forbidden("Unsupported service: getanyfile");
+}
+
 static void send_strbuf(const char *type, struct strbuf *buf)
 {
        hdr_int(content_length, buf->len);
 
 static void get_text_file(char *name)
 {
+       select_getanyfile();
        hdr_nocache();
        send_file("text/plain", name);
 }
 
 static void get_loose_object(char *name)
 {
+       select_getanyfile();
        hdr_cache_forever();
        send_file("application/x-git-loose-object", name);
 }
 
 static void get_pack_file(char *name)
 {
+       select_getanyfile();
        hdr_cache_forever();
        send_file("application/x-git-packed-objects", name);
 }
 
 static void get_idx_file(char *name)
 {
+       select_getanyfile();
        hdr_cache_forever();
        send_file("application/x-git-packed-objects-toc", name);
 }
 
 static int http_config(const char *var, const char *value, void *cb)
 {
-       struct rpc_service *svc = cb;
-
-       if (!prefixcmp(var, "http.") &&
-           !strcmp(var + 5, svc->config_name)) {
-               svc->enabled = git_config_bool(var, value);
+       if (!strcmp(var, "http.getanyfile")) {
+               getanyfile = git_config_bool(var, value);
                return 0;
        }
 
+       if (!prefixcmp(var, "http.")) {
+               int i;
+
+               for (i = 0; i < ARRAY_SIZE(rpc_service); i++) {
+                       struct rpc_service *svc = &rpc_service[i];
+                       if (!strcmp(var + 5, svc->config_name)) {
+                               svc->enabled = git_config_bool(var, value);
+                               return 0;
+                       }
+               }
+       }
+
        /* we are not interested in parsing any other configuration here */
        return 0;
 }
        if (!svc)
                forbidden("Unsupported service: '%s'", name);
 
-       git_config(http_config, svc);
        if (svc->enabled < 0) {
                const char *user = getenv("REMOTE_USER");
                svc->enabled = (user && *user) ? 1 : 0;
                run_service(argv);
 
        } else {
+               select_getanyfile();
                for_each_ref(show_text_ref, &buf);
                send_strbuf("text/plain", &buf);
        }
        struct packed_git *p;
        size_t cnt = 0;
 
+       select_getanyfile();
        prepare_packed_git();
        for (p = packed_git; p; p = p->next) {
                if (p->pack_local)
        if (!enter_repo(dir, 0))
                not_found("Not a git repository: '%s'", dir);
 
+       git_config(http_config, NULL);
        cmd->imp(cmd_arg);
        return 0;
 }