Skip to content

Conversation

gaby
Copy link
Member

@gaby gaby commented Jun 5, 2025

Summary

  • keep the original casing of the Origin header when responding
  • separate simple vs. preflight header helpers
  • avoid Access-Control-Max-Age on simple requests
  • add regression tests for new behaviours

Copy link
Contributor

coderabbitai bot commented Jun 5, 2025

Walkthrough

The CORS middleware was updated to preserve the original casing of the Origin header in responses while maintaining case-insensitive origin checks. Header-setting logic was refactored by introducing a new function for preflight requests. Corresponding tests were added to verify these behaviors and ensure correct header handling.

Changes

File(s) Change Summary
middleware/cors/cors.go Preserves original Origin header case, refactors header-setting logic with setPreflightHeaders, removes unused parameter, fixes typos, removes slices import.
middleware/cors/cors_test.go Adds tests for max-age header exclusion in simple requests and origin case preservation in responses.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant FiberApp
    participant CORS_Middleware

    Client->>FiberApp: Send request with Origin header
    FiberApp->>CORS_Middleware: Pass request
    CORS_Middleware->>CORS_Middleware: Lowercase Origin for comparison
    CORS_Middleware->>CORS_Middleware: Preserve original Origin for response
    alt Preflight (OPTIONS)
        CORS_Middleware->>CORS_Middleware: setPreflightHeaders()
        CORS_Middleware->>Client: Respond with Access-Control headers (original Origin case)
    else Simple request
        CORS_Middleware->>CORS_Middleware: setSimpleHeaders()
        CORS_Middleware->>Client: Respond with Access-Control headers (original Origin case)
    end
Loading

Suggested reviewers

  • sixcolors
  • efectn

Poem

A rabbit with code on its mind,
Saw headers with case misaligned.
It hopped in to fix,
With some clever new tricks—
Now Origin's casing's refined!
🐇✨


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between babef1b and 59f1e58.

📒 Files selected for processing (1)
  • middleware/cors/cors_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • middleware/cors/cors_test.go
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: unit (1.24.x, macos-13)
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: unit (1.24.x, macos-latest)
  • GitHub Check: unit (1.24.x, ubuntu-latest)
  • GitHub Check: lint
  • GitHub Check: Compare
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

@gaby gaby changed the title Refine CORS middleware 🧹 chore: Improve CORS middleware RFC compliance Jun 5, 2025
@gaby gaby added this to v3 Jun 5, 2025
@gaby gaby added this to the v3 milestone Jun 5, 2025
Copy link

codecov bot commented Jun 5, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.91%. Comparing base (f00e355) to head (59f1e58).
Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3505      +/-   ##
==========================================
+ Coverage   83.88%   83.91%   +0.03%     
==========================================
  Files         120      120              
  Lines       12278    12284       +6     
==========================================
+ Hits        10299    10308       +9     
+ Misses       1555     1553       -2     
+ Partials      424      423       -1     
Flag Coverage Δ
unittests 83.91% <100.00%> (+0.03%) ⬆️

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.

@sixcolors sixcolors marked this pull request as ready for review June 5, 2025 15:39
@Copilot Copilot AI review requested due to automatic review settings June 5, 2025 15:39
@sixcolors sixcolors requested a review from a team as a code owner June 5, 2025 15:39
Copy link
Member

@sixcolors sixcolors left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refines the CORS middleware to align more closely with the CORS RFC by preserving Origin header casing, separating simple vs. preflight header logic, and omitting the Access-Control-Max-Age header on simple requests. It also introduces regression tests for these behaviors.

  • Refactor cors.go to use setSimpleHeaders and setPreflightHeaders, and keep the original Origin casing
  • Remove Max-Age header on non-OPTIONS (simple) requests
  • Add tests for Max-Age omission and origin-case preservation

Reviewed Changes

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

File Description
middleware/cors/cors.go Split header helpers, rename and preserve raw origin header, remove slices import
middleware/cors/cors_test.go Add tests for simple-request MaxAge omission and origin-case preservation
Comments suppressed due to low confidence (4)

middleware/cors/cors.go:86

  • [nitpick] The name originHeaderRaw is descriptive but a bit verbose; you might rename it to rawOrigin or requestOrigin for brevity and clarity.
originHeaderRaw := c.Get(fiber.HeaderOrigin)

middleware/cors/cors.go:189

  • Add a GoDoc comment above setSimpleHeaders to explain its parameters and behavior, which will improve maintainability and aid new contributors.
func setSimpleHeaders(c fiber.Ctx, allowOrigin string, cfg Config) {

middleware/cors/cors_test.go:100

  • There are no tests verifying that ExposeHeaders are correctly applied in both simple and preflight flows—consider adding tests for the Access-Control-Expose-Headers header.
func testDefaultOrEmptyConfig(t *testing.T, app *fiber.App) {

middleware/cors/cors.go:118

  • Consider converting allowOrigins into a map or a set at initialization to avoid linear scans on every request, improving lookup performance for large origin lists.
for _, origin := range allowOrigins {

@sixcolors
Copy link
Member

Neither issue are Non-RFC compliant. Origin header values are case-insensitive and max-age is not required in a non-preflight, but having it also isn’t explicitly not allowed.

The fixes are however improving the middleware. I just changed the title.

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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f9eec85 and babef1b.

📒 Files selected for processing (2)
  • middleware/cors/cors.go (6 hunks)
  • middleware/cors/cors_test.go (1 hunks)
🔇 Additional comments (7)
middleware/cors/cors.go (5)

85-87: Excellent RFC compliance improvement!

Preserving the original case of the Origin header while performing case-insensitive comparisons is the correct approach per CORS RFC standards. The dual-variable approach is clean and efficient.


118-123: Well-implemented case preservation logic.

The switch from slices.Contains to an explicit loop is necessary to preserve the original case in the response while maintaining case-insensitive comparison. The logic correctly compares normalized origins with the lowercase request origin and returns the raw origin header when a match is found.


189-189: Good RFC compliance improvements.

Removing the unused maxAge parameter and adding ExposeHeaders to simple requests aligns better with CORS specifications. The Access-Control-Expose-Headers should indeed be set for both simple and preflight requests when configured.

Also applies to: 204-208


210-220: Clean separation of header-setting logic.

The new setPreflightHeaders function provides a clear separation between simple and preflight request headers. The implementation correctly calls setSimpleHeaders first and then adds preflight-specific headers like Access-Control-Max-Age. This refactoring improves code maintainability and RFC compliance.


150-150: Correct implementation of the refactored architecture.

The function calls correctly route simple requests to setSimpleHeaders (without maxAge) and preflight requests to setPreflightHeaders. This ensures that Access-Control-Max-Age is only set for preflight requests, improving RFC compliance.

Also applies to: 168-168

middleware/cors/cors_test.go (2)

69-81: Comprehensive test for MaxAge behavior on simple requests.

This test correctly verifies that the Access-Control-Max-Age header is not set on simple requests even when the MaxAge configuration is specified. This validates the RFC compliance improvement where MaxAge should only be sent with preflight responses.


83-98: Excellent test coverage for origin case preservation.

This test thoroughly validates that the middleware preserves the exact casing of the Origin header in the response. The test design is particularly good - using lowercase in the configuration and uppercase in the request clearly demonstrates that case-insensitive matching works while preserving the original case in the response.

@sixcolors sixcolors changed the title 🧹 chore: Improve CORS middleware RFC compliance 🧹 chore: Improve CORS middleware response headers Jun 5, 2025
@gaby gaby moved this to In Progress in v3 Jun 5, 2025
@ReneWerner87 ReneWerner87 merged commit b29171c into main Jun 10, 2025
14 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in v3 Jun 10, 2025
@gaby gaby deleted the codex/2025-06-05-15-01-04 branch June 10, 2025 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants