本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.7KB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file or at
  5. // https://developers.google.com/open-source/licenses/bsd.
  6. // this file was taken from the github.com/golang/gddo repository
  7. package middleware
  8. import (
  9. "net/http"
  10. "strings"
  11. "github.com/go-openapi/runtime/middleware/header"
  12. )
  13. // NegotiateContentEncoding returns the best offered content encoding for the
  14. // request's Accept-Encoding header. If two offers match with equal weight and
  15. // then the offer earlier in the list is preferred. If no offers are
  16. // acceptable, then "" is returned.
  17. func NegotiateContentEncoding(r *http.Request, offers []string) string {
  18. bestOffer := "identity"
  19. bestQ := -1.0
  20. specs := header.ParseAccept(r.Header, "Accept-Encoding")
  21. for _, offer := range offers {
  22. for _, spec := range specs {
  23. if spec.Q > bestQ &&
  24. (spec.Value == "*" || spec.Value == offer) {
  25. bestQ = spec.Q
  26. bestOffer = offer
  27. }
  28. }
  29. }
  30. if bestQ == 0 {
  31. bestOffer = ""
  32. }
  33. return bestOffer
  34. }
  35. // NegotiateContentType returns the best offered content type for the request's
  36. // Accept header. If two offers match with equal weight, then the more specific
  37. // offer is preferred. For example, text/* trumps */*. If two offers match
  38. // with equal weight and specificity, then the offer earlier in the list is
  39. // preferred. If no offers match, then defaultOffer is returned.
  40. func NegotiateContentType(r *http.Request, offers []string, defaultOffer string) string {
  41. bestOffer := defaultOffer
  42. bestQ := -1.0
  43. bestWild := 3
  44. specs := header.ParseAccept(r.Header, "Accept")
  45. for _, rawOffer := range offers {
  46. offer := normalizeOffer(rawOffer)
  47. // No Accept header: just return the first offer.
  48. if len(specs) == 0 {
  49. return rawOffer
  50. }
  51. for _, spec := range specs {
  52. switch {
  53. case spec.Q == 0.0:
  54. // ignore
  55. case spec.Q < bestQ:
  56. // better match found
  57. case spec.Value == "*/*":
  58. if spec.Q > bestQ || bestWild > 2 {
  59. bestQ = spec.Q
  60. bestWild = 2
  61. bestOffer = rawOffer
  62. }
  63. case strings.HasSuffix(spec.Value, "/*"):
  64. if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) &&
  65. (spec.Q > bestQ || bestWild > 1) {
  66. bestQ = spec.Q
  67. bestWild = 1
  68. bestOffer = rawOffer
  69. }
  70. default:
  71. if spec.Value == offer &&
  72. (spec.Q > bestQ || bestWild > 0) {
  73. bestQ = spec.Q
  74. bestWild = 0
  75. bestOffer = rawOffer
  76. }
  77. }
  78. }
  79. }
  80. return bestOffer
  81. }
  82. func normalizeOffers(orig []string) (norm []string) {
  83. for _, o := range orig {
  84. norm = append(norm, normalizeOffer(o))
  85. }
  86. return
  87. }
  88. func normalizeOffer(orig string) string {
  89. return strings.SplitN(orig, ";", 2)[0]
  90. }
上海开阖软件有限公司 沪ICP备12045867号-1