Skip to content

Commit

Permalink
♻️Refactor: Simplify content negotiation code (#2865)
Browse files Browse the repository at this point in the history
* refactor: Update to use fasthttp.VisitHeaderParams

The implementation of forEachParameter was upstreamed to fasthttp, so
use that version instead of maintaining our own.

* refactor: use map for header params

The previous implementation of content negotiation used some difficult
to understand techniques in order to reduce allocations, potentially
hurting maintainability. The more natural approach for storing and
comparing unordered media-type parameters is to utilize maps. While the
resulting code still isn't as simple as it could be, it's a step closer.

To reduce allocations, we use a sync.Pool. This actually reduces in fewer
allocations than before at 3 or more parameters. The net result is nearly
identical performance for zero parameters, almost-as-good performance for
1-2 parameters, and better performance for 3+ parameters.

---------

Co-authored-by: Jason McNeil <sixcolors@mac.com>
  • Loading branch information
nickajacks1 and sixcolors committed Feb 19, 2024
1 parent 4c68e02 commit 8ca562c
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 353 deletions.
8 changes: 4 additions & 4 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,22 @@ type ResFmt struct {

// Accepts checks if the specified extensions or content types are acceptable.
func (c *DefaultCtx) Accepts(offers ...string) string {
return getOffer(c.Get(HeaderAccept), acceptsOfferType, offers...)
return getOffer(c.fasthttp.Request.Header.Peek(HeaderAccept), acceptsOfferType, offers...)
}

// AcceptsCharsets checks if the specified charset is acceptable.
func (c *DefaultCtx) AcceptsCharsets(offers ...string) string {
return getOffer(c.Get(HeaderAcceptCharset), acceptsOffer, offers...)
return getOffer(c.fasthttp.Request.Header.Peek(HeaderAcceptCharset), acceptsOffer, offers...)
}

// AcceptsEncodings checks if the specified encoding is acceptable.
func (c *DefaultCtx) AcceptsEncodings(offers ...string) string {
return getOffer(c.Get(HeaderAcceptEncoding), acceptsOffer, offers...)
return getOffer(c.fasthttp.Request.Header.Peek(HeaderAcceptEncoding), acceptsOffer, offers...)
}

// AcceptsLanguages checks if the specified language is acceptable.
func (c *DefaultCtx) AcceptsLanguages(offers ...string) string {
return getOffer(c.Get(HeaderAcceptLanguage), acceptsOffer, offers...)
return getOffer(c.fasthttp.Request.Header.Peek(HeaderAcceptLanguage), acceptsOffer, offers...)
}

// App returns the *App reference to the instance of the Fiber application
Expand Down

0 comments on commit 8ca562c

Please sign in to comment.