diff --git a/lib/smtp.c b/lib/smtp.c index e33999d58..ae63e7beb 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1455,6 +1455,9 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status, CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SMTP *smtp = data->state.proto.smtp; + struct pingpong *pp = &conn->proto.smtpc.pp; + const char *eob; + size_t len; ssize_t bytes_written; (void)premature; @@ -1471,25 +1474,27 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status, result = status; /* use the already set error code */ } else if(!data->set.connect_only) { - struct smtp_conn *smtpc = &conn->proto.smtpc; - struct pingpong *pp = &smtpc->pp; + /* Calculate the EOB taking into account any terminating CRLF from the + previous line of the email or the CRLF of the DATA command when there + is "no mail data". RFC-5321, sect. 4.1.1.4. */ + eob = SMTP_EOB; + len = SMTP_EOB_LEN; + if(smtp->trailing_crlf || !conn->data->set.infilesize) { + eob += 2; + len -= 2; + } /* Send the end of block data */ - result = Curl_write(conn, - conn->writesockfd, /* socket to send to */ - SMTP_EOB, /* buffer pointer */ - SMTP_EOB_LEN, /* buffer size */ - &bytes_written); /* actually sent away */ - + result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written); if(result) return result; - if(bytes_written != SMTP_EOB_LEN) { + if(bytes_written != len) { /* The whole chunk was not sent so keep it around and adjust the pingpong structure accordingly */ - pp->sendthis = strdup(SMTP_EOB); - pp->sendsize = SMTP_EOB_LEN; - pp->sendleft = SMTP_EOB_LEN - bytes_written; + pp->sendthis = strdup(eob); + pp->sendsize = len; + pp->sendleft = len - bytes_written; } else /* Successfully sent so adjust the response timeout relative to now */ @@ -1812,8 +1817,15 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread) /* This loop can be improved by some kind of Boyer-Moore style of approach but that is saved for later... */ for(i = 0, si = 0; i < nread; i++) { - if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) + if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) { smtp->eob++; + + /* Is the EOB potentially the terminating CRLF? */ + if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob) + smtp->trailing_crlf = TRUE; + else + smtp->trailing_crlf = FALSE; + } else if(smtp->eob) { /* A previous substring matched so output that first */ memcpy(&data->state.scratch[si], SMTP_EOB, smtp->eob); @@ -1824,6 +1836,9 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread) smtp->eob = 1; else smtp->eob = 0; + + /* Reset the trailing CRLF flag as there was more data */ + smtp->trailing_crlf = FALSE; } /* Do we have a match for CRLF. as per RFC-2821, sect. 4.5.2 */ diff --git a/lib/smtp.h b/lib/smtp.h index 7a03e51ce..4aff0c5f9 100644 --- a/lib/smtp.h +++ b/lib/smtp.h @@ -62,6 +62,7 @@ struct SMTP { struct curl_slist *rcpt; /* Recipient list */ size_t eob; /* Number of bytes of the EOB (End Of Body) that have been received so far */ + bool trailing_crlf; /* Specifies if the tailing CRLF is present */ }; /* smtp_conn is used for struct connection-oriented data in the connectdata diff --git a/tests/data/test1320 b/tests/data/test1320 index f1c7328e6..15ec7bb6c 100644 --- a/tests/data/test1320 +++ b/tests/data/test1320 @@ -58,7 +58,6 @@ From: different To: another body - . diff --git a/tests/data/test1406 b/tests/data/test1406 index b7727edfd..6245c513e 100644 --- a/tests/data/test1406 +++ b/tests/data/test1406 @@ -49,7 +49,6 @@ From: different To: another body - . diff --git a/tests/data/test900 b/tests/data/test900 index e71fa94fd..749a96574 100644 --- a/tests/data/test900 +++ b/tests/data/test900 @@ -46,7 +46,6 @@ From: different To: another body - . diff --git a/tests/data/test901 b/tests/data/test901 index cc3409990..ed2451824 100644 --- a/tests/data/test901 +++ b/tests/data/test901 @@ -57,7 +57,6 @@ To: another .. body - . diff --git a/tests/data/test902 b/tests/data/test902 index c3b9fb442..4da1b9912 100644 --- a/tests/data/test902 +++ b/tests/data/test902 @@ -52,7 +52,6 @@ From: different To: another body - . diff --git a/tests/data/test903 b/tests/data/test903 index defadf903..157bd48cb 100644 --- a/tests/data/test903 +++ b/tests/data/test903 @@ -49,7 +49,6 @@ QUIT mail body - . diff --git a/tests/data/test904 b/tests/data/test904 index 19e6f2226..1a23f4157 100644 --- a/tests/data/test904 +++ b/tests/data/test904 @@ -50,7 +50,6 @@ QUIT mail body - . diff --git a/tests/data/test905 b/tests/data/test905 index 451a73d49..fccd84bae 100644 --- a/tests/data/test905 +++ b/tests/data/test905 @@ -52,7 +52,6 @@ QUIT mail body - . diff --git a/tests/data/test906 b/tests/data/test906 index 80c1e7ee6..1f88990fd 100644 --- a/tests/data/test906 +++ b/tests/data/test906 @@ -45,7 +45,6 @@ From: different To: another body - . diff --git a/tests/data/test907 b/tests/data/test907 index 45e453db0..511d51970 100644 --- a/tests/data/test907 +++ b/tests/data/test907 @@ -47,7 +47,6 @@ QUIT mail body - . diff --git a/tests/data/test908 b/tests/data/test908 index c1689287f..61d56c5e0 100644 --- a/tests/data/test908 +++ b/tests/data/test908 @@ -48,7 +48,6 @@ QUIT mail body - . diff --git a/tests/data/test909 b/tests/data/test909 index 89c8b0fb8..2fc1f191d 100644 --- a/tests/data/test909 +++ b/tests/data/test909 @@ -50,7 +50,6 @@ From: different To: another body - .