mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
config: Replace robfig with envconfig for #86
- Initial envconfig system is working, not bulletproof. - Added sane defaults for required parameters.
This commit is contained in:
@@ -536,7 +536,7 @@ func (ses *Session) enterState(state State) {
|
||||
|
||||
// Calculate the next read or write deadline based on maxIdleSeconds
|
||||
func (ses *Session) nextDeadline() time.Time {
|
||||
return time.Now().Add(time.Duration(ses.server.maxIdleSeconds) * time.Second)
|
||||
return time.Now().Add(ses.server.maxIdle)
|
||||
}
|
||||
|
||||
// Send requested message, store errors in Session.sendError
|
||||
|
||||
@@ -2,7 +2,6 @@ package pop3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -16,7 +15,7 @@ import (
|
||||
type Server struct {
|
||||
host string
|
||||
domain string
|
||||
maxIdleSeconds int
|
||||
maxIdle time.Duration
|
||||
dataStore storage.Store
|
||||
listener net.Listener
|
||||
globalShutdown chan bool
|
||||
@@ -24,12 +23,12 @@ type Server struct {
|
||||
}
|
||||
|
||||
// New creates a new Server struct
|
||||
func New(cfg config.POP3Config, shutdownChan chan bool, ds storage.Store) *Server {
|
||||
func New(cfg config.POP3, shutdownChan chan bool, ds storage.Store) *Server {
|
||||
return &Server{
|
||||
host: fmt.Sprintf("%v:%v", cfg.IP4address, cfg.IP4port),
|
||||
host: cfg.Addr,
|
||||
domain: cfg.Domain,
|
||||
dataStore: ds,
|
||||
maxIdleSeconds: cfg.MaxIdleSeconds,
|
||||
maxIdle: cfg.MaxIdle,
|
||||
globalShutdown: shutdownChan,
|
||||
waitgroup: new(sync.WaitGroup),
|
||||
}
|
||||
|
||||
@@ -412,9 +412,9 @@ func (ss *Session) greet() {
|
||||
ss.send(fmt.Sprintf("220 %v Inbucket SMTP ready", ss.server.domain))
|
||||
}
|
||||
|
||||
// Calculate the next read or write deadline based on maxIdleSeconds
|
||||
// Calculate the next read or write deadline based on maxIdle
|
||||
func (ss *Session) nextDeadline() time.Time {
|
||||
return time.Now().Add(time.Duration(ss.server.maxIdleSeconds) * time.Second)
|
||||
return time.Now().Add(ss.server.maxIdle)
|
||||
}
|
||||
|
||||
// Send requested message, store errors in Session.sendError
|
||||
|
||||
@@ -361,13 +361,12 @@ func (m *mockConn) SetWriteDeadline(t time.Time) error { return nil }
|
||||
|
||||
func setupSMTPServer(ds storage.Store) (s *Server, buf *bytes.Buffer, teardown func()) {
|
||||
// Test Server Config
|
||||
cfg := config.SMTPConfig{
|
||||
IP4address: net.IPv4(127, 0, 0, 1),
|
||||
IP4port: 2500,
|
||||
cfg := config.SMTP{
|
||||
Addr: "127.0.0.1:2500",
|
||||
Domain: "inbucket.local",
|
||||
DomainNoStore: "bitbucket.local",
|
||||
MaxRecipients: 5,
|
||||
MaxIdleSeconds: 5,
|
||||
MaxIdle: 5,
|
||||
MaxMessageBytes: 5000,
|
||||
StoreMessages: true,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"container/list"
|
||||
"context"
|
||||
"expvar"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -43,7 +42,7 @@ type Server struct {
|
||||
domain string
|
||||
domainNoStore string
|
||||
maxRecips int
|
||||
maxIdleSeconds int
|
||||
maxIdle time.Duration
|
||||
maxMessageBytes int
|
||||
storeMessages bool
|
||||
|
||||
@@ -80,17 +79,17 @@ var (
|
||||
|
||||
// NewServer creates a new Server instance with the specificed config
|
||||
func NewServer(
|
||||
cfg config.SMTPConfig,
|
||||
cfg config.SMTP,
|
||||
globalShutdown chan bool,
|
||||
manager message.Manager,
|
||||
apolicy *policy.Addressing,
|
||||
) *Server {
|
||||
return &Server{
|
||||
host: fmt.Sprintf("%v:%v", cfg.IP4address, cfg.IP4port),
|
||||
host: cfg.Addr,
|
||||
domain: cfg.Domain,
|
||||
domainNoStore: strings.ToLower(cfg.DomainNoStore),
|
||||
maxRecips: cfg.MaxRecipients,
|
||||
maxIdleSeconds: cfg.MaxIdleSeconds,
|
||||
maxIdle: cfg.MaxIdle,
|
||||
maxMessageBytes: cfg.MaxMessageBytes,
|
||||
storeMessages: cfg.StoreMessages,
|
||||
globalShutdown: globalShutdown,
|
||||
|
||||
@@ -12,13 +12,15 @@ import (
|
||||
)
|
||||
|
||||
// Context is passed into every request handler function
|
||||
// TODO remove redundant web config
|
||||
type Context struct {
|
||||
Vars map[string]string
|
||||
Session *sessions.Session
|
||||
MsgHub *msghub.Hub
|
||||
Manager message.Manager
|
||||
WebConfig config.WebConfig
|
||||
IsJSON bool
|
||||
Vars map[string]string
|
||||
Session *sessions.Session
|
||||
MsgHub *msghub.Hub
|
||||
Manager message.Manager
|
||||
RootConfig *config.Root
|
||||
WebConfig config.Web
|
||||
IsJSON bool
|
||||
}
|
||||
|
||||
// Close the Context (currently does nothing)
|
||||
@@ -57,12 +59,13 @@ func NewContext(req *http.Request) (*Context, error) {
|
||||
err = nil
|
||||
}
|
||||
ctx := &Context{
|
||||
Vars: vars,
|
||||
Session: sess,
|
||||
MsgHub: msgHub,
|
||||
Manager: manager,
|
||||
WebConfig: webConfig,
|
||||
IsJSON: headerMatch(req, "Accept", "application/json"),
|
||||
Vars: vars,
|
||||
Session: sess,
|
||||
MsgHub: msgHub,
|
||||
Manager: manager,
|
||||
RootConfig: rootConfig,
|
||||
WebConfig: rootConfig.Web,
|
||||
IsJSON: headerMatch(req, "Accept", "application/json"),
|
||||
}
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ package web
|
||||
import (
|
||||
"context"
|
||||
"expvar"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -30,7 +29,7 @@ var (
|
||||
// incoming requests to the correct handler function
|
||||
Router = mux.NewRouter()
|
||||
|
||||
webConfig config.WebConfig
|
||||
rootConfig *config.Root
|
||||
server *http.Server
|
||||
listener net.Listener
|
||||
sessionStore sessions.Store
|
||||
@@ -47,12 +46,12 @@ func init() {
|
||||
|
||||
// Initialize sets up things for unit tests or the Start() method
|
||||
func Initialize(
|
||||
cfg config.WebConfig,
|
||||
conf *config.Root,
|
||||
shutdownChan chan bool,
|
||||
mm message.Manager,
|
||||
mh *msghub.Hub) {
|
||||
|
||||
webConfig = cfg
|
||||
rootConfig = conf
|
||||
globalShutdown = shutdownChan
|
||||
|
||||
// NewContext() will use this DataStore for the web handlers
|
||||
@@ -60,36 +59,35 @@ func Initialize(
|
||||
manager = mm
|
||||
|
||||
// Content Paths
|
||||
log.Infof("HTTP templates mapped to %q", cfg.TemplateDir)
|
||||
log.Infof("HTTP static content mapped to %q", cfg.PublicDir)
|
||||
log.Infof("HTTP templates mapped to %q", conf.Web.TemplateDir)
|
||||
log.Infof("HTTP static content mapped to %q", conf.Web.PublicDir)
|
||||
Router.PathPrefix("/public/").Handler(http.StripPrefix("/public/",
|
||||
http.FileServer(http.Dir(cfg.PublicDir))))
|
||||
http.FileServer(http.Dir(conf.Web.PublicDir))))
|
||||
http.Handle("/", Router)
|
||||
|
||||
// Session cookie setup
|
||||
if cfg.CookieAuthKey == "" {
|
||||
if conf.Web.CookieAuthKey == "" {
|
||||
log.Infof("HTTP generating random cookie.auth.key")
|
||||
sessionStore = sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
|
||||
} else {
|
||||
log.Tracef("HTTP using configured cookie.auth.key")
|
||||
sessionStore = sessions.NewCookieStore([]byte(cfg.CookieAuthKey))
|
||||
sessionStore = sessions.NewCookieStore([]byte(conf.Web.CookieAuthKey))
|
||||
}
|
||||
}
|
||||
|
||||
// Start begins listening for HTTP requests
|
||||
func Start(ctx context.Context) {
|
||||
addr := fmt.Sprintf("%v:%v", webConfig.IP4address, webConfig.IP4port)
|
||||
server = &http.Server{
|
||||
Addr: addr,
|
||||
Addr: rootConfig.Web.Addr,
|
||||
Handler: nil,
|
||||
ReadTimeout: 60 * time.Second,
|
||||
WriteTimeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
// We don't use ListenAndServe because it lacks a way to close the listener
|
||||
log.Infof("HTTP listening on TCP4 %v", addr)
|
||||
log.Infof("HTTP listening on TCP4 %v", server.Addr)
|
||||
var err error
|
||||
listener, err = net.Listen("tcp", addr)
|
||||
listener, err = net.Listen("tcp", server.Addr)
|
||||
if err != nil {
|
||||
log.Errorf("HTTP failed to start TCP4 listener: %v", err)
|
||||
emergencyShutdown()
|
||||
|
||||
@@ -50,7 +50,7 @@ func ParseTemplate(name string, partial bool) (*template.Template, error) {
|
||||
}
|
||||
|
||||
tempPath := strings.Replace(name, "/", string(filepath.Separator), -1)
|
||||
tempFile := filepath.Join(webConfig.TemplateDir, tempPath)
|
||||
tempFile := filepath.Join(rootConfig.Web.TemplateDir, tempPath)
|
||||
log.Tracef("Parsing template %v", tempFile)
|
||||
|
||||
var err error
|
||||
@@ -62,14 +62,14 @@ func ParseTemplate(name string, partial bool) (*template.Template, error) {
|
||||
t, err = t.ParseFiles(tempFile)
|
||||
} else {
|
||||
t = template.New("_base.html").Funcs(TemplateFuncs)
|
||||
t, err = t.ParseFiles(filepath.Join(webConfig.TemplateDir, "_base.html"), tempFile)
|
||||
t, err = t.ParseFiles(filepath.Join(rootConfig.Web.TemplateDir, "_base.html"), tempFile)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Allows us to disable caching for theme development
|
||||
if webConfig.TemplateCache {
|
||||
if rootConfig.Web.TemplateCache {
|
||||
if partial {
|
||||
log.Tracef("Caching partial %v", name)
|
||||
cachedTemplates[name] = t
|
||||
|
||||
Reference in New Issue
Block a user