mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
* Ran gopls modernize to fix everything go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./... * Override rules_go provided dependency for golang.org/x/tools to v0.38.0. To update this, checked out rules_go, then ran `bazel run //go/tools/releaser -- upgrade-dep -mirror=false org_golang_x_tools` and copied the patches. * Fix buildtag violations and ignore buildtag violations in external * Introduce modernize analyzer package. * Add modernize "any" analyzer. * Fix violations of any analyzer * Add modernize "appendclipped" analyzer. * Fix violations of appendclipped * Add modernize "bloop" analyzer. * Add modernize "fmtappendf" analyzer. * Add modernize "forvar" analyzer. * Add modernize "mapsloop" analyzer. * Add modernize "minmax" analyzer. * Fix violations of minmax analyzer * Add modernize "omitzero" analyzer. * Add modernize "rangeint" analyzer. * Fix violations of rangeint. * Add modernize "reflecttypefor" analyzer. * Fix violations of reflecttypefor analyzer. * Add modernize "slicescontains" analyzer. * Add modernize "slicessort" analyzer. * Add modernize "slicesdelete" analyzer. This is disabled by default for now. See https://go.dev/issue/73686. * Add modernize "stringscutprefix" analyzer. * Add modernize "stringsbuilder" analyzer. * Fix violations of stringsbuilder analyzer. * Add modernize "stringsseq" analyzer. * Add modernize "testingcontext" analyzer. * Add modernize "waitgroup" analyzer. * Changelog fragment * gofmt * gazelle * Add modernize "newexpr" analyzer. * Disable newexpr until go1.26 * Add more details in WORKSPACE on how to update the override * @nalepae feedback on min() * gofmt * Fix violations of forvar
123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
package apiutil
|
||
|
||
import (
|
||
"mime"
|
||
"sort"
|
||
"strconv"
|
||
"strings"
|
||
|
||
log "github.com/sirupsen/logrus"
|
||
)
|
||
|
||
type mediaRange struct {
|
||
mt string // canonicalised media‑type, e.g. "application/json"
|
||
q float64 // quality factor (0‑1)
|
||
raw string // original string – useful for logging/debugging
|
||
spec int // 2=exact, 1=type/*, 0=*/*
|
||
}
|
||
|
||
func parseMediaRange(field string) (mediaRange, bool) {
|
||
field = strings.TrimSpace(field)
|
||
|
||
mt, params, err := mime.ParseMediaType(field)
|
||
if err != nil {
|
||
log.WithError(err).Debug("Failed to parse header field")
|
||
return mediaRange{}, false
|
||
}
|
||
|
||
r := mediaRange{mt: mt, q: 1, spec: 2, raw: field}
|
||
|
||
if qs, ok := params["q"]; ok {
|
||
v, err := strconv.ParseFloat(qs, 64)
|
||
if err != nil || v < 0 || v > 1 {
|
||
log.WithField("q", qs).Debug("Invalid quality factor (0‑1)")
|
||
return mediaRange{}, false // skip invalid entry
|
||
}
|
||
r.q = v
|
||
}
|
||
|
||
switch {
|
||
case mt == "*/*":
|
||
r.spec = 0
|
||
case strings.HasSuffix(mt, "/*"):
|
||
r.spec = 1
|
||
}
|
||
return r, true
|
||
}
|
||
|
||
func hasExplicitQ(r mediaRange) bool {
|
||
return strings.Contains(strings.ToLower(r.raw), ";q=")
|
||
}
|
||
|
||
// ParseAccept returns media ranges sorted by q (desc) then specificity.
|
||
func ParseAccept(header string) []mediaRange {
|
||
if header == "" {
|
||
return []mediaRange{{mt: "*/*", q: 1, spec: 0, raw: "*/*"}}
|
||
}
|
||
|
||
var out []mediaRange
|
||
for field := range strings.SplitSeq(header, ",") {
|
||
if r, ok := parseMediaRange(field); ok {
|
||
out = append(out, r)
|
||
}
|
||
}
|
||
|
||
sort.SliceStable(out, func(i, j int) bool {
|
||
ei, ej := hasExplicitQ(out[i]), hasExplicitQ(out[j])
|
||
if ei != ej {
|
||
return ei // explicit beats implicit
|
||
}
|
||
if out[i].q != out[j].q {
|
||
return out[i].q > out[j].q
|
||
}
|
||
return out[i].spec > out[j].spec
|
||
})
|
||
return out
|
||
}
|
||
|
||
// Matches reports whether content type is acceptable per the header.
|
||
func Matches(header, ct string) bool {
|
||
for _, r := range ParseAccept(header) {
|
||
switch {
|
||
case r.q == 0:
|
||
continue
|
||
case r.mt == "*/*":
|
||
return true
|
||
case strings.HasSuffix(r.mt, "/*"):
|
||
if strings.HasPrefix(ct, r.mt[:len(r.mt)-1]) {
|
||
return true
|
||
}
|
||
case r.mt == ct:
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// Negotiate selects the best server type according to the header.
|
||
// Returns the chosen type and true, or "", false when nothing matches.
|
||
func Negotiate(header string, serverTypes []string) (string, bool) {
|
||
for _, r := range ParseAccept(header) {
|
||
if r.q == 0 {
|
||
continue
|
||
}
|
||
for _, s := range serverTypes {
|
||
if Matches(r.mt, s) {
|
||
return s, true
|
||
}
|
||
}
|
||
}
|
||
return "", false
|
||
}
|
||
|
||
// PrimaryAcceptMatches only checks if the first accept matches
|
||
func PrimaryAcceptMatches(header, produced string) bool {
|
||
for _, r := range ParseAccept(header) {
|
||
if r.q == 0 {
|
||
continue // explicitly unacceptable – skip
|
||
}
|
||
return Matches(r.mt, produced)
|
||
}
|
||
return false
|
||
}
|