Skip to content

Fix caching of bodyless HTTP responses - #194

Closed
thavaahariharangit wants to merge 5 commits into
mainfrom
harry/fix-cache-bodyless-responses
Closed

Fix caching of bodyless HTTP responses#194
thavaahariharangit wants to merge 5 commits into
mainfrom
harry/fix-cache-bodyless-responses

Conversation

@thavaahariharangit

@thavaahariharangit thavaahariharangit commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What are you trying to accomplish?

Prevent the proxy cache from turning bodyless HTTP responses into responses with a wrapped body.

When using newer versions of goproxy(https://github.com/elazarl/goproxy), wrapping the body of a 304 Not Modified response can cause it to be serialized with chunked body data. This corrupts persistent HTTP connections and causes clients such as Cargo to fail with:

[8] Weird server reply (Invalid status line)

The change preserves http.NoBody for HEAD requests and responses with statuses that do not permit a body, including 1xx, 204, and 304.

Anything you want to highlight for special attention from reviewers?

This is a defensive fix at the cache boundary. Although goproxy should enforce bodyless response semantics during serialization, the cache should not wrap or cache a body that HTTP semantics prohibit.

The response’s original body is still closed so resources are released correctly.

How will you know you've accomplished your goal?

Regression tests verify that bodyless responses:

  • Retain http.NoBody
  • Do not get wrapped by the cache
  • Close the original response body
  • Do not create a cache entry
    The focused cache tests and full Go test suite pass.

The original failure was reproduced using Dependabot job 1404166863. After applying this change and rerunning the same job with the updated proxy image, the Cargo update completed without the Invalid status line error.

using this PR Branch: #184
set -o pipefail && dependabot update -f input.yml --proxy-image=my-proxy-fix -o output.yml 2>&1 | tee tofile.txt
After fix:

updater | 2026/08/10 10:12:47 INFO Finished job processing
updater | 2026/08/10 10:12:47 INFO Results:
updater | +------------------------------------------+
updater | |   Changes to Dependabot Pull Requests    |
updater | +---------+--------------------------------+
updater | | updated | sha2 ( from 0.10.9 to 0.11.0 ) |
updater | +---------+--------------------------------+
  proxy | 2026/08/10 10:12:50 Skipping sending metrics because api endpoint is empty

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

dependabot Bot and others added 2 commits August 10, 2026 03:26
Bumps [github.com/elazarl/goproxy](https://github.com/elazarl/goproxy) from 0.0.0-20240726154733-8b0c20506380 to 1.9.0.
- [Release notes](https://github.com/elazarl/goproxy/releases)
- [Commits](https://github.com/elazarl/goproxy/commits/v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/elazarl/goproxy
  dependency-version: 1.9.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@thavaahariharangit
thavaahariharangit requested a review from a team as a code owner August 10, 2026 10:26
Copilot AI balanced review requested due to automatic review settings August 10, 2026 10:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes caching of bodyless responses while upgrading goproxy to v1.9.0.

Changes:

  • Preserves http.NoBody for HEAD, 204, and 304 responses.
  • Adds regression coverage for bodyless responses.
  • Vendors goproxy v1.9.0 and its HTTP/2-related changes.
Show a summary per file
File Description
internal/cache/handlers.go Bypasses caching for bodyless responses.
internal/cache/handlers_test.go Tests body preservation and cleanup.
go.mod Upgrades goproxy.
go.sum Updates dependency checksums.
vendor/modules.txt Updates vendored module metadata.
vendor/github.com/elazarl/goproxy/.golangci.yml Adds upstream lint configuration.
vendor/github.com/elazarl/goproxy/README.md Updates upstream documentation.
vendor/github.com/elazarl/goproxy/actions.go Updates handler documentation.
vendor/github.com/elazarl/goproxy/certs.go Updates CA initialization.
vendor/github.com/elazarl/goproxy/chunked.go Removes obsolete chunk writer.
vendor/github.com/elazarl/goproxy/ctx.go Extends proxy context behavior.
vendor/github.com/elazarl/goproxy/dispatcher.go Updates request conditions.
vendor/github.com/elazarl/goproxy/doc.go Updates package examples.
vendor/github.com/elazarl/goproxy/h2.go Removes legacy HTTP/2 transport.
vendor/github.com/elazarl/goproxy/http.go Adds HTTP response forwarding logic.
vendor/github.com/elazarl/goproxy/http2.go Adds HTTP/2 MITM support.
vendor/github.com/elazarl/goproxy/https.go Updates CONNECT and MITM handling.
vendor/github.com/elazarl/goproxy/internal/http1parser/header.go Adds HTTP/1 header parsing.
vendor/github.com/elazarl/goproxy/internal/http1parser/request.go Adds request parsing support.
vendor/github.com/elazarl/goproxy/internal/signer/counterecryptor.go Moves and extends signer utilities.
vendor/github.com/elazarl/goproxy/internal/signer/signer.go Adds internal certificate signing.
vendor/github.com/elazarl/goproxy/logger.go Updates logger documentation and types.
vendor/github.com/elazarl/goproxy/proxy.go Refactors proxy dispatch and configuration.
vendor/github.com/elazarl/goproxy/responses.go Modernizes response construction.
vendor/github.com/elazarl/goproxy/signer.go Removes superseded signer implementation.
vendor/github.com/elazarl/goproxy/websocket.go Refactors WebSocket proxying.

Review details

Tip

Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 3/26 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread internal/cache/handlers.go

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 3/26 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@thavaahariharangit
thavaahariharangit changed the base branch from main to dependabot/go_modules/github.com/elazarl/goproxy-1.9.0 August 10, 2026 16:15
@thavaahariharangit
thavaahariharangit changed the base branch from dependabot/go_modules/github.com/elazarl/goproxy-1.9.0 to main August 10, 2026 16:20

@kbukum1 kbukum1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this we need to understand breaking change happened in the goproxy so accordingly we should be able to check the root cause of this error happening

@kbukum1

kbukum1 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Before this we need to understand breaking change happened in the goproxy so accordingly we should be able to check the root cause of this error happening

@thavaahariharangit
I don't think skipping/bypassing empty responses at the cache boundary is the right solution here — it feels like we're patching a symptom rather than fixing the root cause.

My concern is that the real problem most likely isn't that we're legitimately receiving bodyless/empty responses. It seems more likely that something in the new proxy behavior is causing crates.io to return these responses in the first place — possibly because our implementation is now generating far more requests than before, triggering rate limiting or similar server-side behavior. So instead of defensively wrapping/skipping these responses, we should understand what actually changed in goproxy v1.9.0 and adapt our implementation to it properly.

In summary, I think we need to:

  • Audit our implementation against the new version — compare our current proxy code against the changes in the bump (where the vendored diffs are visible) and confirm our implementation is still fully valid under new version 1.8.5, 1.8.6, 1.9.0.

  • Decide the fix based on the root cause — if refactoring is needed, determine whether the issue is purely on our side (a runtime issue that compiles fine but behaves incorrectly) and refactor accordingly, or whether the library itself also needs a fix.

  • Escalate upstream if the issue is in the library — if the root cause is in the new goproxy code rather than ours, we should open an issue with the maintainer to see if they can address it.

@thavaahariharangit

Copy link
Copy Markdown
Contributor Author

closing this PR, as this implementation is covered here: #200

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants