refactor: Migrate Session middleware to new extractors package#3744
refactor: Migrate Session middleware to new extractors package#3744ReneWerner87 merged 7 commits intomainfrom
Conversation
- 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.
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughSession middleware was migrated to use the shared Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~55 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
|
There was a problem hiding this comment.
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
sessionmiddleware package to a new, dedicatedextractorspackage, promoting modularity and reusability across the framework. - Codebase Simplification: The previously existing
extractors.goandextractors_test.gofiles within thesessionmiddleware have been removed, streamlining the session package and reducing redundancy. - Updated Configuration and Usage: All references to session extractors in the
sessionmiddleware's configuration, internal logic, and documentation examples have been updated to utilize the functions from the newextractorspackage. - 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
-
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. ↩
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
| 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 { |
There was a problem hiding this comment.
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.
| 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 { |
There was a problem hiding this comment.
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 usingextractors.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: SourceHeaderwill 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
📒 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 viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake modernize)
Files:
middleware/session/store.gomiddleware/session/store_test.gomiddleware/session/middleware_test.gomiddleware/session/config_test.gomiddleware/session/session.gomiddleware/session/config.gomiddleware/session/session_test.go
docs/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Review and update the contents of the
docsfolder 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.gomiddleware/session/middleware_test.gomiddleware/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.gomiddleware/session/session_test.godocs/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.gomiddleware/session/middleware_test.gomiddleware/session/config_test.gomiddleware/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.gomiddleware/session/middleware_test.gomiddleware/session/config_test.gomiddleware/session/session.gomiddleware/session/config.gomiddleware/session/session_test.godocs/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
Chainare correct.
336-345: Docs correct — cookie/header write; query/form/param read-onlyConfirmed — 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 Report❌ Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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()andRelease()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 sessionAlso applies to: 134-139
376-397: Don’t echo Authorization back in responses; make the extractor read‑only.Setting
SourceHeaderwill 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
📒 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 viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake modernize)
Files:
middleware/csrf/csrf_test.go
docs/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Review and update the contents of the
docsfolder 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.godocs/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.godocs/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.
There was a problem hiding this comment.
⚠️ 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.
|
@coderabbitai, your comments about 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() |
|
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 Save() method (lines ~272-293):
Release() method (lines ~295-301):
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: Length of output: 1047 🏁 Script executed: Length of output: 1343 🏁 Script executed: Length of output: 1356 @sixcolors, thank you for the correction! After examining the actual implementation in Save() method (lines 294-308):
Release() method (lines 82-87):
The evidence from the codebase confirms that users must call I've removed the incorrect learnings about 🐰💡 grateful for the learning correction ✏️ Learnings added
⛔ Learnings removed🧠 Learnings used |
…havior and configuration notes
There was a problem hiding this comment.
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 signaturesmiddleware/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.
getExtractorInfocurrently returns only cookie and non-Authorization header extractors (by checking onlySourceCookieandSourceHeader). That matches the “read‑only Authorization” policy, but the comment “returns all cookie and header extractors” can be misread to includeSourceAuthHeader. 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: MakeSourceAuthHeaderhandling explicit (read‑only).Behavior is correct (do nothing), but an explicit case improves readability and prevents future regressions if
defaulthandling 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 explicitSourceAuthHeaderhandling 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 betime.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 setCookieDomain.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
📒 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 viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake modernize)
Files:
middleware/session/session.go
docs/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Review and update the contents of the
docsfolder 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.godocs/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.
Uh oh!
There was an error while loading. Please reload this page.