Skip to content

🧹 chore: Fix AcceptsLanguages() RFC compliance#3672

Merged
ReneWerner87 merged 6 commits intomainfrom
2025-08-10-00-28-14
Aug 11, 2025
Merged

🧹 chore: Fix AcceptsLanguages() RFC compliance#3672
ReneWerner87 merged 6 commits intomainfrom
2025-08-10-00-28-14

Conversation

@gaby
Copy link
Member

@gaby gaby commented Aug 10, 2025

Summary

  • fix RFC compliance of AcceptsLanguages() by only allowing Basic Filtering as defined in RFC 4647
  • add extended Accept-Language filtering with wildcard subtags via AcceptsLanguagesExtended()

Related #3383

Copilot AI review requested due to automatic review settings August 10, 2025 00:28
@gaby gaby requested a review from a team as a code owner August 10, 2025 00:28
@gaby gaby added the codex label Aug 10, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 10, 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.

Warning

Rate limit exceeded

@gaby has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 47 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8b185b2 and 8626f4c.

📒 Files selected for processing (2)
  • ctx_test.go (2 hunks)
  • docs/whats_new.md (1 hunks)

Walkthrough

This change introduces RFC 4647 Extended Filtering support for language negotiation by adding new methods and helpers for extended language matching. It updates interface comments for clarity, expands test coverage for both basic and extended filtering, and documents the new functionality. Supported content types for auto-formatting are also updated in interface comments.

Changes

Cohort / File(s) Change Summary
Ctx Interface & Documentation
ctx_interface_gen.go, docs/api/ctx.md
Added AcceptsLanguagesExtended method for extended filtering; clarified that AcceptsLanguages uses RFC 4647 Basic Filtering; updated AutoFormat documentation to include new content types.
Request Handling
req.go, req_interface_gen.go
Implemented AcceptsLanguagesExtended in DefaultReq and interface; updated AcceptsLanguages to use basic filtering and clarified documentation.
Language Offer Helpers
helpers.go
Renamed and revised acceptsLanguageOffer to acceptsLanguageOfferBasic for stricter RFC 4647 Basic Filtering compliance; added acceptsLanguageOfferExtended for extended filtering.
Tests for Language Offer Helpers
helpers_test.go
Updated and expanded tests for both basic and extended filtering, including new negative and wildcard cases.
Ctx Language Acceptance Tests
ctx_test.go
Extended existing tests and added new tests for AcceptsLanguagesExtended, covering extended wildcard matching.
Response Interface Documentation
res_interface_gen.go
Updated AutoFormat method comment to include application/vnd.msgpack and application/cbor as supported content types.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server
    participant Req
    participant Helpers

    Client->>Server: HTTP Request with Accept-Language header
    Server->>Req: Call AcceptsLanguages(offers...) or AcceptsLanguagesExtended(offers...)
    Req->>Helpers: Use acceptsLanguageOfferBasic or acceptsLanguageOfferExtended
    Helpers-->>Req: Return matching offer (or empty string)
    Req-->>Server: Return selected language
    Server-->>Client: Response based on negotiated language
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

Suggested reviewers

  • sixcolors
  • efectn
  • ReneWerner87

Poem

A bunny hops through code so bright,
Adding wildcards to languages right.
Now “en-” and “-US” can play,
Thanks to RFCs guiding the way!
With new docs and tests in the mix,
This rabbit’s proud of these clever tricks.
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2025-08-10-00-28-14

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.
  • 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.

Support

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

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 generate unit tests to generate unit tests for 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.

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 @gaby, 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!

I've implemented enhancements to the Accept-Language header parsing, introducing support for RFC 4647 Extended Filtering and refining the existing basic filtering to correctly reject invalid language ranges. This change also updates the AutoFormat method's documentation to reflect additional supported content types.

Highlights

  • Improved Accept-Language Basic Filtering: The AcceptsLanguages method now strictly adheres to RFC 4647 Basic Filtering, which means it will reject language ranges that contain a wildcard (*) after a hyphen (e.g., en-*).
  • New Extended Language Filtering: I've introduced a new method, AcceptsLanguagesExtended, which implements RFC 4647 Extended Filtering. This allows for more flexible language range matching, including the use of wildcard subtags (e.g., en-* or *-US).
  • Updated Documentation: The API documentation for Ctx and Req interfaces, as well as the docs/api/ctx.md file, have been updated to reflect the new AcceptsLanguagesExtended method and clarify the behavior of AcceptsLanguages.
  • Expanded AutoFormat Support: The AutoFormat method's documentation has been updated to include application/vnd.msgpack and application/cbor as additional supported content types.
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 or fill out our survey to provide feedback.

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.

@gaby gaby added this to v3 Aug 10, 2025
@gaby gaby added this to the v3 milestone Aug 10, 2025
@gaby gaby moved this to In Progress in v3 Aug 10, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances Accept-Language header processing by implementing RFC 4647 Basic and Extended Filtering standards. It rejects invalid language ranges containing wildcards after hyphens and adds support for extended filtering with wildcard subtags.

  • Adds AcceptsLanguagesExtended() method implementing RFC 4647 Extended Filtering with wildcard support
  • Updates existing AcceptsLanguages() to use strict RFC 4647 Basic Filtering that rejects invalid wildcard patterns
  • Updates documentation to reflect expanded content type support and new language filtering methods

Reviewed Changes

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

Show a summary per file
File Description
helpers.go Implements Basic and Extended language filtering algorithms with wildcard validation
req.go Adds AcceptsLanguagesExtended method and updates AcceptsLanguages to use Basic filtering
helpers_test.go Updates and adds test cases for both Basic and Extended language filtering
ctx_test.go Adds comprehensive tests for the new AcceptsLanguagesExtended functionality
docs/api/ctx.md Documents the new AcceptsLanguagesExtended method with usage examples
*_interface_gen.go Updates generated interfaces with new method signatures and documentation

@codecov
Copy link

codecov bot commented Aug 10, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.90%. Comparing base (77667e5) to head (8626f4c).
⚠️ Report is 269 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3672      +/-   ##
==========================================
+ Coverage   91.85%   91.90%   +0.05%     
==========================================
  Files         113      113              
  Lines       11453    11492      +39     
==========================================
+ Hits        10520    10562      +42     
+ Misses        669      667       -2     
+ Partials      264      263       -1     
Flag Coverage Δ
unittests 91.90% <100.00%> (+0.05%) ⬆️

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

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

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

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces extended language filtering and rejects invalid language ranges. The core logic for extended filtering in helpers.go is not fully compliant with RFC 4647, as it allows prefix matching instead of requiring an equal number of subtags. I've identified this as a critical issue and provided a fix. Additionally, I've suggested improvements to the test structure for better maintainability and to the documentation for clarity.

@gaby gaby changed the title Reject invalid Accept-Language ranges and add extended filtering 🧹 chore: Fix AcceptsLanguages() RFC compliance. Add support for AcceptsLanguagesExtended() Aug 10, 2025
@gaby
Copy link
Member Author

gaby commented Aug 10, 2025

Working code-review comments now

@gaby gaby changed the title 🧹 chore: Fix AcceptsLanguages() RFC compliance. Add support for AcceptsLanguagesExtended() 🧹 chore: Fix AcceptsLanguages() RFC compliance Aug 10, 2025
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

♻️ Duplicate comments (3)
docs/api/ctx.md (1)

524-526: Clarify the AcceptsLanguagesExtended example with a concrete header and expected output

The current example “depends on extended ranges” is ambiguous. Replace it with a concrete Accept-Language header and expected result. Also consider adding a second example for a different wildcard pattern.

Apply this diff:

-  c.AcceptsLanguagesExtended("en-US", "fr-CA")
-  // depends on extended ranges in the request header
+  // Accept-Language: en-*, fr-CA
+  c.AcceptsLanguagesExtended("en-US", "de-DE") // "en-US"

Optional follow-ups (nearby in the same example block):

  • Example 2:
    • Header: “Accept-Language: *-US”
    • Call: c.AcceptsLanguagesExtended("en-US", "fr-CA") // "en-US"
  • Note invalid patterns:
    • Header: “Accept-Language: en-US-*” → c.AcceptsLanguagesExtended("en-US") // "" (invalid range is rejected)
ctx_test.go (1)

335-349: Refactor to table-driven tests for extended filtering scenarios

The assertions are correct and valuable. For maintainability and extensibility, convert to a table-driven test as previously suggested.

Here’s a table-driven variant:

func Test_Ctx_AcceptsLanguagesExtended(t *testing.T) {
	t.Parallel()
	app := New()
	c := app.AcquireCtx(&fasthttp.RequestCtx{})
	defer app.ReleaseCtx(c)

	testCases := []struct {
		name     string
		header   string
		offers   []string
		expected string
	}{
		{"wildcard suffix matches", "en-*", []string{"en-US"}, "en-US"},
		{"wildcard prefix matches", "*-US", []string{"en-US", "fr-CA"}, "en-US"},
		{"invalid trailing wildcard", "en-US-*", []string{"en-US"}, ""},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			c.Request().Header.Set(HeaderAcceptLanguage, tc.header)
			require.Equal(t, tc.expected, c.AcceptsLanguagesExtended(tc.offers...))
		})
	}
}
helpers.go (1)

204-209: Micro-opt: avoid Contains; use IndexByte (duplicate of existing feedback)

Use IndexByte to avoid extra allocs/scans and keep the intent explicit that only the presence of '' matters (spec == "" already handled).

- if strings.Contains(spec, "*") { // only "*" is allowed in Basic
+ if strings.IndexByte(spec, '*') != -1 { // only "*" is allowed in Basic
     return false
 }
🧹 Nitpick comments (3)
helpers_test.go (2)

66-73: Good Basic Filtering coverage; add a couple of edge cases

Looks correct and aligns with RFC 4647 Basic Filtering. Consider adding:

  • A positive case for the sole wildcard.
  • A negative selection case where a wildcard range is rejected under Basic but a concrete tag is still chosen.

You can extend this block like so:

 require.True(t, acceptsLanguageOfferBasic("EN", "en-us", nil))
 require.False(t, acceptsLanguageOfferBasic("en", "en_US", nil))
 require.Equal(t, "en-US", getOffer([]byte("fr-CA;q=0.8, en-US"), acceptsLanguageOfferBasic, "en-US", "fr-CA"))
 require.Equal(t, "", getOffer([]byte("xx"), acceptsLanguageOfferBasic, "en"))
 require.False(t, acceptsLanguageOfferBasic("en-*", "en-US", nil))
+// sole wildcard should match anything
+require.True(t, acceptsLanguageOfferBasic("*", "en-US", nil))
+// wildcard range is invalid in Basic; ensure negotiation still picks a concrete alternative
+require.Equal(t, "fr-CA", getOffer([]byte("en-*;q=1.0, fr-CA;q=0.8"), acceptsLanguageOfferBasic, "en-US", "fr-CA"))

74-79: Extended Filtering tests look solid; add a couple more to pin semantics

These cases validate wildcard-per-subtag and length rules well. Two more helpful assertions:

  • en-*-US should match en-Latn-US
  • *-US should not match en-Latn-US (position must match)

Suggested additions:

 require.True(t, acceptsLanguageOfferExtended("en-*", "en-US", nil))
 require.True(t, acceptsLanguageOfferExtended("*-US", "en-US", nil))
 require.False(t, acceptsLanguageOfferExtended("en-US-*", "en-US", nil))
 require.Equal(t, "en-US", getOffer([]byte("fr-CA;q=0.8, en-*"), acceptsLanguageOfferExtended, "en-US", "fr-CA"))
+require.True(t, acceptsLanguageOfferExtended("en-*-US", "en-Latn-US", nil))
+require.False(t, acceptsLanguageOfferExtended("*-US", "en-Latn-US", nil))
helpers.go (1)

218-240: Extended Filtering: correct per-subtag wildcard semantics

  • Permits wildcard as a full subtag that matches exactly one subtag.
  • Requires the offer to have at least as many subtags as the range.
  • Allows extra trailing subtags in the offer, which is correct for extended filtering.

Optional micro-optimization: fast-path exact match to skip splits.

 func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) bool {
+    // Fast path for exact case-insensitive match
+    if utils.EqualFold(spec, offer) {
+        return true
+    }
     if spec == "*" {
         return true
     }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9ca6ebd and 50a6135.

📒 Files selected for processing (8)
  • ctx_interface_gen.go (2 hunks)
  • ctx_test.go (2 hunks)
  • docs/api/ctx.md (2 hunks)
  • helpers.go (1 hunks)
  • helpers_test.go (1 hunks)
  • req.go (1 hunks)
  • req_interface_gen.go (1 hunks)
  • res_interface_gen.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**

📄 CodeRabbit Inference Engine (.github/copilot-instructions.md)

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

Files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • docs/api/ctx.md
  • ctx_test.go
📚 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:

  • docs/api/ctx.md
  • helpers_test.go
  • ctx_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:

  • helpers_test.go
  • ctx_test.go
📚 Learning: 2024-07-26T21:00:12.902Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • helpers_test.go
  • ctx_test.go
📚 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:

  • helpers_test.go
📚 Learning: 2024-11-29T12:37:27.581Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: app_test.go:893-895
Timestamp: 2024-11-29T12:37:27.581Z
Learning: In the `Test_App_ShutdownWithContext` function in `app_test.go`, the `clientDone` channel is used to synchronize the client's request completion before proceeding, eliminating the need for additional `time.Sleep` calls.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-10-16T12:12:30.506Z
Learnt from: gaby
PR: gofiber/fiber#3170
File: ctx_test.go:1721-1724
Timestamp: 2024-10-16T12:12:30.506Z
Learning: In the Go unit tests in `ctx_test.go`, it is acceptable to use invalid CIDR notation such as `"0.0.0.1/31junk"` for testing purposes.

Applied to files:

  • ctx_test.go
  • helpers.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: gaby
PR: gofiber/fiber#3056
File: middleware/encryptcookie/utils.go:22-25
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `encryptcookie_test.go` file contains unit tests that validate key lengths for both `EncryptCookie` and `DecryptCookie` functions, ensuring that invalid key lengths raise appropriate errors.

Applied to files:

  • ctx_test.go
📚 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:

  • ctx_test.go
⏰ 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). (1)
  • GitHub Check: Compare
🔇 Additional comments (9)
docs/api/ctx.md (1)

447-447: Signature addition looks good

The addition of AcceptsLanguagesExtended(offers ...string) string aligns with the new extended filtering behavior documented elsewhere in this page.

res_interface_gen.go (1)

47-47: AutoFormat comment update is correct and consistent

The additional content types (application/vnd.msgpack, application/cbor) match the implementation and tests for AutoFormat.

req_interface_gen.go (1)

19-24: Interface additions and RFC references are accurate

  • AcceptsLanguages explicitly documents RFC 4647 Basic Filtering.
  • AcceptsLanguagesExtended documents RFC 4647 Extended Filtering.
    These match the implementation and doc examples.
req.go (2)

52-57: Basic Filtering implementation swap is correct

Switching to acceptsLanguageOfferBasic enforces RFC 4647 Basic Filtering. Header extraction via joinHeaderValues remains consistent with other Accepts* methods.


59-64: Extended Filtering method is implemented as expected

AcceptsLanguagesExtended delegates to acceptsLanguageOfferExtended, enabling wildcard subtags in extended ranges, and aligns with the new tests and docs.

ctx_test.go (1)

318-323: Good coverage for invalid and wildcard ranges under Basic Filtering

  • “en_US” is correctly treated as invalid.
  • “en-*” correctly returns no match under Basic Filtering.
ctx_interface_gen.go (2)

162-167: Interface: Basic vs Extended filtering separation is clear

Adding AcceptsLanguagesExtended and clarifying AcceptsLanguages as Basic Filtering aligns with RFC 4647 and keeps API intent explicit. LGTM.


327-327: AutoFormat docs: content types list updated

Updated comment to include application/vnd.msgpack and application/cbor is accurate and consistent with Res docs. LGTM.

helpers.go (1)

197-216: Basic Filtering logic is correct and stricter on invalid wildcards

  • Sole "" accepted; any other occurrence of "" rejected.
  • Prefix match enforced at subtag boundary via hyphen.
  • Case-insensitive checks. This matches RFC 4647 Basic Filtering.

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

♻️ Duplicate comments (3)
helpers.go (1)

207-209: Nit: micro-optimization for asterisk detection

After the explicit check for spec == "*", use IndexByte for a tiny perf win and to avoid allocating in Contains.

-	if strings.Contains(spec, "*") { // only "*" is allowed in Basic
+	if strings.IndexByte(spec, '*') != -1 { // only "*" is allowed in Basic
 		return false
 	}
docs/api/ctx.md (1)

525-527: Provide a concrete example for Extended Filtering

“depends on extended ranges in the request header” is vague. Show an actual header and expected result to make usage obvious.

-  c.AcceptsLanguagesExtended("en-US", "fr-CA")
-  // depends on extended ranges in the request header
+  // Accept-Language: en-*, fr-CA
+  c.AcceptsLanguagesExtended("en-US", "de-DE") // "en-US"
ctx_test.go (1)

335-349: Extended filtering tests are correct; consider table-driven expansion

Current cases validate wildcard semantics and the “exactly one subtag” rule. To scale, refactor to a table-driven test and add a few canonical RFC scenarios:

  • "de-CH" matches "de-CH-1996"
  • "de-*-DE" matches "de-Latn-DE", not "de-DE"
  • "*-US" matches "en-US", "es-US" if offered
  • "en" matches "en-US" (range shorter than tag is allowed)

Example additional cases:

t.Run("extended_examples", func(t *testing.T) {
  app := New()
  c := app.AcquireCtx(&fasthttp.RequestCtx{})
  defer app.ReleaseCtx(c)

  cases := []struct{
    header string
    offers []string
    want   string
  }{
    {"de-CH", []string{"de-CH-1996", "de"}, "de-CH-1996"},
    {"de-*-DE", []string{"de-Latn-DE", "de-DE"}, "de-Latn-DE"},
    {"*-US", []string{"en-US", "es-US"}, "en-US"},
    {"en", []string{"en-US"}, "en-US"},
  }
  for _, tc := range cases {
    c.Request().Header.Set(HeaderAcceptLanguage, tc.header)
    require.Equal(t, tc.want, c.AcceptsLanguagesExtended(tc.offers...))
  }
})
🧹 Nitpick comments (4)
helpers.go (2)

200-202: Clarify comment: any non-standalone “*” is invalid in Basic

Current wording mentions “after a hyphen”; Basic filtering actually disallows “*” anywhere unless it's the entire range.

-// followed by a hyphen. The comparison is case-insensitive. Only a single "*"
-// as the entire range is allowed. Any "*" appearing after a hyphen renders the
-// range invalid and will not match.
+// followed by a hyphen (case-insensitive). Only a single "*" as the entire
+// range is allowed; any occurrence of "*" in any other position renders the
+// range invalid and will not match.

222-240: Extended filtering correctly allows wildcard subtags and extra trailing subtags

  • The “at least as many subtags as the range” guard (len(rs) > len(ts) ⇒ false) is correct.
  • Wildcard matches exactly one subtag; additional subtags in the offer are allowed, which aligns with RFC 4647 Extended Filtering (e.g., "en-*" matches "en-US-CA").

Consider adding tests that demonstrate:

  • "de-CH" matches "de-CH-1996" (extra subtag allowed).
  • "de-*-DE" matches "de-Latn-DE" but not "de-DE" (wildcard must match exactly one subtag).

Would you like me to open a follow-up PR adding these tests to helpers/ctx tests?

req.go (1)

59-64: Extended filtering API addition looks good; consider de-dup of header read

The new AcceptsLanguagesExtended maps cleanly to the extended matcher and mirrors the Basic variant. Implementation is solid.

To remove duplication and centralize future changes, consider a small helper:

// outside selected lines, for illustration only
func (r *DefaultReq) acceptsLang(offerFn func(string, string, headerParams) bool, offers ...string) string {
    header := joinHeaderValues(r.Request().Header.PeekAll(HeaderAcceptLanguage))
    return getOffer(header, offerFn, offers...)
}

func (r *DefaultReq) AcceptsLanguages(offers ...string) string {
    return r.acceptsLang(acceptsLanguageOfferBasic, offers...)
}
func (r *DefaultReq) AcceptsLanguagesExtended(offers ...string) string {
    return r.acceptsLang(acceptsLanguageOfferExtended, offers...)
}
helpers_test.go (1)

66-79: Good coverage split between Basic and Extended; add a few edge cases

The tests clearly differentiate RFC 4647 Basic and Extended behavior. Consider adding a couple of small cases to harden coverage:

  • Basic: reject other wildcard-subtag forms like "*-US".
  • Extended: reject underscore separators.
  • Extended: verify q-weight ordering when a wildcard competes with a specific tag.

You can append assertions like:

   // Accept-Language Basic Filtering
   require.True(t, acceptsLanguageOfferBasic("en", "en-US", nil))
   require.False(t, acceptsLanguageOfferBasic("en-US", "en", nil))
   require.True(t, acceptsLanguageOfferBasic("EN", "en-us", nil))
   require.False(t, acceptsLanguageOfferBasic("en", "en_US", nil))
   require.Equal(t, "en-US", getOffer([]byte("fr-CA;q=0.8, en-US"), acceptsLanguageOfferBasic, "en-US", "fr-CA"))
   require.Equal(t, "", getOffer([]byte("xx"), acceptsLanguageOfferBasic, "en"))
   require.False(t, acceptsLanguageOfferBasic("en-*", "en-US", nil))
+  require.False(t, acceptsLanguageOfferBasic("*-US", "en-US", nil))

   // Accept-Language Extended Filtering
   require.True(t, acceptsLanguageOfferExtended("en-*", "en-US", nil))
   require.True(t, acceptsLanguageOfferExtended("*-US", "en-US", nil))
   require.False(t, acceptsLanguageOfferExtended("en-US-*", "en-US", nil))
   require.Equal(t, "en-US", getOffer([]byte("fr-CA;q=0.8, en-*"), acceptsLanguageOfferExtended, "en-US", "fr-CA"))
+  require.False(t, acceptsLanguageOfferExtended("en_*", "en-US", nil))
+  require.Equal(t, "fr-CA", getOffer([]byte("en-*;q=0.5, fr-CA;q=0.9"), acceptsLanguageOfferExtended, "en-US", "fr-CA"))
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9ca6ebd and 50a6135.

📒 Files selected for processing (8)
  • ctx_interface_gen.go (2 hunks)
  • ctx_test.go (2 hunks)
  • docs/api/ctx.md (2 hunks)
  • helpers.go (1 hunks)
  • helpers_test.go (1 hunks)
  • req.go (1 hunks)
  • req_interface_gen.go (1 hunks)
  • res_interface_gen.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**

📄 CodeRabbit Inference Engine (.github/copilot-instructions.md)

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

Files:

  • docs/api/ctx.md
🧠 Learnings (13)
📓 Common learnings
Learnt from: ReneWerner87
PR: gofiber/fiber#0
File: :0-0
Timestamp: 2024-12-01T10:28:36.011Z
Learning: Feature request #3224 has been created to add support for square bracket notation and comma-separated values in multipart form data in Fiber, while maintaining binary data transfer capabilities. This would bring parity with the existing form-urlencoded functionality.
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

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

Applied to files:

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

Applied to files:

  • docs/api/ctx.md
  • ctx_test.go
📚 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:

  • docs/api/ctx.md
  • helpers_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:

  • helpers_test.go
  • ctx_test.go
📚 Learning: 2024-07-26T21:00:12.902Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • helpers_test.go
  • ctx_test.go
📚 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:

  • helpers_test.go
📚 Learning: 2024-10-16T12:12:30.506Z
Learnt from: gaby
PR: gofiber/fiber#3170
File: ctx_test.go:1721-1724
Timestamp: 2024-10-16T12:12:30.506Z
Learning: In the Go unit tests in `ctx_test.go`, it is acceptable to use invalid CIDR notation such as `"0.0.0.1/31junk"` for testing purposes.

Applied to files:

  • helpers.go
  • ctx_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: gaby
PR: gofiber/fiber#3056
File: middleware/encryptcookie/utils.go:22-25
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `encryptcookie_test.go` file contains unit tests that validate key lengths for both `EncryptCookie` and `DecryptCookie` functions, ensuring that invalid key lengths raise appropriate errors.

Applied to files:

  • ctx_test.go
📚 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:

  • ctx_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: gaby
PR: gofiber/fiber#3056
File: middleware/encryptcookie/utils.go:20-23
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests for key length enforcement in both `EncryptCookie` and `DecryptCookie` functions have been added to ensure robust validation and prevent potential runtime errors.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-11-29T12:37:27.581Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: app_test.go:893-895
Timestamp: 2024-11-29T12:37:27.581Z
Learning: In the `Test_App_ShutdownWithContext` function in `app_test.go`, the `clientDone` channel is used to synchronize the client's request completion before proceeding, eliminating the need for additional `time.Sleep` calls.

Applied to files:

  • ctx_test.go
🧬 Code Graph Analysis (1)
req.go (1)
constants.go (1)
  • HeaderAcceptLanguage (193-193)
🔇 Additional comments (7)
helpers.go (1)

197-216: Basic filtering logic is correct; rejects invalid post-hyphen wildcards as intended

  • Exact and prefix-with-hyphen matching aligns with RFC 4647 Basic Filtering.
  • Rejecting any "" other than a bare "" is correct for Accept-Language.
docs/api/ctx.md (1)

447-448: API surface documentation addition looks good

Adding AcceptsLanguagesExtended alongside AcceptsLanguages clearly distinguishes Basic vs Extended filtering.

res_interface_gen.go (1)

47-47: AutoFormat supported content types comment updated consistently

The additions of application/vnd.msgpack and application/cbor match the behavior elsewhere. Good consistency.

req_interface_gen.go (1)

19-24: Interfaces clearly separate Basic vs Extended filtering

Commenting the RFC variant used by each method removes ambiguity. LGTM.

ctx_test.go (1)

318-323: Basic filtering: invalid wildcard range rejected — good coverage

The test correctly asserts that "en-*" does not match under Basic filtering.

ctx_interface_gen.go (2)

162-167: AcceptsLanguagesExtended Generation Verified

Verified that AcceptsLanguagesExtended is present across the generated interfaces and implementation without any manual edits:

  • req_interface_gen.go (line 24)
  • ctx_interface_gen.go (line 167)
  • Implementation in DefaultReq (req.go:61)
  • Covered by Test_Ctx_AcceptsLanguagesExtended in ctx_test.go
  • Documented in docs/api/ctx.md

No further action needed; generator output is consistent.


325-328: No changes required: AutoFormat already supports MsgPack & CBOR
Implementation in res.go (around line 367) calls

accept := r.c.Accepts("html", "json", "txt", "xml", "msgpack", "cbor")
…
switch accept {
case "msgpack":
    return r.MsgPack(body)
case "cbor":
    return r.CBOR(body)
…
}

Tests in ctx_test.go cover both AutoFormat→MsgPack and →CBOR paths. The documentation matches the implementation.

@gaby
Copy link
Member Author

gaby commented Aug 10, 2025

/gemini summary

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 50a6135 and 8196825.

📒 Files selected for processing (3)
  • ctx_test.go (2 hunks)
  • helpers.go (1 hunks)
  • helpers_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • helpers_test.go
  • ctx_test.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ReneWerner87
PR: gofiber/fiber#0
File: :0-0
Timestamp: 2024-12-01T10:28:36.011Z
Learning: Feature request #3224 has been created to add support for square bracket notation and comma-separated values in multipart form data in Fiber, while maintaining binary data transfer capabilities. This would bring parity with the existing form-urlencoded functionality.
📚 Learning: 2024-10-16T12:12:30.506Z
Learnt from: gaby
PR: gofiber/fiber#3170
File: ctx_test.go:1721-1724
Timestamp: 2024-10-16T12:12:30.506Z
Learning: In the Go unit tests in `ctx_test.go`, it is acceptable to use invalid CIDR notation such as `"0.0.0.1/31junk"` for testing purposes.

Applied to files:

  • helpers.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: lint
  • GitHub Check: Analyse
  • GitHub Check: Compare
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: unit (1.24.x, macos-latest)
  • GitHub Check: repeated
🔇 Additional comments (1)
helpers.go (1)

197-216: Basic Filtering logic looks correct and RFC 4647-compliant

  • Only full-range "" is allowed; any other '' makes the range invalid.
  • Case-insensitive exact or prefix-with-hyphen match.

LGTM.

@gofiber gofiber deleted a comment from gemini-code-assist bot Aug 10, 2025
@gaby
Copy link
Member Author

gaby commented Aug 10, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors language negotiation to be more compliant with RFC 4647. It correctly separates Basic Filtering into AcceptsLanguages and introduces AcceptsLanguagesExtended for Extended Filtering. The changes are well-tested and documented. I have one suggestion to improve performance in the new acceptsLanguageOfferExtended function.

@gaby
Copy link
Member Author

gaby commented Aug 10, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request does a great job of improving RFC compliance for language tag matching by implementing Basic and Extended Filtering from RFC 4647. The introduction of AcceptsLanguagesExtended is a valuable addition, and the test coverage for both filtering methods is thorough. The documentation has also been updated clearly. I have one suggestion regarding performance in the new acceptsLanguageOfferExtended function to avoid memory allocations on a potentially hot path.

Copy link
Member

@ReneWerner87 ReneWerner87 left a comment

Choose a reason for hiding this comment

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

  • pls add something in the What´s new file

rest LGTM

@gaby
Copy link
Member Author

gaby commented Aug 11, 2025

  • pls add something in the What´s new file

rest LGTM

done

@ReneWerner87 ReneWerner87 merged commit 8112318 into main Aug 11, 2025
15 checks passed
@ReneWerner87 ReneWerner87 deleted the 2025-08-10-00-28-14 branch August 11, 2025 13:09
@github-project-automation github-project-automation bot moved this from In Progress to Done in v3 Aug 11, 2025
@gaby gaby added the 📜 RFC Compliance Feature, implementation, or contribution adheres to relevant RFC standards. label Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex 📜 RFC Compliance Feature, implementation, or contribution adheres to relevant RFC standards. 🧹 Updates v3

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants