Просмотр исходного кода

bug fix (#106)

修复并非写map造成的panic

Co-authored-by: jinnrry <i@jinnrry.com>
Jinnrry 2 лет назад
Родитель
Сommit
6280264435

+ 1 - 5
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")
 
 	// 邮件落库

+ 2 - 13
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)
 
 }

+ 5 - 5
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)
 }
 

+ 1 - 1
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"`

+ 3 - 16
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 {

+ 11 - 7
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
 
 }