http-backend: handle HTTP_GIT_PROTOCOL CGI variable

When a client requests the v2 protocol over HTTP, they set the
Git-Protocol header. Webservers will generally make that available to
our CGI as HTTP_GIT_PROTOCOL in the environment. However, that's not
sufficient for upload-pack, etc, to respect it; they look in
GIT_PROTOCOL (without the HTTP_ prefix).

Either the webserver or the CGI is responsible for relaying that HTTP
header into the GIT_PROTOCOL variable. Traditionally, our tests have
configured the webserver to do so, but that's a burden on the server
admin. We can make this work out of the box by having the http-backend
CGI copy the contents of HTTP_GIT_PROTOCOL to GIT_PROTOCOL.

There are no new tests here. By removing the SetEnvIf line from our
test Apache config, we're now relying on this behavior of http-backend
to trigger the v2 protocol there (and there are numerous tests that fail
if this doesn't work).

There is one subtlety here: we copy HTTP_GIT_PROTOCOL only if there is
no existing GIT_PROTOCOL variable. That leaves the webserver admin free
to override the client's decision if they choose. This is unlikely to be
useful in practice, but is more flexible. And indeed, it allows the
v2-to-v0 fallback test added in the previous commit to continue working.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2021-09-10 10:05:45 -04:00 committed by Junio C Hamano
parent 26146980f1
commit ff6a37c99e
2 changed files with 4 additions and 2 deletions

View File

@ -739,6 +739,7 @@ static int bad_request(struct strbuf *hdr, const struct service_cmd *c)
int cmd_main(int argc, const char **argv) int cmd_main(int argc, const char **argv)
{ {
char *method = getenv("REQUEST_METHOD"); char *method = getenv("REQUEST_METHOD");
const char *proto_header;
char *dir; char *dir;
struct service_cmd *cmd = NULL; struct service_cmd *cmd = NULL;
char *cmd_arg = NULL; char *cmd_arg = NULL;
@ -789,6 +790,9 @@ int cmd_main(int argc, const char **argv)
http_config(); http_config();
max_request_buffer = git_env_ulong("GIT_HTTP_MAX_REQUEST_BUFFER", max_request_buffer = git_env_ulong("GIT_HTTP_MAX_REQUEST_BUFFER",
max_request_buffer); max_request_buffer);
proto_header = getenv("HTTP_GIT_PROTOCOL");
if (proto_header)
setenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);
cmd->imp(&hdr, cmd_arg); cmd->imp(&hdr, cmd_arg);
return 0; return 0;

View File

@ -81,8 +81,6 @@ PassEnv GIT_TRACE
PassEnv GIT_CONFIG_NOSYSTEM PassEnv GIT_CONFIG_NOSYSTEM
PassEnv GIT_TEST_SIDEBAND_ALL PassEnv GIT_TEST_SIDEBAND_ALL
SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0
Alias /dumb/ www/ Alias /dumb/ www/
Alias /auth/dumb/ www/auth/dumb/ Alias /auth/dumb/ www/auth/dumb/