From: "Vaidas Pilkauskas via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Taylor Blau <me@ttaylorr.com>, Jeff King <peff@peff.net>,
Junio C Hamano <gitster@pobox.com>,
Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
Subject: [PATCH v4 0/5] http: add support for HTTP 429 rate limit retries
Date: Wed, 18 Feb 2026 14:09:03 +0000 [thread overview]
Message-ID: <pull.2008.v4.git.1771423748.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2008.v3.git.1771326521.gitgitgadget@gmail.com>
Changes since v3:
* Clean up of all strbuf_attach() call sites
* Add strbuf_attach() contract enforcement via BUG()
Changes since v2:
* New preparatory patch: Introduced show_http_message_fatal() helper
function to reduce code duplication in remote-curl.c (suggested by Taylor
Blau)
* Removed specific HTTP_RATE_LIMITED error handling from http-push.c and
http-walker.c for the obsolete "dumb" protocol, allowing generic error
handling to take over (suggested by Jeff King)
* Added support for CURLINFO_RETRY_AFTER on curl >= 7.66.0, falling back to
manual header parsing on older versions
* Simplified retry/delay architecture: replaced complex non-blocking
"delayed slot" mechanism with simple blocking sleep() call in the retry
loop, removing ~66 lines of timing logic (suggested by Jeff King)
* Fixed Retry-After: 0 handling to allow immediate retry as specified by
RFC 9110
* Changed http.retryAfter default from -1 to 0, so Git will retry
immediately when encountering HTTP 429 without a Retry-After header,
rather than failing with a configuration error
* Improved error messages: shortened to be more concise
* Fixed coding style issues: removed unnecessary curly braces, changed x ==
0 to !x (per CodingGuidelines)
* Improved test portability: replaced non-portable date(1) commands with
test-tool date, added nanosecond-precision timing with getnanos, replaced
cut(1) with POSIX shell parameter expansion
* Split out strbuf.c bugfix into separate preparatory patch (the
strbuf_reencode alloc size fix is unrelated to HTTP 429 support)
* Squashed separate trace2 logging patch into main HTTP 429 retry support
commit
* Kept header_is_last_match assignment for Retry-After to prevent incorrect
handling of HTTP header continuation lines
The implementation includes:
1. A bug fix in strbuf_reencode() that corrects the allocation size passed
to strbuf_attach(), passing len+1 instead of len so that the existing
buffer is reused rather than immediately reallocated.
2. A cleanup of all strbuf_attach() call sites that were passing alloc ==
len, leaving no room for the NUL terminator. Sites with a
known-NUL-terminated buffer now pass len+1; sites where the source
buffer has no trailing NUL (ll_merge output) are converted to use
strbuf_add() instead.
3. A hardening of strbuf_attach() itself: the internal strbuf_grow() that
silently papered over incorrect alloc values is replaced with an
explicit BUG() check, enforcing the documented contract that alloc must
be greater than len.
4. A new show_http_message_fatal() helper in remote-curl.c that combines
the repeated pattern of show_http_message() followed by die() into a
single NORETURN function, reducing boilerplate at existing call sites
and providing a clean hook for the retry logic.
5. The main feature: HTTP 429 retry logic with support for the Retry-After
header (both delay-seconds and HTTP-date formats), configurable via
http.maxRetries, http.retryAfter, and http.maxRetryTime options. If any
computed delay exceeds maxRetryTime the request fails immediately with a
clear diagnostic rather than capping and retrying silently.
Vaidas Pilkauskas (5):
strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()
strbuf_attach: fix all call sites to pass correct alloc
strbuf: replace strbuf_grow() in strbuf_attach() with BUG() check
remote-curl: introduce show_http_message_fatal() helper
http: add support for HTTP 429 rate limit retries
Documentation/config/http.adoc | 23 +++
apply.c | 3 +-
builtin/am.c | 2 +-
builtin/fast-import.c | 2 +-
git-curl-compat.h | 8 +
http.c | 190 +++++++++++++++++++++--
http.h | 2 +
mailinfo.c | 2 +-
refs/files-backend.c | 2 +-
remote-curl.c | 49 +++---
rerere.c | 3 +-
strbuf.c | 5 +-
t/lib-httpd.sh | 1 +
t/lib-httpd/apache.conf | 8 +
t/lib-httpd/http-429.sh | 98 ++++++++++++
t/meson.build | 1 +
t/t5584-http-429-retry.sh | 266 +++++++++++++++++++++++++++++++++
trailer.c | 2 +-
18 files changed, 629 insertions(+), 38 deletions(-)
create mode 100644 t/lib-httpd/http-429.sh
create mode 100755 t/t5584-http-429-retry.sh
base-commit: 73fd77805fc6406f31c36212846d9e2541d19321
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2008%2Fvaidas-shopify%2Fretry-after-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2008/vaidas-shopify/retry-after-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/2008
Range-diff vs v3:
1: 821043c664 ! 1: a3386f5b56 strbuf: fix incorrect alloc size in strbuf_reencode()
@@ Metadata
Author: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
## Commit message ##
- strbuf: fix incorrect alloc size in strbuf_reencode()
+ strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()
- The strbuf_reencode() function incorrectly passes the string length
- as the allocation size to strbuf_attach(), when it should pass
- length + 1 to account for the null terminator.
+ reencode_string_len() allocates len+1 bytes (including the NUL) and
+ returns the string length in len. strbuf_reencode() was calling
+ strbuf_attach(sb, out, len, len), so alloc was one byte too small.
- The reencode_string_len() function allocates len + 1 bytes (including
- the null terminator) and returns the string length (excluding the null
- terminator) via the len parameter. However, strbuf_reencode() then
- calls strbuf_attach() with this length value as both the len and alloc
- parameters:
-
- strbuf_attach(sb, out, len, len);
-
- This is incorrect because strbuf_attach()'s alloc parameter should
- reflect the actual allocated buffer size, which includes space for the
- null terminator. This could lead to incorrect memory management in code
- that relies on sb->alloc being accurate.
-
- Fix by passing len + 1 as the alloc parameter:
-
- strbuf_attach(sb, out, len, len + 1);
+ strbuf_attach() then calls strbuf_grow(sb, 0). With alloc < len+1,
+ ALLOC_GROW always reallocates, so we reallocated immediately after
+ attach even when the strbuf was not extended further. Pass len+1 as
+ the alloc argument so the existing buffer is reused and the
+ reallocation is avoided.
Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
-: ---------- > 2: f48b1f07c4 strbuf_attach: fix all call sites to pass correct alloc
-: ---------- > 3: 557fd77444 strbuf: replace strbuf_grow() in strbuf_attach() with BUG() check
2: 3653067f0e = 4: 3a39dc9e39 remote-curl: introduce show_http_message_fatal() helper
3: 3cece62a63 = 5: 5e0f4a56ef http: add support for HTTP 429 rate limit retries
--
gitgitgadget
next prev parent reply other threads:[~2026-02-18 14:09 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-26 12:30 [PATCH 0/3] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2025-11-26 12:30 ` [PATCH 1/3] " Vaidas Pilkauskas via GitGitGadget
2025-12-09 23:15 ` Taylor Blau
2025-12-12 12:36 ` Vaidas Pilkauskas
2025-11-26 12:30 ` [PATCH 2/3] remote-curl: fix memory leak in show_http_message() Vaidas Pilkauskas via GitGitGadget
2025-12-09 23:52 ` Taylor Blau
2025-11-26 12:30 ` [PATCH 3/3] http: add trace2 logging for retry operations Vaidas Pilkauskas via GitGitGadget
2025-12-18 14:44 ` [PATCH v2 0/2] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2025-12-18 14:44 ` [PATCH v2 1/2] " Vaidas Pilkauskas via GitGitGadget
2026-02-11 1:05 ` Taylor Blau
2026-02-11 9:13 ` Jeff King
2026-02-13 13:41 ` Vaidas Pilkauskas
2026-02-15 9:13 ` Jeff King
2026-02-13 13:30 ` Vaidas Pilkauskas
2025-12-18 14:44 ` [PATCH v2 2/2] http: add trace2 logging for retry operations Vaidas Pilkauskas via GitGitGadget
2026-02-11 1:06 ` Taylor Blau
2026-02-17 11:08 ` [PATCH v3 0/3] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2026-02-17 11:08 ` [PATCH v3 1/3] strbuf: fix incorrect alloc size in strbuf_reencode() Vaidas Pilkauskas via GitGitGadget
2026-02-17 20:51 ` Junio C Hamano
2026-02-18 13:43 ` Vaidas Pilkauskas
2026-02-17 11:08 ` [PATCH v3 2/3] remote-curl: introduce show_http_message_fatal() helper Vaidas Pilkauskas via GitGitGadget
2026-02-17 11:08 ` [PATCH v3 3/3] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2026-02-18 14:09 ` Vaidas Pilkauskas via GitGitGadget [this message]
2026-02-18 14:09 ` [PATCH v4 1/5] strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode() Vaidas Pilkauskas via GitGitGadget
2026-02-18 14:09 ` [PATCH v4 2/5] strbuf_attach: fix all call sites to pass correct alloc Vaidas Pilkauskas via GitGitGadget
2026-02-20 22:55 ` Junio C Hamano
2026-02-23 12:49 ` Vaidas Pilkauskas
2026-02-18 14:09 ` [PATCH v4 3/5] strbuf: replace strbuf_grow() in strbuf_attach() with BUG() check Vaidas Pilkauskas via GitGitGadget
2026-02-18 14:09 ` [PATCH v4 4/5] remote-curl: introduce show_http_message_fatal() helper Vaidas Pilkauskas via GitGitGadget
2026-02-18 14:09 ` [PATCH v4 5/5] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2026-02-23 14:20 ` [PATCH v5 0/4] " Vaidas Pilkauskas via GitGitGadget
2026-02-23 14:20 ` [PATCH v5 1/4] strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode() Vaidas Pilkauskas via GitGitGadget
2026-02-23 14:20 ` [PATCH v5 2/4] strbuf_attach: fix call sites to pass correct alloc Vaidas Pilkauskas via GitGitGadget
2026-02-23 14:20 ` [PATCH v5 3/4] remote-curl: introduce show_http_message_fatal() helper Vaidas Pilkauskas via GitGitGadget
2026-03-10 17:44 ` Jeff King
2026-02-23 14:20 ` [PATCH v5 4/4] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2026-03-10 19:07 ` Jeff King
2026-02-24 0:07 ` [PATCH v5 0/4] " Junio C Hamano
2026-03-09 23:34 ` Junio C Hamano
2026-03-10 19:10 ` Jeff King
2026-03-10 19:19 ` Junio C Hamano
2026-03-17 13:00 ` [PATCH v6 0/3] " Vaidas Pilkauskas via GitGitGadget
2026-03-17 13:00 ` [PATCH v6 1/3] strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode() Vaidas Pilkauskas via GitGitGadget
2026-03-17 13:00 ` [PATCH v6 2/3] strbuf_attach: fix call sites to pass correct alloc Vaidas Pilkauskas via GitGitGadget
2026-03-17 13:00 ` [PATCH v6 3/3] http: add support for HTTP 429 rate limit retries Vaidas Pilkauskas via GitGitGadget
2026-03-21 3:30 ` Taylor Blau
2026-03-21 3:31 ` [PATCH v6 0/3] " Taylor Blau
2026-03-21 4:57 ` Junio C Hamano
2026-03-23 6:58 ` Vaidas Pilkauskas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.2008.v4.git.1771423748.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=me@ttaylorr.com \
--cc=peff@peff.net \
--cc=vaidas.pilkauskas@shopify.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox