[PATCH v3 3/3] t/lib-httpd: document writing concurrency-safe CGI helpers
"Michael Montalbo via GitGitGadget" <[email protected]>
| Newsgroups | org.kernel.vger.git |
|---|---|
| Message-ID | <374d148f43036077c31c5a55ddb1b59da4d3a923.1786583137.git.gitgitgadget@gmail.com> |
From: Michael Montalbo <[email protected]> The apply-one-time-script.sh and http-429.sh fixes share a root cause: a CGI helper assumed it had a file to itself, when Apache can run the helper for several requests at once. Document the atomic idioms that avoid this next to where lib-httpd.sh installs the CGI scripts, so the advice is in front of anyone adding another one. The note describes the anti-pattern, a "test -f" check followed by a separate action, and the two atomic alternatives these helpers now use: - "mkdir", which fails if the directory exists, to elect the first request (http-429.sh); and - "rm" without "-f", which fails once the file is gone, to consume a one-shot marker (apply-one-time-script.sh). Signed-off-by: Michael Montalbo <[email protected]> --- t/lib-httpd.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index fc646447d5..f26e1594ab 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -159,6 +159,19 @@ prepare_httpd() { mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH" cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" cp "$TEST_PATH"/proxy-passwd "$HTTPD_ROOT_PATH" + # Apache runs each of these CGI scripts once per request. Apache can run one + # script for several requests at the same time. A helper that keeps state + # between requests must update that state with one atomic operation. A check + # and then a separate action is not safe: two requests can both pass the + # check before either one acts. Test the exit status of one atomic operation + # instead: + # - "mkdir dir" fails if the directory exists, so only one request + # succeeds. http-429.sh selects the first request this way. + # - "rm marker" (without "-f") fails if the marker is gone, so only one + # request consumes it. apply-one-time-script.sh claims its one-shot + # marker this way. + # A scratch file name includes the process ID ($$), so concurrent requests + # do not overwrite each other's files. install_script incomplete-length-upload-pack-v2-http.sh install_script incomplete-body-upload-pack-v2-http.sh install_script error-no-report.sh -- gitgitgadget