flashmob / go-guerrilla

Mini SMTP server written in golang
MIT License
2.79k stars 366 forks source link

Internationalized Email Support #152

Open dcormier opened 5 years ago

dcormier commented 5 years ago

Some SMTP clients will only send to internationalized email addresses (addresses with non-ASCII Unicode characters in the localpart) if the receiving server supports the SMTPUTF8 SMTP extension. Gmail, for example, won't send to a non-ASCII address if the receiving server doesn't advertise SMTPUTF8.

It would be nice if guerilla supported SMTPUTF8.

Relevant RFC: https://tools.ietf.org/html/rfc6531

Implementation I added to a different project: mailhog/smtp#3 (this bit, specifically)

flashmob commented 5 years ago

Thanks for the feature request! Currently, there's nobody working on this, so you're welcome to pick this up if you like. Could even discuss a bounty/reward from the donations fund, interested?

Some technical thoughts:

It looks like it changes the syntax slightly to the ABNF rule, so parse.go would need to be extended this add this. On first look, it looks like the isAtext rule would need modification for the local part. Likewise, it looks like the subdomain rule would need to be modified to, since we can't use isLetDig.

The feature should also be enabled / disabled in the config, as not everyone wants to accept Internationalized addresses. Instead of making direct changes to Parse in parse.go, it would be better to create a new, say, ParseUTF struct, embed the Parse in it and then override the isAtext and subdomain rules. Then we can modify client.go so that it can switch between the Parse and ParseUTF depending on the config. rfc5321.Parser is used in the Client struct. This would need to be changed to an interface, eg

type AddressParser interface {
    RcptTo(input []byte) (err error)
    MailFrom(input []byte) (err error)
    Reset()
} 
ben-sab commented 4 years ago

Hi @flashmob, I'm happy to work on this issue and put a PR in, but need clarification on a few points. I looked at parse.go and most methods work with bytes, and it seems like runes would be the way to go (since some unicode characters occupy more than a single byte and methods like next and peek are only returning single bytes). Do you mind sharing your thoughts on that please?

flashmob commented 4 years ago

Thanks for the offer! Development of internationalized support has already started with the addition of 8BITMIME in this PR https://github.com/flashmob/go-guerrilla/pull/135 - and the plan is to add full support early next year.

Also, there are a few more tweaks to the parser being made right now, then internationalized supported can be added.

Btw, yes. Ideally, you would need to work with runes instead of bytes.

Another idea - would it be possible to work with bytes, but then at the end check that all the bits align? e.g use [utf8.ValidString](https://golang.org/pkg/unicode/utf8/#ValidString on the local part? (only if characters > 127 were present). Same thing to domains, and whatever else can be internationalized.

rishabh625 commented 4 years ago

Is the development on this undertaken? If not can i work on this? If it is already developed when can we see this feature?

rhettli commented 3 years ago

i dont't know who ti use pop to pull email in gui client.