-
Notifications
You must be signed in to change notification settings - Fork 220
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
server: DATA command timeout should close the connection #196
Comments
I also noticed that DATA timeout is implemented incorrectly. While client sends email data, the deadline isn't updated. In order to fix this particular issue I suggest the fix below: --- a/data.go
+++ b/data.go
@@ -1,8 +1,8 @@
package smtp
import (
- "bufio"
"io"
+ "time"
)
type EnhancedCode [3]int
@@ -43,7 +43,7 @@ var ErrDataTooLarge = &SMTPError{
}
type dataReader struct {
- r *bufio.Reader
+ c *Conn
state int
limited bool
@@ -52,7 +52,7 @@ type dataReader struct {
func newDataReader(c *Conn) *dataReader {
dr := &dataReader{
- r: c.text.R,
+ c: c,
}
if c.server.MaxMessageBytes > 0 {
@@ -87,8 +87,14 @@ func (r *dataReader) Read(b []byte) (n int, err error) {
stateEOF // reached .\r\n end marker line
)
for n < len(b) && r.state != stateEOF {
+ if r.c.server.ReadTimeout != 0 {
+ err = r.c.conn.SetReadDeadline(time.Now().Add(r.c.server.ReadTimeout))
+ if err != nil {
+ break
+ }
+ }
var c byte
- c, err = r.r.ReadByte()
+ c, err = r.c.text.R.ReadByte()
if err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
|
This is by design. |
Ideally the server would be improved to have two options, one for regular command timeouts, the other for the DATA command timeout, like the client has. |
Basically go-smtp issues two timeouts, configured by
ReadTimeout
: for DATA command, for the idle connection:For instance AWS SES closes the connection on data timeout:
See RFC5321
451 Requested action aborted: error in processing
.Not closing the connection on DATA timeout causes a slow postfix client talking to go-smtp server to send the data even, when the go-smtp server responds with
421 4.0.0
and the DATA's leftover data is considered as a mangled SMTP command in go-smtp server.I suggest to catch the DATA timeout exception and close the connection, e.g.
Ideally it would be better to preserve the original err inside the SMTPError struct, e.g. implement some kind of err wrapping like it's done with https://go.dev/blog/go1.13-errors#errors-in-go-113
The text was updated successfully, but these errors were encountered: