server_helpers.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package app
  2. import (
  3. "bytes"
  4. "context"
  5. "net/http"
  6. "strings"
  7. opentracing "github.com/opentracing/opentracing-go"
  8. "github.com/ugorji/go/codec"
  9. "github.com/weaveworks/scope/report"
  10. log "github.com/sirupsen/logrus"
  11. )
  12. func respondWith(ctx context.Context, w http.ResponseWriter, code int, response interface{}) {
  13. if err, ok := response.(error); ok {
  14. log.Errorf("Error %d: %v", code, err)
  15. response = err.Error()
  16. } else if 500 <= code && code < 600 {
  17. log.Errorf("Non-error %d: %v", code, response)
  18. } else if ctx.Err() != nil {
  19. log.Debugf("Context error %v", ctx.Err())
  20. code = 499
  21. response = nil
  22. }
  23. if span := opentracing.SpanFromContext(ctx); span != nil {
  24. span.LogKV("response-code", code)
  25. }
  26. w.Header().Set("Content-Type", "application/json")
  27. w.Header().Add("Cache-Control", "no-cache")
  28. w.WriteHeader(code)
  29. encoder := codec.NewEncoder(w, &codec.JsonHandle{})
  30. if err := encoder.Encode(response); err != nil {
  31. log.Errorf("Error encoding response: %v", err)
  32. }
  33. }
  34. // Similar to the above function, but respect the request's Accept header.
  35. // Possibly we should do a complete parse of Accept, but for now just rudimentary check
  36. func respondWithReport(ctx context.Context, w http.ResponseWriter, req *http.Request, response report.Report) {
  37. accept := req.Header.Get("Accept")
  38. if strings.HasPrefix(accept, "application/msgpack") {
  39. buf := bytes.Buffer{}
  40. encoder := codec.NewEncoder(&buf, &codec.MsgpackHandle{})
  41. if err := encoder.Encode(response); err != nil {
  42. log.Errorf("Error encoding response: %v", err)
  43. }
  44. if span := opentracing.SpanFromContext(ctx); span != nil {
  45. span.LogKV("encoded-size", len(buf.Bytes()))
  46. }
  47. w.Header().Set("Content-Type", "application/msgpack")
  48. w.WriteHeader(http.StatusOK)
  49. w.Write(buf.Bytes())
  50. return
  51. }
  52. w.Header().Set("Content-Type", "application/json")
  53. w.Header().Add("Cache-Control", "no-cache")
  54. w.WriteHeader(http.StatusOK)
  55. encoder := codec.NewEncoder(w, &codec.JsonHandle{})
  56. if err := encoder.Encode(response); err != nil {
  57. log.Errorf("Error encoding response: %v", err)
  58. }
  59. }