97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
|
package notification
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"mime/multipart"
|
||
|
"mime/quotedprintable"
|
||
|
"net/textproto"
|
||
|
|
||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||
|
)
|
||
|
|
||
|
func smtpMIMEHeaders(ext8BITMIME bool, contentType string, data []byte) textproto.MIMEHeader {
|
||
|
headers := textproto.MIMEHeader{
|
||
|
headerContentType: []string{fmt.Sprintf(smtpFmtContentType, contentType)},
|
||
|
headerContentDisposition: []string{smtpFmtContentDispositionInline},
|
||
|
}
|
||
|
|
||
|
characteristics := NewMIMECharacteristics(data)
|
||
|
|
||
|
if !ext8BITMIME || characteristics.LongLines || characteristics.Characters8BIT {
|
||
|
headers.Set(headerContentTransferEncoding, smtpEncodingQuotedPrintable)
|
||
|
} else {
|
||
|
headers.Set(headerContentTransferEncoding, smtpEncoding8bit)
|
||
|
}
|
||
|
|
||
|
return headers
|
||
|
}
|
||
|
|
||
|
func multipartWrite(mwr *multipart.Writer, header textproto.MIMEHeader, data []byte) (err error) {
|
||
|
var (
|
||
|
wc io.WriteCloser
|
||
|
wr io.Writer
|
||
|
)
|
||
|
|
||
|
if wr, err = mwr.CreatePart(header); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
switch header.Get(headerContentTransferEncoding) {
|
||
|
case smtpEncodingQuotedPrintable:
|
||
|
wc = quotedprintable.NewWriter(wr)
|
||
|
case smtpEncoding8bit, "":
|
||
|
wc = utils.NewWriteCloser(wr)
|
||
|
default:
|
||
|
return fmt.Errorf("unknown encoding: %s", header.Get(headerContentTransferEncoding))
|
||
|
}
|
||
|
|
||
|
if _, err = wc.Write(data); err != nil {
|
||
|
_ = wc.Close()
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
_ = wc.Close()
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// NewMIMECharacteristics detects the SMTP MIMECharacteristics for the given data bytes.
|
||
|
func NewMIMECharacteristics(data []byte) MIMECharacteristics {
|
||
|
characteristics := MIMECharacteristics{}
|
||
|
|
||
|
cl := 0
|
||
|
|
||
|
n := len(data)
|
||
|
|
||
|
for i := 0; i < n; i++ {
|
||
|
cl++
|
||
|
|
||
|
if cl > 1000 {
|
||
|
characteristics.LongLines = true
|
||
|
}
|
||
|
|
||
|
if data[i] == 10 {
|
||
|
cl = 0
|
||
|
|
||
|
if i == 0 || data[i-1] != 13 {
|
||
|
characteristics.LineFeeds = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if data[i] >= 128 {
|
||
|
characteristics.Characters8BIT = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return characteristics
|
||
|
}
|
||
|
|
||
|
// MIMECharacteristics represents specific MIME related characteristics.
|
||
|
type MIMECharacteristics struct {
|
||
|
LongLines bool
|
||
|
LineFeeds bool
|
||
|
Characters8BIT bool
|
||
|
}
|