mime.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package restful
  2. import (
  3. "strconv"
  4. "strings"
  5. )
  6. type mime struct {
  7. media string
  8. quality float64
  9. }
  10. // insertMime adds a mime to a list and keeps it sorted by quality.
  11. func insertMime(l []mime, e mime) []mime {
  12. for i, each := range l {
  13. // if current mime has lower quality then insert before
  14. if e.quality > each.quality {
  15. left := append([]mime{}, l[0:i]...)
  16. return append(append(left, e), l[i:]...)
  17. }
  18. }
  19. return append(l, e)
  20. }
  21. const qFactorWeightingKey = "q"
  22. // sortedMimes returns a list of mime sorted (desc) by its specified quality.
  23. // e.g. text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
  24. func sortedMimes(accept string) (sorted []mime) {
  25. for _, each := range strings.Split(accept, ",") {
  26. typeAndQuality := strings.Split(strings.Trim(each, " "), ";")
  27. if len(typeAndQuality) == 1 {
  28. sorted = insertMime(sorted, mime{typeAndQuality[0], 1.0})
  29. } else {
  30. // take factor
  31. qAndWeight := strings.Split(typeAndQuality[1], "=")
  32. if len(qAndWeight) == 2 && strings.Trim(qAndWeight[0], " ") == qFactorWeightingKey {
  33. f, err := strconv.ParseFloat(qAndWeight[1], 64)
  34. if err != nil {
  35. traceLogger.Printf("unable to parse quality in %s, %v", each, err)
  36. } else {
  37. sorted = insertMime(sorted, mime{typeAndQuality[0], f})
  38. }
  39. } else {
  40. sorted = insertMime(sorted, mime{typeAndQuality[0], 1.0})
  41. }
  42. }
  43. }
  44. return
  45. }