Commit 6774f8f383302bc656f47a9295baeab0b6b4e2e4
1 parent
e5bc687a
send_mail now support list of recipients. The recipients must belonging to the same MX server.
In sending process the client invoke RSET between each recipient. With that method we don't need to disconnect from the server and reconnect to it for each send.
Showing
3 changed files
with
97 additions
and
41 deletions
Show diff stats
mail/send_mail.anubis
| @@ -18,6 +18,7 @@ read system/data_io.anubis | @@ -18,6 +18,7 @@ read system/data_io.anubis | ||
| 18 | read system/logger.anubis | 18 | read system/logger.anubis |
| 19 | 19 | ||
| 20 | read calexium_lib/net_services_protocols/logger_service.anubis | 20 | read calexium_lib/net_services_protocols/logger_service.anubis |
| 21 | +read calexium_lib/mail/send_mail_type.anubis | ||
| 21 | 22 | ||
| 22 | read lexers/enhanced_status.anubis | 23 | read lexers/enhanced_status.anubis |
| 23 | read smtp_server_extensions.anubis | 24 | read smtp_server_extensions.anubis |
| @@ -34,25 +35,23 @@ define Int _sendmail_time_out = 300. //5 minutes of timeout | @@ -34,25 +35,23 @@ define Int _sendmail_time_out = 300. //5 minutes of timeout | ||
| 34 | error, | 35 | error, |
| 35 | reply(Int code, String enhanced_status, List(String) lines). | 36 | reply(Int code, String enhanced_status, List(String) lines). |
| 36 | 37 | ||
| 37 | -public type Str_HostName: | ||
| 38 | - str_host_name(String str). | 38 | +public type Smtp_Recipient: |
| 39 | + smtp_recipient(String email, //email address of the recipient | ||
| 40 | + | ||
| 41 | + Int nb_tries, | ||
| 42 | + Int uid, //parameter used by handle_status (mail_uid) | ||
| 43 | + Int uid2 //same (contact_id) | ||
| 44 | + ). | ||
| 39 | 45 | ||
| 40 | -public type Str_Sender: | ||
| 41 | - str_sender(String str). | ||
| 42 | - | ||
| 43 | -public type Str_Recipient: | ||
| 44 | - str_recipient(String str). | ||
| 45 | 46 | ||
| 46 | -public type Str_UID: | ||
| 47 | - str_UID(String str). | ||
| 48 | 47 | ||
| 49 | public type Send_Param: | 48 | public type Send_Param: |
| 50 | - send_param( Str_HostName host_name, //domain of the sender like "mail.calexium.com" | ||
| 51 | - Str_Sender sender, //sender email address | ||
| 52 | - Str_Recipient recipient, //recipient email address | ||
| 53 | - List(Data_IO) mail_parts, //email to send | ||
| 54 | - SmtpAuth auth, // | ||
| 55 | - Str_UID mail_uid, | 49 | + send_param( Str_HostName host_name, //domain of the sender like "mail.calexium.com" |
| 50 | + Str_Sender sender, //sender email address | ||
| 51 | + List(Data_IO) mail_parts, //all parts of the email to send | ||
| 52 | + List(Smtp_Recipient) recipients, //recipient email address | ||
| 53 | + SmtpAuth auth, // | ||
| 54 | + Str_UID mail_uid, | ||
| 56 | Int last_smtp_code //0 means it's the first time | 55 | Int last_smtp_code //0 means it's the first time |
| 57 | ). | 56 | ). |
| 58 | 57 | ||
| @@ -62,20 +61,23 @@ public type Send_Param: | @@ -62,20 +61,23 @@ public type Send_Param: | ||
| 62 | define Result(SmtpClientResult, One) | 61 | define Result(SmtpClientResult, One) |
| 63 | sm_MAIL_FROM | 62 | sm_MAIL_FROM |
| 64 | ( | 63 | ( |
| 65 | - RWStream conn, | ||
| 66 | - Send_Param param, | ||
| 67 | - SmtpClientSession sm_session, | ||
| 68 | - (Int) -> One progress_report, | ||
| 69 | - (LogLevel, String) -> One logger | 64 | + RWStream conn, //TCP connection |
| 65 | + Str_Sender sender, //email address of the sender | ||
| 66 | + List(Data_IO) mail_parts, //all parts to send | ||
| 67 | + Smtp_Recipient recipient, //contain email address and uid | ||
| 68 | + SmtpClientSession sm_session, //smtp session | ||
| 69 | + (Int) -> One progress_report, //don't know what it is for the moment | ||
| 70 | + (LogLevel, String) -> One logger //logger | ||
| 70 | ) = | 71 | ) = |
| 71 | with enhanced_status = sm_session.enhanced_status, | 72 | with enhanced_status = sm_session.enhanced_status, |
| 73 | + since recipient is smtp_recipient(rcpt_address, try, uid, uid2), | ||
| 72 | //send MAIL FROM | 74 | //send MAIL FROM |
| 73 | - if send_mail_from(conn, param.sender.str, sm_session, _sendmail_time_out, logger) is | 75 | + if send_mail_from(conn, sender.str, sm_session, _sendmail_time_out, logger) is |
| 74 | { | 76 | { |
| 75 | error(result) then error(result), | 77 | error(result) then error(result), |
| 76 | ok(_) then | 78 | ok(_) then |
| 77 | //send RCPT TO | 79 | //send RCPT TO |
| 78 | - if send_recipient(conn, param.recipient.str, sm_session, _sendmail_time_out, logger) is | 80 | + if send_recipient(conn, rcpt_address, sm_session, _sendmail_time_out, logger) is |
| 79 | { | 81 | { |
| 80 | error(result) then error(result), | 82 | error(result) then error(result), |
| 81 | ok(_) then | 83 | ok(_) then |
| @@ -84,18 +86,48 @@ define Result(SmtpClientResult, One) | @@ -84,18 +86,48 @@ define Result(SmtpClientResult, One) | ||
| 84 | { | 86 | { |
| 85 | error(result) then error(result), | 87 | error(result) then error(result), |
| 86 | ok(_) then | 88 | ok(_) then |
| 87 | - if send_content(conn, param.mail_parts, sm_session, _sendmail_time_out, progress_report, logger) is | ||
| 88 | - { | ||
| 89 | - error(result) then error(result), | ||
| 90 | - ok(_) then | ||
| 91 | - send_quit(conn, sm_session, _sendmail_time_out, logger); | ||
| 92 | - logger(logTrace, "SENT Mail FROM "+param.sender.str+" TO "+param.recipient.str); | ||
| 93 | - ok(unique) | ||
| 94 | - } | 89 | + if rewind(mail_parts) then |
| 90 | + if send_content(conn, mail_parts, sm_session, _sendmail_time_out, progress_report, logger) is | ||
| 91 | + { | ||
| 92 | + error(result) then error(result), | ||
| 93 | + ok(_) then | ||
| 94 | + //send_quit(conn, sm_session, _sendmail_time_out, logger); | ||
| 95 | + logger(logTrace, "SENT Mail FROM "+sender.str+" TO "+rcpt_address); | ||
| 96 | + ok(unique) | ||
| 97 | + } | ||
| 98 | + else | ||
| 99 | + error(error) | ||
| 95 | } | 100 | } |
| 96 | } | 101 | } |
| 97 | }. | 102 | }. |
| 98 | 103 | ||
| 104 | +define Result(SmtpClientResult, One) | ||
| 105 | + send_to_recipients_list | ||
| 106 | + ( | ||
| 107 | + RWStream conn, //TCP connection | ||
| 108 | + Send_Param param, | ||
| 109 | + List(Smtp_Recipient) recipients, //recipients with email to send | ||
| 110 | + SmtpClientSession sm_session, //smtp session | ||
| 111 | + (Int) -> One progress_report, //don't know what it is for the moment | ||
| 112 | + (LogLevel, String) -> One logger, //logger | ||
| 113 | + (Result(SmtpClientResult, One), Smtp_Recipient) -> One handle_result | ||
| 114 | + )= | ||
| 115 | + if recipients is | ||
| 116 | + { | ||
| 117 | + [] then ok(unique), | ||
| 118 | + [ rcpt . tail ] then | ||
| 119 | + with result = sm_MAIL_FROM(conn, param.sender, param.mail_parts, rcpt, sm_session, progress_report, logger), | ||
| 120 | + //here we apply the function provided by application to handle the result | ||
| 121 | + handle_result(result, rcpt); | ||
| 122 | + //if there is another recipient we send a RSET and we are able to send the | ||
| 123 | + //email to the next recipient within the same smtp session | ||
| 124 | + if length(tail) > 0 then | ||
| 125 | + send_rset(conn, sm_session, _sendmail_time_out, logger); | ||
| 126 | + send_to_recipients_list(conn, param, tail, sm_session, progress_report, logger, handle_result) | ||
| 127 | + else | ||
| 128 | + ok(unique) | ||
| 129 | + } | ||
| 130 | + . | ||
| 99 | 131 | ||
| 100 | Apply the whole protocol: | 132 | Apply the whole protocol: |
| 101 | 133 | ||
| @@ -110,7 +142,8 @@ public define Result(SmtpClientResult, One) | @@ -110,7 +142,8 @@ public define Result(SmtpClientResult, One) | ||
| 110 | Send_Param param, | 142 | Send_Param param, |
| 111 | (SmtpClientSession, Send_Param) -> Result(SmtpClientResult, Send_Param) prepare_mail_callback, | 143 | (SmtpClientSession, Send_Param) -> Result(SmtpClientResult, Send_Param) prepare_mail_callback, |
| 112 | (Int) -> One progress_report, | 144 | (Int) -> One progress_report, |
| 113 | - (LogLevel, String) -> One logger | 145 | + (LogLevel, String) -> One logger, |
| 146 | + (Result(SmtpClientResult, One), Smtp_Recipient) -> One handle_result | ||
| 114 | ) = | 147 | ) = |
| 115 | // | 148 | // |
| 116 | // Our connection to the SMTP server is opened. We just have to apply the protocol. | 149 | // Our connection to the SMTP server is opened. We just have to apply the protocol. |
| @@ -135,7 +168,10 @@ public define Result(SmtpClientResult, One) | @@ -135,7 +168,10 @@ public define Result(SmtpClientResult, One) | ||
| 135 | if prepare_mail_callback(sm_session, param) is | 168 | if prepare_mail_callback(sm_session, param) is |
| 136 | { | 169 | { |
| 137 | error(prepare_result) then error(prepare_result), | 170 | error(prepare_result) then error(prepare_result), |
| 138 | - ok(new_param) then sm_MAIL_FROM(conn, new_param, sm_session, progress_report, logger) | 171 | + ok(new_param) then |
| 172 | + with result = send_to_recipients_list(conn, new_param, new_param.recipients, sm_session, progress_report, logger, handle_result), | ||
| 173 | + send_quit(conn, sm_session, _sendmail_time_out, logger); | ||
| 174 | + result | ||
| 139 | } | 175 | } |
| 140 | } | 176 | } |
| 141 | } | 177 | } |
| @@ -154,13 +190,15 @@ public define Result(SmtpClientResult, One) | @@ -154,13 +190,15 @@ public define Result(SmtpClientResult, One) | ||
| 154 | RWStream conn, | 190 | RWStream conn, |
| 155 | Send_Param param, | 191 | Send_Param param, |
| 156 | (SmtpClientSession, Send_Param) -> Result(SmtpClientResult, Send_Param) prepare_mail_callback, | 192 | (SmtpClientSession, Send_Param) -> Result(SmtpClientResult, Send_Param) prepare_mail_callback, |
| 193 | + (Result(SmtpClientResult, One), Smtp_Recipient) -> One handle_result | ||
| 157 | ) = | 194 | ) = |
| 158 | send_mail(conn, | 195 | send_mail(conn, |
| 159 | param, | 196 | param, |
| 160 | prepare_mail_callback, | 197 | prepare_mail_callback, |
| 161 | (Int _) |-> unique, | 198 | (Int _) |-> unique, |
| 162 | (LogLevel level, String txt) |-> if level is logTrace then logTrace(send_mail_log, send_mail_mask, txt) | 199 | (LogLevel level, String txt) |-> if level is logTrace then logTrace(send_mail_log, send_mail_mask, txt) |
| 163 | - else log(level, send_mail_log, txt) | 200 | + else log(level, send_mail_log, txt), |
| 201 | + handle_result | ||
| 164 | ). | 202 | ). |
| 165 | 203 | ||
| 166 | public define Result(SmtpClientResult, One) | 204 | public define Result(SmtpClientResult, One) |
| @@ -168,10 +206,12 @@ public define Result(SmtpClientResult, One) | @@ -168,10 +206,12 @@ public define Result(SmtpClientResult, One) | ||
| 168 | ( | 206 | ( |
| 169 | RWStream conn, | 207 | RWStream conn, |
| 170 | Send_Param param, | 208 | Send_Param param, |
| 209 | + (Result(SmtpClientResult, One), Smtp_Recipient) -> One handle_result | ||
| 171 | ) = | 210 | ) = |
| 172 | send_mail(conn, | 211 | send_mail(conn, |
| 173 | param, | 212 | param, |
| 174 | - (SmtpClientSession sm_session, Send_Param param) |-> ok(param) | 213 | + (SmtpClientSession sm_session, Send_Param param) |-> ok(param), |
| 214 | + handle_result | ||
| 175 | ). | 215 | ). |
| 176 | 216 | ||
| 177 | public define Result(SmtpClientResult, One) | 217 | public define Result(SmtpClientResult, One) |
| @@ -198,7 +238,7 @@ public define Result(SmtpClientResult, One) | @@ -198,7 +238,7 @@ public define Result(SmtpClientResult, One) | ||
| 198 | error(error), | 238 | error(error), |
| 199 | 239 | ||
| 200 | ok(server_conn) then | 240 | ok(server_conn) then |
| 201 | - send_mail(server_conn, param), | 241 | + send_mail(server_conn, param, (Result(SmtpClientResult, One) dum, Smtp_Recipient my) |-> unique), |
| 202 | } | 242 | } |
| 203 | }. | 243 | }. |
| 204 | 244 |
mail/send_mail_type.anubis
| @@ -12,6 +12,18 @@ read tools/basis.anubis | @@ -12,6 +12,18 @@ read tools/basis.anubis | ||
| 12 | 12 | ||
| 13 | read calexium_lib/mail/smtp_client.anubis | 13 | read calexium_lib/mail/smtp_client.anubis |
| 14 | 14 | ||
| 15 | +public type Str_HostName: | ||
| 16 | + str_host_name(String str). | ||
| 17 | + | ||
| 18 | +public type Str_Sender: | ||
| 19 | + str_sender(String str). | ||
| 20 | + | ||
| 21 | +public type Str_Recipient: | ||
| 22 | + str_recipient(String str). | ||
| 23 | + | ||
| 24 | +public type Str_UID: | ||
| 25 | + str_UID(String str). | ||
| 26 | + | ||
| 15 | public type Send_Status: | 27 | public type Send_Status: |
| 16 | ready, //ready to send | 28 | ready, //ready to send |
| 17 | finished, //the mail is delivered correctly | 29 | finished, //the mail is delivered correctly |
mail/smtp_client.anubis
| @@ -532,12 +532,16 @@ public define One | @@ -532,12 +532,16 @@ public define One | ||
| 532 | ) = | 532 | ) = |
| 533 | forget(smtp_send_command(conn, "QUIT", 221, session, timeout, logger)). | 533 | forget(smtp_send_command(conn, "QUIT", 221, session, timeout, logger)). |
| 534 | 534 | ||
| 535 | -// if smtp_send_line(conn,"QUIT", logger) is | ||
| 536 | -// { | ||
| 537 | -// failure then logger(logWarning, "error sending QUIT"), | ||
| 538 | -// success(_) then forget(receive_reply(conn, session.enhanced_status, timeout, logger)) | ||
| 539 | -// }. | ||
| 540 | - | 535 | +public define One |
| 536 | + send_rset | ||
| 537 | + ( | ||
| 538 | + RWStream conn, | ||
| 539 | + SmtpClientSession session, | ||
| 540 | + Int timeout, | ||
| 541 | + (LogLevel, String) -> One logger | ||
| 542 | + ) = | ||
| 543 | + forget(smtp_send_command(conn, "RSET", 250, session, timeout, logger)). | ||
| 544 | + | ||
| 541 | define List(String) | 545 | define List(String) |
| 542 | get_auth_method | 546 | get_auth_method |
| 543 | ( | 547 | ( |