11#include < bloomail/base_clients/smtp.h>
22
3+ const int bloomail::BaseClient::Smtp::CHUNK_SIZE = 57 ;
4+
35bloomail::BaseClient::Smtp::Smtp (const std::string &host, int port, bool debug)
46 : tcp(host, port), tls(tcp), bloomail::BaseClient::IBaseClient(debug),
57 tlsConnected(false ) {
@@ -31,6 +33,16 @@ void bloomail::BaseClient::Smtp::login(const std::string &username,
3133 this ->isLoggedIn = true ;
3234}
3335
36+ void bloomail::BaseClient::Smtp::sendEmail () {
37+ this ->validate ();
38+ this ->sendHeaders ();
39+ this ->sendAttachments ();
40+ this ->send (" --" + bloomail::BaseClient::IBaseClient::BOUNDARY + " --\r\n ." );
41+ this ->recv ();
42+ this ->clear ();
43+ return ;
44+ }
45+
3446void bloomail::BaseClient::Smtp::send (const std::string &cmd) {
3547 if (this ->debug ) {
3648 logger::debug ((this ->tlsConnected ? " [TLS] " : " [TCP] " ) + cmd);
@@ -74,9 +86,7 @@ void bloomail::BaseClient::Smtp::quit() {
7486 this ->recv ();
7587}
7688
77- void bloomail::BaseClient::Smtp::sendEmail () {
78- this ->validate ();
79-
89+ void bloomail::BaseClient::Smtp::sendHeaders () {
8090 this ->send (" MAIL FROM:<" + this ->rawUsername + " >" );
8191 this ->recv ();
8292
@@ -120,11 +130,42 @@ void bloomail::BaseClient::Smtp::sendEmail() {
120130 header += " \r\n " ;
121131 }
122132
123- header += " Content-Type: text/plain; charset=UTF-8\r\n " ;
133+ header += " MIME-Version: 1.0\r\n " ;
134+ header += " Content-Type: multipart/mixed; boundary=" +
135+ bloomail::BaseClient::IBaseClient::BOUNDARY + " \r\n " ;
124136 header += " \r\n " ;
125- this ->send (header + brewtils::string::replace (message, " \n " , " \r\n " ) +
126- " \r\n ." );
127- this ->recv ();
137+ header += " --" + bloomail::BaseClient::IBaseClient::BOUNDARY + " \r\n " ;
138+ header += " Content-Type: text/plain; charset=UTF-8\r\n " ;
139+ header += " Content-Transfer-Encoding: 7bit\r\n\r\n " ;
140+ header += brewtils::string::replace (this ->message , " \n " , " \r\n " );
141+ this ->send (header);
142+ }
128143
129- return this ->clear ();
144+ void bloomail::BaseClient::Smtp::sendAttachments () {
145+ for (const auto &[filePath, fileName] : this ->attachments ) {
146+ std::ifstream file (filePath, std::ios::binary);
147+ if (!file.is_open ()) {
148+ logger::error (" Could not open file " + filePath);
149+ continue ;
150+ }
151+
152+ std::string attachmentHeader;
153+ attachmentHeader +=
154+ " --" + bloomail::BaseClient::IBaseClient::BOUNDARY + " \r\n " ;
155+ attachmentHeader +=
156+ " Content-Type: " + brewtils::os::file::getMimeType (filePath) + " \r\n " ;
157+ attachmentHeader +=
158+ " Content-Disposition: attachment; filename=\" " + fileName + " \"\r\n " ;
159+ attachmentHeader += " Content-Transfer-Encoding: base64\r\n\r\n " ;
160+ this ->send (attachmentHeader);
161+
162+ char buffer[bloomail::BaseClient::Smtp::CHUNK_SIZE];
163+ while (file.read (buffer, sizeof (buffer)) || file.gcount () > 0 ) {
164+ std::string chunk (buffer, file.gcount ());
165+ std::string encoded = brewtils::base64::encode (chunk);
166+ this ->send (encoded);
167+ }
168+ this ->send (" \r\n " );
169+ }
170+ return ;
130171}
0 commit comments