Hey golang-nuts,
After working in go for almost a year now and finding the net/http server package so eloquent and productive to work in I found myself wanting an smtp implementation as well. The go project has a few relevant packages that have gotten me to a successful go mail server (perhaps more just a Mail Exchanger) I then began wondering if I could create an smtp package that would make it really simple for devs to start up a smtp server in the same spirit of simplicity that the http package provides. Something like:
fmt.Println("Incoming message!")
fmt.Println(" RemoteAddr:", r.RemoteAddr)
fmt.Println(" From:", r.From)
for _, t := range r.To{
fmt.Println(" To:", t)
}
fmt.Println(" Message:", r.Message)
}
smtp.ListenAndServeTLS(":2525", "cert.pem", "key.pem", nil)
Questions
1. Because smtp is stateful, I'm not really sure how to handle things like authentication, verification, expand, etc
a. One of my ideas is to make 'handlers' more than a .ServeSMTP(r *smtp.Request) interface, perhaps it has multiple callbacks for each command that might come through smtp, but abstracted away from the protocol a bit. For example verify might have the signature func Verify(email string) bool, and expand: func Expand(email string) []string
b. I thought about utilizing the handler to 'verify' addresses that the server can handle. So internally the server would just call the .Handle method and if the muxer had a registered result than the server would allow that recipient or respond accordingly to verify command.
c. Authentication would obviously need some callback, should that be on the server? Or perhaps on the servers handler as mentioned above?
2. The smtp rfc's have recommendations for limits on line length. My idea is to expand textproto to read lines up to a certain length before they would return with an error perhaps. This would need some additional methods, or some way to set the read length on the connection.
3. I'd also like to expand message a bit more, add the ability to set headers, write/modify the body. It also seems like a good place to throw in a method for dkim validation and signing.
4. Is there interest for adding this to the standard library?
Proposal
To sum up what I'm thinking:
Add sa server to the net/smtp package
- A default server will be provided
- The default server will use a smtp muxer that surfaces HandleFunc and Handle methods
Provide byte limit readers to the net/textproto package
Add functionality to the net/message package
- Ability to write new/replace headers
Thanks for taking the time to read through this and consider a contribution to golang. I hope this sparks a good discussion and gives me a better idea of whether this would be a valuable contribution.