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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.