Skip to content

🔥 feat: Add HTTP QUERY method support (RFC 10008)#4436

Merged
ReneWerner87 merged 14 commits into
gofiber:mainfrom
neko-sc:feat/http-query-method
Jun 25, 2026
Merged

🔥 feat: Add HTTP QUERY method support (RFC 10008)#4436
ReneWerner87 merged 14 commits into
gofiber:mainfrom
neko-sc:feat/http-query-method

Conversation

@nekoworks-magic

Copy link
Copy Markdown
Contributor

Description

Add first-class support for the HTTP QUERY method (RFC 10008). QUERY is safe and idempotent like GET, but allows request bodies for complex queries.

Changes introduced

  • MethodQuery constant, methodQuery iota, DefaultMethods entry
  • Query() on Router, Register interfaces and all implementations (App, Group, Registering, domainRouter, domainRegistering)
  • Request.Query() client shorthand
  • IsMethodSafe returns true for QUERY
  • CSRF safe-method branch includes QUERY
  • CORS default AllowMethods includes QUERY
  • Logger color: shares Cyan with GET

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist

  • Conducted a self-review of the code and provided comments for complex or critical parts.
  • Updated the documentation in the /docs/ directory for Fiber's documentation.
  • Added or updated unit tests to validate the effectiveness of the changes or new features.
  • Ensured that new and existing unit tests pass locally with the changes.
  • Verified that any new dependencies are essential and have been agreed upon by the maintainers/community.
  • Aimed for optimal performance with minimal allocations in the new code.

Register QUERY as a first-class HTTP method alongside the existing nine.
QUERY is safe and idempotent, allowing request bodies for complex queries
without the URL-length constraints of GET.

- Add MethodQuery constant and methodQuery iota
- Add Query() to Router, Register interfaces and all implementations
  (App, Group, Registering, domainRouter, domainRegistering)
- Add Query() client shorthand on Request
- Mark QUERY as safe in IsMethodSafe (idempotent follows from safe)
- Include QUERY in CSRF safe-method branch (no token required)
- Include QUERY in CORS default AllowMethods
- Add QUERY color to logger middleware
- Update constants documentation
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds the QUERY HTTP method as a first-class method in Fiber. A MethodQuery = "QUERY" constant is introduced, the method is registered in DefaultMethods, Router and Register interfaces gain Query(...) signatures, and all concrete implementations (App, Group, domainRouter, domainRegistering, Registering) implement the method. IsMethodSafe and methodInt are updated to classify it correctly. CORS, CSRF, cache, and logger middleware are updated, as is the HTTP client with comprehensive test coverage.

Changes

QUERY HTTP Method Integration

Layer / File(s) Summary
Constant definition and interface contracts
constants.go, app.go, router.go, register.go
Defines MethodQuery = "QUERY" constant, adds internal methodQuery enum between PATCH and TRACE, includes MethodQuery in DefaultMethods, and extends Router and Register public interfaces with Query method signature.
Routing implementations across App, Group, Domain, and Register
app.go, group.go, domain.go, register.go
Implements Query(path, handler, ...handlers) on App, Group, domainRouter, domainRegistering, and Registering, all delegating to their respective Add helpers with MethodQuery.
Method classification and middleware integration
helpers.go, middleware/cors/config.go, middleware/csrf/csrf.go, middleware/logger/utils.go, middleware/cache/cache.go
Maps MethodQuery in methodInt, classifies it as safe/idempotent in IsMethodSafe, adds it to CORS default AllowMethods, treats it as safe in CSRF validation, maps it to cyan color in logger, and includes SHA-256 request-body hashing in cache key generation for QUERY requests.
HTTP client Query method
client/request.go
Adds Request.Query(url) convenience method that sets the request URL, assigns fiber.MethodQuery, and delegates to Send().
Tests and documentation
app_test.go, client/request_test.go, domain_test.go, middleware/cors/cors_test.go, middleware/cache/cache_test.go, docs/api/constants.md, docs/partials/routing/handler.md, docs/client/request.md
Adds route registration tests for Query across App, Group, domain routing, and route chains; extends CORS test matrix to include QUERY in Access-Control-Allow-Methods expectations; adds HTTP client Query request test; introduces cache behavior test and benchmark for MethodQuery with body-based key variation; and updates constants, routing handler, and client request documentation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • gofiber/fiber#4224: Both PRs modify cache key generation in middleware/cache/cache.go's defaultKeyGenerator—this PR adds MethodQuery request-body hashing while the related PR restructures the overall key composition logic.

Suggested reviewers

  • sixcolors
  • gaby
  • efectn
  • ReneWerner87

Poem

🐇 Hop, hop, a new method appears!
QUERY joins GET and POST with cheers.
Safe and idempotent, cyan and bright,
CORS and CSRF treat it right.
The cache key hops along its way —
A brand-new verb has come to stay! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding HTTP QUERY method support (RFC 10008) to Fiber.
Description check ✅ Passed The description covers key areas from the template: purpose (RFC 10008 support), changes introduced (MethodQuery constant, Query() methods, middleware integration, etc.), type of change (new feature), and most checklist items completed with evidence of testing and documentation updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ReneWerner87 ReneWerner87 added this to v3 Jun 18, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Jun 18, 2026
@nekoworks-magic

nekoworks-magic commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

I intentionally excluded cache middleware since its signature cannot handle body, maybe some kind of change needed for this?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
middleware/cors/cors_test.go (1)

645-645: ⚡ Quick win

Add a preflight case where Access-Control-Request-Method is QUERY.

These assertions now expect QUERY, but the looped methods table still omits fiber.MethodQuery, so the request-type path for QUERY itself isn’t exercised. Add it to the table to close the test gap.

Also applies to: 679-679

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@middleware/cors/cors_test.go` at line 645, The test assertions at lines 645
and 679 now expect QUERY to be included in the Access-Control-Allow-Methods
header, but the methods table being looped in the preflight test case does not
include fiber.MethodQuery. Add fiber.MethodQuery to the methods table in the
test to ensure the preflight request path for QUERY method is actually exercised
and tested, closing the gap between the assertion expectations and the actual
test coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@middleware/cors/cors_test.go`:
- Line 645: The test assertions at lines 645 and 679 now expect QUERY to be
included in the Access-Control-Allow-Methods header, but the methods table being
looped in the preflight test case does not include fiber.MethodQuery. Add
fiber.MethodQuery to the methods table in the test to ensure the preflight
request path for QUERY method is actually exercised and tested, closing the gap
between the assertion expectations and the actual test coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 364fe260-35d6-4f4f-849e-9255b8bde8c9

📥 Commits

Reviewing files that changed from the base of the PR and between 1148bb6 and 49d45f1.

📒 Files selected for processing (16)
  • app.go
  • app_test.go
  • client/request.go
  • constants.go
  • docs/api/constants.md
  • docs/client/request.md
  • docs/partials/routing/handler.md
  • domain.go
  • group.go
  • helpers.go
  • middleware/cors/config.go
  • middleware/cors/cors_test.go
  • middleware/csrf/csrf.go
  • middleware/logger/utils.go
  • register.go
  • router.go

@ReneWerner87

Copy link
Copy Markdown
Member

I intentionally excluded cache middleware since its signature cannot handle body, maybe some kind of change needed for this?

Yes, we should add that, since the QUERY explicitly states that it can be cached.

@nekoworks-magic

nekoworks-magic commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Small changes needed but need to decide how can we generate cache key in defaultKeyGenerator for QUERY request.
I can think adding hash of request body to current result, but need to decide,

  • What hash would be used (blake2b can be used without adding deps and have good performance)
  • How can keep performance great
    etc.

@gaby gaby changed the title 🔥 Feature: Add HTTP QUERY method support (RFC 10008) 🔥 feat: Add HTTP QUERY method support (RFC 10008) Jun 18, 2026
@gaby

gaby commented Jun 18, 2026

Copy link
Copy Markdown
Member
  • Unit-tests missing
  • Documentation missing

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.60%. Comparing base (db4c533) to head (fc3d025).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
helpers.go 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4436      +/-   ##
==========================================
+ Coverage   91.58%   91.60%   +0.02%     
==========================================
  Files         134      134              
  Lines       13548    13513      -35     
==========================================
- Hits        12408    12379      -29     
+ Misses        725      723       -2     
+ Partials      415      411       -4     
Flag Coverage Δ
unittests 91.60% <95.00%> (+0.02%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

@nekoworks-magic

Copy link
Copy Markdown
Contributor Author
  • Unit-tests missing
  • Documentation missing

@gaby What documentation and units should be added?
I do not know what documentation needed beside of already edited ones.

@gaby

gaby commented Jun 18, 2026

Copy link
Copy Markdown
Member

Codecov Report

❌ Patch coverage is 35.29412% with 11 lines in your changes missing coverage. Please review. ✅ Project coverage is 91.52%. Comparing base (1148bb6) to head (49d45f1).

Files with missing lines Patch % Lines
domain.go 0.00% 4 Missing ⚠️
client/request.go 0.00% 2 Missing ⚠️
group.go 0.00% 2 Missing ⚠️
register.go 0.00% 2 Missing ⚠️
helpers.go 66.66% 1 Missing ⚠️
Additional details and impacted files
☔ View full report in Codecov by Harness. 📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:

@nekoworks-magic ^ Coverage report

@gaby

gaby commented Jun 18, 2026

Copy link
Copy Markdown
Member

Small changes needed but need to decide how can we generate cache key in defaultKeyGenerator for QUERY request. I can think adding hash of request body to current result, but need to decide,

  • What hash would be used (blake2b can be used without adding deps and have good performance)
  • How can keep performance great
    etc.

That would be a bad idea, a large body would take a while to hash and can be used to cause DoS.

@nekoworks-magic

Copy link
Copy Markdown
Contributor Author

Then we can do:

  • Do not cache QUERY by default and make user tick the option if they need it
  • Set max size of hashable request body

@gaby

gaby commented Jun 19, 2026

Copy link
Copy Markdown
Member

@nekoworks-magic Shouldnt it do the same as POST? What does the RFC say?

@nekoworks-magic

Copy link
Copy Markdown
Contributor Author

RFC says:
“The response to a QUERY method is cacheable; a cache MAY use it to satisfy subsequent QUERY requests.
The cache key for a QUERY request MUST incorporate the request content and related metadata.
Caching QUERY method responses is inherently more complex than caching responses to GET, as the request content must be read completely in order to determine the cache key.”

So no, it is different from POST. When caching QUERY responses, the cache key MUST include the request content, as required by the RFC.

RFC 10008 requires the cache key to incorporate request content for
QUERY responses. Hash the body with SHA-256 in defaultKeyGenerator
when the method is QUERY. QUERY is not in the default Methods list,
so this is opt-in only.
@nekoworks-magic

Copy link
Copy Markdown
Contributor Author

I added draft implementation.

@gaby

gaby commented Jun 20, 2026

Copy link
Copy Markdown
Member

I added draft implementation.

@nekoworks-magic I think we got to use a pool, similar to how makeHashAuthFunc works.

Cover cache behavior when the HTTP QUERY method (RFC 10008) is in the
Methods allow-list: same body → hit, different body → miss, empty body,
and default Methods exclusion. Add a benchmark for the QUERY cache path.
@nekoworks-magic

Copy link
Copy Markdown
Contributor Author

Did some benchmark and profiling, then I found current implementation does not allocate anything, and adding pool actually makes things slower.
Also I added some tests and benchmarks relevant to cache middleware.

gaby commented Jun 21, 2026

Copy link
Copy Markdown
Member

Review — HTTP QUERY method (RFC 10008)

I went through the full diff and the discussion thread. Overall this is a clean, well-tested addition: the new method is wired consistently through constants.go, the Router/Register interfaces and every implementation (App, Group, Registering, domainRouter, domainRegistering), the client shorthand, and the relevant middleware. The methodQuery iota and DefaultMethods entry are appended in the same position, so the index mapping stays consistent, and methodInt handles the new constant. Method classification is correct per RFC 10008 — QUERY is safe + idempotent, so IsMethodSafe (and transitively IsMethodIdempotent) returning true and CSRF treating it as a non-mutating method are both right.

A few things worth confirming before merge:

1. Cache body hashing — DoS surface (the open thread)

The cache key now does sha256.Sum256(c.Request().Body()) for QUERY. This is correctly opt-in: default cfg.Methods is {GET, HEAD}, and the body branch only runs after the slices.Contains(cfg.Methods, …) gate, so the default config never hashes anything. That addresses the "don't enable by default" concern from the thread.

However, @gaby's original point about hashing large bodies isn't fully resolved: once a user adds QUERY to Methods, every QUERY request pays an O(body-size) hash pass before the cache lookup, with no upper bound. The body is already buffered by fasthttp and SHA-256 is fast, so this is a constant-factor cost rather than an amplification bug, but it's still attacker-controlled CPU work. Two reasonable options (both raised earlier in the thread):

  • Add a configurable max-hashable-body-size; treat over-limit requests as uncacheable (cacheUnreachable) rather than hashing.
  • Or, at minimum, document on the Methods field that enabling QUERY caching hashes the full request body on every request.

Not a blocker given the opt-in gating, but I'd lean toward documenting it explicitly.

2. Cache key — no method component (verify, not a bug here)

defaultKeyGenerator doesn't include the HTTP method in the key. With Methods: {GET, QUERY} on the same path this happens to be safe because QUERY appends the |b=<hash> segment that GET never has, so keys can't collide. Just flagging that the safety here is incidental to the |b= suffix rather than an explicit method dimension — worth a comment so a future refactor doesn't drop it.

3. CORS default change (intentional behavior change)

Adding QUERY to the default AllowMethods means every CORS-enabled app now advertises QUERY in preflight Access-Control-Allow-Methods by default, even when no QUERY routes exist. Harmless and reasonable for v3, but it is a default-behavior change — make sure it's called out in the v3 changelog/migration notes.

Minor

  • Logger color: GET and QUERY now share Cyan, so the two are visually indistinguishable in logs. Cosmetic — a distinct color would be friendlier, but fine as-is.
  • Coverage: Codecov flags the MethodQuery arm of methodInt in helpers.go as uncovered. A tiny assertion (e.g. via the existing method-mapping tests) would close that.

Nice work overall — the test coverage across app/group/domain/route-chain/client and the cache scenarios (same body hit, different body miss, empty body, not-in-Methods) is thorough.


Generated by Claude Code

@gaby

gaby commented Jun 21, 2026

Copy link
Copy Markdown
Member
  • BodyLimit is applied at the Fasthttp level, so that's fine.
  • The change to CORS, i'm not sure. Thoughts @sixcolors ?

@gaby gaby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One performance suggestion on the QUERY cache-key body hashing — details inline. The current code is correct; this just keeps SHA-256 off the hot path for typical (small) request bodies by reusing the existing boundKeySegment helper.


Generated by Claude Code

Comment thread middleware/cache/cache.go Outdated

@gaby gaby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, only thing left is the CORS change. Pending @sixcolors review.

@gaby

gaby commented Jun 23, 2026

Copy link
Copy Markdown
Member

This is what the RFC says about CORS:

A QUERY request from user agents implementing Cross-Origin Resource Sharing (CORS) will require a "preflight" request, as QUERY does not belong to the set of CORS-safelisted methods (see [FETCH]).

@gaby gaby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One optional test suggestion on the CORS side: a small dedicated regression test documenting RFC 10008's preflight requirement for QUERY (it's not CORS-safelisted). Details inline — no production change needed, the middleware already behaves correctly.


Generated by Claude Code

Comment thread middleware/cors/cors_test.go
@ReneWerner87
ReneWerner87 merged commit 9df17c3 into gofiber:main Jun 25, 2026
18 checks passed
@welcome

welcome Bot commented Jun 25, 2026

Copy link
Copy Markdown

Congrats on merging your first pull request! 🎉 We here at Fiber are proud of you! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@github-project-automation github-project-automation Bot moved this to Done in v3 Jun 25, 2026
ReneWerner87 added a commit that referenced this pull request Jun 25, 2026
feat: complete HTTP QUERY method support (follow-up to #4436)
@ReneWerner87 ReneWerner87 modified the milestones: v3, v3.4.0 Jul 2, 2026
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