Skip to content

feat(gateway): make request body size configurable via env#186

Open
PranavAgarkar07 wants to merge 10 commits into
AnkanMisra:mainfrom
PranavAgarkar07:feat/configurable-body-size
Open

feat(gateway): make request body size configurable via env#186
PranavAgarkar07 wants to merge 10 commits into
AnkanMisra:mainfrom
PranavAgarkar07:feat/configurable-body-size

Conversation

@PranavAgarkar07

@PranavAgarkar07 PranavAgarkar07 commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the hardcoded const maxBodySize = 10 * 1024 * 1024 in gateway/main.go with a configurable value driven by the MAX_REQUEST_BODY_MB environment variable. A new helper getMaxBodySize() in gateway/config.go handles parsing and falls back to 10 MB when the variable is unset or invalid.

Also fixes a P1 issue introduced when the original hardcoded constant was replaced: the 413 error response JSON key drifted from "max_size" to "max_size_mb" with a type change (string → int). Restored the original response format so clients parsing the error do not break.

Related Issue

Closes #116

Type Of Change

  • Bug fix
  • Feature
  • Documentation
  • Tests
  • Refactor
  • Deployment/config

Affected Areas

  • Gateway (gateway/)
  • Verifier (verifier/)
  • Web (web/)
  • E2E/tests
  • Benchmarks
  • Deployment/config
  • Documentation/community files

Contributor Checklist

  • I kept the change focused and avoided unrelated refactors.
  • I updated README/service docs/OpenAPI/env examples when behavior, config, headers, status codes, or public APIs changed.
  • I did not commit secrets, private keys, funded wallets, API keys, or real production URLs.
  • I checked x402/EIP-712 field parity when touching payment context, signatures, timestamps, nonces, chain IDs, receipts, or wallet flow.
  • I checked Docker/Compose/Fly/Vercel docs when touching ports, service names, health checks, or environment variables.

Verification

$ cd gateway && go vet ./... && go test -v ./...
ok  gateway	10.009s
ok  gateway/internal/ai	0.006s

Notes For Reviewers

The getMaxBodySize() helper lives in config.go alongside the other typed-helper functions (getEnvAsDuration, getEnvAsBool, etc.) and follows the same pattern: log a warning and return the default when parsing fails.

Summary by CodeRabbit

  • New Features

    • Request body size limit is now configurable via environment variable (default 10 MB, maximum 100 MB). Oversized requests return a 413 with the configured limit shown.
  • Documentation

    • Added docs and example env entries for the new request body size setting.
  • Tests

    • Added tests covering configuration parsing, clamping behavior, and enforcement of the request-body limit.

Add dedicated duplicate-nonce error kind for nonce_already_used
(was incorrectly mapped to 'expired'). Sanitize raw gateway JSON
blobs in debug detail to show clean error codes instead.

Closes AnkanMisra#165
Covers all HTTP status -> error kind mappings (400/402/403/408/409/429/
502/504/5xx), gateway error codes (nonce_already_used, invalid_signature,
upstream_unavailable, verification_unavailable, verifier_timeout, etc.),
wallet error patterns (rejection codes 4001/ACTION_REJECTED, wrong chain
messages, missing wallet, network errors), and detail sanitization.
Replace hardcoded 10MB limit with MAX_REQUEST_BODY_MB env
var parsed by getMaxBodySize() helper in config.go. Falls
back to 10MB when unset or invalid.

Also fixes a P1 regression from the original implementation:
the 413 error response key was mistakenly changed from
'max_size' to 'max_size_mb' with a different format. The
original 'max_size' key with '%dMB' string format is
restored, now driven by the configurable value.

Closes AnkanMisra#116
@vercel

vercel Bot commented May 29, 2026

Copy link
Copy Markdown

@PranavAgarkar07 is attempting to deploy a commit to the ankanmisra's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Replaces hardcoded 10MB limits with a configurable MAX_REQUEST_BODY_MB. Adds getMaxBodySize() to parse and clamp the value, updates handlers and middleware to use the dynamic limit, documents the variable, and adds tests for parsing and route-level enforcement.

Changes

Request Body Size Configuration

Layer / File(s) Summary
Environment configuration for request body limits
.env.example, .env.production.example, gateway/README.md
MAX_REQUEST_BODY_MB (default 10, clamped to 100) added to env examples and README.
Configuration parsing and validation for body size limit
gateway/config.go
getMaxBodySize() reads MAX_REQUEST_BODY_MB, defaults to 10MB, warns/falls back on non-positive inputs, clamps to 100MB, and returns bytes.
Gateway request body enforcement across handlers and middleware
gateway/main.go, gateway/cache.go
handleSummarize and CacheMiddleware use getMaxBodySize() for http.MaxBytesReader limits and return 413 with computed max_size in MB on overflow.
Test coverage for parsing and route enforcement
gateway/config_test.go
Adds TestGetMaxBodySize and TestRequestBodyLimit_EnforcedAtRouteLevel to validate parsing, defaults, fallbacks, clamping, and route-level 413 behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

SWoC26, level:intermediate

Suggested reviewers

  • AnkanMisra

Poem

A rabbit sniffed the env with care,
Found limits fixed in dusty code,
Tuned them gently, now aware,
Ten or a hundred — set the mode,
Hop, the gateway handles every load! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: making request body size configurable via environment variable.
Description check ✅ Passed The description is comprehensive, includes summary, type of change, affected areas, contributor checklist items completed, verification commands, and notes for reviewers.
Linked Issues check ✅ Passed All acceptance criteria from #116 are met: MAX_REQUEST_BODY_MB environment variable controls the limit, default remains 10MB, .env.example includes the variable, and getMaxBodySize() helper is implemented following the code hint.
Out of Scope Changes check ✅ Passed All changes directly support the configurable request body size feature. Minor adjustments to web/package.json and bun.lock were merge conflict resolutions, not out-of-scope additions.

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

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

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 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 `@gateway/config.go`:
- Around line 99-102: The getMaxBodySize function must guard against
non-positive values returned by getEnvAsInt (e.g., MAX_REQUEST_BODY_MB=0 or
negative) by clamping them to the default used elsewhere (like
getPositiveTimeout); update getMaxBodySize to treat mb <= 0 as the default 10
(or use the same default constant if present) before converting to bytes so
http.MaxBytesReader never receives a zero/negative limit and accidentally
rejects valid requests.

In `@gateway/main.go`:
- Around line 419-425: Replace the hardcoded const maxBodySize = 10*1024*1024 in
gateway/cache.go and any Content-Length checks or http.MaxBytesReader uses with
the dynamic value from getMaxBodySize(); update the cache middleware (e.g., the
Cache middleware/handler function) to call maxSize := getMaxBodySize(), use
http.MaxBytesReader(c.Writer, c.Request.Body, maxSize), compare Content-Length
against maxSize, and when returning 413 include the same formatted max_size
string as in gateway/main.go (fmt.Sprintf("%dMB", maxSize/1024/1024)) so
CACHE_ENABLED respects MAX_REQUEST_BODY_MB.
🪄 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: 169325ae-7afd-47d8-8070-93b825677bde

📥 Commits

Reviewing files that changed from the base of the PR and between 8985ec7 and f290dbe.

📒 Files selected for processing (6)
  • .env.example
  • gateway/config.go
  • gateway/main.go
  • web/package.json
  • web/src/lib/errors.test.ts
  • web/src/lib/errors.ts

Comment thread gateway/config.go
Comment thread gateway/main.go

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Resolve conflicts

…y-size

# Conflicts:
#	web/package.json
#	web/src/lib/errors.test.ts
…e.go

Co-authored-by: codex <codex@users.noreply.github.com>
@PranavAgarkar07

Copy link
Copy Markdown
Contributor Author

Resolved merge conflicts with main (web/package.json scripts moved to bun:test, web/src/lib/errors.test.ts import changed from vitest to bun:test).

Also addressed the two CodeRabbit findings:

Finding 1 (config.go): Added non-positive guard to getMaxBodySize — treats MAX_REQUEST_BODY_MB=0 or negative as the default 10MB with a logged warning, matching getPositiveTimeout's pattern.

Finding 2 (cache.go): Replaced hardcoded const maxBodySize = 1010241024 with getMaxBodySize() and dynamic fmt.Sprintf("%dMB", maxSize/1024/1024) for the 413 response. CACHE_ENABLED now honors MAX_REQUEST_BODY_MB.

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
microai-paygate Ready Ready Preview, Comment Jun 4, 2026 4:21pm

@AnkanMisra

Copy link
Copy Markdown
Owner

vercel logs:

19:11:23.010 Running build in Washington, D.C., USA (East) – iad1
19:11:23.011 Build machine configuration: 2 cores, 8 GB
19:11:23.221 Cloning github.com/AnkanMisra/MicroAI-Paygate (Branch: feat/configurable-body-size, Commit: 2538326)
19:11:24.355 Cloning completed: 1.134s
19:11:24.845 Restored build cache from previous deployment (3ynGXicmuDhWAVvP5YkpEPmJqbVS)
19:11:25.070 Running "vercel build"
19:11:25.091 Vercel CLI 54.7.1
19:11:25.319 Running "install" command: `bun install --frozen-lockfile`...
19:11:25.359 bun install v1.3.12 (700fc117)
19:11:25.383 Resolving dependencies
19:11:26.606 Resolved, downloaded and extracted [268]
19:11:26.608 error: lockfile had changes, but lockfile is frozen
19:11:26.608 note: try re-running without --frozen-lockfile and commit the updated lockfile
19:11:26.622 Error: Command "bun install --frozen-lockfile" exited with 1

…-size

bun install was needed to sync web/bun.lock with web/package.json after
vitest was added as a devDependency during merge conflict resolution.
@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 37dffe69fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/package.json Outdated
Comment thread .env.example

# Request Body Size Configuration
# Maximum request body size in MB (default: 10)
MAX_REQUEST_BODY_MB=10

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.

P2 Badge Document MAX_REQUEST_BODY_MB in config references

This introduces a new operator-facing gateway setting, but only .env.example mentions it; the main README configuration table, gateway/README.md optional-variable table, and .env.production.example still omit it. In production/setup contexts users will not discover the new limit knob or know its default/unit, so please keep those config references aligned with this new env var.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Comment thread gateway/config.go Outdated
Comment thread gateway/config.go

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

…s, tests

- Clamp MAX_REQUEST_BODY_MB to 10240 before converting to bytes to
  prevent int64 overflow (P3 finding)
- Remove unused vitest devDependency from web/package.json (P2 finding)
- Add MAX_REQUEST_BODY_MB to gateway/README.md env table and
  .env.production.example (P2 finding)
- Add TestGetMaxBodySize regression tests covering default, custom,
  zero, negative, overflow-clamped, and non-numeric paths (P2 finding)

Co-authored-by: codex <codex@users.noreply.github.com>
@PranavAgarkar07

Copy link
Copy Markdown
Contributor Author

Addressed all 4 Codex findings in a0484b1:

P2 — Remove unused Vitest dependency: Removed vitest from web/package.json devDependencies and regenerated web/bun.lock. The test:unit script uses bun test, not vitest.

P2 — Document MAX_REQUEST_BODY_MB: Added to gateway/README.md optional-variable table (default: 10, clamped to 10240) and .env.production.example as a commented-out entry.

P2 — Add regression coverage: Added TestGetMaxBodySize with 6 sub-tests covering: default (unset), custom value (25MB), zero fallback, negative fallback, overflow clamp (99999→10240), and non-numeric fallback.

P3 — Clamp MAX_REQUEST_BODY_MB before multiplying: Added maxBodySizeMBMax = 10240 constant and clamp in getMaxBodySize(). Values exceeding 10240 MB are logged and clamped to prevent int64 overflow.

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review

@AnkanMisra

Copy link
Copy Markdown
Owner

@PranavAgarkar07 which issue does it solve, please mention it in the description

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0484b101d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gateway/config.go Outdated
Comment thread web/bun.lock Outdated
@PranavAgarkar07

Copy link
Copy Markdown
Contributor Author

Done — added Closes #116 in the PR description under a new "Related Issue" section.

… churn

- Reduce maxBodySizeMBMax from 10240 to 100 to prevent memory-exhaustion
  risk from io.ReadAll buffering (Codex P2 finding)
- Revert web/bun.lock to origin/main to drop unrelated transitive dep
  bumps from this gateway-only PR (Codex P2 finding)

Co-authored-by: codex <codex@users.noreply.github.com>
@PranavAgarkar07

Copy link
Copy Markdown
Contributor Author

Addressed both open Codex findings from the second review (commit a0484b1):

P2 — Cap configurable request bodies below memory-exhaustion size

  • Reduced maxBodySizeMBMax from 10240 MB (10 GiB) to 100 MB — still 10x the default, but prevents a single request from forcing the gateway to buffer 10 GiB in memory
  • Updated docs and tests to match

P2 — Revert unrelated web lockfile updates

  • Reverted web/bun.lock to origin/main version, dropping 501 lines of unrelated transitive dependency bumps (Babel, TypeScript ESLint packages, etc.)

Ran go test -v ./... and go vet ./... — all passing.

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review the pr

@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@AnkanMisra AnkanMisra added enhancement New feature or request go Pull requests that update go code level:beginner Small, well-scoped work suitable for newer contributors. type:feature New user-facing or API-facing capability. type:security Security, abuse resistance, secret safety, or payment integrity work. labels Jun 4, 2026

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@PranavAgarkar07 Final Changes wrt to pr

Comment thread .env.example

# Request Body Size Configuration
# Maximum request body size in MB (default: 10)
MAX_REQUEST_BODY_MB=10

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Comment thread gateway/config_test.go
Comment on lines +478 to +485
func TestGetMaxBodySize(t *testing.T) {
t.Run("default when unset", func(t *testing.T) {
t.Setenv("MAX_REQUEST_BODY_MB", "")
if got := getMaxBodySize(); got != 10*1024*1024 {
t.Fatalf("expected 10MB default, got %d", got)
}
})

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Add route-level regression coverage for configured 413 responses

These added tests only validate getMaxBodySize() parsing, but they never exercise handleSummarize or CacheMiddleware with MAX_REQUEST_BODY_MB set to a smaller value and an oversized request body

That leaves both the cached and uncached 413 responses unprotected, so a future drift in the actual rejection path or max_size payload would still pass CI even though this PR changes a public error contract there

@PranavAgarkar07

Copy link
Copy Markdown
Contributor Author

Addressed review feedback - added TestRequestBodyLimit_EnforcedAtRouteLevel with 5 sub-tests covering body size enforcement at the route level (below/at/over limit with env-driven config). Debug test removed. Commit 66adb49. All tests pass.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
gateway/config_test.go (1)

531-620: 🏗️ Heavy lift

Consider adding integration tests for the actual handlers.

The test validates the enforcement pattern and 413 response format, which is valuable. However, it uses a simplified mock handler rather than exercising handleSummarize or CacheMiddleware directly.

Testing the actual handlers would provide stronger protection against:

  • Changes to the 413 response format in production code
  • Removal of body-limit enforcement from specific handlers
  • Differences between cached and uncached error paths
💡 Potential approach

Add integration tests that:

  1. Set up a test Gin engine with the actual CacheMiddleware (cache disabled for simplicity)
  2. Call handleSummarize with MAX_REQUEST_BODY_MB=1 and a 2MB payload
  3. Assert 413 response with "max_size": "1MB"
  4. Optionally, test the cached path by enabling cache and verifying both cache miss and cache hit scenarios

This would complement the current pattern-validation test by ensuring the actual handlers maintain the contract.

Based on learnings: Changes to gateway status codes or response bodies require matching tests in the actual handlers.

🤖 Prompt for 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.

In `@gateway/config_test.go` around lines 531 - 620, The current
TestRequestBodyLimit_EnforcedAtRouteLevel test validates the body limit
enforcement pattern using a mock handler but does not exercise the actual
production handlers like handleSummarize or CacheMiddleware. Add a new
integration test function that sets up a test Gin engine with the actual
CacheMiddleware and calls handleSummarize directly with MAX_REQUEST_BODY_MB
environment variable set to a specific limit (e.g., 1MB) and a payload exceeding
that limit, then verify the response returns status 413 with the correct
max_size format in the response body. This ensures the actual handlers maintain
the expected contract and response format, rather than just testing the
enforcement pattern in isolation.
🤖 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.

Nitpick comments:
In `@gateway/config_test.go`:
- Around line 531-620: The current TestRequestBodyLimit_EnforcedAtRouteLevel
test validates the body limit enforcement pattern using a mock handler but does
not exercise the actual production handlers like handleSummarize or
CacheMiddleware. Add a new integration test function that sets up a test Gin
engine with the actual CacheMiddleware and calls handleSummarize directly with
MAX_REQUEST_BODY_MB environment variable set to a specific limit (e.g., 1MB) and
a payload exceeding that limit, then verify the response returns status 413 with
the correct max_size format in the response body. This ensures the actual
handlers maintain the expected contract and response format, rather than just
testing the enforcement pattern in isolation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84e302c8-27da-4b4d-a666-6896415079cd

📥 Commits

Reviewing files that changed from the base of the PR and between 4506231 and 66adb49.

📒 Files selected for processing (1)
  • gateway/config_test.go

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

Labels

enhancement New feature or request go Pull requests that update go code level:beginner Small, well-scoped work suitable for newer contributors. type:feature New user-facing or API-facing capability. type:security Security, abuse resistance, secret safety, or payment integrity work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make Request Body Size Configurable

2 participants