From: Junio C Hamano Date: Mon, 1 Jun 2015 19:45:09 +0000 (-0700) Subject: Merge branch 'jk/http-backend-deadlock' X-Git-Tag: v2.5.0-rc0~69 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/777e75b60568b613e452ebbb30a1fb27c4fd7d8a?ds=inline;hp=-c Merge branch 'jk/http-backend-deadlock' Communication between the HTTP server and http_backend process can lead to a dead-lock when relaying a large ref negotiation request. Diagnose the situation better, and mitigate it by reading such a request first into core (to a reasonable limit). * jk/http-backend-deadlock: http-backend: spool ref negotiation requests to buffer t5551: factor out tag creation http-backend: fix die recursion with custom handler --- 777e75b60568b613e452ebbb30a1fb27c4fd7d8a diff --combined Documentation/git-http-backend.txt index 3ca18c4de5,8c6acbe440..9268fb6b1e --- a/Documentation/git-http-backend.txt +++ b/Documentation/git-http-backend.txt @@@ -65,8 -65,8 +65,8 @@@ automatically by the web server EXAMPLES -------- -All of the following examples map 'http://$hostname/git/foo/bar.git' -to '/var/www/git/foo/bar.git'. +All of the following examples map `http://$hostname/git/foo/bar.git` +to `/var/www/git/foo/bar.git`. Apache 2.x:: Ensure mod_cgi, mod_alias, and mod_env are enabled, set @@@ -255,6 -255,15 +255,15 @@@ The GIT_HTTP_EXPORT_ALL environmental v 'git-http-backend' to bypass the check for the "git-daemon-export-ok" file in each repository before allowing export of that repository. + The `GIT_HTTP_MAX_REQUEST_BUFFER` environment variable (or the + `http.maxRequestBuffer` config variable) may be set to change the + largest ref negotiation request that git will handle during a fetch; any + fetch requiring a larger buffer will not succeed. This value should not + normally need to be changed, but may be helpful if you are fetching from + a repository with an extremely large number of refs. The value can be + specified with a unit (e.g., `100M` for 100 megabytes). The default is + 10 megabytes. + The backend process sets GIT_COMMITTER_NAME to '$REMOTE_USER' and GIT_COMMITTER_EMAIL to '$\{REMOTE_USER}@http.$\{REMOTE_ADDR\}', ensuring that any reflogs created by 'git-receive-pack' contain some diff --combined t/t5551-http-fetch-smart.sh index 2b29311901,a540c6da23..58207d8825 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@@ -2,6 -2,12 +2,6 @@@ test_description='test smart fetching over http via http-backend' . ./test-lib.sh - -if test -n "$NO_CURL"; then - skip_all='skipping test, git built without http support' - test_done -fi - . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd @@@ -218,27 -224,35 +218,35 @@@ test_expect_success 'transfer.hiderefs git -C hidden.git rev-parse --verify b ' - test_expect_success 'create 2,000 tags in the repo' ' - ( - cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && - for i in $(test_seq 2000) + # create an arbitrary number of tags, numbered from tag-$1 to tag-$2 + create_tags () { + rm -f marks && + for i in $(test_seq "$1" "$2") do - echo "commit refs/heads/too-many-refs" - echo "mark :$i" - echo "committer git $i +0000" - echo "data 0" - echo "M 644 inline bla.txt" - echo "data 4" - echo "bla" + # don't use here-doc, because it requires a process + # per loop iteration + echo "commit refs/heads/too-many-refs-$1" && + echo "mark :$i" && + echo "committer git $i +0000" && + echo "data 0" && + echo "M 644 inline bla.txt" && + echo "data 4" && + echo "bla" && # make every commit dangling by always # rewinding the branch after each commit - echo "reset refs/heads/too-many-refs" - echo "from :1" + echo "reset refs/heads/too-many-refs-$1" && + echo "from :$1" done | git fast-import --export-marks=marks && # now assign tags to all the dangling commits we created above tag=$(perl -e "print \"bla\" x 30") && sed -e "s|^:\([^ ]*\) \(.*\)$|\2 refs/tags/$tag-\1|" >packed-refs + } + + test_expect_success 'create 2,000 tags in the repo' ' + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + create_tags 1 2000 ) ' @@@ -259,5 -273,20 +267,20 @@@ test_expect_success 'large fetch-pack r test_line_count = 2 posts ' + test_expect_success EXPENSIVE 'http can handle enormous ref negotiation' ' + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + create_tags 2001 50000 + ) && + git -C too-many-refs fetch -q --tags && + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + create_tags 50001 100000 + ) && + git -C too-many-refs fetch -q --tags && + git -C too-many-refs for-each-ref refs/tags >tags && + test_line_count = 100000 tags + ' + stop_httpd test_done