diff --git a/pkg/message/manager.go b/pkg/message/manager.go index c9b74f1..2a8bb47 100644 --- a/pkg/message/manager.go +++ b/pkg/message/manager.go @@ -43,10 +43,10 @@ func (s *StoreManager) Deliver( from string, recipients []*policy.Recipient, prefix string, - content []byte, + source []byte, ) (string, error) { // TODO enmime is too heavy for this step, only need header - env, err := enmime.ReadEnvelope(bytes.NewReader(content)) + env, err := enmime.ReadEnvelope(bytes.NewReader(source)) if err != nil { return "", err } @@ -69,7 +69,7 @@ func (s *StoreManager) Deliver( Date: time.Now(), Subject: env.GetHeader("Subject"), }, - Reader: io.MultiReader(strings.NewReader(prefix), bytes.NewReader(content)), + Reader: io.MultiReader(strings.NewReader(prefix), bytes.NewReader(source)), } id, err := s.Store.AddMessage(delivery) if err != nil { @@ -110,7 +110,7 @@ func (s *StoreManager) GetMessage(mailbox, id string) (*Message, error) { if err != nil { return nil, err } - r, err := sm.RawReader() + r, err := sm.Source() if err != nil { return nil, err } @@ -139,7 +139,7 @@ func (s *StoreManager) SourceReader(mailbox, id string) (io.ReadCloser, error) { if err != nil { return nil, err } - return sm.RawReader() + return sm.Source() } // MailboxForAddress parses an email address to return the canonical mailbox name. @@ -147,8 +147,8 @@ func (s *StoreManager) MailboxForAddress(mailbox string) (string, error) { return policy.ParseMailboxName(mailbox) } -// makeMetadata populates Metadata from a StoreMessage. -func makeMetadata(m storage.StoreMessage) *Metadata { +// makeMetadata populates Metadata from a storage.Message. +func makeMetadata(m storage.Message) *Metadata { return &Metadata{ Mailbox: m.Mailbox(), ID: m.ID(), diff --git a/pkg/message/message.go b/pkg/message/message.go index 3994ca3..7f8bec0 100644 --- a/pkg/message/message.go +++ b/pkg/message/message.go @@ -34,7 +34,7 @@ type Delivery struct { Reader io.Reader } -var _ storage.StoreMessage = &Delivery{} +var _ storage.Message = &Delivery{} // Mailbox getter. func (d *Delivery) Mailbox() string { @@ -71,7 +71,7 @@ func (d *Delivery) Size() int64 { return d.Meta.Size } -// RawReader contains the raw content of the message. -func (d *Delivery) RawReader() (io.ReadCloser, error) { +// Source contains the raw content of the message. +func (d *Delivery) Source() (io.ReadCloser, error) { return ioutil.NopCloser(d.Reader), nil } diff --git a/pkg/server/pop3/handler.go b/pkg/server/pop3/handler.go index c022619..f8229ca 100644 --- a/pkg/server/pop3/handler.go +++ b/pkg/server/pop3/handler.go @@ -57,17 +57,17 @@ var commands = map[string]bool{ // Session defines an active POP3 session type Session struct { - server *Server // Reference to the server we belong to - id int // Session ID number - conn net.Conn // Our network connection - remoteHost string // IP address of client - sendError error // Used to bail out of read loop on send error - state State // Current session state - reader *bufio.Reader // Buffered reader for our net conn - user string // Mailbox name - messages []storage.StoreMessage // Slice of messages in mailbox - retain []bool // Messages to retain upon UPDATE (true=retain) - msgCount int // Number of undeleted messages + server *Server // Reference to the server we belong to + id int // Session ID number + conn net.Conn // Our network connection + remoteHost string // IP address of client + sendError error // Used to bail out of read loop on send error + state State // Current session state + reader *bufio.Reader // Buffered reader for our net conn + user string // Mailbox name + messages []storage.Message // Slice of messages in mailbox + retain []bool // Messages to retain upon UPDATE (true=retain) + msgCount int // Number of undeleted messages } // NewSession creates a new POP3 session @@ -415,8 +415,8 @@ func (ses *Session) transactionHandler(cmd string, args []string) { } // Send the contents of the message to the client -func (ses *Session) sendMessage(msg storage.StoreMessage) { - reader, err := msg.RawReader() +func (ses *Session) sendMessage(msg storage.Message) { + reader, err := msg.Source() if err != nil { ses.logError("Failed to read message for RETR command") ses.send("-ERR Failed to RETR that message, internal error") @@ -448,8 +448,8 @@ func (ses *Session) sendMessage(msg storage.StoreMessage) { } // Send the headers plus the top N lines to the client -func (ses *Session) sendMessageTop(msg storage.StoreMessage, lineCount int) { - reader, err := msg.RawReader() +func (ses *Session) sendMessageTop(msg storage.Message, lineCount int) { + reader, err := msg.Source() if err != nil { ses.logError("Failed to read message for RETR command") ses.send("-ERR Failed to RETR that message, internal error") diff --git a/pkg/storage/file/fmessage.go b/pkg/storage/file/fmessage.go index cf06d5c..cf375b4 100644 --- a/pkg/storage/file/fmessage.go +++ b/pkg/storage/file/fmessage.go @@ -90,8 +90,8 @@ func (m *Message) rawPath() string { return filepath.Join(m.mailbox.path, m.Fid+".raw") } -// RawReader opens the .raw portion of a Message as an io.ReadCloser -func (m *Message) RawReader() (reader io.ReadCloser, err error) { +// Source opens the .raw portion of a Message as an io.ReadCloser +func (m *Message) Source() (reader io.ReadCloser, err error) { file, err := os.Open(m.rawPath()) if err != nil { return nil, err diff --git a/pkg/storage/file/fstore.go b/pkg/storage/file/fstore.go index f6a60ec..ebe5c7e 100644 --- a/pkg/storage/file/fstore.go +++ b/pkg/storage/file/fstore.go @@ -75,14 +75,14 @@ func New(cfg config.DataStoreConfig) storage.Store { } // AddMessage adds a message to the specified mailbox. -func (fs *Store) AddMessage(m storage.StoreMessage) (id string, err error) { +func (fs *Store) AddMessage(m storage.Message) (id string, err error) { mb, err := fs.mbox(m.Mailbox()) if err != nil { return "", err } mb.Lock() defer mb.Unlock() - r, err := m.RawReader() + r, err := m.Source() if err != nil { return "", err } @@ -136,7 +136,7 @@ func (fs *Store) AddMessage(m storage.StoreMessage) (id string, err error) { } // GetMessage returns the messages in the named mailbox, or an error. -func (fs *Store) GetMessage(mailbox, id string) (storage.StoreMessage, error) { +func (fs *Store) GetMessage(mailbox, id string) (storage.Message, error) { mb, err := fs.mbox(mailbox) if err != nil { return nil, err @@ -147,7 +147,7 @@ func (fs *Store) GetMessage(mailbox, id string) (storage.StoreMessage, error) { } // GetMessages returns the messages in the named mailbox, or an error. -func (fs *Store) GetMessages(mailbox string) ([]storage.StoreMessage, error) { +func (fs *Store) GetMessages(mailbox string) ([]storage.Message, error) { mb, err := fs.mbox(mailbox) if err != nil { return nil, err @@ -181,7 +181,7 @@ func (fs *Store) PurgeMessages(mailbox string) error { // VisitMailboxes accepts a function that will be called with the messages in each mailbox while it // continues to return true. -func (fs *Store) VisitMailboxes(f func([]storage.StoreMessage) (cont bool)) error { +func (fs *Store) VisitMailboxes(f func([]storage.Message) (cont bool)) error { infos1, err := ioutil.ReadDir(fs.mailPath) if err != nil { return err diff --git a/pkg/storage/file/fstore_test.go b/pkg/storage/file/fstore_test.go index 18b1fe7..589bf18 100644 --- a/pkg/storage/file/fstore_test.go +++ b/pkg/storage/file/fstore_test.go @@ -133,7 +133,7 @@ func TestFSMissing(t *testing.T) { assert.Nil(t, err) // Try to read parts of message - _, err = msg.RawReader() + _, err = msg.Source() assert.Error(t, err) if t.Failed() { diff --git a/pkg/storage/file/mbox.go b/pkg/storage/file/mbox.go index ea6d7f4..cb5c1b9 100644 --- a/pkg/storage/file/mbox.go +++ b/pkg/storage/file/mbox.go @@ -28,13 +28,13 @@ type mbox struct { // getMessages scans the mailbox directory for .gob files and decodes them into // a slice of Message objects. -func (mb *mbox) getMessages() ([]storage.StoreMessage, error) { +func (mb *mbox) getMessages() ([]storage.Message, error) { if !mb.indexLoaded { if err := mb.readIndex(); err != nil { return nil, err } } - messages := make([]storage.StoreMessage, len(mb.messages)) + messages := make([]storage.Message, len(mb.messages)) for i, m := range mb.messages { messages[i] = m } @@ -42,7 +42,7 @@ func (mb *mbox) getMessages() ([]storage.StoreMessage, error) { } // getMessage decodes a single message by ID and returns a Message object. -func (mb *mbox) getMessage(id string) (storage.StoreMessage, error) { +func (mb *mbox) getMessage(id string) (storage.Message, error) { if !mb.indexLoaded { if err := mb.readIndex(); err != nil { return nil, err diff --git a/pkg/storage/retention.go b/pkg/storage/retention.go index 2da706e..6c7adb0 100644 --- a/pkg/storage/retention.go +++ b/pkg/storage/retention.go @@ -119,7 +119,7 @@ func (rs *RetentionScanner) DoScan() error { cutoff := time.Now().Add(-1 * rs.retentionPeriod) retained := 0 // Loop over all mailboxes. - err := rs.ds.VisitMailboxes(func(messages []StoreMessage) bool { + err := rs.ds.VisitMailboxes(func(messages []Message) bool { for _, msg := range messages { if msg.Date().Before(cutoff) { log.Tracef("Purging expired message %v/%v", msg.Mailbox(), msg.ID()) diff --git a/pkg/storage/retention_test.go b/pkg/storage/retention_test.go index a49cc59..234a377 100644 --- a/pkg/storage/retention_test.go +++ b/pkg/storage/retention_test.go @@ -37,13 +37,13 @@ func TestDoRetentionScan(t *testing.T) { t.Error(err) } // Delete should not have been called on new messages - for _, m := range []storage.StoreMessage{new1, new2, new3} { + for _, m := range []storage.Message{new1, new2, new3} { if ds.MessageDeleted(m) { t.Errorf("Expected %v to be present, was deleted", m.ID()) } } // Delete should have been called once on old messages - for _, m := range []storage.StoreMessage{old1, old2, old3} { + for _, m := range []storage.Message{old1, old2, old3} { if !ds.MessageDeleted(m) { t.Errorf("Expected %v to be deleted, was present", m.ID()) } @@ -51,7 +51,7 @@ func TestDoRetentionScan(t *testing.T) { } // stubMessage creates a message stub of a specific age -func stubMessage(mailbox string, ageHours int) storage.StoreMessage { +func stubMessage(mailbox string, ageHours int) storage.Message { return &message.Delivery{ Meta: message.Metadata{ Mailbox: mailbox, diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index f8bcaef..edc4afd 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -19,22 +19,22 @@ var ( // Store is the interface Inbucket uses to interact with storage implementations. type Store interface { // AddMessage stores the message, message ID and Size will be ignored. - AddMessage(message StoreMessage) (id string, err error) - GetMessage(mailbox, id string) (StoreMessage, error) - GetMessages(mailbox string) ([]StoreMessage, error) + AddMessage(message Message) (id string, err error) + GetMessage(mailbox, id string) (Message, error) + GetMessages(mailbox string) ([]Message, error) PurgeMessages(mailbox string) error RemoveMessage(mailbox, id string) error - VisitMailboxes(f func([]StoreMessage) (cont bool)) error + VisitMailboxes(f func([]Message) (cont bool)) error } -// StoreMessage represents a message to be stored, or returned from a storage implementation. -type StoreMessage interface { +// Message represents a message to be stored, or returned from a storage implementation. +type Message interface { Mailbox() string ID() string From() *mail.Address To() []*mail.Address Date() time.Time Subject() string - RawReader() (reader io.ReadCloser, err error) + Source() (io.ReadCloser, error) Size() int64 } diff --git a/pkg/test/storage.go b/pkg/test/storage.go index 2c45b10..b52445d 100644 --- a/pkg/test/storage.go +++ b/pkg/test/storage.go @@ -9,20 +9,20 @@ import ( // StoreStub stubs storage.Store for testing. type StoreStub struct { storage.Store - mailboxes map[string][]storage.StoreMessage - deleted map[storage.StoreMessage]struct{} + mailboxes map[string][]storage.Message + deleted map[storage.Message]struct{} } // NewStore creates a new StoreStub. func NewStore() *StoreStub { return &StoreStub{ - mailboxes: make(map[string][]storage.StoreMessage), - deleted: make(map[storage.StoreMessage]struct{}), + mailboxes: make(map[string][]storage.Message), + deleted: make(map[storage.Message]struct{}), } } // AddMessage adds a message to the specified mailbox. -func (s *StoreStub) AddMessage(m storage.StoreMessage) (id string, err error) { +func (s *StoreStub) AddMessage(m storage.Message) (id string, err error) { mb := m.Mailbox() msgs := s.mailboxes[mb] s.mailboxes[mb] = append(msgs, m) @@ -30,7 +30,7 @@ func (s *StoreStub) AddMessage(m storage.StoreMessage) (id string, err error) { } // GetMessage gets a message by ID from the specified mailbox. -func (s *StoreStub) GetMessage(mailbox, id string) (storage.StoreMessage, error) { +func (s *StoreStub) GetMessage(mailbox, id string) (storage.Message, error) { if mailbox == "messageerr" { return nil, errors.New("internal error") } @@ -43,7 +43,7 @@ func (s *StoreStub) GetMessage(mailbox, id string) (storage.StoreMessage, error) } // GetMessages gets all the messages for the specified mailbox. -func (s *StoreStub) GetMessages(mailbox string) ([]storage.StoreMessage, error) { +func (s *StoreStub) GetMessages(mailbox string) ([]storage.Message, error) { if mailbox == "messageserr" { return nil, errors.New("internal error") } @@ -54,7 +54,7 @@ func (s *StoreStub) GetMessages(mailbox string) ([]storage.StoreMessage, error) func (s *StoreStub) RemoveMessage(mailbox, id string) error { mb, ok := s.mailboxes[mailbox] if ok { - var msg storage.StoreMessage + var msg storage.Message for i, m := range mb { if m.ID() == id { msg = m @@ -72,7 +72,7 @@ func (s *StoreStub) RemoveMessage(mailbox, id string) error { // VisitMailboxes accepts a function that will be called with the messages in each mailbox while it // continues to return true. -func (s *StoreStub) VisitMailboxes(f func([]storage.StoreMessage) (cont bool)) error { +func (s *StoreStub) VisitMailboxes(f func([]storage.Message) (cont bool)) error { for _, v := range s.mailboxes { if !f(v) { return nil @@ -82,7 +82,7 @@ func (s *StoreStub) VisitMailboxes(f func([]storage.StoreMessage) (cont bool)) e } // MessageDeleted returns true if the specified message was deleted -func (s *StoreStub) MessageDeleted(m storage.StoreMessage) bool { +func (s *StoreStub) MessageDeleted(m storage.Message) bool { _, ok := s.deleted[m] return ok } diff --git a/pkg/test/storage_suite.go b/pkg/test/storage_suite.go index 80e8626..3d167b5 100644 --- a/pkg/test/storage_suite.go +++ b/pkg/test/storage_suite.go @@ -138,7 +138,7 @@ func testContent(t *testing.T, store storage.Store) { if err != nil { t.Fatal(err) } - r, err := m.RawReader() + r, err := m.Source() if err != nil { t.Fatal(err) } @@ -269,7 +269,7 @@ func testVisitMailboxes(t *testing.T, ds storage.Store) { deliverMessage(t, ds, name, "New Message", time.Now()) } seen := 0 - err := ds.VisitMailboxes(func(messages []storage.StoreMessage) bool { + err := ds.VisitMailboxes(func(messages []storage.Message) bool { seen++ count := len(messages) if count != 2 { @@ -317,7 +317,7 @@ func deliverMessage( // getAndCountMessages is a test helper that expects to receive count messages or fails the test, it // also checks return error. -func getAndCountMessages(t *testing.T, s storage.Store, mailbox string, count int) []storage.StoreMessage { +func getAndCountMessages(t *testing.T, s storage.Store, mailbox string, count int) []storage.Message { t.Helper() msgs, err := s.GetMessages(mailbox) if err != nil {