mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 08:23:48 +03:00
move checking whether a message needs smtputf8 (has utf8 in any of the header sections) to package message
This commit is contained in:
parent
3f727cf380
commit
0871bf5219
3 changed files with 49 additions and 57 deletions
32
main.go
32
main.go
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
"crypto"
|
||||||
|
@ -3519,35 +3518,10 @@ func cmdMessageParse(c *cmd) {
|
||||||
err = enc.Encode(part)
|
err = enc.Encode(part)
|
||||||
xcheckf(err, "write")
|
xcheckf(err, "write")
|
||||||
|
|
||||||
hasNonASCII := func(r io.Reader) bool {
|
|
||||||
br := bufio.NewReader(r)
|
|
||||||
for {
|
|
||||||
b, err := br.ReadByte()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
xcheckf(err, "read header")
|
|
||||||
if b > 0x7f {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var walk func(p *message.Part) bool
|
|
||||||
walk = func(p *message.Part) bool {
|
|
||||||
if hasNonASCII(p.HeaderReader()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, pp := range p.Parts {
|
|
||||||
if walk(&pp) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if smtputf8 {
|
if smtputf8 {
|
||||||
fmt.Println("message needs smtputf8:", walk(&part))
|
needs, err := part.NeedsSMTPUTF8()
|
||||||
|
xcheckf(err, "checking if message needs smtputf8")
|
||||||
|
fmt.Println("message needs smtputf8:", needs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"golang.org/x/text/encoding/ianaindex"
|
"golang.org/x/text/encoding/ianaindex"
|
||||||
|
|
||||||
|
@ -598,6 +599,38 @@ func (p *Part) IsDSN() bool {
|
||||||
(p.Parts[1].MediaSubType == "DELIVERY-STATUS" || p.Parts[1].MediaSubType == "GLOBAL-DELIVERY-STATUS")
|
(p.Parts[1].MediaSubType == "DELIVERY-STATUS" || p.Parts[1].MediaSubType == "GLOBAL-DELIVERY-STATUS")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasNonASCII(r io.Reader) (bool, error) {
|
||||||
|
br := bufio.NewReader(r)
|
||||||
|
for {
|
||||||
|
b, err := br.ReadByte()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if b > unicode.MaxASCII {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NeedsSMTPUTF8 returns whether the part needs the SMTPUTF8 extension to be
|
||||||
|
// transported, due to non-ascii in message headers.
|
||||||
|
func (p *Part) NeedsSMTPUTF8() (bool, error) {
|
||||||
|
if has, err := hasNonASCII(p.HeaderReader()); err != nil {
|
||||||
|
return false, fmt.Errorf("reading header: %w", err)
|
||||||
|
} else if has {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
for _, pp := range p.Parts {
|
||||||
|
if has, err := pp.NeedsSMTPUTF8(); err != nil || has {
|
||||||
|
return has, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
var ErrParamEncoding = errors.New("bad header parameter encoding")
|
var ErrParamEncoding = errors.New("bad header parameter encoding")
|
||||||
|
|
||||||
// DispositionFilename tries to parse the disposition header and the "filename"
|
// DispositionFilename tries to parse the disposition header and the "filename"
|
||||||
|
|
|
@ -1940,47 +1940,32 @@ func (c *conn) cmdRcpt(p *parser) {
|
||||||
c.bwritecodeline(smtp.C250Completed, smtp.SeAddr1Other0, "now on the list", nil)
|
c.bwritecodeline(smtp.C250Completed, smtp.SeAddr1Other0, "now on the list", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ../rfc/6531:497
|
func hasNonASCII(s string) bool {
|
||||||
func (c *conn) isSMTPUTF8Required(part *message.Part) bool {
|
for _, c := range []byte(s) {
|
||||||
hasNonASCII := func(r io.Reader) bool {
|
if c > unicode.MaxASCII {
|
||||||
br := bufio.NewReader(r)
|
|
||||||
for {
|
|
||||||
b, err := br.ReadByte()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
xcheckf(err, "read header")
|
|
||||||
if b > unicode.MaxASCII {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var hasNonASCIIPartHeader func(p *message.Part) bool
|
|
||||||
hasNonASCIIPartHeader = func(p *message.Part) bool {
|
|
||||||
if hasNonASCII(p.HeaderReader()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, pp := range p.Parts {
|
|
||||||
if hasNonASCIIPartHeader(&pp) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ../rfc/6531:497
|
||||||
|
func (c *conn) isSMTPUTF8Required(part *message.Part) bool {
|
||||||
// Check "MAIL FROM".
|
// Check "MAIL FROM".
|
||||||
if hasNonASCII(strings.NewReader(string(c.mailFrom.Localpart))) {
|
if hasNonASCII(string(c.mailFrom.Localpart)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Check all "RCPT TO".
|
// Check all "RCPT TO".
|
||||||
for _, rcpt := range c.recipients {
|
for _, rcpt := range c.recipients {
|
||||||
if hasNonASCII(strings.NewReader(string(rcpt.Addr.Localpart))) {
|
if hasNonASCII(string(rcpt.Addr.Localpart)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check header in all message parts.
|
// Check header in all message parts.
|
||||||
return hasNonASCIIPartHeader(part)
|
smtputf8, err := part.NeedsSMTPUTF8()
|
||||||
|
xcheckf(err, "checking if smtputf8 is required")
|
||||||
|
return smtputf8
|
||||||
}
|
}
|
||||||
|
|
||||||
// ../rfc/5321:1992 ../rfc/5321:1098
|
// ../rfc/5321:1992 ../rfc/5321:1098
|
||||||
|
|
Loading…
Reference in a new issue