2014-04-16 22:29:23 +00:00
package main
import (
"flag"
2014-11-23 04:21:53 +00:00
"io"
2014-10-29 16:59:59 +00:00
"net"
"os"
2014-06-23 16:41:03 +00:00
"github.com/ian-kent/Go-MailHog/mailhog/config"
2014-11-23 12:43:33 +00:00
"github.com/ian-kent/Go-MailHog/mailhog/data"
2014-06-24 21:21:06 +00:00
mhhttp "github.com/ian-kent/Go-MailHog/mailhog/http"
2014-06-23 18:21:20 +00:00
"github.com/ian-kent/Go-MailHog/mailhog/http/api"
2014-11-22 16:11:04 +00:00
smtp "github.com/ian-kent/Go-MailHog/mailhog/smtp/server"
2014-06-23 16:41:03 +00:00
"github.com/ian-kent/Go-MailHog/mailhog/storage"
2014-10-29 16:59:59 +00:00
"github.com/ian-kent/envconf"
2014-06-23 18:21:20 +00:00
"github.com/ian-kent/go-log/log"
2014-06-24 21:21:06 +00:00
gotcha "github.com/ian-kent/gotcha/app"
"github.com/ian-kent/gotcha/events"
"github.com/ian-kent/gotcha/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-10-29 16:59:59 +00:00
flag . StringVar ( & smtpbindaddr , "smtpbindaddr" , envconf . FromEnvP ( "MH_SMTP_BIND_ADDR" , "0.0.0.0:1025" ) . ( string ) , "SMTP bind interface and port, e.g. 0.0.0.0:1025 or just :1025" )
flag . StringVar ( & httpbindaddr , "httpbindaddr" , envconf . FromEnvP ( "MH_HTTP_BIND_ADDR" , "0.0.0.0:8025" ) . ( string ) , "HTTP bind interface and port, e.g. 0.0.0.0:8025 or just :8025" )
flag . StringVar ( & hostname , "hostname" , envconf . FromEnvP ( "MH_HOSTNAME" , "mailhog.example" ) . ( string ) , "Hostname for EHLO/HELO response, e.g. mailhog.example" )
flag . StringVar ( & storage_type , "storage" , envconf . FromEnvP ( "MH_STORAGE" , "memory" ) . ( string ) , "Message storage: memory (default) or mongodb" )
flag . StringVar ( & mongouri , "mongouri" , envconf . FromEnvP ( "MH_MONGO_URI" , "127.0.0.1:27017" ) . ( string ) , "MongoDB URI, e.g. 127.0.0.1:27017" )
flag . StringVar ( & mongodb , "mongodb" , envconf . FromEnvP ( "MH_MONGO_DB" , "mailhog" ) . ( string ) , "MongoDB database, e.g. mailhog" )
flag . StringVar ( & mongocoll , "mongocoll" , envconf . FromEnvP ( "MH_MONGO_COLLECTION" , "messages" ) . ( string ) , "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-11-23 12:43:33 +00:00
MessageChan : make ( chan * data . Message ) ,
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" )
2014-11-23 00:23:39 +00:00
s := storage . CreateMongoDB ( conf . MongoUri , conf . MongoDb , conf . MongoColl )
2014-04-24 18:16:35 +00:00
if s == nil {
log . Println ( "MongoDB storage unavailable, reverting to in-memory storage" )
2014-11-23 00:23:39 +00:00
conf . Storage = storage . CreateInMemory ( )
2014-04-24 18:16:35 +00:00
} else {
log . Println ( "Connected to MongoDB" )
conf . Storage = s
}
} else if storage_type == "memory" {
log . Println ( "Using in-memory message storage" )
2014-11-23 00:23:39 +00:00
conf . Storage = storage . CreateInMemory ( )
2014-04-23 23:22:50 +00:00
} 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-06-24 21:21:06 +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
2014-06-24 21:21:06 +00:00
app . On ( events . BeforeHandler , func ( session * http . Session , next func ( ) ) {
session . Stash [ "config" ] = conf
next ( )
} )
2014-06-23 18:21:20 +00:00
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 )
2014-06-24 21:21:06 +00:00
app . Config . LeftDelim = "[:"
app . Config . RightDelim = ":]"
2014-06-23 18:21:20 +00:00
app . Start ( )
<- make ( chan int )
2014-06-24 21:21:06 +00:00
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-11-23 12:43:33 +00:00
go smtp . Accept (
conn . ( * net . TCPConn ) . RemoteAddr ( ) . String ( ) ,
io . ReadWriteCloser ( conn ) ,
conf . Storage ,
conf . MessageChan ,
conf . Hostname ,
)
2014-04-16 22:29:23 +00:00
}
}