1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-18 01:57:02 +00:00

Follow meta-linter recommendations for all of Inbucket

- Rename BUILD_DATE to BUILDDATE in goxc
- Update travis config
- Follow linter recommendations for inbucket.go
- Follow linter recommendations for config package
- Follow linter recommendations for log package
- Follow linter recommendations for pop3d package
- Follow linter recommendations for smtpd package
- Follow linter recommendations for web package
- Fix Id -> ID in templates
- Add shebang to REST demo scripts
- Add or refine many comments
This commit is contained in:
James Hillyerd
2016-02-20 23:20:22 -08:00
parent 83f9c6aa49
commit e6b7e335cb
34 changed files with 607 additions and 411 deletions

View File

@@ -15,11 +15,15 @@ import (
"github.com/jhillyerd/inbucket/smtpd"
)
// State tracks the current mode of our POP3 state machine
type State int
const (
AUTHORIZATION State = iota // The client must now identify and authenticate
TRANSACTION // Mailbox open, client may now issue commands
// AUTHORIZATION state: the client must now identify and authenticate
AUTHORIZATION State = iota
// TRANSACTION state: mailbox open, client may now issue commands
TRANSACTION
// QUIT state: client requests us to end session
QUIT
)
@@ -51,6 +55,7 @@ var commands = map[string]bool{
"CAPA": true,
}
// Session defines an active POP3 session
type Session struct {
server *Server // Reference to the server we belong to
id int // Session ID number
@@ -66,6 +71,7 @@ type Session struct {
msgCount int // Number of undeleted messages
}
// NewSession creates a new POP3 session
func NewSession(server *Server, id int, conn net.Conn) *Session {
reader := bufio.NewReader(conn)
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
@@ -85,10 +91,12 @@ func (ses *Session) String() string {
* 5. Goto 2
*/
func (s *Server) startSession(id int, conn net.Conn) {
log.LogInfo("POP3 connection from %v, starting session <%v>", conn.RemoteAddr(), id)
log.Infof("POP3 connection from %v, starting session <%v>", conn.RemoteAddr(), id)
//expConnectsCurrent.Add(1)
defer func() {
conn.Close()
if err := conn.Close(); err != nil {
log.Errorf("Error closing POP3 connection for <%v>: %v", id, err)
}
s.waitgroup.Done()
//expConnectsCurrent.Add(-1)
}()
@@ -235,7 +243,7 @@ func (ses *Session) transactionHandler(cmd string, args []string) {
var size int64
for i, msg := range ses.messages {
if ses.retain[i] {
count += 1
count++
size += msg.Size()
}
}
@@ -306,12 +314,12 @@ func (ses *Session) transactionHandler(cmd string, args []string) {
ses.send(fmt.Sprintf("-ERR You deleted message %v", msgNum))
return
}
ses.send(fmt.Sprintf("+OK %v %v", msgNum, ses.messages[msgNum-1].Id()))
ses.send(fmt.Sprintf("+OK %v %v", msgNum, ses.messages[msgNum-1].ID()))
} else {
ses.send(fmt.Sprintf("+OK Listing %v messages", ses.msgCount))
for i, msg := range ses.messages {
if ses.retain[i] {
ses.send(fmt.Sprintf("%v %v", i+1, msg.Id()))
ses.send(fmt.Sprintf("%v %v", i+1, msg.ID()))
}
}
ses.send(".")
@@ -340,7 +348,7 @@ func (ses *Session) transactionHandler(cmd string, args []string) {
}
if ses.retain[msgNum-1] {
ses.retain[msgNum-1] = false
ses.msgCount -= 1
ses.msgCount--
ses.send(fmt.Sprintf("+OK Deleted message %v", msgNum))
} else {
ses.logWarn("Client tried to DELE an already deleted message")
@@ -431,7 +439,12 @@ func (ses *Session) sendMessage(msg smtpd.Message) {
ses.send("-ERR Failed to RETR that message, internal error")
return
}
defer reader.Close()
defer func() {
if err := reader.Close(); err != nil {
ses.logError("Failed to close message: %v", err)
}
}()
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()
@@ -459,7 +472,12 @@ func (ses *Session) sendMessageTop(msg smtpd.Message, lineCount int) {
ses.send("-ERR Failed to RETR that message, internal error")
return
}
defer reader.Close()
defer func() {
if err := reader.Close(); err != nil {
ses.logError("Failed to close message: %v", err)
}
}()
scanner := bufio.NewScanner(reader)
inBody := false
for scanner.Scan() {
@@ -473,7 +491,7 @@ func (ses *Session) sendMessageTop(msg smtpd.Message, lineCount int) {
if lineCount < 1 {
break
} else {
lineCount -= 1
lineCount--
}
} else {
if line == "" {
@@ -522,7 +540,9 @@ func (ses *Session) processDeletes() {
for i, msg := range ses.messages {
if !ses.retain[i] {
ses.logTrace("Deleting %v", msg)
msg.Delete()
if err := msg.Delete(); err != nil {
ses.logWarn("Error deleting %v: %v", msg, err)
}
}
}
}
@@ -562,13 +582,17 @@ func (ses *Session) readByteLine(buf *bytes.Buffer) error {
if err != nil {
return err
}
buf.Write(line)
if _, err = buf.Write(line); err != nil {
return err
}
// Read the next byte looking for '\n'
c, err := ses.reader.ReadByte()
if err != nil {
return err
}
buf.WriteByte(c)
if err := buf.WriteByte(c); err != nil {
return err
}
if c == '\n' {
// We've reached the end of the line, return
return nil
@@ -612,21 +636,21 @@ func (ses *Session) ooSeq(cmd string) {
// Session specific logging methods
func (ses *Session) logTrace(msg string, args ...interface{}) {
log.LogTrace("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
log.Tracef("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
}
func (ses *Session) logInfo(msg string, args ...interface{}) {
log.LogInfo("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
log.Infof("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
}
func (ses *Session) logWarn(msg string, args ...interface{}) {
// Update metrics
//expWarnsTotal.Add(1)
log.LogWarn("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
log.Warnf("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
}
func (ses *Session) logError(msg string, args ...interface{}) {
// Update metrics
//expErrorsTotal.Add(1)
log.LogError("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
log.Errorf("POP3[%v]<%v> %v", ses.remoteHost, ses.id, fmt.Sprintf(msg, args...))
}

View File

@@ -11,7 +11,7 @@ import (
"github.com/jhillyerd/inbucket/smtpd"
)
// Real server code starts here
// Server defines an instance of our POP3 server
type Server struct {
domain string
maxIdleSeconds int
@@ -21,30 +21,30 @@ type Server struct {
waitgroup *sync.WaitGroup
}
// Init a new Server object
// New creates a new Server struct
func New() *Server {
// TODO is two filestores better/worse than sharing w/ smtpd?
ds := smtpd.DefaultFileDataStore()
cfg := config.GetPop3Config()
cfg := config.GetPOP3Config()
return &Server{domain: cfg.Domain, dataStore: ds, maxIdleSeconds: cfg.MaxIdleSeconds,
waitgroup: new(sync.WaitGroup)}
}
// Main listener loop
// Start the server and listen for connections
func (s *Server) Start() {
cfg := config.GetPop3Config()
cfg := config.GetPOP3Config()
addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%v:%v",
cfg.Ip4address, cfg.Ip4port))
cfg.IP4address, cfg.IP4port))
if err != nil {
log.LogError("POP3 Failed to build tcp4 address: %v", err)
log.Errorf("POP3 Failed to build tcp4 address: %v", err)
// TODO More graceful early-shutdown procedure
panic(err)
}
log.LogInfo("POP3 listening on TCP4 %v", addr)
log.Infof("POP3 listening on TCP4 %v", addr)
s.listener, err = net.ListenTCP("tcp4", addr)
if err != nil {
log.LogError("POP3 failed to start tcp4 listener: %v", err)
log.Errorf("POP3 failed to start tcp4 listener: %v", err)
// TODO More graceful early-shutdown procedure
panic(err)
}
@@ -63,12 +63,12 @@ func (s *Server) Start() {
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
log.LogError("POP3 accept error: %v; retrying in %v", err, tempDelay)
log.Errorf("POP3 accept error: %v; retrying in %v", err, tempDelay)
time.Sleep(tempDelay)
continue
} else {
if s.shutdown {
log.LogTrace("POP3 listener shutting down on request")
log.Tracef("POP3 listener shutting down on request")
return
}
// TODO Implement a max error counter before shutdown?
@@ -85,13 +85,15 @@ func (s *Server) Start() {
// Stop requests the POP3 server closes it's listener
func (s *Server) Stop() {
log.LogTrace("POP3 shutdown requested, connections will be drained")
log.Tracef("POP3 shutdown requested, connections will be drained")
s.shutdown = true
s.listener.Close()
if err := s.listener.Close(); err != nil {
log.Errorf("Error closing POP3 listener: %v", err)
}
}
// Drain causes the caller to block until all active POP3 sessions have finished
func (s *Server) Drain() {
s.waitgroup.Wait()
log.LogTrace("POP3 connections drained")
log.Tracef("POP3 connections drained")
}