Skip to content

fix(server): restore original request.emit method in Node Body Limit Plugin #863

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 13, 2025

Conversation

unnoq
Copy link
Owner

@unnoq unnoq commented Aug 12, 2025

Summary by CodeRabbit

  • Bug Fixes

    • More accurate enforcement of maximum request body size, leveraging Content-Length when available.
    • Consistent 413 Payload Too Large errors without duplicate or premature checks.
    • Prevents over-reading by tracking streamed body size per chunk.
  • Refactor

    • Improved stability of request event handling during and after middleware execution, ensuring original behavior is restored.
    • Streamlined internal flow to perform size checks once and maintain reliable processing of incoming requests.

Copy link

vercel bot commented Aug 12, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Project Deployment Preview Comments Updated (UTC)
orpc Ready Preview 💬 Add feedback Aug 12, 2025 8:37am

Copy link

coderabbitai bot commented Aug 12, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Warning

Rate limit exceeded

@unnoq has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 15 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 1fef57d and 9b17a0e.

📒 Files selected for processing (1)
  • packages/server/src/adapters/node/body-limit-plugin.ts (3 hunks)

Walkthrough

Implements a one-time header-length check using once(), refactors request emit wrapping with bound emitters, tracks body size per data chunk, awaits the next handler with a try/finally to restore the original emit, and imports once from @orpc/shared.

Changes

Cohort / File(s) Summary
Node body-limit plugin
packages/server/src/adapters/node/body-limit-plugin.ts
Replace isHeaderChecked with once()-based header check using content-length; wrap and bind request.emit (originalEmit/bindedEmit); accumulate currentBodySize on 'data'; throw PAYLOAD_TOO_LARGE on limit breach; await options.next with try/finally restoring emit; import once from @orpc/shared.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant NodeServer as Node Server
  participant Plugin as BodyLimitPlugin
  participant Next as NextHandler

  Client->>NodeServer: HTTP Request
  NodeServer->>Plugin: Initialize plugin for request
  Plugin->>Plugin: Wrap request.emit (bindedEmit)
  Note over Plugin: once(): header-length check on first 'data'
  Plugin->>Next: await next(options)
  loop on 'data' events
    NodeServer->>Plugin: 'data' chunk
    Plugin->>Plugin: Check headers once, track currentBodySize
    Plugin-->>NodeServer: Delegate to bindedEmit
  end
  Plugin->>Plugin: finally restore original emit
  Next-->>NodeServer: Response
  NodeServer-->>Client: Response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related PRs

Poem

A nibble of bytes, a sniff of the air,
I count little crumbs with meticulous care.
One hop for headers, checked only once—
Then bounce through chunks, no overflow stunts.
I restore what I borrowed, tail held high—
Limits respected, requests pass by. 🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/server/body-limit-plugin-modify-request-in-nodejs

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @unnoq, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a potential issue in the Node Body Limit Plugin by ensuring that the request.emit method is properly restored to its original state after the plugin's logic has executed. This prevents unintended side effects or interference with other parts of the application that might rely on the standard behavior of request.emit. Additionally, it optimizes the header checking mechanism by using a once utility to ensure the content-length validation is performed only once per request, improving efficiency and correctness.

Highlights

  • request.emit restoration: The request.emit method is now restored to its original implementation after the BodyLimitPlugin has processed the request, preventing potential side effects from the overridden method.
  • checkHeader optimization: The checkHeader function, which validates the content-length header against the maxBodySize, now uses the once utility to ensure it's executed only a single time.
  • originalEmit binding: The originalEmit method is now explicitly bound to options.request to ensure correct context when called, addressing potential this binding issues.
  • Removal of isHeaderChecked flag: The isHeaderChecked flag has been removed, as its functionality is now handled by the once utility.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Aug 12, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request fixes an important bug by ensuring the monkey-patched request.emit method in the BodyLimitPlugin is restored after use. This prevents potential side-effects. The refactoring to use the once utility is also a nice improvement for code clarity. I have one suggestion to further improve the robustness of the fix by using a try...finally block and correcting the call to the next interceptor.

Copy link

codecov bot commented Aug 12, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link

pkg-pr-new bot commented Aug 12, 2025

More templates

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@863

@orpc/client

npm i https://pkg.pr.new/@orpc/client@863

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@863

@orpc/experimental-durable-event-iterator

npm i https://pkg.pr.new/@orpc/experimental-durable-event-iterator@863

@orpc/hey-api

npm i https://pkg.pr.new/@orpc/hey-api@863

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@863

@orpc/json-schema-typed

npm i https://pkg.pr.new/@orpc/json-schema-typed@863

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@863

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@863

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@863

@orpc/otel

npm i https://pkg.pr.new/@orpc/otel@863

@orpc/react

npm i https://pkg.pr.new/@orpc/react@863

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@863

@orpc/server

npm i https://pkg.pr.new/@orpc/server@863

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@863

@orpc/solid-query

npm i https://pkg.pr.new/@orpc/solid-query@863

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@863

@orpc/standard-server-aws-lambda

npm i https://pkg.pr.new/@orpc/standard-server-aws-lambda@863

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@863

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@863

@orpc/standard-server-peer

npm i https://pkg.pr.new/@orpc/standard-server-peer@863

@orpc/svelte-query

npm i https://pkg.pr.new/@orpc/svelte-query@863

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@863

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@863

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@863

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@863

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@863

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@863

commit: 9b17a0e

Copy link

@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: 0

🧹 Nitpick comments (2)
packages/server/src/adapters/node/body-limit-plugin.ts (2)

36-37: Consider adding defensive null check for request.emit

While unlikely in practice, it would be safer to verify that request.emit exists before storing and manipulating it.

+      if (!options.request.emit || typeof options.request.emit !== 'function') {
+        return await options.next(options)
+      }
+
       const originalEmit = options.request.emit
       const bindedEmit = originalEmit.bind(options.request)

55-59: Minor: Fix ESLint brace style warning

The static analysis tool flagged a brace style issue where the closing brace appears on the same line as the subsequent block.

       try {
         return await options.next(options)
-      } finally {
+      }
+      finally {
         options.request.emit = originalEmit
       }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9e0a4c and 1fef57d.

📒 Files selected for processing (1)
  • packages/server/src/adapters/node/body-limit-plugin.ts (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/server/src/adapters/node/body-limit-plugin.ts (1)
packages/shared/src/function.ts (1)
  • once (3-16)
🪛 ESLint
packages/server/src/adapters/node/body-limit-plugin.ts

[error] 57-57: Closing curly brace appears on the same line as the subsequent block.

(style/brace-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: publish-commit
🔇 Additional comments (2)
packages/server/src/adapters/node/body-limit-plugin.ts (2)

29-60: Well-implemented fix that properly restores the original emit method!

The refactored implementation correctly addresses the issue by:

  1. Storing the original emit method reference
  2. Creating a bound version for safe delegation
  3. Using try...finally to guarantee restoration even if errors occur
  4. Properly passing options to next()

This ensures the original emit method is always restored, preventing potential issues with downstream handlers.


30-34: Elegant use of once() for header validation

The replacement of the isHeaderChecked flag with the once() utility function is a cleaner, more functional approach that ensures the header check runs exactly once.

@unnoq unnoq merged commit 584cfcf into main Aug 13, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size:S This PR changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant