Skip to content

Fix: only create the buffer once in responseInterceptor, fixes #929#1235

Closed
fozcode wants to merge 1 commit into
chimurai:masterfrom
fozcode:master
Closed

Fix: only create the buffer once in responseInterceptor, fixes #929#1235
fozcode wants to merge 1 commit into
chimurai:masterfrom
fozcode:master

Conversation

@fozcode
Copy link
Copy Markdown
Contributor

@fozcode fozcode commented May 21, 2026

Description

As described in #929, the old code has a serious performance issue:

_proxyRes.on('data', (chunk) => (buffer = Buffer.concat([buffer, chunk])));

This recreates a new buffer from the previous buffer for every chunk. Additionally the copied previous buffer is larger for every chunk so this gives exponentially worse performance the larger the buffer.

Motivation and Context

Logging from old code:

1779358511730 HTTPPM intercepting response
1779358511732 HTTPPM chunk len 16384
1779358517866 HTTPPM sending intercepted, len 25246241
-->
total time = 6136 millis
number of buffer rewrites and concats = 1541

Logging from new code:

1779359112361 HTTPPM intercepting response
1779359112363 HTTPPM chunk len 16384
1779359112556 HTTPPM sending intercepted, len 25246243
-->
total time = 195 millis
number of buffer rewrites and concats = 1

How has this been tested?

Test suite still passes (at least - as well as it did before - ipv6 tests fail on my machine before and after).
Build has been run and manual testing of new JS performed to prove the buffering works correctly.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.

No other updates are required.

Summary by CodeRabbit

  • Bug Fixes

    • Optimized response data handling for improved performance and memory efficiency during proxy operations.
    • Enhanced error recovery with proper resource cleanup in error conditions.
  • Chores

    • Temporarily adjusted build output handling to accommodate a transitional merge.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

responseInterceptor now buffers decompressed proxy response chunks in a Buffer[], concatenates them once on stream end, and clears buffers on error. .gitignore comment was added to temporarily allow dist by commenting out the ignore rule.

Changes

Buffer chunking optimization

Layer / File(s) Summary
Chunked buffer implementation and error handling
src/handlers/response-interceptor.ts
Incoming decompressed chunks are pushed to buffers: Buffer[] on data, concatenated once on end (or set to an empty UTF-8 buffer), and the buffers array is cleared. The decompressed stream error handler clears the buffer array before ending the response with an error message.
Allow dist temporarily in repo
.gitignore
Commented out the dist ignore entry and added a comment explaining that dist is temporarily published and should not be ignored for now.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I’m a rabbit in the code, nibbling chunks one by one,
I gather them in rows until the final concat is done.
No wasted reallocations, tidy buffers in a heap,
Cleared when errors dance about, then off I hop to sleep. 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change—optimizing buffer creation in responseInterceptor to occur once instead of repeatedly, and clearly references the associated issue #929.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.gitignore:
- Around line 89-91: Revert the temporary .gitignore changes that expose the
dist directory: remove the added comment block and the uncommented/dist entry
from the PR so the upstream .gitignore does not track dist; instead keep any
dist-related ignore changes only in your fork or a dedicated branch (do not
commit the "dist" line or the temporary comment into the shared .gitignore).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 475e2553-5740-43ec-a5d6-529457392192

📥 Commits

Reviewing files that changed from the base of the PR and between a693837 and c096dc3.

⛔ Files ignored due to path filters (62)
  • dist/configuration.d.ts is excluded by !**/dist/**
  • dist/configuration.js is excluded by !**/dist/**
  • dist/debug.d.ts is excluded by !**/dist/**
  • dist/debug.js is excluded by !**/dist/**
  • dist/errors.d.ts is excluded by !**/dist/**
  • dist/errors.js is excluded by !**/dist/**
  • dist/factory-hono.d.ts is excluded by !**/dist/**
  • dist/factory-hono.js is excluded by !**/dist/**
  • dist/factory.d.ts is excluded by !**/dist/**
  • dist/factory.js is excluded by !**/dist/**
  • dist/get-plugins.d.ts is excluded by !**/dist/**
  • dist/get-plugins.js is excluded by !**/dist/**
  • dist/handlers/fix-request-body.d.ts is excluded by !**/dist/**
  • dist/handlers/fix-request-body.js is excluded by !**/dist/**
  • dist/handlers/index.d.ts is excluded by !**/dist/**
  • dist/handlers/index.js is excluded by !**/dist/**
  • dist/handlers/public.d.ts is excluded by !**/dist/**
  • dist/handlers/public.js is excluded by !**/dist/**
  • dist/handlers/response-interceptor.d.ts is excluded by !**/dist/**
  • dist/handlers/response-interceptor.js is excluded by !**/dist/**
  • dist/http-proxy-middleware.d.ts is excluded by !**/dist/**
  • dist/http-proxy-middleware.js is excluded by !**/dist/**
  • dist/index-hono.d.ts is excluded by !**/dist/**
  • dist/index-hono.js is excluded by !**/dist/**
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.js is excluded by !**/dist/**
  • dist/logger.d.ts is excluded by !**/dist/**
  • dist/logger.js is excluded by !**/dist/**
  • dist/path-filter.d.ts is excluded by !**/dist/**
  • dist/path-filter.js is excluded by !**/dist/**
  • dist/path-rewriter.d.ts is excluded by !**/dist/**
  • dist/path-rewriter.js is excluded by !**/dist/**
  • dist/plugins/default/debug-proxy-errors-plugin.d.ts is excluded by !**/dist/**
  • dist/plugins/default/debug-proxy-errors-plugin.js is excluded by !**/dist/**
  • dist/plugins/default/error-response-plugin.d.ts is excluded by !**/dist/**
  • dist/plugins/default/error-response-plugin.js is excluded by !**/dist/**
  • dist/plugins/default/index.d.ts is excluded by !**/dist/**
  • dist/plugins/default/index.js is excluded by !**/dist/**
  • dist/plugins/default/logger-plugin.d.ts is excluded by !**/dist/**
  • dist/plugins/default/logger-plugin.js is excluded by !**/dist/**
  • dist/plugins/default/proxy-events.d.ts is excluded by !**/dist/**
  • dist/plugins/default/proxy-events.js is excluded by !**/dist/**
  • dist/plugins/define-plugin.d.ts is excluded by !**/dist/**
  • dist/plugins/define-plugin.js is excluded by !**/dist/**
  • dist/plugins/index.d.ts is excluded by !**/dist/**
  • dist/plugins/index.js is excluded by !**/dist/**
  • dist/router.d.ts is excluded by !**/dist/**
  • dist/router.js is excluded by !**/dist/**
  • dist/status-code.d.ts is excluded by !**/dist/**
  • dist/status-code.js is excluded by !**/dist/**
  • dist/types.d.ts is excluded by !**/dist/**
  • dist/types.js is excluded by !**/dist/**
  • dist/utils/create-url.d.ts is excluded by !**/dist/**
  • dist/utils/create-url.js is excluded by !**/dist/**
  • dist/utils/function.d.ts is excluded by !**/dist/**
  • dist/utils/function.js is excluded by !**/dist/**
  • dist/utils/ipv6.d.ts is excluded by !**/dist/**
  • dist/utils/ipv6.js is excluded by !**/dist/**
  • dist/utils/logger-plugin.d.ts is excluded by !**/dist/**
  • dist/utils/logger-plugin.js is excluded by !**/dist/**
  • dist/utils/sanitize.d.ts is excluded by !**/dist/**
  • dist/utils/sanitize.js is excluded by !**/dist/**
📒 Files selected for processing (1)
  • .gitignore

Comment thread .gitignore Outdated
@chimurai
Copy link
Copy Markdown
Owner

Thanks for opening the PR

Improved the implementation and added some test. (Added you as co-author)

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.

2 participants