Commit 6774f8f383302bc656f47a9295baeab0b6b4e2e4

Authored by totoro
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.
mail/send_mail.anubis
... ... @@ -18,6 +18,7 @@ read system/data_io.anubis
18 18 read system/logger.anubis
19 19  
20 20 read calexium_lib/net_services_protocols/logger_service.anubis
  21 +read calexium_lib/mail/send_mail_type.anubis
21 22  
22 23 read lexers/enhanced_status.anubis
23 24 read smtp_server_extensions.anubis
... ... @@ -34,25 +35,23 @@ define Int _sendmail_time_out = 300. //5 minutes of timeout
34 35 error,
35 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 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 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 61 define Result(SmtpClientResult, One)
63 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 72 with enhanced_status = sm_session.enhanced_status,
  73 + since recipient is smtp_recipient(rcpt_address, try, uid, uid2),
72 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 77 error(result) then error(result),
76 78 ok(_) then
77 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 82 error(result) then error(result),
81 83 ok(_) then
... ... @@ -84,18 +86,48 @@ define Result(SmtpClientResult, One)
84 86 {
85 87 error(result) then error(result),
86 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 132 Apply the whole protocol:
101 133  
... ... @@ -110,7 +142,8 @@ public define Result(SmtpClientResult, One)
110 142 Send_Param param,
111 143 (SmtpClientSession, Send_Param) -> Result(SmtpClientResult, Send_Param) prepare_mail_callback,
112 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 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 168 if prepare_mail_callback(sm_session, param) is
136 169 {
137 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 190 RWStream conn,
155 191 Send_Param param,
156 192 (SmtpClientSession, Send_Param) -> Result(SmtpClientResult, Send_Param) prepare_mail_callback,
  193 + (Result(SmtpClientResult, One), Smtp_Recipient) -> One handle_result
157 194 ) =
158 195 send_mail(conn,
159 196 param,
160 197 prepare_mail_callback,
161 198 (Int _) |-> unique,
162 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 204 public define Result(SmtpClientResult, One)
... ... @@ -168,10 +206,12 @@ public define Result(SmtpClientResult, One)
168 206 (
169 207 RWStream conn,
170 208 Send_Param param,
  209 + (Result(SmtpClientResult, One), Smtp_Recipient) -> One handle_result
171 210 ) =
172 211 send_mail(conn,
173 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 217 public define Result(SmtpClientResult, One)
... ... @@ -198,7 +238,7 @@ public define Result(SmtpClientResult, One)
198 238 error(error),
199 239  
200 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 12  
13 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 27 public type Send_Status:
16 28 ready, //ready to send
17 29 finished, //the mail is delivered correctly
... ...
mail/smtp_client.anubis
... ... @@ -532,12 +532,16 @@ public define One
532 532 ) =
533 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 545 define List(String)
542 546 get_auth_method
543 547 (
... ...