summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-08-03 11:50:24 +0700
committerShulhan <ms@kilabit.info>2024-08-04 11:33:27 +0700
commit9902b65d3feef74a30001b8f150299467693e699 (patch)
treece5e018cb52be956ed50cd93d0f83c26d615f82d
parent7f215d6ff48191644732cbca7d350dc87b6d8edc (diff)
downloadpakakeh.go-9902b65d3feef74a30001b8f150299467693e699.tar.xz
lib/email: export the field Fields in Header
By exporting the field, this allow the caller to filter or manage the Header Fields manually.
-rw-r--r--lib/email/header.go63
-rw-r--r--lib/email/message.go14
2 files changed, 39 insertions, 38 deletions
diff --git a/lib/email/header.go b/lib/email/header.go
index 1e0eae03..10f84b86 100644
--- a/lib/email/header.go
+++ b/lib/email/header.go
@@ -12,14 +12,15 @@ import (
"strings"
)
-// Header represent list of fields in message.
+// Header represent header of message.
+// It contains list of field in message.
type Header struct {
- // fields is ordered from top to bottom, the first field in message
+ // Fields is ordered from top to bottom, the first field in message
// header is equal to the first element in slice.
//
// We are not using map here it to prevent the header being reordered
// when packing the message back into raw format.
- fields []*Field
+ Fields []*Field
}
// ParseHeader parse the raw header from top to bottom.
@@ -59,7 +60,7 @@ func ParseHeader(raw []byte) (hdr *Header, rest []byte, err error) {
if hdr == nil {
hdr = &Header{}
}
- hdr.fields = append(hdr.fields, field)
+ hdr.Fields = append(hdr.Fields, field)
}
if len(rest) == 0 {
return hdr, rest, nil
@@ -75,7 +76,7 @@ func (hdr *Header) addMailboxes(ft FieldType, mailboxes []byte) (err error) {
f, field *Field
)
- for _, f = range hdr.fields {
+ for _, f = range hdr.Fields {
if f.Type == ft {
field = f
break
@@ -85,7 +86,7 @@ func (hdr *Header) addMailboxes(ft FieldType, mailboxes []byte) (err error) {
field = &Field{
Type: ft,
}
- hdr.fields = append(hdr.fields, field)
+ hdr.Fields = append(hdr.Fields, field)
field.setName([]byte(fieldNames[ft]))
field.setValue(mailboxes)
return field.unpack()
@@ -107,7 +108,7 @@ func (hdr *Header) Boundary() string {
// ContentType return the unpacked value of field "Content-Type", or nil if no
// field Content-Type exist or there is an error when unpacking.
func (hdr *Header) ContentType() *ContentType {
- for _, f := range hdr.fields {
+ for _, f := range hdr.Fields {
if f.Type != FieldTypeContentType {
continue
}
@@ -129,27 +130,27 @@ func (hdr *Header) ContentType() *ContentType {
// For example, to get the second DKIM-Signature from the top, call it with
// "n=2", but if no second DKIM-Signature it will return nil.
func (hdr *Header) DKIM(n int) (dkimHeader *Header) {
- if n == 0 || len(hdr.fields) == 0 {
+ if n == 0 || len(hdr.Fields) == 0 {
return nil
}
x := 0
- for ; x < len(hdr.fields); x++ {
- if hdr.fields[x].Type == FieldTypeDKIMSignature {
+ for ; x < len(hdr.Fields); x++ {
+ if hdr.Fields[x].Type == FieldTypeDKIMSignature {
n--
if n == 0 {
break
}
}
}
- if x == len(hdr.fields) {
+ if x == len(hdr.Fields) {
return nil
}
dkimHeader = &Header{
- fields: make([]*Field, 0, len(hdr.fields)-x),
+ Fields: make([]*Field, 0, len(hdr.Fields)-x),
}
- for ; x < len(hdr.fields); x++ {
- dkimHeader.fields = append(dkimHeader.fields, hdr.fields[x])
+ for ; x < len(hdr.Fields); x++ {
+ dkimHeader.Fields = append(dkimHeader.Fields, hdr.Fields[x])
}
return dkimHeader
@@ -158,9 +159,9 @@ func (hdr *Header) DKIM(n int) (dkimHeader *Header) {
// Filter specific field type. If multiple fields type exist it will
// return all of them.
func (hdr *Header) Filter(ft FieldType) (fields []*Field) {
- for x := len(hdr.fields) - 1; x >= 0; x-- {
- if hdr.fields[x].Type == ft {
- fields = append(fields, hdr.fields[x])
+ for x := len(hdr.Fields) - 1; x >= 0; x-- {
+ if hdr.Fields[x].Type == ft {
+ fields = append(fields, hdr.Fields[x])
}
}
return
@@ -168,9 +169,9 @@ func (hdr *Header) Filter(ft FieldType) (fields []*Field) {
// ID return the Message-ID or empty if not exist.
func (hdr *Header) ID() string {
- for x := len(hdr.fields) - 1; x >= 0; x-- {
- if hdr.fields[x].Type == FieldTypeMessageID {
- return hdr.fields[x].oriValue
+ for x := len(hdr.Fields) - 1; x >= 0; x-- {
+ if hdr.Fields[x].Type == FieldTypeMessageID {
+ return hdr.Fields[x].oriValue
}
}
return ``
@@ -178,14 +179,14 @@ func (hdr *Header) ID() string {
// PushTop put the field at the top of header.
func (hdr *Header) PushTop(f *Field) {
- hdr.fields = append([]*Field{f}, hdr.fields...)
+ hdr.Fields = append([]*Field{f}, hdr.Fields...)
}
// Relaxed canonicalize the header using "relaxed" algorithm and return it.
func (hdr *Header) Relaxed() []byte {
var bb bytes.Buffer
- for _, f := range hdr.fields {
+ for _, f := range hdr.Fields {
if len(f.Name) > 0 && len(f.Value) > 0 {
bb.Write(f.Relaxed())
}
@@ -213,13 +214,13 @@ func (hdr *Header) Set(ft FieldType, value []byte) (err error) {
return fmt.Errorf("Set: %w", err)
}
- for x, f = range hdr.fields {
+ for x, f = range hdr.Fields {
if f.Type == ft {
- hdr.fields[x] = field
+ hdr.Fields[x] = field
return nil
}
}
- hdr.fields = append(hdr.fields, field)
+ hdr.Fields = append(hdr.Fields, field)
return nil
}
@@ -227,7 +228,7 @@ func (hdr *Header) Set(ft FieldType, value []byte) (err error) {
func (hdr *Header) Simple() []byte {
var bb bytes.Buffer
- for _, f := range hdr.fields {
+ for _, f := range hdr.Fields {
if len(f.oriName) > 0 && len(f.oriValue) > 0 {
bb.WriteString(f.oriName)
bb.WriteByte(':')
@@ -240,10 +241,10 @@ func (hdr *Header) Simple() []byte {
// popByName remove the field where the name match from header.
func (hdr *Header) popByName(name string) (f *Field) {
- for x := len(hdr.fields) - 1; x >= 0; x-- {
- if strings.EqualFold(hdr.fields[x].Name, name) {
- f = hdr.fields[x]
- hdr.fields = append(hdr.fields[:x], hdr.fields[x+1:]...)
+ for x := len(hdr.Fields) - 1; x >= 0; x-- {
+ if strings.EqualFold(hdr.Fields[x].Name, name) {
+ f = hdr.Fields[x]
+ hdr.Fields = append(hdr.Fields[:x], hdr.Fields[x+1:]...)
}
}
return f
@@ -276,7 +277,7 @@ func (hdr *Header) WriteTo(w io.Writer) (n int64, err error) {
f *Field
m int
)
- for _, f = range hdr.fields {
+ for _, f = range hdr.Fields {
switch f.Type {
case FieldTypeContentType:
m, err = fmt.Fprintf(w, "%s: %s\r\n", f.Name, f.contentType.String())
diff --git a/lib/email/message.go b/lib/email/message.go
index a3028267..e2570947 100644
--- a/lib/email/message.go
+++ b/lib/email/message.go
@@ -212,9 +212,9 @@ func (msg *Message) DKIMSign(pk *rsa.PrivateKey, sig *dkim.Signature) (err error
}
subHeader := &Header{
- fields: make([]*Field, len(msg.Header.fields)),
+ Fields: make([]*Field, len(msg.Header.Fields)),
}
- copy(subHeader.fields, msg.Header.fields)
+ copy(subHeader.Fields, msg.Header.Fields)
hh, _ := sig.Hash(msg.CanonHeader(subHeader, dkimField))
@@ -247,12 +247,12 @@ func (msg *Message) DKIMVerify() (*dkim.Status, error) {
// Only process the first DKIM-Signature for now.
subHeader := msg.Header.DKIM(1)
- if subHeader == nil || len(subHeader.fields) == 0 {
+ if subHeader == nil || len(subHeader.Fields) == 0 {
msg.dkimStatus.Type = dkim.StatusNoSignature
return msg.dkimStatus, nil
}
- sig, err := dkim.Parse([]byte(subHeader.fields[0].Value))
+ sig, err := dkim.Parse([]byte(subHeader.Fields[0].Value))
if sig != nil && len(sig.SDID) > 0 {
msg.dkimStatus.SDID = libbytes.Copy(sig.SDID)
@@ -303,7 +303,7 @@ func (msg *Message) DKIMVerify() (*dkim.Status, error) {
return nil, err
}
- canonHeader := msg.CanonHeader(subHeader, subHeader.fields[0])
+ canonHeader := msg.CanonHeader(subHeader, subHeader.Fields[0])
hh, _ := sig.Hash(canonHeader)
err = sig.Verify(key, hh)
@@ -636,9 +636,9 @@ func (msg *Message) setDKIMHeaders(sig *dkim.Signature) {
return
}
- sig.Headers = make([][]byte, 0, len(msg.Header.fields))
+ sig.Headers = make([][]byte, 0, len(msg.Header.Fields))
- for _, f := range msg.Header.fields {
+ for _, f := range msg.Header.Fields {
sig.Headers = append(sig.Headers, []byte(f.Name))
}
}