This is a creation in Article, where the information may have evolved or changed.
Implementation of e-mail based on simple Golang of SMTP protocol
The protocol format is as follows
From:sender_user@demo.netTo:to_user@demo.netSubject:这是主题Mime-Version:1.0 //通常是1.0Content-Type:Multipart/mixed;Boundary="THIS_IS_BOUNDARY_JUST_MAKE_YOURS" //boundary为分界字符,跟http传文件时类似Date:当前时间--THIS_IS_BOUNDARY_JUST_MAKE_YOURS //boundary前边需要加上连接符 -- , 首部和第一个boundary之间有两个空行Content-Type:text/plain;chart-set=utf-8 //单个部分的首部和正文间有个空行这是正文1这是正文2--THIS_IS_BOUNDARY_JUST_MAKE_YOURS //每个部分的与上一部分之间一个空行Content-Type:image/jpg;name="test.jpg"Content-Transfer-Encoding:base64Content-Description:这个是描述 //单个部分的首部和正文间有个空行base64编码的文件 //文件内容使用base64 编码,单行不超过80字节,需要插入\r\n进行换行--THIS_IS_BOUNDARY_JUST_MAKE_YOURS-- //最后结束的标识--boundary--
The Golang code is implemented as follows
Email/email.go
Package Emailimport ("bytes" "Encoding/base64" "FMT" "Io/ioutil" "NET/SMTP" "Strings" "Time")//sende Mailwithattachment:send Email with attachmentfunc sendemailwithattachment (user, passwd, host, to, subject string) error {HP: = strings. Split (Host, ":") Auth: = SMTP. Plainauth ("", User, passwd, hp[0]) Buffer: = bytes. Newbuffer (nil) Boudary: = "This_is_boundary_just_make_yours" header: = Fmt. Sprintf ("to:%s\r\n" + "from:%s\r\n" + "subject:%s\r\n" + "content-type:multipart/mixed; Boundary=\ "%s\" \ r \ n "+" mime-version:1.0\r\n "+" date:%s\r\n ", to, user, subject, boudary, time. Now (). String ()) buffer. WriteString (header) fmt. Print (header) Msg1: = "\r\n\r\n--" + boudary + "\ r \ n" + "content-type:text/plain;charset=utf-8\r\n\r\n this is the body. \ r \ n" buf Fer. WriteString (MSG1) fmt. Print (MSG1) MSG2: = Fmt. Sprintf ("\r\n--%s\r\n" + "content-transfer-encoding:base64\r\n" + "Content-disposition:attac Hment;\r\n "+" content-type:image/jpg;name=\ "test.jpg\" \ r \ n ", boudary) buffer. WriteString (MSG2) fmt. Print (MSG2) attachmentbytes, err: = Ioutil. ReadFile ("./test.jpg") if err! = Nil {fmt. Println ("ReadFile./test.jpg Error:" + Err. Error ()) Return err} B: = make ([]byte, Base64. Stdencoding.encodedlen (Len (attachmentbytes))) Base64. Stdencoding.encode (b, attachmentbytes) buffer. WriteString ("\ r \ n") fmt. Print ("\ r \ n") fmt. Print ("Picture base64 encoded") for I, L: = 0, Len (b); I < L; i++ {buffer. WriteByte (B[i]) if (i+1)%76 = = 0 {buffer. WriteString ("\ r \ n")}} buffer. WriteString ("\r\n--" + boudary + "--") fmt. Print ("\r\n--" + boudary + "--") SendTo: = Strings. Split (To, ";") Err = SMTP. SendMail (host, auth, user, sendto, buffer. Bytes ()) Return err}
Email_test.go
package emailimport "testing"func TestSendEmailWithAttachment(t *testing.T) { err := SendEmailWithAttachment("xx@example.com", "passwd", "smtp.xx.com:25", "xx@example.com", "测试附件") if err != nil { t.Fatal(err) }}
The go test prints out the following
To:xx@example.comFrom:xx@example.comSubject:测试附件Content-Type:multipart/mixed;Boundary="THIS_IS_BOUNDARY_JUST_MAKE_YOURS"Mime-Version:1.0Date:2016-09-11 12:17:37.268146477 +0800 CST--THIS_IS_BOUNDARY_JUST_MAKE_YOURSContent-Type:text/plain;charset=utf-8这是正文啊--THIS_IS_BOUNDARY_JUST_MAKE_YOURSContent-Transfer-Encoding: base64Content-Disposition: attachment;Content-Type:image/jpg;name="test.jpg"图片base64编码--THIS_IS_BOUNDARY_JUST_MAKE_YOURS--
The library can be used in a specific project for a partial implementation reference https://github.com/scorredoira/email.
Problems encountered
- Boundary The format of the error, the head of the boundary in the bottom of the use of the time to spell-the prefix
- contains attachments, the first boundary and header in the middle of two blank lines
- end marked as--boun dary--
- The contents of the loop file are inserted and wrapped, and if there is a logic error, the transmitted attachment is displayed abnormally and cannot be viewed and downloaded properly.