Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement Close. #24

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ func (s *ClientSession) Abort() error {

// Close releases resources associated with the session.
//
// If there a milter sequence in progress - it is aborted.
// If there's a milter sequence in progress - it is aborted.
func (s *ClientSession) Close() error {
if s.needAbort {
_ = s.Abort()
Expand Down
4 changes: 4 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ func (mm *MockMilter) Abort(m *Modifier) error {
return mm.AbortErr
}

func (mm *MockMilter) Close(m *Modifier) {
return
}

func TestMilterClient_UsualFlow(t *testing.T) {
mm := MockMilter{
ConnResp: RespContinue,
Expand Down
24 changes: 24 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ type Milter interface {
// should be reset to prior to the Helo callback. Connection data should be
// preserved.
Abort(m *Modifier) error

// Close is called once at the end of each connection.
//
// - Close may be called "out-of-order", i.e. before even the
// Connect is called. After a connection is established by the
// MTA to the filter, if the MTA decides this connection's
// traffic will be discarded, no data will be passed to the
// filter from the MTA until the client closes down. At that time,
// Close is called. It can therefore be the only callback ever
// used for a given connection, and developers should anticipate
// this possibility when crafting their Close code. In particular,
// it is incorrect to assume the private context pointer will be
// something other than NULL in this callback.
// - Close is called on close even if the previous mail
// transaction was aborted.
// - Close is responsible for freeing any resources allocated on
// a per-connection basis.
// - Since the connection is already closing, the return value is
// currently ignored.
Close(m *Modifier)
}

// NoOpMilter is a dummy Milter implementation that does nothing.
Expand Down Expand Up @@ -97,6 +117,10 @@ func (NoOpMilter) Abort(m *Modifier) error {
return nil
}

func (NoOpMilter) Close(m *Modifier) {
return
}

// Server is a milter server.
type Server struct {
NewMilter func() Milter
Expand Down
2 changes: 1 addition & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ func (m *milterSession) Process(msg *Message) (Response, error) {

case CodeQuit:
// client requested session close
m.backend.Close(newModifier(m))
return nil, errCloseSession

case CodeRcpt:
// envelope to address
to := readCString(msg.Data)
Expand Down