| 1 | #!/bin/sh |
| 2 | |
| 3 | # If "one-time-script" exists in $HTTPD_ROOT_PATH, run the script on the HTTP |
| 4 | # response. If the response was modified as a result, delete "one-time-script" |
| 5 | # so that subsequent HTTP responses are no longer modified. |
| 6 | # |
| 7 | # This can be used to simulate the effects of the repository changing in |
| 8 | # between HTTP request-response pairs. |
| 9 | # |
| 10 | # Apache can run this CGI for concurrent requests (for example a partial fetch |
| 11 | # that lazily fetches a missing object while the first response is still in |
| 12 | # flight), so the helper claims the marker atomically with a rename, and only |
| 13 | # once it has decided to modify the response. A request that loses the race |
| 14 | # finds the marker already gone and serves its response unchanged; no request |
| 15 | # is left emitting an empty body, which the server would report as HTTP 500. |
| 16 | # Scratch files are per-request ($$) so concurrent requests do not clobber each |
| 17 | # other. |
| 18 | # |
| 19 | # The script may run more than once: the marker is consumed when the response |
| 20 | # actually changes (the rename after "cmp"), not when the script runs, so a |
| 21 | # request whose response is not the targeted one runs the script, sees no |
| 22 | # change, and leaves the marker for a later request. That is safe because the |
| 23 | # scripts are stateless filters over the captured response. |
| 24 | |
| 25 | test -f one-time-script || exec "$GIT_EXEC_PATH/git-http-backend" |
| 26 | |
| 27 | LC_ALL=C |
| 28 | export LC_ALL |
| 29 | |
| 30 | out=out.$$ |
| 31 | modified=out-modified.$$ |
| 32 | "$GIT_EXEC_PATH/git-http-backend" >"$out" |
| 33 | |
| 34 | if ./one-time-script "$out" 2>/dev/null >"$modified" && |
| 35 | ! cmp -s "$out" "$modified" && |
| 36 | mv one-time-script one-time-script.$$ 2>/dev/null |
| 37 | then |
| 38 | cat "$modified" |
| 39 | else |
| 40 | cat "$out" |
| 41 | fi |
| 42 | rm -f "$out" "$modified" one-time-script.$$ |