summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-05-27 19:18:59 +0700
committerShulhan <ms@kilabit.info>2023-05-30 23:34:53 +0700
commit3ccb88936cb68eb9c8063fbf55d0e6fc521da173 (patch)
treee5105a7c0b2518aa97a389f81b52bb38669fce76
parente9fd20a4031c8708a9c8d4eb1f01792047913371 (diff)
downloadpakakeh.go-3ccb88936cb68eb9c8063fbf55d0e6fc521da173.tar.xz
lib/email: make the ContentType match case insensitive
The GetParamValue and SetBoundary should match any parameter key in case insensitive matter. While at it, add examples for ParseContentType and SetBoundary, and move test for GetParamValue to Example.
-rw-r--r--lib/email/contenttype.go14
-rw-r--r--lib/email/contenttype_example_test.go74
-rw-r--r--lib/email/contenttype_test.go45
3 files changed, 107 insertions, 26 deletions
diff --git a/lib/email/contenttype.go b/lib/email/contenttype.go
index 62f4f7b0..7018efaa 100644
--- a/lib/email/contenttype.go
+++ b/lib/email/contenttype.go
@@ -138,30 +138,30 @@ func isValidToken(tok []byte, quoted bool) bool {
// GetParamValue return parameter value related to specific name.
func (ct *ContentType) GetParamValue(name []byte) []byte {
- name = bytes.ToLower(name)
for _, p := range ct.Params {
- if bytes.Equal(p.Key, name) {
+ if bytes.EqualFold(p.Key, name) {
return p.Value
}
}
return nil
}
-// isEqual will return true if the ct's Top and Sub matched with other.
+// isEqual will return true if the Top and Sub matched with other, in
+// case-insensitive matter.
func (ct *ContentType) isEqual(other *ContentType) bool {
if other == nil {
return false
}
- if !bytes.Equal(ct.Top, other.Top) {
+ if !bytes.EqualFold(ct.Top, other.Top) {
return false
}
- return bytes.Equal(ct.Sub, other.Sub)
+ return bytes.EqualFold(ct.Sub, other.Sub)
}
-// SetBoundary set the parameter boundary in content-type header's value.
+// SetBoundary set or replace the Value for Key "boundary".
func (ct *ContentType) SetBoundary(boundary []byte) {
for x := 0; x < len(ct.Params); x++ {
- if bytes.Equal(ct.Params[x].Key, ParamNameBoundary) {
+ if bytes.EqualFold(ct.Params[x].Key, ParamNameBoundary) {
ct.Params[x].Value = boundary
return
}
diff --git a/lib/email/contenttype_example_test.go b/lib/email/contenttype_example_test.go
new file mode 100644
index 00000000..64e43d49
--- /dev/null
+++ b/lib/email/contenttype_example_test.go
@@ -0,0 +1,74 @@
+// Copyright 2023, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package email_test
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/shuLhan/share/lib/email"
+)
+
+func ExampleParseContentType() {
+ var (
+ raw = []byte(`text/plain; key1=val1; key2="value 2"`)
+
+ ct *email.ContentType
+ err error
+ )
+
+ ct, err = email.ParseContentType(raw)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(ct.String())
+
+ // Output:
+ // text/plain; key1=val1; key2="value 2"
+}
+
+func ExampleContentType_GetParamValue() {
+ var (
+ raw = []byte(`text/plain; key1=val1; key2="value 2"`)
+
+ ct *email.ContentType
+ err error
+ )
+
+ ct, err = email.ParseContentType(raw)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var key = []byte(`notexist`)
+ fmt.Printf("%s=%q\n", key, ct.GetParamValue(key))
+
+ key = []byte(`KEY1`)
+ fmt.Printf("%s=%q\n", key, ct.GetParamValue(key))
+
+ key = []byte(`key2`)
+ fmt.Printf("%s=%q\n", key, ct.GetParamValue(key))
+
+ // Output:
+ // notexist=""
+ // KEY1="val1"
+ // key2="value 2"
+
+}
+
+func ExampleContentType_SetBoundary() {
+ var ct = &email.ContentType{}
+
+ ct.SetBoundary([]byte(`42`))
+ fmt.Println(ct.String())
+
+ ct.SetBoundary([]byte(`43`))
+ fmt.Println(ct.String())
+
+ // Output:
+ // /; boundary=42
+ // /; boundary=43
+}
diff --git a/lib/email/contenttype_test.go b/lib/email/contenttype_test.go
index 66c88c14..99897c35 100644
--- a/lib/email/contenttype_test.go
+++ b/lib/email/contenttype_test.go
@@ -80,28 +80,35 @@ func TestParseContentType(t *testing.T) {
}
}
-func TestGetParamValue(t *testing.T) {
- paramValue := []byte("multipart/mixed; boundary=\"----=_Part_1245\"\r\n")
- ct, err := ParseContentType(paramValue)
- if err != nil {
- t.Fatal(err)
- }
+func TestContentType_isEqual(t *testing.T) {
+ var (
+ ct = &ContentType{
+ Top: []byte(`text`),
+ Sub: []byte(`plain`),
+ }
+ got bool
+ )
- cases := []struct {
- in []byte
- exp []byte
- }{{
- in: []byte("notexist"),
- }, {
- in: []byte("Boundary"),
- exp: []byte("----=_Part_1245"),
- }}
+ // Case: with nil.
+ got = ct.isEqual(nil)
+ if got != false {
+ t.Fatalf(`want false, got %v`, got)
+ }
- for _, c := range cases {
- t.Log(c.in)
+ // Case: with Top not match.
+ got = ct.isEqual(&ContentType{Top: []byte(`TEX`)})
+ if got != false {
+ t.Fatalf(`want false, got %v`, got)
+ }
- got := ct.GetParamValue(c.in)
+ // Case: with Sub not match.
+ got = ct.isEqual(&ContentType{Top: []byte(`TEXT`), Sub: []byte(`PLAI`)})
+ if got != false {
+ t.Fatalf(`want false, got %v`, got)
+ }
- test.Assert(t, "GetParamValue", c.exp, got)
+ got = ct.isEqual(&ContentType{Top: []byte(`TEXT`), Sub: []byte(`PLAIN`)})
+ if got != true {
+ t.Fatalf(`want true, got %v`, got)
}
}