2014-04-16 22:29:23 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
2014-06-23 16:41:03 +00:00
|
|
|
"github.com/ian-kent/Go-MailHog/mailhog/config"
|
|
|
|
"github.com/ian-kent/Go-MailHog/mailhog/smtp"
|
2014-06-23 18:21:20 +00:00
|
|
|
"github.com/ian-kent/Go-MailHog/mailhog/http/api"
|
2014-06-23 16:41:03 +00:00
|
|
|
"github.com/ian-kent/Go-MailHog/mailhog/storage"
|
2014-06-23 18:21:20 +00:00
|
|
|
gotcha "github.com/ian-kent/gotcha/app"
|
|
|
|
"github.com/ian-kent/go-log/log"
|
2014-04-20 16:12:32 +00:00
|
|
|
"net"
|
|
|
|
"os"
|
2014-06-23 18:21:20 +00:00
|
|
|
mhhttp "github.com/ian-kent/Go-MailHog/mailhog/http"
|
2014-04-16 22:29:23 +00:00
|
|
|
)
|
|
|
|
|
2014-04-23 23:22:50 +00:00
|
|
|
var conf *config.Config
|
2014-04-20 14:35:59 +00:00
|
|
|
var exitCh chan int
|
2014-04-16 22:29:23 +00:00
|
|
|
|
2014-04-23 23:22:50 +00:00
|
|
|
func configure() {
|
2014-04-24 18:16:35 +00:00
|
|
|
var smtpbindaddr, httpbindaddr, hostname, storage_type, mongouri, mongodb, mongocoll string
|
2014-04-16 22:29:23 +00:00
|
|
|
|
2014-04-20 14:35:59 +00:00
|
|
|
flag.StringVar(&smtpbindaddr, "smtpbindaddr", "0.0.0.0:1025", "SMTP bind interface and port, e.g. 0.0.0.0:1025 or just :1025")
|
|
|
|
flag.StringVar(&httpbindaddr, "httpbindaddr", "0.0.0.0:8025", "HTTP bind interface and port, e.g. 0.0.0.0:8025 or just :8025")
|
2014-04-16 22:59:25 +00:00
|
|
|
flag.StringVar(&hostname, "hostname", "mailhog.example", "Hostname for EHLO/HELO response, e.g. mailhog.example")
|
2014-04-24 18:16:35 +00:00
|
|
|
flag.StringVar(&storage_type, "storage", "memory", "Message storage: memory (default) or mongodb")
|
2014-04-20 14:35:59 +00:00
|
|
|
flag.StringVar(&mongouri, "mongouri", "127.0.0.1:27017", "MongoDB URI, e.g. 127.0.0.1:27017")
|
|
|
|
flag.StringVar(&mongodb, "mongodb", "mailhog", "MongoDB database, e.g. mailhog")
|
|
|
|
flag.StringVar(&mongocoll, "mongocoll", "messages", "MongoDB collection, e.g. messages")
|
2014-04-16 22:59:25 +00:00
|
|
|
|
2014-04-16 22:29:23 +00:00
|
|
|
flag.Parse()
|
|
|
|
|
2014-04-23 23:22:50 +00:00
|
|
|
conf = &config.Config{
|
2014-04-20 14:35:59 +00:00
|
|
|
SMTPBindAddr: smtpbindaddr,
|
|
|
|
HTTPBindAddr: httpbindaddr,
|
2014-04-20 16:12:32 +00:00
|
|
|
Hostname: hostname,
|
|
|
|
MongoUri: mongouri,
|
|
|
|
MongoDb: mongodb,
|
|
|
|
MongoColl: mongocoll,
|
2014-04-27 15:06:58 +00:00
|
|
|
Assets: Asset,
|
2014-04-27 22:38:43 +00:00
|
|
|
MessageChan: make(chan interface{}),
|
2014-04-19 11:19:17 +00:00
|
|
|
}
|
2014-04-20 19:33:42 +00:00
|
|
|
|
2014-04-24 18:16:35 +00:00
|
|
|
if storage_type == "mongodb" {
|
|
|
|
log.Println("Using MongoDB message storage")
|
|
|
|
s := storage.CreateMongoDB(conf)
|
|
|
|
if s == nil {
|
|
|
|
log.Println("MongoDB storage unavailable, reverting to in-memory storage")
|
|
|
|
conf.Storage = storage.CreateMemory(conf)
|
|
|
|
} else {
|
|
|
|
log.Println("Connected to MongoDB")
|
|
|
|
conf.Storage = s
|
|
|
|
}
|
|
|
|
} else if storage_type == "memory" {
|
|
|
|
log.Println("Using in-memory message storage")
|
2014-04-23 23:22:50 +00:00
|
|
|
conf.Storage = storage.CreateMemory(conf)
|
|
|
|
} else {
|
2014-04-24 18:16:35 +00:00
|
|
|
log.Fatalf("Invalid storage type %s", storage_type)
|
2014-04-23 23:22:50 +00:00
|
|
|
}
|
2014-04-16 22:29:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2014-04-23 23:22:50 +00:00
|
|
|
configure()
|
2014-04-16 22:29:23 +00:00
|
|
|
|
2014-04-20 14:35:59 +00:00
|
|
|
exitCh = make(chan int)
|
|
|
|
go web_listen()
|
2014-04-20 16:12:32 +00:00
|
|
|
go smtp_listen()
|
2014-04-20 14:35:59 +00:00
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
2014-04-27 22:38:43 +00:00
|
|
|
case <-exitCh:
|
|
|
|
log.Printf("Received exit signal")
|
|
|
|
os.Exit(0)
|
2014-04-20 14:35:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func web_listen() {
|
2014-06-23 18:21:20 +00:00
|
|
|
log.Info("[HTTP] Binding to address: %s", conf.HTTPBindAddr)
|
|
|
|
|
|
|
|
var app = gotcha.Create(Asset)
|
|
|
|
app.Config.Listen = conf.HTTPBindAddr
|
|
|
|
|
|
|
|
r := app.Router
|
|
|
|
|
|
|
|
r.Get("/images/(?P<file>.*)", r.Static("assets/images/{{file}}"))
|
|
|
|
r.Get("/js/(?P<file>.*)", r.Static("assets/js/{{file}}"))
|
|
|
|
r.Get("/", mhhttp.Index)
|
|
|
|
|
|
|
|
api.CreateAPIv1(conf, app)
|
|
|
|
|
|
|
|
app.Config.LeftDelim = ">>";
|
|
|
|
app.Config.RightDelim = "<<";
|
|
|
|
|
|
|
|
app.Start()
|
|
|
|
|
|
|
|
<-make(chan int)
|
|
|
|
exitCh<-1
|
2014-04-20 14:35:59 +00:00
|
|
|
}
|
|
|
|
|
2014-04-20 16:12:32 +00:00
|
|
|
func smtp_listen() *net.TCPListener {
|
2014-04-20 14:35:59 +00:00
|
|
|
log.Printf("[SMTP] Binding to address: %s\n", conf.SMTPBindAddr)
|
|
|
|
ln, err := net.Listen("tcp", conf.SMTPBindAddr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("[SMTP] Error listening on socket: %s\n", err)
|
|
|
|
}
|
2014-04-16 22:29:23 +00:00
|
|
|
defer ln.Close()
|
|
|
|
|
|
|
|
for {
|
|
|
|
conn, err := ln.Accept()
|
|
|
|
if err != nil {
|
2014-04-20 14:35:59 +00:00
|
|
|
log.Printf("[SMTP] Error accepting connection: %s\n", err)
|
2014-04-16 22:29:23 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
|
2014-04-23 23:22:50 +00:00
|
|
|
go smtp.StartSession(conn.(*net.TCPConn), conf)
|
2014-04-16 22:29:23 +00:00
|
|
|
}
|
|
|
|
}
|