diff options
| author | Shulhan <ms@kilabit.info> | 2023-05-27 19:18:59 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-05-30 23:34:53 +0700 |
| commit | 3ccb88936cb68eb9c8063fbf55d0e6fc521da173 (patch) | |
| tree | e5105a7c0b2518aa97a389f81b52bb38669fce76 | |
| parent | e9fd20a4031c8708a9c8d4eb1f01792047913371 (diff) | |
| download | pakakeh.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.go | 14 | ||||
| -rw-r--r-- | lib/email/contenttype_example_test.go | 74 | ||||
| -rw-r--r-- | lib/email/contenttype_test.go | 45 |
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) } } |
