framework.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package framework
  2. import (
  3. "encoding/json"
  4. log "github.com/sirupsen/logrus"
  5. "io"
  6. "net"
  7. "net/http"
  8. "os"
  9. "path/filepath"
  10. "pmail/dto/parsemail"
  11. "pmail/utils/context"
  12. "time"
  13. )
  14. type EmailHook interface {
  15. // SendBefore 邮件发送前的数据
  16. SendBefore(ctx *context.Context, email *parsemail.Email)
  17. // SendAfter 邮件发送后的数据,err是每个收信服务器的错误信息
  18. SendAfter(ctx *context.Context, email *parsemail.Email, err map[string]error)
  19. // ReceiveParseBefore 接收到邮件,解析之前的原始数据
  20. ReceiveParseBefore(ctx *context.Context, email *[]byte)
  21. // ReceiveParseAfter 接收到邮件,解析之后的结构化数据
  22. ReceiveParseAfter(ctx *context.Context, email *parsemail.Email)
  23. }
  24. // HookDTO PMail 主程序和插件通信的结构体
  25. type HookDTO struct {
  26. ServerVersion string // 服务端程序版本
  27. Ctx *context.Context // 上下文
  28. Email *parsemail.Email // 邮件内容
  29. EmailByte *[]byte // 未解析前的文件内容
  30. ErrMap map[string]error // 错误信息
  31. }
  32. type Plugin struct {
  33. name string
  34. hook EmailHook
  35. }
  36. func CreatePlugin(name string, hook EmailHook) *Plugin {
  37. return &Plugin{
  38. name: name,
  39. hook: hook,
  40. }
  41. }
  42. func (p *Plugin) Run() {
  43. if len(os.Args) < 2 {
  44. panic("Command Params Error!")
  45. }
  46. mux := http.NewServeMux()
  47. mux.HandleFunc("/SendBefore", func(writer http.ResponseWriter, request *http.Request) {
  48. log.Debugf("[%s] SendBefore Start", p.name)
  49. var hookDTO HookDTO
  50. body, _ := io.ReadAll(request.Body)
  51. err := json.Unmarshal(body, &hookDTO)
  52. if err != nil {
  53. log.Errorf("params error %+v", err)
  54. return
  55. }
  56. p.hook.SendBefore(hookDTO.Ctx, hookDTO.Email)
  57. body, _ = json.Marshal(hookDTO)
  58. writer.Write(body)
  59. log.Debugf("[%s] SendBefore End", p.name)
  60. })
  61. mux.HandleFunc("/SendAfter", func(writer http.ResponseWriter, request *http.Request) {
  62. log.Debugf("[%s] SendAfter Start", p.name)
  63. var hookDTO HookDTO
  64. body, _ := io.ReadAll(request.Body)
  65. err := json.Unmarshal(body, &hookDTO)
  66. if err != nil {
  67. log.Errorf("params error %+v", err)
  68. return
  69. }
  70. p.hook.SendAfter(hookDTO.Ctx, hookDTO.Email, hookDTO.ErrMap)
  71. body, _ = json.Marshal(hookDTO)
  72. writer.Write(body)
  73. log.Debugf("[%s] SendAfter End", p.name)
  74. })
  75. mux.HandleFunc("/ReceiveParseBefore", func(writer http.ResponseWriter, request *http.Request) {
  76. log.Debugf("[%s] ReceiveParseBefore Start", p.name)
  77. var hookDTO HookDTO
  78. body, _ := io.ReadAll(request.Body)
  79. err := json.Unmarshal(body, &hookDTO)
  80. if err != nil {
  81. log.Errorf("params error %+v", err)
  82. return
  83. }
  84. p.hook.ReceiveParseBefore(hookDTO.Ctx, hookDTO.EmailByte)
  85. body, _ = json.Marshal(hookDTO)
  86. writer.Write(body)
  87. log.Debugf("[%s] ReceiveParseBefore End", p.name)
  88. })
  89. mux.HandleFunc("/ReceiveParseAfter", func(writer http.ResponseWriter, request *http.Request) {
  90. log.Debugf("[%s] ReceiveParseAfter Start", p.name)
  91. var hookDTO HookDTO
  92. body, _ := io.ReadAll(request.Body)
  93. err := json.Unmarshal(body, &hookDTO)
  94. if err != nil {
  95. log.Errorf("params error %+v", err)
  96. return
  97. }
  98. p.hook.ReceiveParseAfter(hookDTO.Ctx, hookDTO.Email)
  99. body, _ = json.Marshal(hookDTO)
  100. writer.Write(body)
  101. log.Debugf("[%s] ReceiveParseAfter End", p.name)
  102. })
  103. server := http.Server{
  104. ReadTimeout: 5 * time.Second,
  105. WriteTimeout: 5 * time.Second,
  106. Handler: mux,
  107. }
  108. unixListener, err := net.Listen("unix", getExePath()+"/"+os.Args[1])
  109. if err != nil {
  110. panic(err)
  111. }
  112. err = server.Serve(unixListener)
  113. if err != nil {
  114. panic(err)
  115. }
  116. }
  117. func getExePath() string {
  118. ex, err := os.Executable()
  119. if err != nil {
  120. panic(err)
  121. }
  122. exePath := filepath.Dir(ex)
  123. return exePath
  124. }