Continued e-mail support
This commit is contained in:
parent
6b46eb46e2
commit
f553cdb282
10 changed files with 132 additions and 10 deletions
|
@ -8,14 +8,14 @@ import (
|
|||
)
|
||||
|
||||
type mailer interface {
|
||||
Send(to string, m *message) error
|
||||
Send(from, to string, m *message) error
|
||||
}
|
||||
|
||||
type smtpMailer struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (s *smtpMailer) Send(to string, m *message) error {
|
||||
func (s *smtpMailer) Send(from, to string, m *message) error {
|
||||
host, _, err := net.SplitHostPort(s.config.SMTPAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -26,10 +26,18 @@ func (s *smtpMailer) Send(to string, m *message) error {
|
|||
}
|
||||
subject += " - " + m.Topic
|
||||
subject = strings.ReplaceAll(strings.ReplaceAll(subject, "\r", ""), "\n", " ")
|
||||
message := m.Message
|
||||
if len(m.Tags) > 0 {
|
||||
message += "\nTags: " + strings.Join(m.Tags, ", ") // FIXME emojis
|
||||
}
|
||||
if m.Priority != 0 && m.Priority != 3 {
|
||||
message += fmt.Sprintf("\nPriority: %d", m.Priority) // FIXME to string
|
||||
}
|
||||
message += fmt.Sprintf("\n\n--\nMessage was sent via %s by client %s", m.Topic, from) // FIXME short URL
|
||||
msg := []byte(fmt.Sprintf("From: %s\r\n"+
|
||||
"To: %s\r\n"+
|
||||
"Subject: %s\r\n\r\n"+
|
||||
"%s\r\n", s.config.SMTPFrom, to, subject, m.Message))
|
||||
"%s\r\n", s.config.SMTPFrom, to, subject, message))
|
||||
auth := smtp.PlainAuth("", s.config.SMTPUser, s.config.SMTPPass, host)
|
||||
return smtp.SendMail(s.config.SMTPAddr, auth, s.config.SMTPFrom, []string{to}, msg)
|
||||
}
|
||||
|
|
|
@ -344,7 +344,7 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visito
|
|||
}
|
||||
if s.mailer != nil && email != "" && !delayed {
|
||||
go func() {
|
||||
if err := s.mailer.Send(email, m); err != nil {
|
||||
if err := s.mailer.Send(v.ip, email, m); err != nil {
|
||||
log.Printf("Unable to send email: %v", err.Error())
|
||||
}
|
||||
}()
|
||||
|
@ -772,7 +772,7 @@ func (s *Server) visitor(r *http.Request) *visitor {
|
|||
}
|
||||
v, exists := s.visitors[ip]
|
||||
if !exists {
|
||||
s.visitors[ip] = newVisitor(s.config)
|
||||
s.visitors[ip] = newVisitor(s.config, ip)
|
||||
return s.visitors[ip]
|
||||
}
|
||||
v.Keepalive()
|
||||
|
|
|
@ -511,10 +511,10 @@ func TestServer_Curl_Publish_Poll(t *testing.T) {
|
|||
|
||||
type testMailer struct {
|
||||
count int
|
||||
mu sync.Mutex
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (t *testMailer) Send(to string, m *message) error {
|
||||
func (t *testMailer) Send(from, to string, m *message) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.count++
|
||||
|
|
|
@ -17,6 +17,7 @@ const (
|
|||
// visitor represents an API user, and its associated rate.Limiter used for rate limiting
|
||||
type visitor struct {
|
||||
config *Config
|
||||
ip string
|
||||
requests *rate.Limiter
|
||||
emails *rate.Limiter
|
||||
subscriptions *util.Limiter
|
||||
|
@ -24,9 +25,10 @@ type visitor struct {
|
|||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func newVisitor(conf *Config) *visitor {
|
||||
func newVisitor(conf *Config, ip string) *visitor {
|
||||
return &visitor{
|
||||
config: conf,
|
||||
ip: ip,
|
||||
requests: rate.NewLimiter(rate.Every(conf.VisitorRequestLimitReplenish), conf.VisitorRequestLimitBurst),
|
||||
emails: rate.NewLimiter(rate.Every(conf.VisitorEmailLimitReplenish), conf.VisitorEmailLimitBurst),
|
||||
subscriptions: util.NewLimiter(int64(conf.VisitorSubscriptionLimit)),
|
||||
|
@ -34,6 +36,10 @@ func newVisitor(conf *Config) *visitor {
|
|||
}
|
||||
}
|
||||
|
||||
func (v *visitor) IP() string {
|
||||
return v.ip
|
||||
}
|
||||
|
||||
func (v *visitor) RequestAllowed() error {
|
||||
if !v.requests.Allow() {
|
||||
return errHTTPTooManyRequests
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue