p_compressor.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package backends
  2. import (
  3. "bytes"
  4. "compress/zlib"
  5. "github.com/flashmob/go-guerrilla/envelope"
  6. "io"
  7. "sync"
  8. )
  9. // compressedData struct will be compressed using zlib when printed via fmt
  10. type compressor struct {
  11. extraHeaders []byte
  12. data *bytes.Buffer
  13. pool *sync.Pool
  14. }
  15. // newCompressedData returns a new CompressedData
  16. func newCompressor() *compressor {
  17. var p = sync.Pool{
  18. New: func() interface{} {
  19. var b bytes.Buffer
  20. return &b
  21. },
  22. }
  23. return &compressor{
  24. pool: &p,
  25. }
  26. }
  27. // Set the extraheaders and buffer of data to compress
  28. func (c *compressor) set(b []byte, d *bytes.Buffer) {
  29. c.extraHeaders = b
  30. c.data = d
  31. }
  32. // implement Stringer interface
  33. func (c *compressor) String() string {
  34. if c.data == nil {
  35. return ""
  36. }
  37. //borrow a buffer form the pool
  38. b := c.pool.Get().(*bytes.Buffer)
  39. // put back in the pool
  40. defer func() {
  41. b.Reset()
  42. c.pool.Put(b)
  43. }()
  44. var r *bytes.Reader
  45. w, _ := zlib.NewWriterLevel(b, zlib.BestSpeed)
  46. r = bytes.NewReader(c.extraHeaders)
  47. io.Copy(w, r)
  48. io.Copy(w, c.data)
  49. w.Close()
  50. return b.String()
  51. }
  52. // clear it, without clearing the pool
  53. func (c *compressor) clear() {
  54. c.extraHeaders = []byte{}
  55. c.data = nil
  56. }
  57. // The hasher decorator computes a hash of the email for each recipient
  58. // It appends the hashes to envelope's Hashes slice.
  59. func Compressor() Decorator {
  60. return func(c Processor) Processor {
  61. return ProcessorFunc(func(e *envelope.Envelope) (BackendResult, error) {
  62. compressor := newCompressor()
  63. compressor.set([]byte(e.DeliveryHeader), &e.Data)
  64. if e.Meta == nil {
  65. e.Meta = make(map[string]interface{})
  66. }
  67. e.Meta["zlib-compressor"] = compressor
  68. return c.Process(e)
  69. })
  70. }
  71. }