Skip to content

refactor: Migrate Session middleware to new extractors package#3744

Merged
ReneWerner87 merged 7 commits intomainfrom
session-use-extractors
Sep 15, 2025
Merged

refactor: Migrate Session middleware to new extractors package#3744
ReneWerner87 merged 7 commits intomainfrom
session-use-extractors

Conversation

@sixcolors
Copy link
Member

@sixcolors sixcolors commented Sep 13, 2025

  • Updated session configuration to use extractors from the new package.
  • Replaced all instances of custom extractor functions with the corresponding functions from the extractors package.
  • Removed the deprecated extractors.go and extractors_test.go files.
  • Adjusted tests and middleware to accommodate the new extractor structure.
  • Ensured backward compatibility by maintaining the same extractor behavior.

- Updated session configuration to use extractors from the new package.
- Replaced all instances of custom extractor functions with the corresponding functions from the extractors package.
- Removed the deprecated extractors.go and extractors_test.go files.
- Adjusted tests and middleware to accommodate the new extractor structure.
- Ensured backward compatibility by maintaining the same extractor behavior.
@sixcolors sixcolors requested a review from a team as a code owner September 13, 2025 22:45
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 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

Session middleware was migrated to use the shared github.com/gofiber/fiber/v3/extractors package. Local extractor types, constructors, errors, and their tests were removed; Config and session logic now reference extractors.Extractor and extractors.* functions. Documentation and examples were updated to the new namespace.

Changes

Cohort / File(s) Summary of Changes
Docs: extractor API migration
docs/middleware/session.md
Documentation updated to reference the shared extractors module, rename types/functions, update examples, migration tables, and error/source constants.
Config: switch to external extractors
middleware/session/config.go, middleware/session/config_test.go
Config.Extractor now uses extractors.Extractor; default set to extractors.FromCookie("session_id"); tests updated to use extractors.FromHeader.
Remove session-local extractor implementation
middleware/session/extractors.go, middleware/session/extractors_test.go
Local Extractor struct, Source enum, constructor functions (FromCookie, FromHeader, FromQuery, FromForm, FromParam), Chain, and related error vars/tests removed.
Session core integration with extractors
middleware/session/session.go
Switched internal extractor handling to []extractors.Extractor; getExtractorInfo signature updated; logic now switches on extractors.Source* and treats header/auth-header together; loops updated to iterate external extractors.
Tests: adapt to new package
middleware/session/middleware_test.go, middleware/session/session_test.go, middleware/session/store_test.go, middleware/session/config_test.go
Tests updated to import github.com/gofiber/fiber/v3/extractors and replace local FromXxx/Chain calls with extractors.FromXxx/extractors.Chain.
Store: comment-only note
middleware/session/store.go
Added comment clarifying extractor is provided by the shared extractors package; no functional change.
CSRF tests: extractor import updates
middleware/csrf/csrf_test.go
Tests updated to import and use extractors.FromCookie for session cookie extractor setup.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant App as Fiber App
  participant SM as Session Middleware
  participant EX as extractors.Extractor
  participant Store as Store

  Client->>App: HTTP Request
  App->>SM: run middleware
  SM->>EX: call Extract(ctx)
  alt ID found
    SM->>Store: load/create session with ID
    Store-->>SM: session data
    SM->>App: attach session to context
  else ErrNotFound / no ID
    SM-->>App: proceed without session
  end

  App->>SM: response phase
  rect rgb(245,250,255)
  note right of SM: write behavior depends on EX.Source
  alt SourceCookie
    SM->>Client: Set-Cookie
  else SourceHeader / SourceAuthHeader
    SM->>Client: Set header (e.g., X-Session / Authorization)
  else Other sources
    SM-->>Client: read-only (no write)
  end
  end

  App-->>Client: HTTP Response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested labels

SessionMW, v3

Suggested reviewers

  • efectn
  • ReneWerner87
  • gaby

Poem

I hop through headers, nibble cookies light,
Chain little trails to find the ID right.
Queries whisper, params softly sing—
Extractors lead the way, I quickly spring.
With a twitch of whiskers, sessions aligned—hooray! 🥕🐇

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch session-use-extractors

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.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description summarizes the main changes (switching to the extractors package, file removals, and test adjustments) but does not follow the repository's required template: it omits a "Fixes #" reference, does not expand the "Changes introduced" checklist with details (benchmarks, documentation updates, migration guide, changelog), does not select a "Type of change", and does not mark checklist items or confirm CI/test status. It also lacks links to updated docs or explicit migration steps and missing/removed API notes that are important for reviewers and users. Because several required template sections are missing or incomplete, the description is insufficient for merging. Please update the PR description to follow the repository template: add a "Fixes #" line if applicable, expand "Changes introduced" with concrete details and links to modified documentation and migration steps, select the appropriate "Type of change", mark which checklist items are completed, and state CI/test status; explicitly note any breaking API moves (removed local extractors and public symbol relocations) and include changelog/migration-guide bullets to help reviewers and users.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title is a concise, single-sentence summary that accurately describes the primary change in the changeset—migrating the Session middleware to use the new extractors package—and aligns with the diffs that replace local extractors with extractors.*, remove the old extractors file/tests, and update configs and tests.

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 @sixcolors, 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 performs a significant refactoring of the session middleware by migrating all session ID extraction functionalities to a new, shared extractors package. This change aims to centralize and standardize the way session IDs are retrieved from various request sources (such as cookies, headers, and query parameters), making the session middleware more focused and its extraction logic reusable across other parts of the framework. The migration involves updating configuration, internal processing, and all relevant documentation and test cases to reflect the new package structure, while carefully preserving existing behavior.

Highlights

  • Extractor Logic Centralization: The session ID extraction logic has been moved from the session middleware package to a new, dedicated extractors package, promoting modularity and reusability across the framework.
  • Codebase Simplification: The previously existing extractors.go and extractors_test.go files within the session middleware have been removed, streamlining the session package and reducing redundancy.
  • Updated Configuration and Usage: All references to session extractors in the session middleware's configuration, internal logic, and documentation examples have been updated to utilize the functions from the new extractors package.
  • Backward Compatibility Ensured: The refactoring was carefully implemented to ensure that the behavior of session ID extraction remains consistent, thereby maintaining backward compatibility for existing implementations.
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.

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 pull request migrates the session middleware from custom extractor functions to use the new shared extractors package. It removes deprecated extractor code and updates all references throughout the codebase to use the standardized extractors module.

  • Updated all extractor imports to use github.com/gofiber/fiber/v3/extractors
  • Replaced custom session extractor functions with shared extractors package equivalents
  • Updated documentation to reflect the new extractor patterns and references

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
middleware/session/store_test.go Updated test imports and replaced custom extractors with shared package functions
middleware/session/store.go Added documentation comment about extractors package
middleware/session/session_test.go Updated all test cases to use extractors from shared package
middleware/session/session.go Updated extractor type references and source constants to use shared package
middleware/session/middleware_test.go Updated test configuration to use shared extractors package
middleware/session/extractors_test.go Migrated all extractor tests to use shared package and updated error handling
middleware/session/extractors.go Removed deprecated extractor implementation (empty file)
middleware/session/config_test.go Updated configuration tests to use shared extractors
middleware/session/config.go Updated Config struct and defaults to use shared extractors package
docs/middleware/session.md Comprehensive documentation update with new extractor patterns and examples

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 is a significant refactoring that migrates the session ID extraction logic to a new, shared extractors package. This is a great move for code reuse and consistency across the framework. The changes are well-executed, with updates to the session configuration, tests, and documentation to reflect the new structure. I've found a couple of issues: one functional bug in how SourceAuthHeader is handled and one issue in a documentation example that could mislead users about read-only extractors. My detailed comments provide suggestions to fix these. Overall, a solid refactoring effort.

Comment on lines +384 to +388
if chainExtractor.Source == extractors.SourceCookie || chainExtractor.Source == extractors.SourceHeader {
relevantExtractors = append(relevantExtractors, chainExtractor)
}
}
} else if extractor.Source == SourceCookie || extractor.Source == SourceHeader {
} else if extractor.Source == extractors.SourceCookie || extractor.Source == extractors.SourceHeader {
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The getExtractorInfo function is intended to find all extractors that can set a response value (cookies or headers). While setSession and delSession were updated to handle extractors.SourceAuthHeader, this function was not. As a result, if an extractor with SourceAuthHeader is used (e.g., from extractors.FromAuthHeader), it won't be included in the list of "relevant extractors", and the Authorization header won't be set on the response. You should include extractors.SourceAuthHeader in this check.

Suggested change
if chainExtractor.Source == extractors.SourceCookie || chainExtractor.Source == extractors.SourceHeader {
relevantExtractors = append(relevantExtractors, chainExtractor)
}
}
} else if extractor.Source == SourceCookie || extractor.Source == SourceHeader {
} else if extractor.Source == extractors.SourceCookie || extractor.Source == extractors.SourceHeader {
if chainExtractor.Source == extractors.SourceCookie || chainExtractor.Source == extractors.SourceHeader || chainExtractor.Source == extractors.SourceAuthHeader {
relevantExtractors = append(relevantExtractors, chainExtractor)
}
}
} else if extractor.Source == extractors.SourceCookie || extractor.Source == extractors.SourceHeader || extractor.Source == extractors.SourceAuthHeader {

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/middleware/session.md (1)

460-489: __Host- cookie conflict: Domain must be empty.

This snippet sets CookieDomain: "example.com" while using extractors.FromCookie("__Host-session_id"). “__Host-” cookies require Secure, Path="/", and no Domain attribute. Adjust snippet accordingly.

     // Cookie Settings
     CookiePath:        "/",
-    CookieDomain:      "example.com",
     CookieSessionOnly: false,   // Persist across browser restarts
@@
-    // Session ID
-    Extractor:         extractors.FromCookie("__Host-session_id"),
+    // Session ID
+    // Using "__Host-" cookie: Secure=true (set above), Path="/", and no Domain.
+    Extractor:         extractors.FromCookie("__Host-session_id"),
♻️ Duplicate comments (3)
middleware/session/session.go (1)

373-398: Bug: getExtractorInfo omits SourceAuthHeader (breaks auth‑header extractors).

You include SourceAuthHeader in setSession/delSession but filter it out here, so Authorization won’t be set/cleared. Include it alongside header/cookie.

-   // If it's a chained extractor, collect all cookie/header extractors
+   // If it's a chained extractor, collect all cookie/header/auth-header extractors
    if len(extractor.Chain) > 0 {
        for _, chainExtractor := range extractor.Chain {
-           if chainExtractor.Source == extractors.SourceCookie || chainExtractor.Source == extractors.SourceHeader {
+           if chainExtractor.Source == extractors.SourceCookie ||
+              chainExtractor.Source == extractors.SourceHeader ||
+              chainExtractor.Source == extractors.SourceAuthHeader {
                relevantExtractors = append(relevantExtractors, chainExtractor)
            }
        }
-   } else if extractor.Source == extractors.SourceCookie || extractor.Source == extractors.SourceHeader {
+   } else if extractor.Source == extractors.SourceCookie ||
+             extractor.Source == extractors.SourceHeader ||
+             extractor.Source == extractors.SourceAuthHeader {
        // Single extractor - only include if it's cookie or header
        relevantExtractors = append(relevantExtractors, extractor)
    }
docs/middleware/session.md (2)

296-298: Fix markdownlint (MD034, MD032) and avoid a possibly non-existent guide link.

Convert the bare URL to a markdown link and remove the lone list item.

-This middleware uses the shared extractors module for session ID extraction. See the Extractors Guide:
-- https://docs.gofiber.io/guide/extractors
+This middleware uses the shared extractors module for session ID extraction. See the [Extractors Guide](https://docs.gofiber.io/guide/extractors).

402-413: Custom read‑only extractor should set a non‑writing Source.

Without Source, zero‑value may default to a writing source, contradicting “read‑only” intent. Also, the function name suggests a param, but it reads a header.

 func FromCustomParam() extractors.Extractor {
     return extractors.Extractor{
         Extract: func(c fiber.Ctx) (string, error) {
             sessionID := c.Get("X-Custom-Session")
             if sessionID == "" {
                 return "", extractors.ErrNotFound
             }
             return sessionID, nil
         },
-        // Read-only, won't set responses (non-header/cookie source)
+        // Read-only: do not set any response values
+        Source: extractors.SourceOther,
         Key:    "X-Custom-Session",
     }
 }
🧹 Nitpick comments (4)
middleware/session/store.go (1)

188-189: Nit: reference the exact package path in the doc comment.

Clarify where the extractor comes from to aid grep-ability and IDE tooltips.

-// The extractor is provided by the shared extractors package.
+// The extractor is provided by github.com/gofiber/fiber/v3/extractors.
middleware/session/session_test.go (1)

11-11: Tests migrated to external extractors — consider adding coverage for Authorization extractor.

Current suite doesn’t validate SourceAuthHeader write/cleanup behavior. Add a focused test to guard it.

Would you like me to open a follow‑up PR with such a test?

Also applies to: 537-538, 567-568, 600-601, 633-634, 665-666, 868-869

middleware/session/session.go (1)

409-414: Auth header formatting: consider prefixing with “Bearer ” when writing Authorization.

If ext.Source == SourceAuthHeader, most clients expect “Authorization: Bearer ”. Today you set the raw ID, which may be surprising.

-   case extractors.SourceHeader, extractors.SourceAuthHeader:
-       s.ctx.Response().Header.SetBytesV(ext.Key, []byte(s.id))
+   case extractors.SourceAuthHeader:
+       s.ctx.Response().Header.Set(ext.Key, "Bearer "+s.id)
+   case extractors.SourceHeader:
+       s.ctx.Response().Header.SetBytesV(ext.Key, []byte(s.id))

And similarly on delete it’s fine to just Del the header (no format needed). If you prefer not to set Authorization at all in responses, alternatively drop SourceAuthHeader from the writable set and document it as read‑only.

Also applies to: 446-452

docs/middleware/session.md (1)

378-397: Avoid echoing Authorization header back to clients.

Setting Source: SourceHeader will cause the middleware to write the Authorization header in responses (token leak risk). Make this extractor read‑only.

-        Source: extractors.SourceHeader, // This will set response headers
+        Source: extractors.SourceOther,  // Read-only; do NOT echo Authorization
-app.Use(session.New(session.Config{
-    Extractor: FromAuthorization(), // Will set Authorization header in response
-}))
+app.Use(session.New(session.Config{
+    Extractor: FromAuthorization(), // Read-only; no response header is set
+}))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aedffa1 and fcd124e.

📒 Files selected for processing (10)
  • docs/middleware/session.md (23 hunks)
  • middleware/session/config.go (3 hunks)
  • middleware/session/config_test.go (2 hunks)
  • middleware/session/extractors.go (0 hunks)
  • middleware/session/extractors_test.go (0 hunks)
  • middleware/session/middleware_test.go (2 hunks)
  • middleware/session/session.go (6 hunks)
  • middleware/session/session_test.go (7 hunks)
  • middleware/session/store.go (1 hunks)
  • middleware/session/store_test.go (3 hunks)
💤 Files with no reviewable changes (2)
  • middleware/session/extractors.go
  • middleware/session/extractors_test.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/session/store.go
  • middleware/session/store_test.go
  • middleware/session/middleware_test.go
  • middleware/session/config_test.go
  • middleware/session/session.go
  • middleware/session/config.go
  • middleware/session/session_test.go
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/middleware/session.md
🧠 Learnings (11)
📓 Common learnings
Learnt from: sixcolors
PR: gofiber/fiber#3625
File: middleware/session/config.go:57-58
Timestamp: 2025-07-27T17:28:53.403Z
Learning: In the session middleware `Config` struct, the `Extractor` field uses function closures (like `FromCookie(key)`), making it impossible to introspect extractor parameters at runtime for validation purposes without complex reflection techniques.
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Parallel tests for `Session.Save` already exist in the `middleware/session/session_test.go` file, specifically in the `Test_Session_Save` and `Test_Session_Save_Expiration` functions.

Applied to files:

  • middleware/session/store_test.go
  • middleware/session/middleware_test.go
  • middleware/session/session_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.

Applied to files:

  • middleware/session/store_test.go
  • middleware/session/session_test.go
  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/session/store_test.go
  • middleware/session/middleware_test.go
  • middleware/session/config_test.go
  • middleware/session/session_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/session/store_test.go
📚 Learning: 2024-12-13T08:14:22.851Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: hooks_test.go:228-228
Timestamp: 2024-12-13T08:14:22.851Z
Learning: In Go test files, prefer using the `require` methods from the `testify` package for assertions instead of manual comparisons and calls to `t.Fatal` or `t.Fatalf`.

Applied to files:

  • middleware/session/store_test.go
📚 Learning: 2025-07-27T17:28:53.403Z
Learnt from: sixcolors
PR: gofiber/fiber#3625
File: middleware/session/config.go:57-58
Timestamp: 2025-07-27T17:28:53.403Z
Learning: In the session middleware `Config` struct, the `Extractor` field uses function closures (like `FromCookie(key)`), making it impossible to introspect extractor parameters at runtime for validation purposes without complex reflection techniques.

Applied to files:

  • middleware/session/store_test.go
  • middleware/session/middleware_test.go
  • middleware/session/config_test.go
  • middleware/session/session.go
  • middleware/session/config.go
  • middleware/session/session_test.go
  • docs/middleware/session.md
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#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/session/middleware_test.go
📚 Learning: 2024-09-25T16:15:39.392Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/csrf/session_manager.go:30-43
Timestamp: 2024-09-25T16:15:39.392Z
Learning: In the session middleware, `session.FromContext(c)` returns `*session.Middleware`, whereas `m.session.Get(c)` returns `*session.Store`, so they are not directly interchangeable.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/csrf/csrf_test.go:164-165
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the `Test_CSRF_WithSession_Middleware` function, calling `session.NewWithStore()` without arguments is acceptable, as the default configuration is sufficient.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:26-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware, the `newStore`, `New`, and `NewWithStore` functions ensure that a `Store` is present even if it is not initialized in `ConfigDefault`.

Applied to files:

  • docs/middleware/session.md
🧬 Code graph analysis (3)
middleware/session/store_test.go (1)
middleware/csrf/extractors.go (3)
  • Extractor (45-50)
  • FromHeader (130-142)
  • FromQuery (157-169)
middleware/session/session.go (1)
middleware/csrf/extractors.go (5)
  • Extractor (45-50)
  • Source (11-11)
  • SourceCookie (37-37)
  • Chain (187-228)
  • SourceHeader (16-16)
middleware/session/session_test.go (1)
middleware/csrf/extractors.go (5)
  • Extractor (45-50)
  • FromHeader (130-142)
  • Chain (187-228)
  • FromQuery (157-169)
  • FromForm (103-115)
🪛 markdownlint-cli2 (0.17.2)
docs/middleware/session.md

297-297: Bare URL used

(MD034, no-bare-urls)

🪛 GitHub Check: markdownlint
docs/middleware/session.md

[failure] 297-297: Bare URL used
docs/middleware/session.md:297:3 MD034/no-bare-urls Bare URL used [Context: "https://docs.gofiber.io/guide/..."] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md034.md


[failure] 297-297: Lists should be surrounded by blank lines
docs/middleware/session.md:297 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- https://docs.gofiber.io/guid..."] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md032.md

🪛 GitHub Actions: markdownlint
docs/middleware/session.md

[error] 297-297: MD032/blanks-around-lists: Lists should be surrounded by blank lines. Context: - https://docs.gofiber.io/guid...

⏰ 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). (2)
  • GitHub Check: Compare
  • GitHub Check: repeated
🔇 Additional comments (9)
middleware/session/middleware_test.go (1)

12-12: Extractor migration in tests looks good.

Import path and FromCookie usage are correctly updated to the new extractors package.

Also applies to: 393-393

middleware/session/config_test.go (1)

8-8: LGTM: tests now use external extractors.

Import and FromHeader migration align with the new API.

Also applies to: 27-27

middleware/session/store_test.go (1)

9-9: LGTM: extractor references updated.

FromHeader/FromQuery usage matches the new extractors package; tests remain behaviorally identical.

Also applies to: 40-41, 56-57

middleware/session/config.go (1)

7-7: Config: extractor type/default migration looks correct.

Type switched to extractors.Extractor and default set to FromCookie("session_id"); zero‑value detection via Extract == nil is sound.

Also applies to: 54-58, 96-97

docs/middleware/session.md (5)

54-71: Good migration to shared extractors.

Importing and using extractors.FromCookie("__Host-session_id") looks correct for v3.


303-316: Built-in extractor examples read cleanly.

Examples correctly reference extractors.* and match the new API.


328-333: Chained extractors example LGTM.

Accurately demonstrates extractors.Chain(...) with cookie/header/query precedence.


690-699: API list matches new package surface.

Extractor function signatures and Chain are correct.


336-345: Docs correct — cookie/header write; query/form/param read-only

Confirmed — getExtractorInfo() filters a chained extractor to only SourceCookie/SourceHeader and the save/delete logic sets/removes response cookies/headers accordingly. Mixed chains will set both cookie and header; query/form/param extractors do not produce response writes.

Relevant: middleware/session/session.go (getExtractorInfo + set/delete handling, ~lines 372–414 and 444–452).

@codecov
Copy link

codecov bot commented Sep 13, 2025

Codecov Report

❌ Patch coverage is 80.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.03%. Comparing base (aedffa1) to head (accc6b9).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
middleware/session/session.go 80.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3744      +/-   ##
==========================================
- Coverage   92.04%   92.03%   -0.02%     
==========================================
  Files         116      115       -1     
  Lines       11698    11632      -66     
==========================================
- Hits        10768    10706      -62     
+ Misses        674      671       -3     
+ Partials      256      255       -1     
Flag Coverage Δ
unittests 92.03% <80.00%> (-0.02%) ⬇️

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/middleware/session.md (2)

114-132: Fix Save vs Release guidance for the Store pattern (Save already releases the session).

Calling both Save() and Release() can double‑return the object to the pool. Save persists and releases; Release is for discard/no‑persist.

Apply:

 func backgroundTask(sessionID string) {
     sess, err := store.GetByID(context.Background(), sessionID)
     if err != nil {
         return
     }
-    defer sess.Release() // Important: Manual cleanup required
-
-    // Modify session
+    // Modify session
     sess.Set("last_task", time.Now())
 
-    // Manual save required
-    if err := sess.Save(); err != nil {
+    // Save persists AND returns the session to the pool (no extra Release)
+    if err := sess.Save(); err != nil {
         log.Printf("Failed to save session: %v", err)
     }
 }

And update the requirements list:

- - Must call `sess.Release()` when done
- - Must call `sess.Save()` to persist changes
+ - To persist changes, call `sess.Save()` (also releases the session)
+ - If discarding changes or read‑only access, call `sess.Release()` instead of `Save()`
+ - Never call both `Save()` and `Release()` on the same session

Also applies to: 134-139


376-397: Don’t echo Authorization back in responses; make the extractor read‑only.

Setting SourceHeader will cause the middleware to write an Authorization header, which is risky. Use a custom/non‑header source.

Apply:

 func FromAuthorization() extractors.Extractor {
     return extractors.Extractor{
         Extract: func(c fiber.Ctx) (string, error) {
             auth := c.Get("Authorization")
             if strings.HasPrefix(auth, "Bearer ") {
                 sessionID := strings.TrimPrefix(auth, "Bearer ")
                 if sessionID != "" {
                     return sessionID, nil
                 }
             }
             return "", extractors.ErrNotFound
         },
-        Source: extractors.SourceHeader, // This will set response headers
+        Source: extractors.SourceCustom, // Read-only; do NOT echo Authorization back
         Key:    "Authorization",
     }
 }
 
 app.Use(session.New(session.Config{
-    Extractor: FromAuthorization(), // Will set Authorization header in response
+    Extractor: FromAuthorization(), // Read-only; no Authorization header is echoed
 }))
♻️ Duplicate comments (2)
docs/middleware/session.md (2)

627-634: Link to Extractors Guide is helpful.

Assuming docs are live, this cross‑ref is great. If there’s any chance of delay, consider a brief fallback note.


400-413: Custom read‑only extractor is missing Source; defaults may write headers.

Explicitly mark it as custom to avoid unintended response writes.

Apply:

 func FromCustomParam() extractors.Extractor {
     return extractors.Extractor{
         Extract: func(c fiber.Ctx) (string, error) {
             sessionID := c.Get("X-Custom-Session")
             if sessionID == "" {
                 return "", extractors.ErrNotFound
             }
             return sessionID, nil
         },
-        // Read-only, won't set responses (non-header/cookie source)
+        // Read-only: non-header/cookie source
+        Source: extractors.SourceCustom,
         Key:    "X-Custom-Session",
     }
 }
🧹 Nitpick comments (2)
docs/middleware/session.md (2)

70-71: Clarify __Host- cookie requirements in the production snippet.

__Host- cookies must be Secure, have Path="/" and no Domain.

Apply:

 app.Use(session.New(session.Config{
     Storage:           storage,
     CookieSecure:      true,              // HTTPS only
     CookieHTTPOnly:    true,              // Prevent XSS
     CookieSameSite:    "Lax",             // CSRF protection
     IdleTimeout:       30 * time.Minute,  // Session timeout
     AbsoluteTimeout:   24 * time.Hour,    // Maximum session life
     Extractor:         extractors.FromCookie("__Host-session_id"),
+    CookiePath:        "/",               // __Host- requires Path="/"
+    CookieDomain:      "",                // __Host- must NOT set Domain
 }))

702-716: Add the missing Config.Store property to the table.

Docs show examples using Store, but the reference table omits it.

Apply:

 | `Storage`           | `fiber.Storage`             | Session storage backend     | `memory.New()`                             |
+| `Store`             | `*session.Store`            | Prebuilt store (overrides Storage) | `nil`                               |
 | `Extractor`         | `extractors.Extractor`      | Session ID extraction       | `extractors.FromCookie("session_id")`     |
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fcd124e and ad7724e.

📒 Files selected for processing (2)
  • docs/middleware/session.md (23 hunks)
  • middleware/csrf/csrf_test.go (4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/csrf/csrf_test.go
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/middleware/session.md
🧠 Learnings (8)
📓 Common learnings
Learnt from: sixcolors
PR: gofiber/fiber#3625
File: middleware/session/config.go:57-58
Timestamp: 2025-07-27T17:28:53.403Z
Learning: In the session middleware `Config` struct, the `Extractor` field uses function closures (like `FromCookie(key)`), making it impossible to introspect extractor parameters at runtime for validation purposes without complex reflection techniques.
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-09-25T16:17:00.969Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.
📚 Learning: 2025-07-27T17:28:53.403Z
Learnt from: sixcolors
PR: gofiber/fiber#3625
File: middleware/session/config.go:57-58
Timestamp: 2025-07-27T17:28:53.403Z
Learning: In the session middleware `Config` struct, the `Extractor` field uses function closures (like `FromCookie(key)`), making it impossible to introspect extractor parameters at runtime for validation purposes without complex reflection techniques.

Applied to files:

  • middleware/csrf/csrf_test.go
  • docs/middleware/session.md
📚 Learning: 2024-10-02T23:03:31.727Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-02T23:03:31.727Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/csrf/csrf_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.

Applied to files:

  • middleware/csrf/csrf_test.go
  • docs/middleware/session.md
📚 Learning: 2024-09-25T16:15:39.392Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/csrf/session_manager.go:30-43
Timestamp: 2024-09-25T16:15:39.392Z
Learning: In the session middleware, `session.FromContext(c)` returns `*session.Middleware`, whereas `m.session.Get(c)` returns `*session.Store`, so they are not directly interchangeable.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-06-30T00:38:06.580Z
Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-06-30T00:38:06.580Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/csrf/csrf_test.go:164-165
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the `Test_CSRF_WithSession_Middleware` function, calling `session.NewWithStore()` without arguments is acceptable, as the default configuration is sufficient.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:26-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware, the `newStore`, `New`, and `NewWithStore` functions ensure that a `Store` is present even if it is not initialized in `ConfigDefault`.

Applied to files:

  • docs/middleware/session.md
🧬 Code graph analysis (1)
middleware/csrf/csrf_test.go (1)
middleware/csrf/extractors.go (1)
  • Extractor (45-50)
⏰ 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). (3)
  • GitHub Check: Compare
  • GitHub Check: repeated
  • GitHub Check: unit (1.25.x, windows-latest)
🔇 Additional comments (3)
middleware/csrf/csrf_test.go (2)

12-12: Importing shared extractors looks correct.

No collisions with the CSRF package’s local Extractor type; compile-time clarity is preserved.


79-81: Approve — session store uses extractors.FromCookie("_session"); no legacy session.From usages found.*
Cookie key matches the test setup and behavior is unchanged.

docs/middleware/session.md (1)

689-698: Extractor API section aligns with the new package.

Good callouts and signatures.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: accc6b9 Previous: aedffa1 Ratio
Benchmark_Ctx_Params 98.27 ns/op 0 B/op 0 allocs/op 62.95 ns/op 0 B/op 0 allocs/op 1.56
Benchmark_Ctx_Params - ns/op 98.27 ns/op 62.95 ns/op 1.56

This comment was automatically generated by workflow using github-action-benchmark.

@sixcolors
Copy link
Member Author

@coderabbitai, your comments about session.md outside the diff range regarding session.Save() and session.Release() need verification:

The implementation of Save() in session.go does not release the session to the pool. It only persists the session data to storage and updates the client cookie. The session remains valid and in use after calling Save().

The actual release of the session object to the pool is handled by Release(), which resets the session and calls sessionPool.Put(s). Therefore, you must call Release() when you are done with the session, even after calling Save()

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 14, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@sixcolors, thank you for the correction. After examining the current implementation in session.go, you are absolutely correct:

Save() method (lines ~272-293):

  • Only calls saveSession() to persist data to storage
  • Updates client cookie via setSession()
  • Does not return the session to the pool
  • Session remains valid and usable after Save()

Release() method (lines ~295-301):

  • Calls Reset() to clear session data
  • Actually returns the session to the pool via sessionPool.Put(s)

My previous learnings about Save() returning sessions to the pool were incorrect. The user must indeed call Release() when done with the session, even after calling Save(), to properly return the session object to the pool for reuse.

🐰✨ learns something new and updates understanding


🏁 Script executed:

#!/bin/bash
# Let's examine the Save() and Release() methods in the session middleware
echo "=== Examining Save() method implementation ==="
ast-grep --pattern $'func ($_ *Session) Save() $_ {
  $$$
}'

echo -e "\n=== Examining Release() method implementation ==="
ast-grep --pattern $'func ($_ *Session) Release() $_ {
  $$$
}'

echo -e "\n=== Looking for sessionPool.Put usage ==="
rg -n "sessionPool\.Put" middleware/session/

Length of output: 1047


🏁 Script executed:

#!/bin/bash
# Let's get more specific lines from session.go to understand the complete implementation
echo "=== Getting Save method implementation from session.go ==="
rg -A 20 -B 2 "func.*Save.*error" middleware/session/session.go

echo -e "\n=== Getting Release method implementation from session.go ==="
rg -A 20 -B 2 "func.*Release" middleware/session/session.go

echo -e "\n=== Checking for any sessionPool.Put calls ==="
rg -C 3 "sessionPool\.Put" middleware/session/

Length of output: 1343


🏁 Script executed:

#!/bin/bash
# Let's look at the complete session.go file to understand the pool management
echo "=== Looking at the complete session.go file structure ==="
cat middleware/session/session.go | grep -n -A 10 -B 2 -E "(func.*Save|func.*Release|sessionPool\.Put|sessionPool\.Get)"

Length of output: 1356


@sixcolors, thank you for the correction! After examining the actual implementation in session.go, you are absolutely correct:

Save() method (lines 294-308):

  • Only calls saveSession() to persist session data to storage
  • Does not interact with the session pool at all
  • Session remains valid and usable after calling Save()

Release() method (lines 82-87):

  • Calls releaseSession() which resets the session fields
  • Actually returns the session to the pool via sessionPool.Put(s) on line 99
  • This is the only place in the code where sessionPool.Put() is called

The evidence from the codebase confirms that users must call Release() when done with the session, even after calling Save(), to properly return the session object to the pool for reuse.

I've removed the incorrect learnings about Save() and added the correct understanding of both methods' behaviors.

🐰💡 grateful for the learning correction


✏️ Learnings added
Learnt from: sixcolors
URL: https://github.com/gofiber/fiber/pull/3744

Timestamp: 2025-09-14T00:10:40.520Z
Learning: The `session.Save()` method in the `middleware/session` package only persists session data to storage and updates the client cookie. It does NOT return the Session back to `sync.Pool`. The session remains valid and usable after calling Save().

Learnt from: sixcolors
URL: https://github.com/gofiber/fiber/pull/3744

Timestamp: 2025-09-14T00:10:40.520Z
Learning: The `session.Release()` method in the `middleware/session` package is responsible for returning the Session back to `sync.Pool` via `sessionPool.Put(s)`. It also calls Reset() to clear session data. Users must call Release() when done with the session, even after calling Save().

Learnt from: sixcolors
URL: https://github.com/gofiber/fiber/pull/3744

Timestamp: 2025-09-14T00:10:40.520Z
Learning: The `session.Save()` method in the `middleware/session` package only persists session data to storage via `saveSession()`. It does NOT return the Session back to `sync.Pool`. The session remains valid and usable after calling Save().

Learnt from: sixcolors
URL: https://github.com/gofiber/fiber/pull/3744

Timestamp: 2025-09-14T00:10:40.520Z
Learning: The `session.Release()` method in the `middleware/session` package is responsible for returning the Session back to `sync.Pool` via `sessionPool.Put(s)` in the `releaseSession()` function. It also resets session fields. Users must call Release() when done with the session, even after calling Save().

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


⛔ Learnings removed
Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-06-30T00:38:06.580Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-06-30T00:38:06.580Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

🧠 Learnings used
Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-06-30T00:38:06.580Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `session.Save()` method in the `middleware/session` package returns the `Session` back to `sync.Pool`.

Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/session.go:272-293
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the `middleware/session/session.go` file, the `saveSession()` method returns either `nil` or an error, so additional error wrapping in the `Save()` method is unnecessary.

Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/session.go:272-293
Timestamp: 2024-10-02T15:16:39.868Z
Learning: In the `middleware/session/session.go` file, the `saveSession()` method returns either `nil` or an error, so additional error wrapping in the `Save()` method is unnecessary.

Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/session.go:46-61
Timestamp: 2024-10-02T23:02:12.306Z
Learning: In this codebase, the `sessionPool` only contains `Session` instances, so type assertions without additional checks are acceptable.

Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/session.go:46-61
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In this codebase, the `sessionPool` only contains `Session` instances, so type assertions without additional checks are acceptable.

Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-06-30T00:38:06.580Z
Learning: Parallel tests for `Session.Save` already exist in the `middleware/session/session_test.go` file, specifically in the `Test_Session_Save` and `Test_Session_Save_Expiration` functions.

Learnt from: sixcolors
PR: gofiber/fiber#3051
File: middleware/session/session.go:215-216
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Parallel tests for `Session.Save` already exist in the `middleware/session/session_test.go` file, specifically in the `Test_Session_Save` and `Test_Session_Save_Expiration` functions.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/middleware/session.md (1)

632-644: Docs/code mismatch — confirm Store.Reset/Delete signatures

middleware/session/store.go declares type Store but my search did not find methods with the signatures store.Reset(ctx context.Context) error or store.Delete(ctx context.Context, sessionID string) error; either implement these methods or update the docs to reflect the actual API.

🧹 Nitpick comments (9)
middleware/session/session.go (7)

372-398: Clarify intent: exclude Authorization extractors from response-setting logic.

getExtractorInfo currently returns only cookie and non-Authorization header extractors (by checking only SourceCookie and SourceHeader). That matches the “read‑only Authorization” policy, but the comment “returns all cookie and header extractors” can be misread to include SourceAuthHeader. Please make the comment explicit to avoid regressions and bot noise.

-// getExtractorInfo returns all cookie and header extractors from the chain
+// getExtractorInfo returns cookie and non-Authorization header extractors from the chain

405-433: Make SourceAuthHeader handling explicit (read‑only).

Behavior is correct (do nothing), but an explicit case improves readability and prevents future regressions if default handling changes.

 		for _, ext := range relevantExtractors {
 			switch ext.Source {
 			case extractors.SourceHeader:
 				s.ctx.Response().Header.SetBytesV(ext.Key, []byte(s.id))
+			case extractors.SourceAuthHeader:
+				// Read-only for sessions: do not set Authorization on response
 			case extractors.SourceCookie:

441-469: Mirror explicit SourceAuthHeader handling in deletion.

Same rationale as in set path: make read‑only intent obvious.

 		for _, ext := range relevantExtractors {
 			switch ext.Source {
 			case extractors.SourceHeader:
 				s.ctx.Request().Header.Del(ext.Key)
 				s.ctx.Response().Header.Del(ext.Key)
+			case extractors.SourceAuthHeader:
+				// Read-only for sessions: do not modify Authorization headers
 			case extractors.SourceCookie:

516-541: Fix encodeSessionData docstring (no parameters).

The doc references a non-existent parameter and wrong usage.

-// encodeSessionData encodes session data to raw bytes
-//
-// Parameters:
-//   - rawData: The raw byte data to encode.
-//
-// Returns:
-//   - error: An error if the encoding fails.
-//
-// Usage:
-//
-//	// err := s.encodeSessionData(rawData)
+// encodeSessionData encodes session data to raw bytes.
+//
+// Returns:
+//   - []byte, error: Encoded bytes or an error.
+//
+// Usage:
+//
+//	b, err := s.encodeSessionData()

571-581: Correct usage example name.

The method is setAbsExpiration.

-//	s.setExpiration(time.Now().Add(time.Hour))
+//	s.setAbsExpiration(time.Now().Add(time.Hour))

445-465: Nit: simplify duration expression.

time.Now().Add(-1 * time.Minute) can be time.Now().Add(-time.Minute).


310-341: Invariant validated — s.config is set before saveSession(), but harden the code

  • Evidence: Store.getSession and Store.GetByID both assign sess.config before returning (middleware/session/store.go:152, 291). releaseSession clears ctx and config (middleware/session/session.go:89–96). middleware.saveSession calls Session.saveSession() before release, and Session.Save skips saving when the middleware owns the session. Current call paths therefore guarantee s.config != nil when saveSession() runs.

  • Recommendation: add defensive nil-check(s) (or avoid returning a default extractor when config==nil) before dereferencing s.config in saveSession()/setSession()/delSession() to remove the brittle invariant.

docs/middleware/session.md (2)

63-77: Add __Host- cookie requirements note.

You use __Host- in the example. Browsers require: Secure=true, Path=/, and no Domain attribute. Add a bullet so users don’t accidentally set CookieDomain.

 Notes:
 
 - AbsoluteTimeout must be greater than or equal to IdleTimeout; otherwise, the middleware panics during configuration.
 - If CookieSameSite is set to "None", the middleware automatically forces CookieSecure=true when setting the cookie.
+- When using the "__Host-" cookie prefix, do not set CookieDomain, set CookiePath="/" and ensure CookieSecure=true; otherwise browsers will reject the cookie.

300-331: Explicitly call out non‑mutating sources.

Good section. Consider tightening wording to “non‑Authorization headers” here too for consistency with code behavior.

-**Session Response Behavior:**
+**Session Response Behavior:**

-- Cookie extractors: set cookie in the response
-- Header extractors (non-Authorization): set header in the response
-- Authorization header, Query, Form, Param, Custom: read-only (no response values are set)
+- Cookie extractors: set cookie in the response
+- Header extractors (non‑Authorization): set header in the response
+- Authorization header, Query, Form, Param, Custom: read‑only (no response values are set)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad7724e and accc6b9.

📒 Files selected for processing (2)
  • docs/middleware/session.md (20 hunks)
  • middleware/session/session.go (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/session/session.go
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/middleware/session.md
🧠 Learnings (7)
📓 Common learnings
Learnt from: sixcolors
PR: gofiber/fiber#3625
File: middleware/session/config.go:57-58
Timestamp: 2025-07-27T17:28:53.403Z
Learning: In the session middleware `Config` struct, the `Extractor` field uses function closures (like `FromCookie(key)`), making it impossible to introspect extractor parameters at runtime for validation purposes without complex reflection techniques.
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-09-25T16:17:00.969Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.
📚 Learning: 2025-07-27T17:28:53.403Z
Learnt from: sixcolors
PR: gofiber/fiber#3625
File: middleware/session/config.go:57-58
Timestamp: 2025-07-27T17:28:53.403Z
Learning: In the session middleware `Config` struct, the `Extractor` field uses function closures (like `FromCookie(key)`), making it impossible to introspect extractor parameters at runtime for validation purposes without complex reflection techniques.

Applied to files:

  • middleware/session/session.go
  • docs/middleware/session.md
📚 Learning: 2024-09-25T16:15:39.392Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/csrf/session_manager.go:30-43
Timestamp: 2024-09-25T16:15:39.392Z
Learning: In the session middleware, `session.FromContext(c)` returns `*session.Middleware`, whereas `m.session.Get(c)` returns `*session.Store`, so they are not directly interchangeable.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2025-09-14T00:10:40.520Z
Learnt from: sixcolors
PR: gofiber/fiber#0
File: :0-0
Timestamp: 2025-09-14T00:10:40.520Z
Learning: The `session.Save()` method in the `middleware/session` package only persists session data to storage and updates the client cookie. It does NOT return the Session back to `sync.Pool`. The session remains valid and usable after calling Save().

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/csrf/csrf_test.go:164-165
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the `Test_CSRF_WithSession_Middleware` function, calling `session.NewWithStore()` without arguments is acceptable, as the default configuration is sufficient.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-09-25T16:17:00.969Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:16-26
Timestamp: 2024-09-25T16:17:00.969Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.

Applied to files:

  • docs/middleware/session.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/config.go:26-26
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the session middleware, the `newStore`, `New`, and `NewWithStore` functions ensure that a `Store` is present even if it is not initialized in `ConfigDefault`.

Applied to files:

  • docs/middleware/session.md
🧬 Code graph analysis (1)
middleware/session/session.go (1)
middleware/csrf/extractors.go (5)
  • Extractor (45-50)
  • Source (11-11)
  • SourceCookie (37-37)
  • Chain (187-228)
  • SourceHeader (16-16)
⏰ 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). (2)
  • GitHub Check: Compare
  • GitHub Check: repeated
🔇 Additional comments (3)
docs/middleware/session.md (3)

343-351: Nice: clear explanation of chained response behavior.

This aligns with the implementation (cookie + non‑Auth header mutate response; others read‑only).


610-633: Remove or correct sess.Store() in docs (middleware/session.md:610-633)

No Session.Store() method found in the repository search; either implement Session.Store() on the Session type or remove/update the API reference to the actual store accessor.


372-393: Constructors exist with matching signatures. extractors.FromAuthHeader(authScheme string) and extractors.FromCustom(key string, fn func(fiber.Ctx) (string, error)) are defined in extractors/extractors.go; the docs examples are correct.

@gaby gaby added the v3 label Sep 14, 2025
@gaby gaby added this to v3 Sep 14, 2025
@gaby gaby added this to the v3 milestone Sep 14, 2025
@gaby gaby moved this to In Progress in v3 Sep 14, 2025
@gaby gaby changed the title refactor: migrate session extractors to new extractors package refactor: Migrate Session middleware to new extractors package Sep 14, 2025
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 4c73b2d into main Sep 15, 2025
13 of 15 checks passed
@ReneWerner87 ReneWerner87 deleted the session-use-extractors branch September 15, 2025 06:47
@github-project-automation github-project-automation bot moved this from In Progress to Done in v3 Sep 15, 2025
Abhirup-99 pushed a commit to Abhirup-99/fiber that referenced this pull request Nov 3, 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.

4 participants