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,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 (