Skip to content

Commit

Permalink
Added Read and Write timeouts. (#33)
Browse files Browse the repository at this point in the history
* Added Write and Read timeouts to server.

* Fixed test compilation

* Fixed multiple deadlines.

* Minor fixes.

* Only add timeout when it is not 0.

* Removed IdleTimeout.

* Fixed example.

* Switched to time.Second instead of plain int.

* Fix indentation in example in README.md

* Fix indentation

* Fix the facking indentation.
  • Loading branch information
NamedKitten authored and emersion committed Mar 31, 2019
1 parent 5381b0b commit 6c24079
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 17 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import (
"io"
"io/ioutil"
"log"
"time"

"github.com/emersion/go-smtp"
)
Expand Down Expand Up @@ -115,7 +116,8 @@ func main() {

s.Addr = ":1025"
s.Domain = "localhost"
s.MaxIdleSeconds = 300
s.ReadTimeout = 10 * time.Second
s.WriteTimeout = 10 * time.Second
s.MaxMessageBytes = 1024 * 1024
s.MaxRecipients = 50
s.AllowInsecureAuth = true
Expand Down
22 changes: 8 additions & 14 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func (c *Conn) handleGreet(enhanced bool, arg string) {
}
if c.authAllowed() {
authCap := "AUTH"
for name, _ := range c.server.auths {
for name := range c.server.auths {
authCap += " " + name
}

Expand Down Expand Up @@ -471,19 +471,11 @@ func (c *Conn) greet() {
c.WriteResponse(220, fmt.Sprintf("%v ESMTP Service Ready", c.server.Domain))
}

// Calculate the next read or write deadline based on MaxIdleSeconds.
func (c *Conn) nextDeadline() time.Time {
if c.server.MaxIdleSeconds == 0 {
return time.Time{} // No deadline
}

return time.Now().Add(time.Duration(c.server.MaxIdleSeconds) * time.Second)
}

func (c *Conn) WriteResponse(code int, text ...string) {
// TODO: error handling

c.conn.SetDeadline(c.nextDeadline())
if c.server.WriteTimeout != 0 {
c.conn.SetWriteDeadline(time.Now().Add(c.server.WriteTimeout))
}

for i := 0; i < len(text)-1; i++ {
c.text.PrintfLine("%v-%v", code, text[i])
Expand All @@ -493,8 +485,10 @@ func (c *Conn) WriteResponse(code int, text ...string) {

// Reads a line of input
func (c *Conn) ReadLine() (string, error) {
if err := c.conn.SetReadDeadline(c.nextDeadline()); err != nil {
return "", err
if c.server.ReadTimeout != 0 {
if err := c.conn.SetReadDeadline(time.Now().Add(c.server.ReadTimeout)); err != nil {
return "", err
}
}

return c.text.ReadLine()
Expand Down
4 changes: 3 additions & 1 deletion example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io/ioutil"
"log"
"strings"
"time"

"github.com/emersion/go-sasl"
"github.com/emersion/go-smtp"
Expand Down Expand Up @@ -139,7 +140,8 @@ func ExampleNewServer() {

s.Addr = ":1025"
s.Domain = "localhost"
s.MaxIdleSeconds = 300
s.WriteTimeout = 10 * time.Second
s.ReadTimeout = 10 * time.Second
s.MaxMessageBytes = 1024 * 1024
s.MaxRecipients = 50
s.AllowInsecureAuth = true
Expand Down
4 changes: 3 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"net"
"sync"
"time"

"github.com/emersion/go-sasl"
)
Expand All @@ -27,11 +28,12 @@ type Server struct {

Domain string
MaxRecipients int
MaxIdleSeconds int
MaxMessageBytes int
AllowInsecureAuth bool
Strict bool
Debug io.Writer
ReadTimeout time.Duration
WriteTimeout time.Duration

// If set, the AUTH command will not be advertised and authentication
// attempts will be rejected. This setting overrides AllowInsecureAuth.
Expand Down

0 comments on commit 6c24079

Please sign in to comment.