1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-17 17:47:03 +00:00

Mixed use support

You can now optionally configure a "no store" domain.  When inbucket
receives a message destined for a user at that domain, it will accept
the message but not store it to disk.  This allows the same instance
of Inbucket to be shared by people who wish to view email content and
those who want to load test.
This commit is contained in:
James Hillyerd
2012-11-07 15:26:15 -08:00
parent e2cc4fc8a1
commit b8f2527b93
5 changed files with 48 additions and 17 deletions

View File

@@ -15,6 +15,7 @@ type SmtpConfig struct {
Ip4address net.IP
Ip4port int
Domain string
DomainNoStore string
MaxRecipients int
MaxIdleSeconds int
MaxMessageBytes int
@@ -177,6 +178,15 @@ func parseSmtpConfig() error {
}
smtpConfig.Domain = str
option = "domain.nostore"
if Config.HasOption(section, option) {
str, err = Config.String(section, option)
if err != nil {
return fmt.Errorf("Failed to parse [%v]%v: '%v'", section, option, err)
}
smtpConfig.DomainNoStore = str
}
option = "max.recipients"
smtpConfig.MaxRecipients, err = Config.Int(section, option)
if err != nil {

View File

@@ -25,6 +25,10 @@ ip4.port=2500
# used in SMTP greeting
domain=inbucket.local
# optional: mail sent to accounts at this domain will not be stored,
# for mixed use (content and load testing)
domain.nostore=bitbucket.local
# Maximum number of RCPT TO: addresses we allow from clients, the SMTP
# RFC recommends this be at least 100.
max.recipients=100

View File

@@ -25,6 +25,10 @@ ip4.port=2500
# used in SMTP greeting
domain=inbucket.local
# optional: mail sent to accounts at this domain will not be stored,
# for mixed use (content and load testing)
#domain.nostore=bitbucket.local
# Maximum number of RCPT TO: addresses we allow from clients, the SMTP
# RFC recommends this be at least 100.
max.recipients=100

View File

@@ -300,15 +300,20 @@ func (ss *Session) dataHandler() {
i := 0
for e := ss.recipients.Front(); e != nil; e = e.Next() {
recip := e.Value.(string)
mb, err := ss.server.dataStore.MailboxFor(recip)
if err != nil {
ss.error("Failed to open mailbox for %v", recip)
ss.send(fmt.Sprintf("451 Failed to open mailbox for %v", recip))
ss.reset()
return
if !strings.HasSuffix(strings.ToLower(recip), "@" + ss.server.domainNoStore) {
// Not our "no store" domain, so store the message
mb, err := ss.server.dataStore.MailboxFor(recip)
if err != nil {
ss.error("Failed to open mailbox for %v", recip)
ss.send(fmt.Sprintf("451 Failed to open mailbox for %v", recip))
ss.reset()
return
}
mailboxes[i] = mb
messages[i] = mb.NewMessage()
} else {
log.Trace("Not storing message for '%v'", recip)
}
mailboxes[i] = mb
messages[i] = mb.NewMessage()
i++
}
}
@@ -333,8 +338,10 @@ func (ss *Session) dataHandler() {
// Mail data complete
if ss.server.storeMessages {
for _, m := range messages {
m.Close()
expDeliveredTotal.Add(1)
if m != nil {
m.Close()
expDeliveredTotal.Add(1)
}
}
} else {
expDeliveredTotal.Add(1)
@@ -360,12 +367,14 @@ func (ss *Session) dataHandler() {
// Append to message objects
if ss.server.storeMessages {
for i, m := range messages {
if err := m.Append(line); err != nil {
ss.error("Failed to append to mailbox %v: %v", mailboxes[i], err)
ss.send("554 Something went wrong")
ss.reset()
// TODO: Should really cleanup the crap on filesystem...
return
if m != nil {
if err := m.Append(line); err != nil {
ss.error("Failed to append to mailbox %v: %v", mailboxes[i], err)
ss.send("554 Something went wrong")
ss.reset()
// TODO: Should really cleanup the crap on filesystem...
return
}
}
}
}

View File

@@ -7,12 +7,14 @@ import (
"github.com/jhillyerd/inbucket/config"
"github.com/jhillyerd/inbucket/log"
"net"
"strings"
"time"
)
// Real server code starts here
type Server struct {
domain string
domainNoStore string
maxRecips int
maxIdleSeconds int
maxMessageBytes int
@@ -45,7 +47,7 @@ func New() *Server {
cfg := config.GetSmtpConfig()
return &Server{dataStore: ds, domain: cfg.Domain, maxRecips: cfg.MaxRecipients,
maxIdleSeconds: cfg.MaxIdleSeconds, maxMessageBytes: cfg.MaxMessageBytes,
storeMessages: cfg.StoreMessages}
storeMessages: cfg.StoreMessages, domainNoStore: strings.ToLower(cfg.DomainNoStore)}
}
// Main listener loop
@@ -69,6 +71,8 @@ func (s *Server) Start() {
if !s.storeMessages {
log.Info("Load test mode active, messages will not be stored")
} else if s.domainNoStore != "" {
log.Info("Messages sent to domain '%v' will be discarded", s.domainNoStore)
}
// Start retention scanner