mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-21 21:30:50 +01:00
Compare commits
5 commits
53566a93cd
...
f5bbc558b2
Author | SHA1 | Date | |
---|---|---|---|
f5bbc558b2 | |||
93611e47a5 | |||
f01047855f | |||
3facbde703 | |||
59e85809f7 |
7 changed files with 35 additions and 26 deletions
6
.github/workflows/codecov.yml
vendored
6
.github/workflows/codecov.yml
vendored
|
@ -33,7 +33,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
go: [1.17, 1.18, 1.19, '1.20', '1.21']
|
||||
go: [1.18, 1.19, '1.20', '1.21', '1.22']
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@master
|
||||
|
@ -42,14 +42,14 @@ jobs:
|
|||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: Install sendmail
|
||||
if: matrix.go == '1.21' && matrix.os == 'ubuntu-latest'
|
||||
if: matrix.go == '1.22' && matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get -y install sendmail; which sendmail
|
||||
- name: Run Tests
|
||||
run: |
|
||||
go test -v -race --coverprofile=coverage.coverprofile --covermode=atomic ./...
|
||||
- name: Upload coverage to Codecov
|
||||
if: success() && matrix.go == '1.21' && matrix.os == 'ubuntu-latest'
|
||||
if: success() && matrix.go == '1.22' && matrix.os == 'ubuntu-latest'
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
|
||||
|
|
2
.github/workflows/golangci-lint.yml
vendored
2
.github/workflows/golangci-lint.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version: '1.22'
|
||||
- uses: actions/checkout@v3
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
|
|
2
.github/workflows/sonarqube.yml
vendored
2
.github/workflows/sonarqube.yml
vendored
|
@ -29,7 +29,7 @@ jobs:
|
|||
- name: Setup Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.21.x'
|
||||
go-version: '1.22.x'
|
||||
|
||||
- name: Run unit Tests
|
||||
run: |
|
||||
|
|
33
eml.go
33
eml.go
|
@ -178,9 +178,6 @@ func parseEMLHeaders(mh *nm.Header, m *Msg) error {
|
|||
for _, h := range commonHeaders {
|
||||
if v := mh.Get(h.String()); v != "" {
|
||||
m.SetGenHeader(h, v)
|
||||
if strings.EqualFold(h.String(), "subject") {
|
||||
fmt.Printf("SUBJECT: %s\n", m.GetGenHeader(HeaderSubject)[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +201,8 @@ func parseEMLBodyParts(pm *nm.Message, bodybuf *bytes.Buffer, m *Msg) error {
|
|||
if err := parseEMLBodyPlain(mediatype, pm, bodybuf, m); err != nil {
|
||||
return fmt.Errorf("failed to parse plain body: %w", err)
|
||||
}
|
||||
case strings.EqualFold(mediatype, TypeMultipartAlternative.String()):
|
||||
case strings.EqualFold(mediatype, TypeMultipartAlternative.String()),
|
||||
strings.EqualFold(mediatype, "multipart/mixed"):
|
||||
if err := parseEMLMultipartAlternative(params, bodybuf, m); err != nil {
|
||||
return fmt.Errorf("failed to parse multipart/alternative body: %w", err)
|
||||
}
|
||||
|
@ -266,19 +264,27 @@ func parseEMLMultipartAlternative(params map[string]string, bodybuf *bytes.Buffe
|
|||
if !ok {
|
||||
return fmt.Errorf("failed to get content-type from part")
|
||||
}
|
||||
mpContentTypeSplit := strings.Split(mpContentType[0], "; ")
|
||||
p := m.newPart(ContentType(mpContentTypeSplit[0]))
|
||||
parseEMLMultiPartCharset(mpContentTypeSplit, p)
|
||||
conType, charSet := parseContentType(mpContentType[0])
|
||||
p := m.newPart(ContentType(conType))
|
||||
p.SetCharset(Charset(charSet))
|
||||
|
||||
mpTransferEnc, ok := mpart.Header[HeaderContentTransferEnc.String()]
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get content-transfer-encoding from part")
|
||||
// If CTE is empty we can assume that it's a quoted-printable CTE since the
|
||||
// GO stdlib multipart packages deletes that header
|
||||
// See: https://cs.opensource.google/go/go/+/refs/tags/go1.22.0:src/mime/multipart/multipart.go;l=161
|
||||
mpTransferEnc = []string{EncodingQP.String()}
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.EqualFold(mpTransferEnc[0], EncodingB64.String()):
|
||||
if err := handleEMLMultiPartBase64Encoding(mpdata, p); err != nil {
|
||||
return fmt.Errorf("failed to handle multipart base64 transfer-encoding: %w", err)
|
||||
}
|
||||
case strings.EqualFold(mpTransferEnc[0], EncodingQP.String()):
|
||||
p.SetContent(string(mpdata))
|
||||
default:
|
||||
return fmt.Errorf("unsupported Content-Transfer-Encoding")
|
||||
}
|
||||
|
||||
m.parts = append(m.parts, p)
|
||||
|
@ -291,17 +297,6 @@ func parseEMLMultipartAlternative(params map[string]string, bodybuf *bytes.Buffe
|
|||
return nil
|
||||
}
|
||||
|
||||
// parseEMLMultiPartCharset parses the Charset from a ContentType header and assigns it to a Part
|
||||
// TODO: This might be redundant to parseContentType
|
||||
func parseEMLMultiPartCharset(mpContentTypeSplit []string, p *Part) {
|
||||
if len(mpContentTypeSplit) > 1 && strings.HasPrefix(strings.ToLower(mpContentTypeSplit[1]), "charset=") {
|
||||
valSplit := strings.Split(mpContentTypeSplit[1], "=")
|
||||
if len(valSplit) > 1 {
|
||||
p.SetCharset(Charset(valSplit[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handleEMLMultiPartBase64Encoding sets the content body of a base64 encoded Part
|
||||
func handleEMLMultiPartBase64Encoding(mpdata []byte, p *Part) error {
|
||||
p.SetEncoding(EncodingB64)
|
||||
|
|
|
@ -140,6 +140,8 @@ const (
|
|||
const (
|
||||
TypeAppOctetStream ContentType = "application/octet-stream"
|
||||
TypeMultipartAlternative ContentType = "multipart/alternative"
|
||||
TypeMultipartMixed ContentType = "multipart/mixed"
|
||||
TypeMultipartRelated ContentType = "multipart/related"
|
||||
TypePGPSignature ContentType = "application/pgp-signature"
|
||||
TypePGPEncrypted ContentType = "application/pgp-encrypted"
|
||||
TypeTextHTML ContentType = "text/html"
|
||||
|
|
|
@ -40,6 +40,18 @@ func TestContentType_String(t *testing.T) {
|
|||
"ContentType: application/octet-stream", TypeAppOctetStream,
|
||||
"application/octet-stream",
|
||||
},
|
||||
{
|
||||
"ContentType: multipart/alternative", TypeMultipartAlternative,
|
||||
"multipart/alternative",
|
||||
},
|
||||
{
|
||||
"ContentType: multipart/mixed", TypeMultipartMixed,
|
||||
"multipart/mixed",
|
||||
},
|
||||
{
|
||||
"ContentType: multipart/related", TypeMultipartRelated,
|
||||
"multipart/related",
|
||||
},
|
||||
{
|
||||
"ContentType: application/pgp-signature", TypePGPSignature,
|
||||
"application/pgp-signature",
|
||||
|
|
|
@ -89,11 +89,11 @@ func (mw *msgWriter) writeMsg(m *Msg) {
|
|||
}
|
||||
|
||||
if m.hasMixed() {
|
||||
mw.startMP("mixed", m.boundary)
|
||||
mw.startMP(MIMEMixed, m.boundary)
|
||||
mw.writeString(DoubleNewLine)
|
||||
}
|
||||
if m.hasRelated() {
|
||||
mw.startMP("related", m.boundary)
|
||||
mw.startMP(MIMERelated, m.boundary)
|
||||
mw.writeString(DoubleNewLine)
|
||||
}
|
||||
if m.hasAlt() {
|
||||
|
|
Loading…
Reference in a new issue