From 6280264435f84df4ea3f00dfc720dc70cbdf5a99 Mon Sep 17 00:00:00 2001 From: Jinnrry Date: Sat, 20 Apr 2024 09:13:53 +0800 Subject: [PATCH] bug fix (#106) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复并非写map造成的panic Co-authored-by: jinnrry --- server/controllers/email/send.go | 6 +----- server/hooks/base.go | 15 ++------------- server/hooks/framework/framework.go | 10 +++++----- server/models/email.go | 2 +- server/smtp_server/read_content.go | 19 +++---------------- server/utils/send/send.go | 18 +++++++++++------- 6 files changed, 23 insertions(+), 47 deletions(-) diff --git a/server/controllers/email/send.go b/server/controllers/email/send.go index 1e5073b..417e7fa 100644 --- a/server/controllers/email/send.go +++ b/server/controllers/email/send.go @@ -130,16 +130,12 @@ func Send(ctx *context.Context, w http.ResponseWriter, req *http.Request) { } log.WithContext(ctx).Debugf("插件执行--SendBefore") - as := async.New(ctx) for _, hook := range hooks.HookList { if hook == nil { continue } - as.WaitProcess(func(hk any) { - hk.(framework.EmailHook).SendBefore(ctx, e) - }, hook) + hook.SendBefore(ctx, e) } - as.Wait() log.WithContext(ctx).Debugf("插件执行--SendBefore End") // 邮件落库 diff --git a/server/hooks/base.go b/server/hooks/base.go index 89c209f..c52b218 100644 --- a/server/hooks/base.go +++ b/server/hooks/base.go @@ -35,17 +35,12 @@ func (h *HookSender) ReceiveSaveAfter(ctx *context.Context, email *parsemail.Ema } body, _ := json.Marshal(dto) - ret, err := h.httpc.Post("http://plugin/ReceiveSaveAfter", "application/json", strings.NewReader(string(body))) + _, err := h.httpc.Post("http://plugin/ReceiveSaveAfter", "application/json", strings.NewReader(string(body))) if err != nil { log.WithContext(ctx).Errorf("[%s] Error! %v", h.name, err) return } - body, _ = io.ReadAll(ret.Body) - json.Unmarshal(body, &dto) - - ctx = dto.Ctx - email = dto.Email log.WithContext(ctx).Debugf("[%s]Plugin ReceiveSaveAfter End", h.name) } @@ -82,18 +77,12 @@ func (h *HookSender) SendAfter(ctx *context.Context, email *parsemail.Email, err } body, _ := json.Marshal(dto) - ret, errL := h.httpc.Post("http://plugin/SendAfter", "application/json", strings.NewReader(string(body))) + _, errL := h.httpc.Post("http://plugin/SendAfter", "application/json", strings.NewReader(string(body))) if errL != nil { log.WithContext(ctx).Errorf("[%s] Error! %v", h.name, errL) return } - body, _ = io.ReadAll(ret.Body) - json.Unmarshal(body, &dto) - - ctx = dto.Ctx - email = dto.Email - err = dto.ErrMap log.WithContext(ctx).Debugf("[%s]Plugin SendAfter End", h.name) } diff --git a/server/hooks/framework/framework.go b/server/hooks/framework/framework.go index 1f5ab2c..59fde8e 100644 --- a/server/hooks/framework/framework.go +++ b/server/hooks/framework/framework.go @@ -16,15 +16,15 @@ import ( ) type EmailHook interface { - // SendBefore 邮件发送前的数据 + // SendBefore 邮件发送前的数据 同步执行 SendBefore(ctx *context.Context, email *parsemail.Email) - // SendAfter 邮件发送后的数据,err是每个收信服务器的错误信息 + // SendAfter 邮件发送后的数据,err是每个收信服务器的错误信息 异步执行 SendAfter(ctx *context.Context, email *parsemail.Email, err map[string]error) - // ReceiveParseBefore 接收到邮件,解析之前的原始数据 + // ReceiveParseBefore 接收到邮件,解析之前的原始数据 同步执行 ReceiveParseBefore(ctx *context.Context, email *[]byte) - // ReceiveParseAfter 接收到邮件,解析之后的结构化数据 (收信规则前,写数据库前执行) + // ReceiveParseAfter 接收到邮件,解析之后的结构化数据 (收信规则前,写数据库前执行) 同步执行 ReceiveParseAfter(ctx *context.Context, email *parsemail.Email) - // ReceiveSaveAfter 邮件落库以后执行(收信规则后执行) + // ReceiveSaveAfter 邮件落库以后执行(收信规则后执行) 异步执行 ReceiveSaveAfter(ctx *context.Context, email *parsemail.Email) } diff --git a/server/models/email.go b/server/models/email.go index b8ed539..f7ce5c2 100644 --- a/server/models/email.go +++ b/server/models/email.go @@ -8,7 +8,7 @@ import ( ) type Email struct { - Id int `xorm:"id pk unsigned int autoincr notnull" json:"id"` + Id int `xorm:"id pk unsigned int autoincr notnull default(0)" json:"id"` Type int8 `xorm:"type tinyint(4) notnull default(0) comment('邮件类型,0:收到的邮件,1:发送的邮件')" json:"type"` GroupId int `xorm:"group_id int notnull default(0) comment('分组id')'" json:"group_id"` Subject string `xorm:"subject varchar(1000) notnull default('') comment('邮件标题')" json:"subject"` diff --git a/server/smtp_server/read_content.go b/server/smtp_server/read_content.go index cfb3589..bafcdcb 100644 --- a/server/smtp_server/read_content.go +++ b/server/smtp_server/read_content.go @@ -36,16 +36,12 @@ func (s *Session) Data(r io.Reader) error { return err } log.WithContext(ctx).Debugf("开始执行插件ReceiveParseBefore!") - as1 := async.New(ctx) for _, hook := range hooks.HookList { if hook == nil { continue } - as1.WaitProcess(func(hk any) { - hk.(framework.EmailHook).ReceiveParseBefore(ctx, &emailData) - }, hook) + hook.ReceiveParseBefore(ctx, &emailData) } - as1.Wait() log.WithContext(ctx).Debugf("开始执行插件ReceiveParseBefore End!") log.WithContext(ctx).Infof("邮件原始内容: %s", emailData) @@ -67,18 +63,13 @@ func (s *Session) Data(r io.Reader) error { // 判断是收信还是转发,只要是登陆了,都当成转发处理 //account, domain := email.From.GetDomainAccount() if s.Ctx.UserID > 0 { - log.WithContext(ctx).Debugf("开始执行插件SendBefore!") - as2 := async.New(ctx) for _, hook := range hooks.HookList { if hook == nil { continue } - as2.WaitProcess(func(hk any) { - hk.(framework.EmailHook).SendBefore(ctx, email) - }, hook) + hook.SendBefore(ctx, email) } - as2.Wait() log.WithContext(ctx).Debugf("开始执行插件SendBefore!End") if email == nil { @@ -136,16 +127,12 @@ func (s *Session) Data(r io.Reader) error { SPFStatus = spfCheck(s.RemoteAddress.String(), email.Sender, email.Sender.EmailAddress) log.WithContext(ctx).Debugf("开始执行插件ReceiveParseAfter!") - as2 := async.New(ctx) for _, hook := range hooks.HookList { if hook == nil { continue } - as2.WaitProcess(func(hk any) { - hk.(framework.EmailHook).ReceiveParseAfter(ctx, email) - }, hook) + hook.ReceiveParseAfter(ctx, email) } - as2.Wait() log.WithContext(ctx).Debugf("开始执行插件ReceiveParseAfter!End") if email == nil { diff --git a/server/utils/send/send.go b/server/utils/send/send.go index 14e1d7b..31c543c 100644 --- a/server/utils/send/send.go +++ b/server/utils/send/send.go @@ -12,6 +12,7 @@ import ( "pmail/utils/context" "pmail/utils/smtp" "strings" + "sync" ) type mxDomain struct { @@ -59,8 +60,6 @@ func Forward(ctx *context.Context, e *parsemail.Email, forwardAddress string) er var errEmailAddress []string - errMap := map[string]error{} - as := async.New(ctx) for domain, tos := range toByDomain { domain := domain @@ -96,7 +95,6 @@ func Forward(ctx *context.Context, e *parsemail.Email, forwardAddress string) er errEmailAddress = append(errEmailAddress, user.EmailAddress) } } - errMap[domain.domain] = err }, nil) } as.Wait() @@ -145,7 +143,7 @@ func Send(ctx *context.Context, e *parsemail.Email) (error, map[string]error) { var errEmailAddress []string - errMap := map[string]error{} + errMap := sync.Map{} as := async.New(ctx) for domain, tos := range toByDomain { @@ -183,15 +181,21 @@ func Send(ctx *context.Context, e *parsemail.Email) (error, map[string]error) { errEmailAddress = append(errEmailAddress, user.EmailAddress) } } - errMap[domain.domain] = err + errMap.Store(domain.domain, err) }, nil) } as.Wait() + orgMap := map[string]error{} + errMap.Range(func(key, value any) bool { + orgMap[key.(string)] = value.(error) + return true + }) + if len(errEmailAddress) > 0 { - return errors.New("以下收件人投递失败:" + array.Join(errEmailAddress, ",")), errMap + return errors.New("以下收件人投递失败:" + array.Join(errEmailAddress, ",")), orgMap } - return nil, errMap + return nil, orgMap }