MIME mail encoding and decoding package for Go

enmime

PkgGoDev Build Status Go Report Card Coverage Status

enmime is a MIME encoding and decoding library for Go, focused on generating and parsing MIME encoded emails. It is being developed in tandem with the Inbucket email service.

enmime includes a fluent interface builder for generating MIME encoded messages, see the wiki for example Builder Usage.

See our Pkg Docs for examples and API usage information.

Development Status

enmime is near production quality: it works but struggles to parse a small percentage of emails. It's possible the API will evolve slightly before the 1.0 release.

See CONTRIBUTING.md for more information.

About

enmime is written in Go.

enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime

Owner
James Hillyerd
Google SWE, Go and Rust enthusiast. He/him.
James Hillyerd
Comments
  • feat: add option skip malformed parts

    feat: add option skip malformed parts

    This PR is proposal for the feature which allows to skip parts that can't be parsed. It won't return error, just add them to "problems"

    This can be useful if you need to parse everything what is possible to parse and turned off by default.

    For example, we have emails which have body of the email starting at the beginning of the part (without headers). Currently parser returns error, but it can be beneficial to skip this part.

    ...
    Content-Type: multipart/report; report-type=delivery-status;
    	boundary="12345/example.com"
    Auto-Submitted: auto-generated (failure)
    MIME-Version: 1.0
    
    --12345/example.com
    [EXTERNAL EMAIL]
    
    The original message was received
    ...
    
  • 'slash after first token' when parsing some emails

    'slash after first token' when parsing some emails

    What I did: parsed some mimes

    What I expected: to get parsed object

    What I got: error

    Release or branch I am using: [0.8.2] - 2020-10-10

    (Please attach a sample message if you feel it will help reproduce the issue)

    First of all, thank for the helpful package! But I get error when I parse some mimes: expected slash after first token I parse them like this: enmime.ReadEnvelope(strings.NewReader(mime))

    Can you suggest me please how to avoid this problem ? Below is the example of mime which gives error:

    Return-Path: <[email protected]>
    Delivered-To: [email protected]
    Received: from dcd-15 ([10.103.10.7])
    	by dcbackend-15.iol.local with LMTP id wBOnApYfll9gIAUATByfJw
    	for <[email protected]>; Mon, 26 Oct 2020 02:00:06 +0100
    Received: from dcp-33.iol.local ([10.103.10.7])
    	by dcd-15 with LMTP id qDyMApYfll/wYgAAkA0XfQ
    	; Mon, 26 Oct 2020 02:00:06 +0100
    Received: from libero.it ([10.103.10.7])
    	by dcp-33.iol.local with LMTP id MPfpG5Mfll+4JAEAVzGdtA
    	; Mon, 26 Oct 2020 02:00:06 +0100
    Received: from so254-8.mailgun.net ([198.61.254.8])
    	by smtp-07.iol.local with ESMTP
    	id Wqrkk7ui19msRWqrlkdWIE; Mon, 26 Oct 2020 02:00:06 +0100
    X-IOL-DMARC: Dominio libertycomc.com non supporta DMARC
    X-IOL-DKIM: pass con il dominio d=libertycomc.com
    X-IOL-SPF: pass con l'IP 198.12.44.3;libertycomc.com
    X-IOL-SEC: _SPFOK_DKIMOK_NODMARC
    x-libjamoibt: 2601
    Received-SPF: pass
    X-CNFS-Analysis: v=2.4 cv=KPrksHJo c=1 sm=1 tr=0 ts=5f961f96 b=1
     a=9V+36KcF1VtsQasMD0NMeA==:117 a=9V+36KcF1VtsQasMD0NMeA==:17
     a=IkcTkHD0fZMA:10 a=afefHYAZSVUA:10 a=5KLPUuaC_9wA:10 a=swULO2ODAAAA:8
     a=8IFCRQWyzuk3np_0jKQA:9 a=AFaUXfkzamQ7vrcO:21 a=frz4AuCg-hUA:10
     a=QEXdDO2ut3YA:10 a=VPRn9Uh7xMAA:10 a=PCWqMptlEwVzXmuMJime:22
    Authentication-Results: smtp-07.iol.local;
    	dkim=pass header.d=libertycomc.com header.b=TfJm39aZ
    DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=libertycomc.com; q=dns/txt;
     s=krs; t=1603674005; h=Content-Transfer-Encoding: Mime-Version:
     Content-Type: Subject: From: To: Message-Id: Sender: Date;
     bh=faAL8rCmOc2K1K3IP+7qQSPKUakoqX/vM3mtikLFN0I=; b=TfJm39aZ1YvR3TVhRaf5BOcqO6N5ED/Kch55jvSrHK95UTu6KuKpHzAamCG9yJ4ithTOrC53
     2qQhp5E+1c7Jyt7FMAYxKXhApcqBWd7wj5lmytO+ceEb+x6+BcgmWg2+knuXwexuDlYCFxKM
     fwnBUlp5eb5+Mr3YmWVOptF/r7c=
    X-Mailgun-Sending-Ip: 198.12.44.3
    X-Mailgun-Sid: WyJkMDIzMiIsICJnZW5lcmFsLmNvbnN0cnVjdGlvbkBsaWJlcm8uaXQiLCAiOTQxNWQyIl0=
    Received: by luna.sendgrid.net with HTTP; Mon, 26 Oct 2020 01:00:04 +0000
    Date: Mon, 26 Oct 2020 01:00:04 +0000
    Sender: [email protected]
    Message-Id: <[email protected]>
    To: [email protected]
    From: LibertyComc <[email protected]>
    Subject: =?utf-8?q?Il_tuo_contratto_di_assistenza_LibertyOnCall_Base_?=
     =?utf-8?q?=C3=A8_scaduto?=
    Content-Type: text/html; charset="utf-8"
    Mime-Version: 1.0
    Content-Transfer-Encoding: quoted-printable
    X-CMAE-Envelope: MS4xfNvTvUqy52h0PkJMOD3B7ZoQxPkRJk/JMo2kfmIlF7l6O3wP4UkVrLsi6TBS/nxvz1zrbHrMhIiA9gTN2dELm5hM39y496Dn/14V6nFuqnxTAsnInGBo
     sNc1MmqJGgJu/m9Pgn18xzac7TKMqBPiPCe96YDU4K/A0uPOppvxJ55qoey1cHx+NwBsPzZ1VXDTLf1q+eVnP3cjfhUKW5ii5fBVuHTYbCbfNz0NmEwhpZCc
     KO9wgeZjEWpMkfZ+OzlinhYnRpDDLNYt3vmNI3J9Bsk=
    
    <!-- BEGIN: main --><!DOCTYPE html>
    <html lang=3D"it">
    <head>
       <meta charset=3D"UTF-8">
       <title>Il tuo contratto di assistenza LibertyOnCall Base =C3=A8 scaduto<=
    /title>
       <style type=3D"text/css">
          body {
             font-family: Verdana, Arial, Helvetica, sans-serif;
             font-size: 11px
          }
       </style>
    </head>
    <body>
       <div style=3D"width:100%; background-color:#f7f7f4; padding-bottom:30px;=
     padding-top:10px; margin:0">
          <div style=3D"width:640px; margin-left:auto; margin-right: auto; back=
    ground-color:#ffffff;box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rg=
    ba(0,0,0,0.23);">
             <div style=3D"padding:10px; margin:5px 0 0 0; border-bottom:1px so=
    lid #dddddd; font-size:11px">
                <img src=3D"http://www.libertycomc.com/assets/email/logo_lib=
    ertycommerce_piccolo.png">
             </div>
             <div style=3D"color:#333333; font-weight:bold; background-color:#e=
    fefef; padding:5px 10px 8px 10px; font-size:15px; font-family:Arial,Verdana=
    ,sans-serif">
                Il tuo contratto di assistenza LibertyOnCall Base =C3=A8 scaduto
             </div>
             <div style=3D"color:#333333; padding:10px 10px 10px 10px; font-siz=
    e:15px; font-family:Arial,Verdana,sans-serif">
               =20
    <table width=3D"100%" border=3D"0" cellspacing=3D"2" cellpadding=3D"5">
    	<!--
    	<tr>
    		<td align=3D"center" bgcolor=3D"#FF3F3F">
    			<span style=3D"color: cornsilk; font-weight: bold"> Il tuo contratto di =
    assistenza =C3=A8 scaduto </span>
    		</td>
    	</tr>
    	-->
    
    	<tr>
    		<td>
    
    			Gentile <strong>General C1C</strong>, <b=
    r>
    			<br>
    			dai nostri archivi risulta che il contratto di assistenza
    			<strong>LibertyOnCall Base</strong> da te sottoscritto =C3=A8 scaduto il=
     giorno <strong>23/10/2020</strong>.<br>
    			<br>
    
    			Per poter continuare ad usufruire del servizio ti invitiamo a rinnovarlo=
     per un altro anno. <br>
    			<br>
    			<div align=3D"center" style=3D"margin:10px">
    				<a style=3D"text-decoration:none; font-weight: bold; background-color:#=
    eee; color:#004276; border-radius: 4px; padding:8px; border:1px solid #bbbb=
    bb" href=3D"http://legacy.libertycomc.com/negozio/quickbuy.php?ql=3D7B65=
    D7E0A97BC35F9B576510F11119EC1B8E3205D8B08993E8DC641CC36F7FD38A8E4E219480742=
    C529F7D7182734594A769813DF58839940268A486990C73722FC20809D093A41EB5261F104D=
    301413CC604233EEE6B61139D18A8B94461795">Clicca per rinnovare</a>
    			</div>
    
    		=09
    			<br>
    		</td>
    	</tr>
    </table>
    
             </div>
             <div style=3D"text-align:center; background-color:#f6f6f6; padding=
    :10px; margin:5px 0 5px 0; border-top:1px solid #dddddd; font-size:10px;  f=
    ont-family:Arial,Verdana,sans-serif">&copy;2020 Liberty Line srl</div>
          </div>
       </div>
    <img width=3D"1px" height=3D"1px" alt=3D"" src=3D"http://email.libertycomme=
    rce.it/o/eJw1zDsSgyAUBdDVhJK5j59S0EQ3wueZMKMyg6TI7mOT5pSnBG_IFiVqUFAgKHcDGE=
    lymVearH9qD5qWFQ-DvSbu45vbcXDPLOsQ7-AjJ1J-0yZats5gS4gahXl2cKxFDy8-ucdd5nZeo=
    3_yqO38d-1efrQHKFQ"></body>
    </html><!-- END: main -->
    
  • Requaos/nontermboundry

    Requaos/nontermboundry

    Had an issue where the boundary was not terminated, and I saw some tests around this but my case fell through the cracks. I refactored the Read() function to go one byte at a time and only peek the length of the fullBoundary. (edited) There was a case where the boundary was being detected 2x chars early for whitespace at the head, resolved in b6a4d4e

  • boundary_test failures under Go 1.12.1

    boundary_test failures under Go 1.12.1

    What I did:

    Run unit tests with go version go1.12.1 linux/amd64

    What I expected:

    Success!

    What I got:

    --- FAIL: TestBoundaryReader (0.00s)
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE\r\nafter", want: "\r\n--STOPHERE\r\nafter"
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE\t\r\nafter", want: "\r\n--STOPHERE\t\r\nafter"
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE--\r\nafter", want: "\r\n--STOPHERE--\r\nafter"
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE \t\r\nafter", want: "\r\n--STOPHERE \t\r\nafter"
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE--\t \r\nafter", want: "\r\n--STOPHERE--\t \r\nafter"
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE--\r\nafter", want: "\r\n--STOPHERE--\r\nafter"
        boundary_test.go:95: Rest of reader:
            got: "\n--STOPHERE--\r\nafter", want: "\r\n--STOPHERE--\r\nafter"
    FAIL
    FAIL	github.com/jhillyerd/enmime	1.556s
    

    Release or branch I am using: develop

    https://travis-ci.org/jhillyerd/enmime/jobs/513790838

  • Access all headers from Envelope

    Access all headers from Envelope

    With the later changes, the headers field of the Envelope has been made private. I have need of all headers in the email and there does not seem to be a way of doing this without knowing ahead of time what they are, and using the GetHeader method.

    Do you have a recommended way of doing this, ie perhaps a new HeaderKeys method, make headers public, or a new GetRawHeader method, or perhaps there is something I'm missing?

  • Fix for certain charset duplicate params error

    Fix for certain charset duplicate params error

    If a duplicate param is present then parsing of the entire email fails. This fix handles a misplaced ";" in content-type. It also handles empty name in content-type. I have also added a unit test for this scenario.

  • Bug in parsing logic of readHeader

    Bug in parsing logic of readHeader

    If the header contains fields like "Dkim-Signature" or "Domainkey-Signature" which contain a 'Content-Type:' inside the value then Content-Type header field is parsed wrongly as 'List-Unsubscribe; b=oCvFiVQEh8Fqkfnk9yJ2llkWAnsRxQr8Xf10SjcXK2wrzCXtizroaBbi0FZ7XbHd9fFz03 9UcQ7Vc1EUZ8pAHMG98BRjVaUNuEl2Eqle+NoKi+zRA023xULkCmWzWalclNB/FI5YTEQCpl JBE4+6LWrtWlorhybEDjvi4chJzc0=' instead of 'multipart/alternative; boundary=mimepart_583f950f96b48_6afcdf1038924a'.

    Example headers in the email:- "headers": { "Authentication-Results": "mx.google.com; dkim=pass [email protected]; spf=pass (google.com: domain of [email protected] designates 166.78.70.59 as permitted sender) smtp.mailfrom=bounce+beef2e.191099-deepak=redsift.io@papertrailapp.com", "Content-Type": "multipart/alternative; boundary=mimepart_583f950f96b48_6afcdf1038924a", "Delivered-To": "[email protected]", "Dkim-Signature": "a=rsa-sha256; v=1; c=relaxed/relaxed; d=papertrailapp.com; q=dns/txt; s=krs; t=1480561936; h=List-Unsubscribe: Content-Type: Mime-Version: Subject: Message-Id: To: From: Date: Sender; bh=Ypk2VpJetOH0wE/ecQUh9usmggXKCYSph2kozqlVh78=; b=oBgHqQb5gL9P21CVXgOUN06ByZHE4Znxnyp3JsIePEzsMDF+Z4nuzKl9CeQA1gv6B3v329Tr W6yRYEXPBPANr2EWcbK9gPUjT33SLckZlvFbaIeEv4/bdCrcr0V7CTBQzMLhXmDuv8xth427 FFlyn2Zy0dWTMFd3UUvp64QrTYc=", "Domainkey-Signature": "a=rsa-sha1; c=nofws; d=papertrailapp.com; s=krs; q=dns; h=Sender: Date: From: To: Message-Id: Subject: Mime-Version: Content-Type: List-Unsubscribe; b=oCvFiVQEh8Fqkfnk9yJ2llkWAnsRxQr8Xf10SjcXK2wrzCXtizroaBbi0FZ7XbHd9fFz03 9UcQ7Vc1EUZ8pAHMG98BRjVaUNuEl2Eqle+NoKi+zRA023xULkCmWzWalclNB/FI5YTEQCpl JBE4+6LWrtWlorhybEDjvi4chJzc0=", "List-Unsubscribe": "https://papertrailapp.com/account", "Message-Id": "[email protected]", "Mime-Version": "1.0", "Received": "by 10.31.150.214 with SMTP id y205csp655646vkd; Wed, 30 Nov 2016 19:12:17 -0800 (PST)\nfrom smtp-out.papertrailapp.com (smtp-out.papertrailapp.com. [166.78.70.59]) by mx.google.com with ESMTPS id d12si49552199iof.62.2016.11.30.19.12.16 for [email protected] (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Nov 2016 19:12:16 -0800 (PST)\nfrom papertrailapp.com (pt02rw04.papertrailapp.com [67.214.214.182]) by mxa.mailgun.org with ESMTP id 583f9510.7f4fa0643298-smtp-out-n03; Thu, 01 Dec 2016 03:12:16 -0000 (UTC)", "Received-Spf": "pass (google.com: domain of [email protected] designates 166.78.70.59 as permitted sender) client-ip=166.78.70.59;", "Return-Path": "[email protected]", "Sender": "[email protected]", "X-GM-MSGID": "158b85e4ae57c1ba", "X-GM-THRID": "158b85e4ae57c1ba", "X-Mailgun-Sending-Ip": "166.78.70.59", "X-Mailgun-Sid": "WyI3YjEyNCIsICJkZWVwYWtAcmVkc2lmdC5pbyIsICIxOTEwOTkiXQ==", "X-Received": "by 10.36.101.5 with SMTP id u5mr31628139itb.45.1480561936981; Wed, 30 Nov 2016 19:12:16 -0800 (PST)", "X-Report-Abuse-To": "[email protected]" }

  • Maximal number of errors recorded in Part limited

    Maximal number of errors recorded in Part limited

    Hi,

    I use enmime to parse emails in my service. It happened that instead of valid mime structure, client sent several MBs of base64 data as input. In such case, enmime consumes a lot of memory (several GBs). It's because readHeader function adds many many warnings in order to "Attempt to detect and repair a non-indented continuation of previous line" as comment says.

    In the end, readHeader calls ReadMIMEHeader, which doesn't find valid MIME structure and fails with error and all these warnings are freed. However the memory peak remains and can lead to swapping.

    To make it more robust, I'm adding a MaxPartErrors global public variable, which does not allow to record more than limit errors in one part. Default value is 1000 in my PR, but it can be also 0 if you desire, which means no limit and thus there will be no change in current behavior.

    Best regards Pavel

  • ReadEnvelope panic

    ReadEnvelope panic

    What I did:

    package main
    
    import (
    	"fmt"
    	"log"
    	"os"
    
    	"github.com/jhillyerd/enmime"
    )
    
    func main() {
    	r, err := os.Open("./test_files/071.eml")
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	env, err := enmime.ReadEnvelope(r)
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	fmt.Println(env.Errors)
    }
    

    What I expected: success. What I got:

    panic: runtime error: index out of range [4096] with length 4096
    

    Release or branch I am using: V0.9.2 (Please attach a sample message if you feel it will help reproduce the issue)

    goroutine 1 [running]:
    github.com/jhillyerd/enmime/internal/coding.(*QPCleaner).Read.func1(...)
            C:/Users/John Li/go/pkg/mod/github.com/jhillyerd/[email protected]/internal/coding/quotedprint.go:50
    github.com/jhillyerd/enmime/internal/coding.(*QPCleaner).Read(0xc00007f080, {0xc00019c000, 0x1000, 0xbdd0a7})
            C:/Users/John Li/go/pkg/mod/github.com/jhillyerd/[email protected]/internal/coding/quotedprint.go:125 +0xf31
    ...
    
  • Formatted header breaks email readability when received on mail user agent

    Formatted header breaks email readability when received on mail user agent

    Release or branch I am using: v0.8.1

    Parsing formatted headers using the library leads to an email that is no longer correctly parsable by mail user agents. A sample header is attached here for readability with the original formatting.

    This has been introduced in this commit, function readHeader in header.go file, lines 107-113.

    What is obtained after parsing the incoming email: 0.00 BSF_BESS_OUTBOUND META: BESS Outbound 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 SUBJ_ALL_CAPS META: Subject is all capitals 0.20 BSF_SC0_SAXXX META: Custom Rule BSF_SC0_SAXXX X-Bess-Outbound-Spam-Report: Code version 3.2, rules version 1.2.3.4 [from scanhost.whatever.wherever.com] Rule breakdown below pts rule name description ---- ---------------------- --------------------------------

    Which breaks parsing and displaying.

  • Handle very empty MIME part

    Handle very empty MIME part

    When one MIME boundary immediately follows another, treat it as an empty part.

    This comes from an issue I saw in a production environment where there was an email where a MIME part delimiter was immediately followed by a terminator. Like this:

    Content-type: multipart/mixed; boundary="the-boundary"
    
    --the-boundary
    Content-type: text/plain
    
    Some content.
    
    --the-boundary
    --the-boundary--
    
  • Should enmime detect HTML format and convert to text in this case?

    Should enmime detect HTML format and convert to text in this case?

    Dear all,

    I recently got an email in such format, main content-type is multipart/mixed, one of the part in body is text/plain with Content-Transfer-Encoding: quoted-printable, it contains HTML code and base64 encoded image. enmime doesn't convert html to text, and the encoded image is included in result too.

    Question: should enmime detect HTML format and convert it to text in such case?

    MIME-Version: 1.0
    ... [omit other normal email headers here] ...
    Content-Type: multipart/mixed; 
    	boundary="----=_Part_148993_809028477.1658014818211"
    
    ------=_Part_148992_763979638.1658014818211
    Content-Transfer-Encoding: quoted-printable
    Content-Type: text/plain; charset=UTF-8
    
    <div style=3D"caret-color: rgba(0, 0, 0, 0.847); color: rg=
    ba(0, 0, 0, 0.847); font-size: 12px;"><img src=3D"data:image/jpeg;base64,/9=
    j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAA=
    ... [omit long base64 lines] ...
    ...>...```
    
    
  • Feature request: ordered headers

    Feature request: ordered headers

    Dear @jhillyerd,

    Mail headers stored in header attribute is unordered (the underlying type of *textproto.MIMEHeader is map[string][]string): https://github.com/jhillyerd/enmime/blob/5cd80012a864d71e2fe03bae39079080a4896160/envelope.go#L28

    I wonder whether you're willing to accept PR to make it an ordered map instead. Since header is an internal attribute, i expect no breaking changes will be introduced.

    Ordered headers is very useful when you just modified part of mail body and want to keep the order.

  • mime-extractor: write subject and text

    mime-extractor: write subject and text

    It would be nice to write message text to files. Same as in this patch.

    index 2313bc4..974e0ec 100644
    --- a/cmd/mime-extractor/mime-extractor.go
    +++ b/cmd/mime-extractor/mime-extractor.go
    @@ -81,6 +81,29 @@ func (ex *extractor) extract(file, dir string) int {
     
            // Write errOut attachments
            fmt.Fprintf(ex.errOut, "\nExtracting attachments into %s...", dir)
    +
    +       // Write Subject
    +       newFileName := filepath.Join(dir, ".subject")
    +       err = ex.fileWrite(newFileName, []byte(e.GetHeader("Subject")), 0644)
    +       if err != nil {
    +               fmt.Fprintf(ex.stdOut, "Error writing file %q: %v\n", newFileName, err)
    +       }
    +
    +       // Write TEXT
    +       newFileName = filepath.Join(dir, ".text")
    +       err = ex.fileWrite(newFileName, []byte(e.Text), 0644)
    +       if err != nil {
    +               fmt.Fprintf(ex.stdOut, "Error writing file %q: %v\n", newFileName, err)
    +       }
    +
    +       // Write HTML
    +       newFileName = filepath.Join(dir, ".html")
    +       err = ex.fileWrite(newFileName, []byte(e.HTML), 0644)
    +       if err != nil {
    +               fmt.Fprintf(ex.stdOut, "Error writing file %q: %v\n", newFileName, err)
    +       }
    +
    +       // Write attachments
            for _, a := range e.Attachments {
                    newFileName := filepath.Join(dir, a.FileName)
                    err = ex.fileWrite(newFileName, a.Content, 0644)
    

    I use this patch. May be other users need something the same...

  • Wrong parsing of text/html with boundary

    Wrong parsing of text/html with boundary

    What I did: Parsing a message which has text/html part but it contains also "boundary" marker. I know, this is an strange case but we have the messages with it.

    IMO, https://github.com/jhillyerd/enmime/blob/1f2f4b04f3877165dda8357742c6d00ae09a1652/part.go#L404 we could check if the content type with "detectTextHeader", wdyt?

    Or reporting it with error and providing content to the part. IMO the part is wrongly classified.

    What I expected: To have HTML text loaded from that part.

    What I got: Empty string + I cant access the body of that part :(

    Release or branch I am using: master (Please attach a sample message if you feel it will help reproduce the issue)

    ------=_NextPart_001_0564_01D7A4BE.5DCBAE50
    
    Content-Type: text/html;
    
    boundary="_005_CO1PR15MB50972F18B0F86496F538DA40A1D49CO1PR15MB5097namp_";
    
    charset="us-ascii";
    
    type="multipart/alternative"
    
    Content-Transfer-Encoding: quoted-printable
    
  • Ability to turn off extra processings, e.g. html2text.FromString

    Ability to turn off extra processings, e.g. html2text.FromString

    What I did: Parsing a mime without text/plain part. Field Text on the envelope returns a text using html2text converter. This processing is consuming memory as well as CPU. Would it be possible, e.g. using options, to manage this extra work? By default ON, but having a possiblity to turn it OFF but still reporting ErrorPlainTextFromHTML.

    What I expected: Empty text.

    What I got: Text converted by html2text.

    Release or branch I am using: master

    (Please attach a sample message if you feel it will help reproduce the issue)

Go Mail - A cross platform mail driver for GoLang.
Go Mail  - A cross platform mail driver for GoLang.

Go Mail aims to unify multiple popular mail API's (SparkPost, MailGun & SendGrid) into a singular easy to use interface. Email sending is seriously simple and great for allowing the developer to choose what platform they use.

Dec 16, 2022
Mail-alias-resolve-ldap - Resolve mail alias addresses in LDAP

alias-resolve-ldap alias-resolve-ldap was written to be used as a hook for the c

Jan 30, 2022
An email MIME artist for golang

Marcel is a tool to generate IETF compliant emails in raw MIME format. I mainly use this for generating emails with attachments and sending them via amazon SES. If that's what you're doing too, you may want notifications

Nov 7, 2022
Golang package that generates clean, responsive HTML e-mails for sending transactional mail
Golang package that generates clean, responsive HTML e-mails for sending transactional mail

Hermes Hermes is the Go port of the great mailgen engine for Node.js. Check their work, it's awesome! It's a package that generates clean, responsive

Dec 28, 2022
:envelope: A streaming Go library for the Internet Message Format and mail messages

go-message A Go library for the Internet Message Format. It implements: RFC 5322: Internet Message Format RFC 2045, RFC 2046 and RFC 2047: Multipurpos

Dec 26, 2022
Filtering spam in mail server, protecting both client privacy and server algorithm

HE Spamfilter SNUCSE 2021 "Intelligent Computing System Design Project" Hyesun Kwak Myeonghwan Ahn Dongwon Lee abstract Naïve Bayesian spam filtering

Mar 23, 2022
Inline styling for html mail in golang

go-premailer Inline styling for HTML mail in golang Document install go get github.com/vanng822/go-premailer/premailer Example import ( "fmt" "gith

Nov 30, 2022
Go library for sending mail with the Mailgun API.

Mailgun with Go Go library for interacting with the Mailgun API. Usage package main import ( "context" "fmt" "log" "time" "githu

Dec 25, 2022
✉️ Composable all-in-one mail server.

Maddy Mail Server Composable all-in-one mail server. Maddy Mail Server implements all functionality required to run a e-mail server. It can send messa

Dec 27, 2022
an MDA that sends a webhook on recieval of mail

an MDA that sends a webhook on recieval of mail

Aug 13, 2022
📧 Example of sending mail via SendGrid in Golang.

?? go-sendgrid-example Example of sending mail via SendGrid in Golang. Get it started $ make setup # Edit environment variables $ vim ./env/local.env

Jan 11, 2022
Mail_sender - This library is for sending emails from your mail

Mail Sender This library is for sending emails from your mail Installation mail_

Dec 30, 2021
Mcopa - A library allows for parsing an email message into a more convenient form than the net/mail provides

Mail content parsing This library allows for parsing an email message into a mor

Jan 1, 2022
Simple tool to test SMTP mail send with various settings including TLS1.1 downgrade

smtptest Simple tool to test SMTP mail send with various settings including TLS1.1 downgrade All settings are configurable in the config.yaml file ser

Sep 19, 2022
Go-mail - Email service using Kafka consumer

?? The Project This project consists in a Kafka consumer that reads messages of

Feb 5, 2022
Golang package for send email. Support keep alive connection, TLS and SSL. Easy for bulk SMTP.

Go Simple Mail The best way to send emails in Go with SMTP Keep Alive and Timeout for Connect and Send. IMPORTANT Examples in this README are for v2.2

Jan 8, 2023
Hxgomail - Gomail - a simple and efficient package to send emails

Gomail Introduction Gomail is a simple and efficient package to send emails. It

Jan 4, 2022
DKIM package for golang

go-dkim DKIM package for Golang Getting started Install go get github.com/toorop/go-dkim Warning: you need to use Go 1.4.2-master or 1.4.3 (when it

Dec 10, 2022
POP-3 client package for Go.

GOP-3 (Go + POP-3) is a POP-3 client for Go. It has experimental purpose and it is still under development. RFC 1939 document has been followed while developing package.

Dec 25, 2021