Bug: libfetch connection reuse corrupts proxied requests after cross-host redirect
Observed on: xbps 0.60.7, bundled libfetch
Proxy: HTTP_PROXY=http://localhost:1080 (sing-box mixed inbound, also using ALL_PROXY/SOCKS_PROXY)
Symptoms
xbps-install -S fetches repodata files for all configured repositories sequentially in a single process. The first repository always syncs successfully. Every subsequent repository fails with varying HTTP errors:
[reposync] failed to fetch file `https://github.com/.../x86_64-repodata': Forbidden
The status code depends on which server receives the corrupted request:
- GitHub releases (release-assets.githubusercontent.com): 403 Forbidden or 500 Internal Server Error
- voidlinux mirrors: 404 Not Found
Third-party repositories like the GitHub-hosted librewolf repo are always affected because they're listed last in the xbps config.
Isolated Reproduction
Tested with xbps-fetch -v (same libfetch as xbps-install), fetching two repodata URLs in one invocation:
| # |
1st URL |
2nd URL |
Result |
| 1 |
voidlinux |
voidlinux (same host) |
Both OK |
| 2 |
voidlinux |
github (→ release-assets) |
1st OK, 2nd = 403 |
| 3 |
github (→ release-assets) |
voidlinux |
1st OK, 2nd = 404 |
| 4 |
github (→ release-assets) |
github (→ release-assets) |
1st OK, 2nd = 500 |
| 5 |
github (solo) |
— |
OK |
| 6 |
voidlinux (solo) |
— |
OK |
Root Cause
After following an HTTP redirect to a different host (e.g., github.com → release-assets.githubusercontent.com), libfetch caches the proxy CONNECT tunnel for that host. When the subsequent fetch targets a different host, libfetch incorrectly reuses the cached tunnel — the HTTP request is sent with stale/wrong connection state, causing the server to reject it with varied error codes.
Same-host fetches (voidlinux → voidlinux) work because the cached tunnel still matches the connection target.
Traffic Pattern
libfetch connects to the HTTP proxy and uses a SOCKS5 + HTTP CONNECT sequence:
→ SOCKS5 greeting (method: no-auth)
→ SOCKS5 CONNECT to proxy's own loopback (localhost:1080)
→ HTTP CONNECT <target-host>:443
→ TLS handshake
→ HTTP GET /path
The first request follows this correctly. On the second request it reuses the first tunnel rather than opening a new one.
Workaround
Pre-fetch problem repos' repodata using xbps-fetch in separate invocations, then run xbps-install -S (the failed fetch leaves the existing file intact):
xbps-fetch -o /var/db/xbps/<repodir>/x86_64-repodata <repo-url>/x86_64-repodata
xbps-install -Su
Expected Fix
libfetch should either:
- Open a fresh proxy CONNECT tunnel for each host transition (correct behavior)
- Or properly reset connection state before reusing across hosts
System Details
Void Linux x86_64, kernel 7.1.3_1
xbps-0.60.7 (API: 20250629)
Bug: libfetch connection reuse corrupts proxied requests after cross-host redirect
Observed on: xbps 0.60.7, bundled libfetch
Proxy: HTTP_PROXY=http://localhost:1080 (sing-box mixed inbound, also using ALL_PROXY/SOCKS_PROXY)
Symptoms
xbps-install -Sfetches repodata files for all configured repositories sequentially in a single process. The first repository always syncs successfully. Every subsequent repository fails with varying HTTP errors:The status code depends on which server receives the corrupted request:
Third-party repositories like the GitHub-hosted librewolf repo are always affected because they're listed last in the xbps config.
Isolated Reproduction
Tested with
xbps-fetch -v(same libfetch as xbps-install), fetching two repodata URLs in one invocation:Root Cause
After following an HTTP redirect to a different host (e.g.,
github.com→release-assets.githubusercontent.com), libfetch caches the proxy CONNECT tunnel for that host. When the subsequent fetch targets a different host, libfetch incorrectly reuses the cached tunnel — the HTTP request is sent with stale/wrong connection state, causing the server to reject it with varied error codes.Same-host fetches (voidlinux → voidlinux) work because the cached tunnel still matches the connection target.
Traffic Pattern
libfetch connects to the HTTP proxy and uses a SOCKS5 + HTTP CONNECT sequence:
The first request follows this correctly. On the second request it reuses the first tunnel rather than opening a new one.
Workaround
Pre-fetch problem repos' repodata using
xbps-fetchin separate invocations, then runxbps-install -S(the failed fetch leaves the existing file intact):Expected Fix
libfetch should either:
System Details