-
Notifications
You must be signed in to change notification settings - Fork 366
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
issue #199 - IP addresses are normalized, Address.String() returns an…
… empty string of address is empty, or just "postmaster" it it's a postmaster address
- Loading branch information
Showing
6 changed files
with
172 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import ( | |
"fmt" | ||
"io" | ||
"mime" | ||
"net" | ||
"net/mail" | ||
"net/textproto" | ||
"strings" | ||
|
@@ -41,10 +42,36 @@ type Address struct { | |
PathParams [][]string | ||
// NullPath is true if <> was received | ||
NullPath bool | ||
// Quoted indicates if the local-part needs quotes | ||
Quoted bool | ||
// IP stores the IP Address, if the Host is an IP | ||
IP net.IP | ||
} | ||
|
||
func (ep *Address) String() string { | ||
return fmt.Sprintf("%s@%s", ep.User, ep.Host) | ||
var local string | ||
if ep.IsEmpty() { | ||
return "" | ||
} | ||
if ep.Quoted { | ||
var sb bytes.Buffer | ||
sb.WriteByte('"') | ||
for i := 0; i < len(ep.User); i++ { | ||
if ep.User[i] == '\\' || ep.User[i] == '"' { | ||
// escape | ||
sb.WriteByte('\\') | ||
} | ||
sb.WriteByte(ep.User[i]) | ||
} | ||
sb.WriteByte('"') | ||
local = sb.String() | ||
} else { | ||
local = ep.User | ||
} | ||
if ep.Host != "" { | ||
return fmt.Sprintf("%s@%s", local, ep.Host) | ||
} | ||
return local | ||
} | ||
|
||
func (ep *Address) IsEmpty() bool { | ||
|
@@ -55,20 +82,46 @@ var ap = mail.AddressParser{} | |
|
||
// NewAddress takes a string of an RFC 5322 address of the | ||
// form "Gogh Fir <[email protected]>" or "[email protected]". | ||
func NewAddress(str string) (Address, error) { | ||
a, err := ap.Parse(str) | ||
// TODO its not parsing ip addresses properly | ||
func NewAddress(str string) (*Address, error) { | ||
var isQuoted, isIP bool | ||
var pos int | ||
var a *mail.Address | ||
var err error | ||
address := new(Address) | ||
if pos = strings.LastIndex(str, "@"); pos > 0 && str[pos-1] == '"' { | ||
isQuoted = true | ||
} | ||
if pos > 0 && pos+1 < len(str) && str[pos+1] == '[' { | ||
isIP = true | ||
} | ||
|
||
a, err = ap.Parse(str) | ||
|
||
if err != nil { | ||
return Address{}, err | ||
return nil, err | ||
} | ||
pos := strings.Index(a.Address, "@") | ||
pos = strings.LastIndex(a.Address, "@") | ||
|
||
if pos > 0 { | ||
return Address{ | ||
User: a.Address[0:pos], | ||
Host: a.Address[pos+1:], | ||
}, | ||
nil | ||
address.User = a.Address[0:pos] | ||
address.Host = a.Address[pos+1:] | ||
if isQuoted { | ||
address.Quoted = true | ||
} | ||
if isIP { | ||
// check if the ip address is valid | ||
if v := net.ParseIP(address.Host); v == nil { | ||
return nil, errors.New("invalid ip") | ||
} else { | ||
address.IP = v | ||
// this will normalize ipv6 addresses | ||
address.Host = v.String() | ||
} | ||
} | ||
return address, nil | ||
} | ||
return Address{}, errors.New("invalid address") | ||
return nil, errors.New("invalid address") | ||
} | ||
|
||
// Envelope of Email represents a single SMTP message. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ func TestMimeHeaderDecode(t *testing.T) { | |
*/ | ||
|
||
str := MimeHeaderDecode("=?utf-8?B?55So5oi34oCcRXBpZGVtaW9sb2d5IGluIG51cnNpbmcgYW5kIGg=?= =?utf-8?B?ZWFsdGggY2FyZSBlQm9vayByZWFkL2F1ZGlvIGlkOm8=?= =?utf-8?B?cTNqZWVr4oCd5Zyo572R56uZ4oCcU1BZ5Lit5paH5a6Y5pa5572R56uZ4oCd?= =?utf-8?B?55qE5biQ5Y+36K+m5oOF?=") | ||
if i := strings.Index(str, "用户“Epidemiology in nursing and h ealth care eBook read/audio id:o q3jeek”在网站“SPY中文官方网站” 的帐号详情"); i != 0 { | ||
if i := strings.Index(str, "用户“Epidemiology in nursing and health care eBook read/audio id:oq3jeek”在网站“SPY中文官方网站” 的帐号详情"); i != 0 { | ||
t.Error("expecting 用户“Epidemiology in nursing and h ealth care eBook read/audio id:o q3jeek”在网站“SPY中文官方网站” 的帐号详情, got:", str) | ||
} | ||
str = MimeHeaderDecode("=?ISO-8859-1?Q?Andr=E9?= Pirard <[email protected]>") | ||
|
@@ -39,6 +39,34 @@ func TestNewAddress(t *testing.T) { | |
t.Error("there should be no error:", addr.Host, err) | ||
} | ||
} | ||
|
||
func TestQuotedAddress(t *testing.T) { | ||
|
||
str := `<" yo-- man wazz'''up? surprise \surprise, this is [email protected] "@example.com>` | ||
//str = `<"post\master">` | ||
addr, err := NewAddress(str) | ||
if err != nil { | ||
t.Error("there should be no error:", err) | ||
} | ||
|
||
str = addr.String() | ||
// in this case, string should remove the unnecessary escape | ||
if strings.Contains(str, "\\surprise") { | ||
t.Error("there should be no \\surprise:", err) | ||
} | ||
|
||
} | ||
|
||
func TestAddressWithIP(t *testing.T) { | ||
str := `<" yo-- man wazz'''up? surprise \surprise, this is [email protected] "@[64.233.160.71]>` | ||
addr, err := NewAddress(str) | ||
if err != nil { | ||
t.Error("there should be no error:", err) | ||
} else if addr.IP == nil { | ||
t.Error("expecting the address host to be an IP") | ||
} | ||
} | ||
|
||
func TestEnvelope(t *testing.T) { | ||
e := NewEnvelope("127.0.0.1", 22) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.