mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
storage: More refactoring for #69
- impl Store.AddMessage - file: Use AddMessage() in tests - smtp: Switch to AddMessage - storage: Remove NewMessage, Append, Close methods
This commit is contained in:
@@ -12,7 +12,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jhillyerd/enmime"
|
||||
"github.com/jhillyerd/inbucket/pkg/log"
|
||||
"github.com/jhillyerd/inbucket/pkg/message"
|
||||
"github.com/jhillyerd/inbucket/pkg/msghub"
|
||||
"github.com/jhillyerd/inbucket/pkg/stringutil"
|
||||
)
|
||||
@@ -442,48 +444,61 @@ func (ss *Session) dataHandler() {
|
||||
|
||||
// deliverMessage creates and populates a new Message for the specified recipient
|
||||
func (ss *Session) deliverMessage(r recipientDetails, msgBuf [][]byte) (ok bool) {
|
||||
msg, err := ss.server.dataStore.NewMessage(r.localPart)
|
||||
if err != nil {
|
||||
ss.logError("Failed to create message for %q: %s", r.localPart, err)
|
||||
return false
|
||||
}
|
||||
|
||||
// Generate Received header
|
||||
stamp := time.Now().Format(timeStampFormat)
|
||||
recd := fmt.Sprintf("Received: from %s ([%s]) by %s\r\n for <%s>; %s\r\n",
|
||||
ss.remoteDomain, ss.remoteHost, ss.server.domain, r.address, stamp)
|
||||
if err := msg.Append([]byte(recd)); err != nil {
|
||||
ss.logError("Failed to write received header for %q: %s", r.localPart, err)
|
||||
return false
|
||||
}
|
||||
|
||||
// Append lines from msgBuf
|
||||
for _, line := range msgBuf {
|
||||
if err := msg.Append(line); err != nil {
|
||||
ss.logError("Failed to append to mailbox %v: %v", r.localPart, err)
|
||||
// Should really cleanup the crap on filesystem
|
||||
return false
|
||||
}
|
||||
}
|
||||
if err := msg.Close(); err != nil {
|
||||
ss.logError("Error while closing message for %v: %v", r.localPart, err)
|
||||
return false
|
||||
}
|
||||
name, err := stringutil.ParseMailboxName(r.localPart)
|
||||
if err != nil {
|
||||
// This parse already succeeded when MailboxFor was called, shouldn't fail here.
|
||||
return false
|
||||
}
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
// Generate Received header
|
||||
stamp := time.Now().Format(timeStampFormat)
|
||||
recd := fmt.Sprintf("Received: from %s ([%s]) by %s\r\n for <%s>; %s\r\n",
|
||||
ss.remoteDomain, ss.remoteHost, ss.server.domain, r.address, stamp)
|
||||
buf.WriteString(recd)
|
||||
// Append lines from msgBuf
|
||||
for _, line := range msgBuf {
|
||||
buf.Write(line)
|
||||
}
|
||||
// TODO replace with something that only reads header?
|
||||
env, err := enmime.ReadEnvelope(bytes.NewReader(buf.Bytes()))
|
||||
if err != nil {
|
||||
ss.logError("Failed to parse message for %q: %v", r.localPart, err)
|
||||
return false
|
||||
}
|
||||
from, err := env.AddressList("From")
|
||||
if err != nil {
|
||||
ss.logError("Failed to get From address: %v", err)
|
||||
return false
|
||||
}
|
||||
to, err := env.AddressList("To")
|
||||
if err != nil {
|
||||
ss.logError("Failed to get To addresses: %v", err)
|
||||
return false
|
||||
}
|
||||
delivery := &message.Delivery{
|
||||
Meta: message.Metadata{
|
||||
Mailbox: name,
|
||||
From: from[0],
|
||||
To: to,
|
||||
Date: time.Now(),
|
||||
Subject: env.GetHeader("Subject"),
|
||||
},
|
||||
Reader: bytes.NewReader(buf.Bytes()),
|
||||
}
|
||||
id, err := ss.server.dataStore.AddMessage(delivery)
|
||||
if err != nil {
|
||||
ss.logError("Failed to store message for %q: %s", r.localPart, err)
|
||||
return false
|
||||
}
|
||||
// Broadcast message information
|
||||
broadcast := msghub.Message{
|
||||
Mailbox: name,
|
||||
ID: msg.ID(),
|
||||
From: msg.From().String(),
|
||||
To: stringutil.StringAddressList(msg.To()),
|
||||
Subject: msg.Subject(),
|
||||
Date: msg.Date(),
|
||||
Size: msg.Size(),
|
||||
ID: id,
|
||||
From: delivery.From().String(),
|
||||
To: stringutil.StringAddressList(delivery.To()),
|
||||
Subject: delivery.Subject(),
|
||||
Date: delivery.Date(),
|
||||
Size: delivery.Size(),
|
||||
}
|
||||
ss.server.msgHub.Dispatch(broadcast)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
|
||||
"log"
|
||||
"net"
|
||||
"net/mail"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -141,18 +140,7 @@ func TestReadyState(t *testing.T) {
|
||||
|
||||
// Test commands in MAIL state
|
||||
func TestMailState(t *testing.T) {
|
||||
// Setup mock objects
|
||||
mds := &storage.MockDataStore{}
|
||||
msg1 := &storage.MockMessage{}
|
||||
mds.On("NewMessage", "u1").Return(msg1, nil)
|
||||
msg1.On("ID").Return("")
|
||||
msg1.On("From").Return(&mail.Address{})
|
||||
msg1.On("To").Return(make([]*mail.Address, 0))
|
||||
msg1.On("Date").Return(time.Time{})
|
||||
msg1.On("Subject").Return("")
|
||||
msg1.On("Size").Return(0)
|
||||
msg1.On("Close").Return(nil)
|
||||
|
||||
mds := test.NewStore()
|
||||
server, logbuf, teardown := setupSMTPServer(mds)
|
||||
defer teardown()
|
||||
|
||||
@@ -214,7 +202,7 @@ func TestMailState(t *testing.T) {
|
||||
{"MAIL FROM:<john@gmail.com>", 250},
|
||||
{"RCPT TO:<u1@gmail.com>", 250},
|
||||
{"DATA", 354},
|
||||
{".", 250},
|
||||
{".", 451},
|
||||
}
|
||||
if err := playSession(t, server, script); err != nil {
|
||||
t.Error(err)
|
||||
@@ -253,18 +241,7 @@ func TestMailState(t *testing.T) {
|
||||
|
||||
// Test commands in DATA state
|
||||
func TestDataState(t *testing.T) {
|
||||
// Setup mock objects
|
||||
mds := &storage.MockDataStore{}
|
||||
msg1 := &storage.MockMessage{}
|
||||
mds.On("NewMessage", "u1").Return(msg1, nil)
|
||||
msg1.On("ID").Return("")
|
||||
msg1.On("From").Return(&mail.Address{})
|
||||
msg1.On("To").Return(make([]*mail.Address, 0))
|
||||
msg1.On("Date").Return(time.Time{})
|
||||
msg1.On("Subject").Return("")
|
||||
msg1.On("Size").Return(0)
|
||||
msg1.On("Close").Return(nil)
|
||||
|
||||
mds := test.NewStore()
|
||||
server, logbuf, teardown := setupSMTPServer(mds)
|
||||
defer teardown()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user