Skip to content

Conversation

@ReneWerner87
Copy link
Member

No description provided.

Copilot AI review requested due to automatic review settings December 6, 2025 12:04
@ReneWerner87 ReneWerner87 requested a review from a team as a code owner December 6, 2025 12:04
@ReneWerner87 ReneWerner87 added the v3 label Dec 6, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 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.

Walkthrough

This PR applies targeted performance and parsing refinements across many files: replaces allocation-heavy string operations with Cut/SplitSeq or Index/Count, refactors viewBindMap from sync.Map to Map, adds helper functions and tests, and updates comments/linter annotations. No exported API changes.

Changes

Cohort / File(s) Change Summary
App routing prefix
app.go
Replaced path-segment counting via splitting with strings.Count(prefix, "/") + 1.
Client URL hooks
client/hooks.go
Replaced strings.Split(req.url, "?") with strings.Cut and adjusted query/fragment extraction variables.
Client tests (hooks)
client/client_test.go
Test refactor: separated two anonymous hooks into named hook1, hook2 and passed them as distinct args.
Binder tag & slice parsing
binder/mapping.go
Use strings.Cut to take first tag segment; expand comma-separated slice values by iterating strings.SplitSeq and appending elements individually.
Context view bind map & XHR
ctx.go
Replaced sync.Map with Map for viewBindMap; initialize/clear/iterate via make, maps.Copy, and clear; precompute xmlHTTPRequestBytes and use header Peek for XHR detection.
Helpers: Accepts-Language & cache directives
helpers.go
Optimized Accepts-Language parsing with stack buffers and strings.SplitSeq; expanded isNoCache parsing to accept additional RFC 9111 forms and adjusted comments.
Helpers tests
helpers_test.go
Added Test_HeaderContainsValue, benchmark, and extended Test_Utils_IsNoCache for RFC edge cases.
Middleware static prefix handling
middleware/static/static.go
Replaced strings.Contains + Split with strings.Index + slicing to truncate wildcard prefix.
Middleware/adaptor & cache comments
middleware/adaptor/adaptor.go, middleware/cache/cache.go
Cosmetic comment changes and gosec G115 clarifications; no behavior change.
Request utilities
req.go
GetHeaders pre-allocates result map; Subdomains uses stack [8]string and strings.SplitSeq to avoid allocations, returning copies when needed.
Response utilities
res.go
Added headerContainsValue helper to de-duplicate header elements; Append now uses it; GetHeaders pre-allocates map and iterates efficiently.
Router cookie detection & comments
router.go
Precomputed flashCookieNameBytes for cookie checks; replaced string-byte conversions with the byte slice; updated handler-count comments to reference G115.
Path utilities
path.go
RemoveEscapeChar adds fast-path when no escapes and copies only from first escape; CheckConstraint simplified to switch-based validation for required Data counts.
Misc tests & small comments
ctx_test.go, mount.go, state_test.go, middleware/*
Minor comment updates, nolint/gosec clarifications, and non-functional renames/comments.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review ctx.go carefully for Map semantics and correct clearing/iteration (concurrency implications).
  • Verify RemoveEscapeChar edge cases (strings with leading/back-to-back escapes).
  • Confirm Subdomains stack-buffer safety and correct copying when returning slices.
  • Check binder/mapping.go comma-splitting behavior with trailing/empty values.
  • Validate new header parsing (headerContainsValue) handles whitespace and edge cases.

Possibly related PRs

Suggested reviewers

  • gaby
  • efectn
  • ksw2000
  • sixcolors

Poem

🐰 I nibble bytes and count each slash,
Cutting strings with nary a splash.
Stacks replace heaps, maps shed their locks,
Tests hop in, no build up of rocks.
A tiny tweak — hooray! — and then I dash 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is completely empty, missing all required template sections including purpose, changes introduced, benchmarks, and checklist items. Complete the pull request description following the template, including change rationale, benchmark results, test coverage confirmation, and relevant checklist items for this performance-focused refactoring.
Docstring Coverage ⚠️ Warning Docstring coverage is 48.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: optimizing string handling and memory allocations across multiple functions in the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch optimize-string-handling-and-memory-allocations-in-various-functions

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.

@ReneWerner87 ReneWerner87 added this to the v3 milestone Dec 6, 2025
@ReneWerner87 ReneWerner87 added this to v3 Dec 6, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ReneWerner87, 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 focuses on a comprehensive refactoring effort to enhance the application's performance and reduce its memory footprint. The changes primarily involve optimizing string manipulation techniques by leveraging more efficient Go standard library functions and patterns that minimize heap allocations. Additionally, data structures within the context handling were streamlined for better performance, and HTTP header parsing logic was made more robust and RFC-compliant. These improvements contribute to a more efficient and responsive system.

Highlights

  • String Handling Optimizations: Replaced strings.Split with more efficient alternatives like strings.Count, strings.Cut, and strings.SplitSeq across multiple files (app.go, binder/mapping.go, client/hooks.go, helpers.go, req.go, middleware/static/static.go) to reduce memory allocations and improve performance.
  • Memory Allocation Reduction: Introduced stack-allocated buffers for common string parsing scenarios (e.g., language tags in helpers.go, subdomains in req.go) and pre-allocated map capacities (req.go, res.go) to minimize heap allocations.
  • Context Map Optimization: Refactored ctx.go to replace sync.Map with a standard Map type for viewBindMap, removing sync dependency and associated overhead, and optimizing map operations like initialization, storage, clearing, and iteration.
  • HTTP Header Logic Refinement: Improved the isNoCache function in helpers.go to correctly parse no-cache directives according to RFC 9111, including those with field-name arguments and various spacing. A new helper headerContainsValue was added to res.go for efficient header value checking.
  • Nolint Comments Update: Updated //nolint:gosec comments across several files (ctx_test.go, middleware/cache/cache.go, mount.go, router.go, state_test.go) to provide more specific justifications for ignoring G115 (integer overflow) warnings, indicating that values are small or within safe ranges.
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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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.

@codecov
Copy link

codecov bot commented Dec 6, 2025

Codecov Report

❌ Patch coverage is 96.25000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.67%. Comparing base (0c6cc5d) to head (4720db7).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
binder/mapping.go 50.00% 1 Missing and 1 partial ⚠️
router.go 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3922      +/-   ##
==========================================
+ Coverage   91.60%   91.67%   +0.07%     
==========================================
  Files         119      119              
  Lines       10096    10117      +21     
==========================================
+ Hits         9248     9275      +27     
+ Misses        539      534       -5     
+ Partials      309      308       -1     
Flag Coverage Δ
unittests 91.67% <96.25%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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 introduces several performance optimizations by replacing strings.Split with more efficient alternatives like strings.Count, strings.Cut, and strings.SplitSeq, and by pre-allocating maps to reduce memory allocations. The change from sync.Map to a standard map for viewBindMap is also a good improvement for the context's performance. Most changes are well-implemented and improve efficiency.

However, I've found a critical bug in the new headerContainsValue helper function in res.go. The implementation can fail to correctly detect existing values in comma-separated headers if they are not space-separated, which could lead to incorrect header values being constructed. I've provided a detailed comment and a suggested fix for this issue.

Apart from that, the refactoring is solid and improves the codebase.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes string handling and memory allocations across various functions in the codebase to improve performance and reduce unnecessary heap allocations.

  • Replaces sync.Map with Map (map[string]any) for viewBindMap to simplify the code and improve performance
  • Optimizes string splitting operations using strings.Cut, strings.SplitSeq, and direct slicing to avoid allocations
  • Adds headerContainsValue helper function with optimized string matching for HTTP header values
  • Pre-allocates maps with known capacity to avoid reallocations
  • Uses stack-allocated arrays for common cases to avoid heap allocations
  • Improves nolint comments to be more specific about the ignored gosec warnings

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
state_test.go Updated nolint comments to be more descriptive about why G115 warnings are safe to ignore in test cases
router.go Updated nolint comments for atomic operations to clarify why G115 warnings are safe
res.go Added headerContainsValue helper function and pre-allocated map in GetHeaders with known capacity
req.go Pre-allocated map in GetHeaders and optimized Subdomains with stack-allocated array using strings.SplitSeq
mount.go Updated nolint comment for handler count to be more descriptive
middleware/static/static.go Optimized wildcard prefix handling using direct string slicing instead of strings.Split
middleware/cache/cache.go Updated nolint comments for Unix timestamp conversions to be more descriptive
middleware/adaptor/adaptor.go Added blank line to documentation comment for proper formatting
helpers_test.go Added comprehensive tests for headerContainsValue and expanded isNoCache tests
helpers.go Optimized acceptsLanguageOfferExtended with stack-allocated arrays and enhanced isNoCache to support RFC 9111 no-cache with field-name arguments
ctx_test.go Updated nolint comment to be more descriptive about the test value range
ctx.go Replaced sync.Map with Map for viewBindMap, simplified iteration logic, and improved memory management
client/hooks.go Optimized URL parsing using strings.Cut to avoid unnecessary allocations
client/client_test.go Refactored hook test to use named function variables for better readability
binder/mapping.go Optimized tag parsing with strings.Cut and value splitting with strings.SplitSeq
app.go Optimized path segment counting using strings.Count instead of splitting

Copy link
Contributor

@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 (1)
res.go (1)

136-154: headerContainsValue helper matches Append’s canonical formatting

Centralizing the duplicate-check logic into headerContainsValue keeps Append tight and makes the matching rules explicit. The helper:

  • Handles exact, prefix ("value,..."), suffix ("... , value"), and middle ("..., value, ..." with a leading space) positions.
  • Intentionally does not treat compact forms like "deflate,gzip,br" as containing "gzip", which matches the new tests and Fiber’s own ", "-separated formatting.

The trade-off is that if a response header was manually set in a non-canonical form, Append may now allow a duplicate token (e.g. "deflate,gzip,br, gzip"). That’s harmless for semantics but worth being aware of.

Also applies to: 156-179

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c6cc5d and db4091f.

📒 Files selected for processing (16)
  • app.go (1 hunks)
  • binder/mapping.go (2 hunks)
  • client/client_test.go (1 hunks)
  • client/hooks.go (3 hunks)
  • ctx.go (4 hunks)
  • ctx_test.go (1 hunks)
  • helpers.go (4 hunks)
  • helpers_test.go (2 hunks)
  • middleware/adaptor/adaptor.go (1 hunks)
  • middleware/cache/cache.go (3 hunks)
  • middleware/static/static.go (1 hunks)
  • mount.go (1 hunks)
  • req.go (2 hunks)
  • res.go (3 hunks)
  • router.go (4 hunks)
  • state_test.go (8 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

When adding Go tests, always invoke t.Parallel() at the start of each test and subtest to maximize concurrency

Files:

  • state_test.go
  • ctx_test.go
  • helpers_test.go
  • client/client_test.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Prefer github.com/gofiber/utils/v2 helpers (for example, utils.Trim) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Files:

  • state_test.go
  • middleware/static/static.go
  • ctx_test.go
  • mount.go
  • router.go
  • helpers_test.go
  • req.go
  • middleware/adaptor/adaptor.go
  • middleware/cache/cache.go
  • client/client_test.go
  • app.go
  • binder/mapping.go
  • client/hooks.go
  • ctx.go
  • res.go
  • helpers.go
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: gofiber/fiber PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-26T13:34:08.100Z
Learning: Applies to **/*.go : Prefer `github.com/gofiber/utils/v2` helpers (for example, `utils.Trim`) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code
📚 Learning: 2025-10-16T07:19:52.418Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:19:52.418Z
Learning: In the Fiber codebase, the linter does not allow `require` assertions from within HTTP handlers (including net/http-style handlers). Use `t.Fatalf`, `t.Errorf`, or similar `testing.T` methods for error handling inside handler functions instead.

Applied to files:

  • ctx_test.go
  • ctx.go
📚 Learning: 2025-10-16T07:15:26.529Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.

Applied to files:

  • mount.go
  • router.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/csrf/csrf_test.go:188-193
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the Fiber framework tests, using `ctx.Response.Header.Cookie` may not be suitable for parsing cookies from the response header, as it requires a `*Cookie` and fills it rather than returning a string value; thus, manual parsing of the `Set-Cookie` header may be necessary.

Applied to files:

  • helpers_test.go
  • middleware/cache/cache.go
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • middleware/adaptor/adaptor.go
📚 Learning: 2024-11-08T04:10:42.990Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.

Applied to files:

  • middleware/adaptor/adaptor.go
  • ctx.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • middleware/adaptor/adaptor.go
📚 Learning: 2025-11-26T13:34:08.100Z
Learnt from: CR
Repo: gofiber/fiber PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-26T13:34:08.100Z
Learning: Applies to **/*.go : Prefer `github.com/gofiber/utils/v2` helpers (for example, `utils.Trim`) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Applied to files:

  • ctx.go
🧬 Code graph analysis (4)
req.go (1)
client/request.go (2)
  • Request (46-73)
  • Header (708-710)
client/client_test.go (2)
client/client.go (1)
  • Client (37-67)
client/response.go (1)
  • Response (19-25)
ctx.go (1)
app.go (1)
  • Map (43-43)
res.go (3)
client/response.go (1)
  • Response (19-25)
client/request.go (1)
  • Header (708-710)
bind_test.go (2)
  • Header (331-335)
  • Header (574-578)
🪛 GitHub Actions: Modernize Lint
ctx.go

[error] 325-325: Replace m[k]=v loop with maps.Copy.

🪛 GitHub Check: modernize
ctx.go

[failure] 325-325:
Replace m[k]=v loop with maps.Copy

⏰ 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). (6)
  • GitHub Check: Agent
  • GitHub Check: Compare
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: repeated
  • GitHub Check: lint
🔇 Additional comments (19)
state_test.go (1)

987-987: G115 annotations in benchmarks/tests look correct.

Explicit nolint notes for small, bounded casts make the intent clear and avoid noisy false positives. LGTM.

Also applies to: 1004-1004, 1021-1021, 1038-1038, 1072-1072, 1090-1090, 1107-1107, 1123-1123

middleware/adaptor/adaptor.go (1)

71-71: Minor doc spacing change acknowledged.

Spacer before the Deprecated note is fine; no behavioral impact.

middleware/cache/cache.go (1)

94-94: Clear G115 justifications for conversions.

The added comments document safe bounds for these uint64 casts (Unix seconds, Age). Good clarity without changing behavior.

Also applies to: 107-107, 305-305

mount.go (1)

187-187: G115 note on handler count cast is appropriate.

Route handlers are bounded; documenting the safe uint32 cast is sufficient.

ctx_test.go (1)

6435-6435: Reasonable G115 suppression in test.

Casting lineNum (1–5) to int32 is safe; the nolint note clarifies intent for gosec.

app.go (1)

1305-1315: Slash-counting for mount prefix depth is correct and cheaper

Using strings.Count(prefix, "/") + 1 to derive parts preserves the previous segment-count semantics for normalized prefixes while avoiding allocations from Split. Given prefix != "" and mount prefixes are already normalized, this is a safe perf win.

router.go (1)

472-481: Atomic handler-count adjustments remain consistent

The added //nolint:gosec // G115 - handler count is always small comments simply document the existing bitwise decrement/increment pattern. The atomic updates still correctly mirror route registration and removal across deleteRoute, pruneAutoHeadRouteLocked, register, and ensureAutoHeadRoutesLocked, so no behavioral change is introduced.

Also applies to: 506-510, 571-577, 673-677

client/client_test.go (1)

286-303: Refactoring response hooks into named closures is fine

Extracting the two response hooks into hook1/hook2 and passing them to AddResponseHook keeps the semantics identical while improving readability. Test structure (including t.Parallel()) remains correct.

res.go (1)

440-452: GetHeaders optimization via Response.Header.All is appropriate

Using respHeader.Len() to size the map and iterating respHeader.All() avoids intermediate allocations and keeps key/value lifetimes within the documented handler scope. Converting the iterated []byte key/value pairs to string before storing in the map maintains the existing contract of GetHeaders() while reducing per-call overhead.

helpers_test.go (1)

637-666: Additional cache-control and headerContainsValue tests align with helper semantics

The new isNoCache cases (argument forms like no-cache="Set-Cookie" and spacing variants) accurately exercise the expanded parsing in helpers.go. Likewise, Test_HeaderContainsValue and its benchmark cover the exact/prefix/suffix/middle and empty/similar-token scenarios that headerContainsValue is designed for, guarding against regressions in response-header deduplication.

Also applies to: 683-731

helpers.go (2)

222-278: acceptsLanguageOfferExtended: SplitSeq-based parsing looks correct and efficient

Refactoring acceptsLanguageOfferExtended to:

  • Use small stack buffers ([8]string) with strings.SplitSeq for spec/offer subtags, and
  • Keep the same sliding/wildcard/singleton-barrier logic,

maintains the RFC 4647 extended filtering behavior while reducing heap churn for typical language tags. Tests such as "de-*-DE" vs "de-Latn-DE-1996" and "en-*" vs "en" still pass under this implementation.


739-769: Expanded isNoCache handling correctly covers directive-with-arguments

The new isNoCache implementation:

  • Anchors on case-insensitive no-cache tokens with proper delimiter checks on the left (start, space, or comma).
  • Treats end-of-string, comma, =, or space immediately after no-cache as a valid directive boundary, so forms like "no-cache", "no-cache=Set-Cookie", and "no-cache ,public" are all accepted.
  • Continues to reject substrings like "Xno-cache" and "no-cacheX".

This matches the updated tests and RFC 9111’s directive forms while avoiding spurious matches.

middleware/static/static.go (1)

118-122: Wildcard prefix truncation via Index is a clean micro-optimization

Switching to if idx := strings.Index(prefix, "*"); idx != -1 { prefix = prefix[:idx] } preserves the previous behavior for partial wildcards (e.g. "/john*""/john") while avoiding the extra slice allocations from strings.Split. The subsequent prefixLen handling is unchanged.

ctx.go (1)

62-74: viewBindMap refactor to Map using maps.Copy is correctly implemented

The refactor from sync.Map to the Map alias (map[string]any) is safe and properly implemented:

  • viewBindMap field (line 62) is now type Map, eliminating unnecessary synchronization overhead
  • ViewBind() method lazily initializes the map and uses maps.Copy() from the stdlib to copy entries, replacing the manual for k, v := range vars loop
  • release() method (line 608) resets the map with clear(c.viewBindMap), preserving capacity for reuse across pooled contexts
  • renderExtensions() method directly iterates over c.viewBindMap to merge view bindings without sync overhead

This refactoring is safe because DefaultCtx is request-scoped and reused via an object pool with no concurrent goroutine access to the same instance. The stdlib maps package (Go 1.21+) is the correct choice here—it is idiomatic, satisfies the modernize linter, and gofiber/utils/v2 provides no map copy utility. The coding guideline for preferring gofiber/utils/v2 helpers applies specifically to string manipulation operations, not map operations.

binder/mapping.go (2)

214-221: Struct tag parsing via strings.Cut keeps behavior while avoiding extra alloc

Using strings.Cut to strip options from the tag (Line 217) preserves the previous Split(...)[0] semantics, including edge cases with empty segments, and keeps the path using utils.ToLower consistent with existing style. This is a safe, allocation‑friendly change.

Based on learnings, this also keeps tag handling aligned with our utils‑first string conventions where applicable.


379-386: SplitSeq-based slice binding preserves semantics and cuts allocations

The new assignBindData loop over strings.SplitSeq (Lines 381‑383) still only activates when splitting is enabled, the value actually contains a comma, and the target field is a slice; the resulting elements are appended one by one, matching the former behavior while avoiding the intermediate []string allocation. Looks good for both correctness and performance.

req.go (2)

303-311: Header map preallocation with RequestHeader.All is correct and efficient

Using a local reqHeader plus make(map[string][]string, reqHeader.Len()) and iterating via reqHeader.All() (Lines 304‑307) correctly captures all headers, including multi‑value ones, while reducing reallocations. Converting keys/values through app.toString also respects fasthttp’s iterator lifetime constraints.


837-897: Subdomains stack-buffer + SplitSeq refactor maintains behavior and avoids leaks

The new partsBuf/parts pattern with strings.SplitSeq (Lines 871‑878) avoids a heap slice in the common ≤8‑label case, and the function now always returns heap‑allocated copies (result) for both offset == 0 and trimmed cases (Lines 883‑885, 893‑896), so no stack‑backed data escapes. Existing semantics—default offset 2, empty for IPs or excessive offset, normalized and punycode‑decoded host—are preserved.

Based on learnings, this continues to pair well with existing utils helpers like utils.TrimRight and utils.IsIPv4/IsIPv6.

client/hooks.go (1)

73-75: URL parsing with strings.Cut simplifies path/query/hash handling without changing behavior

Switching to strings.Cut for separating the base URI from ? and then query from # (Lines 74, 101) removes the intermediate slice from Split, while still:

  • Normalizing and templating the full URI before setting it on the request.
  • Parsing only the true query portion into fasthttp.Args (Line 105).
  • Explicitly setting the hash fragment via SetHash(hashPart) (Line 115).

This keeps existing semantics for URLs with and without query/fragment while tightening allocations in a hot path.

Also applies to: 100-106, 115-116

github-actions[bot]

This comment was marked as outdated.

Copy link
Contributor

@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 (1)
helpers_test.go (1)

683-736: HeaderContainsValue tests & benchmark look solid; consider case-sensitivity needs

The new table-driven tests cover exact token matches at start/middle/end, OWS variations, and substring false-positives, which is exactly what this helper needs for comma-separated headers. The benchmark mirrors realistic patterns and asserts a true result to keep the compiler honest; plus t.Parallel() is correctly used on the new test.

If headerContainsValue is intended to treat values case-insensitively for specific headers (e.g., Accept-Encoding tokens), you might optionally add a couple of mixed-case cases (like "GZip" vs "gzip") to document that behavior explicitly; otherwise this is good as-is. As per coding guidelines, the use of t.Parallel() here matches the test-concurrency requirement.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db4091f and 4720db7.

📒 Files selected for processing (5)
  • ctx.go (6 hunks)
  • helpers_test.go (2 hunks)
  • path.go (2 hunks)
  • res.go (3 hunks)
  • router.go (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • router.go
  • res.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Prefer github.com/gofiber/utils/v2 helpers (for example, utils.Trim) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Files:

  • path.go
  • ctx.go
  • helpers_test.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

When adding Go tests, always invoke t.Parallel() at the start of each test and subtest to maximize concurrency

Files:

  • helpers_test.go
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: gofiber/fiber PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-26T13:34:08.100Z
Learning: Applies to **/*.go : Prefer `github.com/gofiber/utils/v2` helpers (for example, `utils.Trim`) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • path.go
📚 Learning: 2025-11-26T13:34:08.100Z
Learnt from: CR
Repo: gofiber/fiber PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-26T13:34:08.100Z
Learning: Applies to **/*.go : Prefer `github.com/gofiber/utils/v2` helpers (for example, `utils.Trim`) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Applied to files:

  • path.go
  • ctx.go
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • ctx.go
📚 Learning: 2024-11-08T04:10:42.990Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.

Applied to files:

  • ctx.go
📚 Learning: 2025-10-16T07:19:52.418Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:19:52.418Z
Learning: In the Fiber codebase, the linter does not allow `require` assertions from within HTTP handlers (including net/http-style handlers). Use `t.Fatalf`, `t.Errorf`, or similar `testing.T` methods for error handling inside handler functions instead.

Applied to files:

  • ctx.go
🧬 Code graph analysis (1)
ctx.go (2)
app.go (1)
  • Map (43-43)
constants.go (1)
  • HeaderXRequestedWith (282-282)
⏰ 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). (5)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: repeated
  • GitHub Check: Compare
  • GitHub Check: lint
🔇 Additional comments (8)
helpers_test.go (1)

653-660: IsNoCache: RFC 9111 field-name and spacing cases covered well

The added cases for no-cache with field-name arguments (quoted and unquoted) and odd spacing nicely pin down the RFC 9111 behaviors and OWS handling. The expectations all look consistent with the usual “any no-cache directive implies no-cache” semantics.

path.go (2)

623-640: LGTM! Excellent optimization.

The fast path avoids allocation when no escape characters are present, and the slow path efficiently starts copying from the first escape index. The logic is correct and should significantly improve performance for strings without escapes.


707-719: LGTM! Efficient constraint validation.

The switch-based validation eliminates slice allocation and clearly groups constraints by their data requirements. The logic correctly validates that single-data constraints have at least one element and two-data constraints have at least two elements.

ctx.go (5)

322-326: LGTM! Cleaner map initialization.

Using make(Map, len(vars)) with capacity hint and maps.Copy is more efficient and readable than individual Store calls. The standard library function handles the copy correctly.


537-544: LGTM! Efficient XHR detection.

Precomputing xmlHTTPRequestBytes eliminates repeated allocations, and using utils.EqualFold with the precomputed byte slice for case-insensitive comparison is the right approach.


625-629: LGTM! Correct map iteration.

The standard map range iteration correctly replaces the sync.Map.Range method, maintaining the same logic of copying keys that don't already exist in bindMap.


63-63: The sync.Map to Map change is safe and improves performance.

The viewBindMap field change from sync.Map to regular Map is correct. Each request acquires a unique context instance from the pool (AcquireCtx) and releases it after request handling (ReleaseCtx), with defer statements preventing concurrent access. The viewBindMap is only accessed within the request lifecycle—once for population via maps.Copy in ViewBind() and once for reading in renderExtensions(). No concurrent goroutine access to the same context instance occurs, making the synchronization overhead of sync.Map unnecessary.


610-611: LGTM! Efficient map reuse.

Using clear(c.viewBindMap) instead of reinitializing preserves the underlying map allocation for reuse, which is more efficient. The clear built-in (Go 1.21+) is fully compatible with Fiber v3's Go 1.25 requirement.

@ReneWerner87
Copy link
Member Author

/gemini review

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 introduces a series of excellent performance optimizations and correctness fixes across various parts of the codebase. The changes effectively reduce memory allocations and improve string handling efficiency by leveraging modern Go features and performance patterns, such as using strings.Cut, strings.SplitSeq, stack-allocated buffers, and pre-computed constants. The refactoring from sync.Map to a standard map for viewBindMap is a good choice for the request context lifecycle. Additionally, the correctness fixes for header parsing logic in isNoCache and the new headerContainsValue function are valuable improvements. Overall, this is a high-quality contribution that enhances the framework's performance and robustness.

@ReneWerner87
Copy link
Member Author

Why sync.Map was replaced with a regular Map
The viewBindMap in DefaultCtx was changed from sync.Map to a regular Map because:

  1. Context is not shared across goroutines - Each DefaultCtx is acquired from a pool and used by a single request handler. There's no concurrent access to viewBindMap within a single request lifecycle.
  2. sync.Map was being recreated on every request - The pool's release() method couldn't efficiently reset a sync.Map, defeating the purpose of pooling. A regular map can simply be cleared with clear(viewBindMap).
  3. sync.Map has overhead - It uses internal locking and type assertions (interface{} storage), adding unnecessary CPU cycles when concurrency protection isn't needed.
  4. Regular map with clear() is faster - Go 1.21's clear() builtin efficiently resets a map while preserving its allocated capacity, making it ideal for pooled objects.

@ReneWerner87
Copy link
Member Author

@gofiber/maintainers In addition to the AI review, I need a human review here, as quite a lot has been adjusted, just to be on the safe side.

@gaby
Copy link
Member

gaby commented Dec 6, 2025

@codex review

@gaby gaby changed the title refactor: optimize string handling and memory allocations in various functions ♻️ refactor: Optimize string handling and memory allocations Dec 6, 2025
@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Keep it up!

ℹ️ 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".

Copy link
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

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

LGTM

@ReneWerner87 ReneWerner87 merged commit eda2197 into main Dec 7, 2025
19 of 20 checks passed
@ReneWerner87 ReneWerner87 deleted the optimize-string-handling-and-memory-allocations-in-various-functions branch December 7, 2025 16:07
@github-project-automation github-project-automation bot moved this to Done in v3 Dec 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants