No Description
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.

content.go 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // Package content contains routines for delivering content to the client.
  2. package phi
  3. import (
  4. "strings"
  5. "maze.io/phi.v1/header"
  6. )
  7. // RenderFunc writes content to the context.
  8. type RenderFunc func(ctx Context, v interface{}) error
  9. // Render method for the Renderer interface.
  10. func (f RenderFunc) Render(ctx Context, v interface{}) error {
  11. return f(ctx, v)
  12. }
  13. // Renderer implements a content writer.
  14. type Renderer interface {
  15. Render(Context, interface{}) error
  16. }
  17. // NegotiateContentType returns the best offered content type for the request's
  18. // Accept header. If two offers match with equal weight, then the more specific
  19. // offer is preferred. For example, text/* trumps */*. If two offers match
  20. // with equal weight and specificity, then the offer earlier in the list is
  21. // preferred. If no offers match, then defaultOffer is returned.
  22. func NegotiateContentType(ctx Context, offers []string, defaultOffer string) string {
  23. bestOffer := defaultOffer
  24. bestQ := -1.0
  25. bestWild := 3
  26. specs := header.ParseAccept(ctx.Request().Header, "Accept")
  27. for _, offer := range offers {
  28. for _, spec := range specs {
  29. switch {
  30. case spec.Q == 0.0:
  31. // ignore
  32. case spec.Q < bestQ:
  33. // better match found
  34. case spec.Value == "*/*":
  35. if spec.Q > bestQ || bestWild > 2 {
  36. bestQ = spec.Q
  37. bestWild = 2
  38. bestOffer = offer
  39. }
  40. case strings.HasSuffix(spec.Value, "/*"):
  41. if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) &&
  42. (spec.Q > bestQ || bestWild > 1) {
  43. bestQ = spec.Q
  44. bestWild = 1
  45. bestOffer = offer
  46. }
  47. default:
  48. if spec.Value == offer &&
  49. (spec.Q > bestQ || bestWild > 0) {
  50. bestQ = spec.Q
  51. bestWild = 0
  52. bestOffer = offer
  53. }
  54. }
  55. }
  56. }
  57. return bestOffer
  58. }