control.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package cache
  2. import (
  3. fmt "fmt"
  4. "net/http"
  5. "sync"
  6. "time"
  7. bm "go-common/library/net/http/blademaster"
  8. "go-common/library/net/http/blademaster/middleware/cache/store"
  9. )
  10. const (
  11. _maxMaxAge = 60 * 5 // 5 minutes
  12. )
  13. // Control is used to work as client side cache orchestrator
  14. type Control struct {
  15. MaxAge int32
  16. pool sync.Pool
  17. }
  18. type controlWriter struct {
  19. *Control
  20. ctx *bm.Context
  21. response http.ResponseWriter
  22. }
  23. var _ http.ResponseWriter = &controlWriter{}
  24. // NewControl will create a new control cache struct
  25. func NewControl(maxAge int32) *Control {
  26. if maxAge > _maxMaxAge {
  27. panic("MaxAge should be less than 300 seconds")
  28. }
  29. ctl := &Control{
  30. MaxAge: maxAge,
  31. }
  32. ctl.pool.New = func() interface{} {
  33. return &controlWriter{}
  34. }
  35. return ctl
  36. }
  37. // Key method is not needed in this situation
  38. func (ctl *Control) Key(ctx *bm.Context) string { return "" }
  39. // Handler is used to execute cache service
  40. func (ctl *Control) Handler(_ store.Store) bm.HandlerFunc {
  41. return func(ctx *bm.Context) {
  42. writer := ctl.pool.Get().(*controlWriter)
  43. writer.Control = ctl
  44. writer.ctx = ctx
  45. writer.response = ctx.Writer
  46. ctx.Writer = writer
  47. ctx.Next()
  48. ctl.pool.Put(writer)
  49. }
  50. }
  51. func (w *controlWriter) Header() http.Header { return w.response.Header() }
  52. func (w *controlWriter) Write(data []byte) (size int, err error) { return w.response.Write(data) }
  53. func (w *controlWriter) WriteHeader(code int) {
  54. // do not inject header if this is an error response
  55. if w.ctx.Error == nil {
  56. headers := w.Header()
  57. headers.Set("Expires", time.Now().UTC().Add(time.Duration(w.MaxAge)*time.Second).Format(http.TimeFormat))
  58. headers.Set("Cache-Control", fmt.Sprintf("max-age=%d", w.MaxAge))
  59. }
  60. w.response.WriteHeader(code)
  61. }