From ee8fa9eb9d078c67d4e89a17dab8d9ef5c76e455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=9E=E6=A5=BD=E5=9D=82=20=E7=99=BD?= Date: Mon, 30 Oct 2023 12:56:01 +0000 Subject: [PATCH] fixbug --- go.mod | 15 ++- go.sum | 24 +++++ mian.go | 319 ++++++++++++++++++++++++++------------------------------ 3 files changed, 185 insertions(+), 173 deletions(-) diff --git a/go.mod b/go.mod index 76d4422..15bee3d 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,17 @@ module gitlab.ni-co.moe/shira/temp-mail-receiver go 1.20 -require github.com/mhale/smtpd v0.8.0 // indirect +require ( + github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect + github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect + github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect + github.com/jhillyerd/enmime v1.0.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mhale/smtpd v0.8.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/text v0.13.0 // indirect +) diff --git a/go.sum b/go.sum index 768d7b7..77bafc1 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,26 @@ +github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI= +github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8= +github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs= +github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= +github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA= +github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= +github.com/jhillyerd/enmime v1.0.1 h1:y6RyqIgBOI2hIinOXIzmeB+ITRVls0zTJIm5GwgXnjE= +github.com/jhillyerd/enmime v1.0.1/go.mod h1:LMMbm6oTlzWHghPavqHtOrP/NosVv3l42CUrZjn03/Q= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mhale/smtpd v0.8.0 h1:5JvdsehCg33PQrZBvFyDMMUDQmvbzVpZgKob7eYBJc0= github.com/mhale/smtpd v0.8.0/go.mod h1:MQl+y2hwIEQCXtNhe5+55n0GZOjSmeqORDIXbqUL3x4= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= +github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= diff --git a/mian.go b/mian.go index 0de5d12..cfd9ae3 100644 --- a/mian.go +++ b/mian.go @@ -1,172 +1,147 @@ -package main - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "mime" - "mime/multipart" - "net" - "net/http" - "net/mail" - "os" - "strings" - "time" - - "github.com/mhale/smtpd" -) - -type Config struct { - Address string `json:"addr"` - ApiUrl string `json:"api_url"` - ApiKey string `json:"api_key"` -} - -type MailContent struct { - Key string `json:"key"` - From string `json:"from"` - To string `json:"to"` - Title string `json:"title"` - Body string `json:"body"` - FromAddr string `json:"from_addr"` - FromProtocol string `json:"from_protocol"` - ReceivedAt string `json:"received_at"` -} - -var appConfig Config - -func decodeHeader(header string) (string, error) { - decoded, err := (&mime.WordDecoder{}).DecodeHeader(header) - if err != nil { - return "", err - } - return decoded, nil -} - -func postMailContent(url string, key string, mailContent *MailContent) error { - // 将邮件内容转换为 JSON - jsonData, err := json.Marshal(mailContent) - if err != nil { - return err - } - - // 创建 HTTP 请求 - req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) - if err != nil { - return err - } - req.Header.Set("Content-Type", "application/json") - - // 发送 HTTP 请求 - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - // 读取响应体(如果需要) - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - log.Println("Response Status:", resp.Status) - log.Println("Response Body:", string(body)) - - return nil -} - -func mailHandler(origin net.Addr, from string, to []string, data []byte) error { - reader := bytes.NewReader(data) - msg, _ := mail.ReadMessage(reader) - subject := msg.Header.Get("Subject") - decodedSubject, _ := decodeHeader(subject) - - mediaType, params, _ := mime.ParseMediaType(msg.Header.Get("Content-Type")) - body, _ := ioutil.ReadAll(msg.Body) - - mailBody := "" - - if strings.HasPrefix(mediaType, "text/plain") || strings.HasPrefix(mediaType, "text/html") { - mailBody = string(body) - } else if strings.HasPrefix(mediaType, "multipart/") { - mr := multipart.NewReader(msg.Body, params["boundary"]) - for { - part, err := mr.NextPart() - if err == io.EOF { - break - } - if err != nil { - log.Fatal(err) - } - - partMediaType, _, err := mime.ParseMediaType(part.Header.Get("Content-Type")) - if err != nil { - log.Fatal(err) - } - - partBody, err := ioutil.ReadAll(part) - if err != nil { - log.Fatal(err) - } - - if strings.HasPrefix(partMediaType, "text/plain") { - mailBody = mailBody + string(partBody) - } else if strings.HasPrefix(partMediaType, "text/html") { - mailBody = mailBody + string(partBody) - } - } - } else { - fmt.Println("Unsupported media type") - } - - log.Printf("Received mail from %s for %s with subject %s", from, to[0], decodedSubject) - - receivedAt := time.Now() // 例如,使用当前时间作为接收时间 - - // 创建 MailContent 对象 - mailContent := &MailContent{ - From: from, - To: to[0], - Title: decodedSubject, - Body: mailBody, - FromAddr: origin.String(), - FromProtocol: origin.Network(), - ReceivedAt: receivedAt.Format(time.RFC3339), - } - - // 将邮件内容发送到 API - err := postMailContent(appConfig.ApiUrl, appConfig.ApiKey, mailContent) - if err != nil { - log.Println("Failed to post mail content:", err) - } - - return nil -} - -func main() { - configPath := flag.String("c", "config.json", "Path to the configuration file") - flag.Parse() - - file, err := os.Open(*configPath) - if err != nil { - log.Fatalf("Error opening config file: %v", err) - } - defer file.Close() - - configBytes, err := ioutil.ReadAll(file) - if err != nil { - log.Fatalf("Error reading config file: %v", err) - } - - if err := json.Unmarshal(configBytes, &appConfig); err != nil { - log.Fatalf("Error parsing config file: %v", err) - } - - log.Printf("Starting server at %s", appConfig.Address) - smtpd.ListenAndServe(appConfig.Address, mailHandler, "MyServerApp", "") -} +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "log" + "mime" + "net" + "net/http" + "os" + "time" + + "github.com/jhillyerd/enmime" + "github.com/mhale/smtpd" +) + +type Config struct { + Address string `json:"addr"` + ApiUrl string `json:"api_url"` + ApiKey string `json:"api_key"` +} + +type MailContent struct { + Key string `json:"key"` + From string `json:"from"` + To string `json:"to"` + Title string `json:"title"` + Body string `json:"body"` + FromAddr string `json:"from_addr"` + FromProtocol string `json:"from_protocol"` + ReceivedAt string `json:"received_at"` +} + +var appConfig Config + +func decodeHeader(header string) (string, error) { + decoded, err := (&mime.WordDecoder{}).DecodeHeader(header) + if err != nil { + return "", err + } + return decoded, nil +} + +func postMailContent(url string, key string, mailContent *MailContent) error { + // 将邮件内容转换为 JSON + jsonData, err := json.Marshal(mailContent) + if err != nil { + return err + } + + // 创建 HTTP 请求 + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + // 发送 HTTP 请求 + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + // 读取响应体(如果需要) + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + log.Println("Response Status:", resp.Status) + log.Println("Response Body:", string(body)) + + return nil +} + +func mailHandler(origin net.Addr, from string, to []string, data []byte) error { + reader := bytes.NewReader(data) + // msg, _ := mail.ReadMessage(reader) + // subject := msg.Header.Get("Subject") + // decodedSubject, _ := decodeHeader(subject) + env, _ := enmime.ReadEnvelope(reader) + + subject := env.GetHeader("Subject") + // The plain text body is available as mime.Text. + fmt.Printf("Text Body: %v chars\n", len(env.Text)) + + // The HTML body is stored in mime.HTML. + fmt.Printf("HTML Body: %v chars\n", len(env.HTML)) + // 获取邮件正文 + // contentType := msg.Header.Get("Content-Type") + // mediaType, params, err := mime.ParseMediaType(contentType) + + body := env.HTML + + fmt.Println("Body:", body) + + log.Printf("Received mail from %s for %s with subject %s body %s", from, to[0], subject, body) + + receivedAt := time.Now() // 例如,使用当前时间作为接收时间 + + // 创建 MailContent 对象 + mailContent := &MailContent{ + Key: appConfig.ApiKey, + From: from, + To: to[0], + Title: subject, + Body: body, + FromAddr: origin.String(), + FromProtocol: origin.Network(), + ReceivedAt: receivedAt.Format(time.RFC3339), + } + + // 将邮件内容发送到 API + err := postMailContent(appConfig.ApiUrl, appConfig.ApiKey, mailContent) + if err != nil { + log.Println("Failed to post mail content:", err) + } + + return nil +} + +func main() { + configPath := flag.String("c", "config.json", "Path to the configuration file") + flag.Parse() + + file, err := os.Open(*configPath) + if err != nil { + log.Fatalf("Error opening config file: %v", err) + } + defer file.Close() + + configBytes, err := ioutil.ReadAll(file) + if err != nil { + log.Fatalf("Error reading config file: %v", err) + } + + if err := json.Unmarshal(configBytes, &appConfig); err != nil { + log.Fatalf("Error parsing config file: %v", err) + } + + log.Printf("Starting server at %s", appConfig.Address) + smtpd.ListenAndServe(appConfig.Address, mailHandler, "MyServerApp", "") +}