Commit 52a42728f3b2354d50bce3d5217089acfec79797
1 parent
ea89b389
Improved send_mail() function:
- ability to define your own logger - callback to capture progression - low limit for transfer rate (64Kb/h)
Showing
2 changed files
with
179 additions
and
116 deletions
Show diff stats
calexium_lib/mail/send_mail.anubis
| @@ -88,22 +88,23 @@ define Command_Result | @@ -88,22 +88,23 @@ define Command_Result | ||
| 88 | RStream conn, | 88 | RStream conn, |
| 89 | List(Word8) so_far, | 89 | List(Word8) so_far, |
| 90 | Word8 previous, | 90 | Word8 previous, |
| 91 | - Int time_out | 91 | + Int time_out, |
| 92 | + (LogLevel, String) -> One logger | ||
| 92 | ) = | 93 | ) = |
| 93 | if read_network_byte(conn, time_out) is | 94 | if read_network_byte(conn, time_out) is |
| 94 | { | 95 | { |
| 95 | - failure then logTrace(send_mail_log, send_mail_mask, "receive_command read_network_byte 0 failure");failure, | ||
| 96 | - timeout then logWarning(send_mail_log, "[send_mail] receive_command timeout"); timeout, | 96 | + failure then logger(logTrace, "receive_command read_network_byte 0 failure");failure, |
| 97 | + timeout then logger(logWarning, "[send_mail] receive_command timeout"); timeout, | ||
| 97 | success(c) then | 98 | success(c) then |
| 98 | if c = 10 & previous = 13 then // <LF> | 99 | if c = 10 & previous = 13 then // <LF> |
| 99 | with result = implode(reverse(so_far)), | 100 | with result = implode(reverse(so_far)), |
| 100 | - logTrace(send_mail_log, send_mail_mask,"<-S-"+result); | 101 | + logger(logTrace, "<-S-"+result); |
| 101 | success(result) | 102 | success(result) |
| 102 | else | 103 | else |
| 103 | if previous = 13 then | 104 | if previous = 13 then |
| 104 | - receive_command(conn, so_far, c, time_out) | 105 | + receive_command(conn, so_far, c, time_out, logger) |
| 105 | else | 106 | else |
| 106 | - receive_command(conn, [previous . so_far], c, time_out) | 107 | + receive_command(conn, [previous . so_far], c, time_out, logger) |
| 107 | }. | 108 | }. |
| 108 | 109 | ||
| 109 | define Command_Result | 110 | define Command_Result |
| @@ -111,13 +112,14 @@ define Command_Result | @@ -111,13 +112,14 @@ define Command_Result | ||
| 111 | ( | 112 | ( |
| 112 | RStream conn, | 113 | RStream conn, |
| 113 | List(Word8) so_far, | 114 | List(Word8) so_far, |
| 114 | - Int time_out | 115 | + Int time_out, |
| 116 | + (LogLevel, String) -> One logger | ||
| 115 | ) = | 117 | ) = |
| 116 | if read_network_byte(conn, time_out) is | 118 | if read_network_byte(conn, time_out) is |
| 117 | { | 119 | { |
| 118 | - failure then logTrace(send_mail_log, send_mail_mask, "receive_command read_network_byte 0 failure"); failure, | ||
| 119 | - timeout then (if time_out = 0 then unique else logWarning(send_mail_log, "[send_mail] receive_command timeout")); timeout, | ||
| 120 | - success(c) then receive_command(conn,[], c, time_out) | 120 | + failure then logger(logTrace, "receive_command read_network_byte 0 failure"); failure, |
| 121 | + timeout then (if time_out = 0 then unique else logger(logWarning, "[send_mail] receive_command timeout")); timeout, | ||
| 122 | + success(c) then receive_command(conn,[], c, time_out, logger) | ||
| 121 | }. | 123 | }. |
| 122 | 124 | ||
| 123 | 125 | ||
| @@ -150,12 +152,13 @@ define Reply_Result | @@ -150,12 +152,13 @@ define Reply_Result | ||
| 150 | ( | 152 | ( |
| 151 | RStream conn, | 153 | RStream conn, |
| 152 | List(String) so_far, | 154 | List(String) so_far, |
| 153 | - Int time_out | 155 | + Int time_out, |
| 156 | + (LogLevel, String) -> One logger | ||
| 154 | ) = | 157 | ) = |
| 155 | - if receive_command(conn, [], time_out) is | 158 | + if receive_command(conn, [], time_out, logger) is |
| 156 | { | 159 | { |
| 157 | - failure then logError(send_mail_log, "receive_reply: error receiving command"); error, | ||
| 158 | - timeout then (if time_out > 0 then logError(send_mail_log, "receive_reply: timeout receiving command") else unique); timeout, | 160 | + failure then logger(logError, "receive_reply: error receiving command"); error, |
| 161 | + timeout then (if time_out > 0 then logger(logError, "receive_reply: timeout receiving command") else unique); timeout, | ||
| 159 | success(line) then | 162 | success(line) then |
| 160 | //check if we must read another line by presence of hyphen after the reply code | 163 | //check if we must read another line by presence of hyphen after the reply code |
| 161 | //220-bla bla bla | 164 | //220-bla bla bla |
| @@ -163,24 +166,24 @@ define Reply_Result | @@ -163,24 +166,24 @@ define Reply_Result | ||
| 163 | if length(line) =< 3 then | 166 | if length(line) =< 3 then |
| 164 | if decimal_scan(line) is | 167 | if decimal_scan(line) is |
| 165 | { | 168 | { |
| 166 | - failure then logError(send_mail_log, "receive_reply: can't extract reply code from '" + line + "'"); error, | 169 | + failure then logger(logError, "receive_reply: can't extract reply code from '" + line + "'"); error, |
| 167 | success(code) then reply(code, reverse(so_far)) | 170 | success(code) then reply(code, reverse(so_far)) |
| 168 | } | 171 | } |
| 169 | else if nth(3, line) is | 172 | else if nth(3, line) is |
| 170 | { | 173 | { |
| 171 | - failure then logError(send_mail_log, "receive_reply: error getting 4th character from '" + line +"'"); error, | 174 | + failure then logger(logError, "receive_reply: error getting 4th character from '" + line +"'"); error, |
| 172 | success(char) then | 175 | success(char) then |
| 173 | if char = '-' then | 176 | if char = '-' then |
| 174 | - receive_reply(conn, [line . so_far], time_out) | 177 | + receive_reply(conn, [line . so_far], time_out, logger) |
| 175 | else | 178 | else |
| 176 | //decode the code | 179 | //decode the code |
| 177 | if sub_string(line, 0, 3) is | 180 | if sub_string(line, 0, 3) is |
| 178 | { | 181 | { |
| 179 | - failure then logError(send_mail_log, "receive_reply: error extracting reply code from '" + line+"'"); error, // should never occure | 182 | + failure then logger(logError, "receive_reply: error extracting reply code from '" + line+"'"); error, // should never occure |
| 180 | success(code_str) then | 183 | success(code_str) then |
| 181 | if decimal_scan(code_str) is | 184 | if decimal_scan(code_str) is |
| 182 | { | 185 | { |
| 183 | - failure then logError(send_mail_log, "receive_reply: can't extract reply code from '" + code_str + "'"); error, //unreadable code | 186 | + failure then logger(logError, "receive_reply: can't extract reply code from '" + code_str + "'"); error, //unreadable code |
| 184 | success(code) then reply(code , reverse([line . so_far])) | 187 | success(code) then reply(code , reverse([line . so_far])) |
| 185 | } | 188 | } |
| 186 | } | 189 | } |
| @@ -191,23 +194,25 @@ define Reply_Result | @@ -191,23 +194,25 @@ define Reply_Result | ||
| 191 | receive_reply | 194 | receive_reply |
| 192 | ( | 195 | ( |
| 193 | RWStream conn, | 196 | RWStream conn, |
| 197 | + (LogLevel, String) -> One logger | ||
| 194 | ) = | 198 | ) = |
| 195 | - receive_reply(weaken(conn), [], smtp_time_out). | 199 | + receive_reply(weaken(conn), [], smtp_time_out, logger). |
| 196 | 200 | ||
| 197 | 201 | ||
| 198 | Sending a piece of text (String) from the begining. | 202 | Sending a piece of text (String) from the begining. |
| 199 | 203 | ||
| 200 | define Maybe(One) | 204 | define Maybe(One) |
| 201 | smtp_send_line | 205 | smtp_send_line |
| 202 | - ( | ||
| 203 | - RWStream conn, | ||
| 204 | - String text | ||
| 205 | - ) = | 206 | + ( |
| 207 | + RWStream conn, | ||
| 208 | + String text, | ||
| 209 | + (LogLevel, String) -> One logger | ||
| 210 | + ) = | ||
| 206 | if reliable_write(tcp(conn),[text + crlf]) is | 211 | if reliable_write(tcp(conn),[text + crlf]) is |
| 207 | { | 212 | { |
| 208 | - failure then logError(send_mail_log, "smtp_send_line: error writing '" + text + "'"); failure, | 213 | + failure then logger(logError, "smtp_send_line: error writing '" + text + "'"); failure, |
| 209 | success(_) then | 214 | success(_) then |
| 210 | - logTrace(send_mail_log,send_mail_mask, "-C->"+text);success(unique) | 215 | + logger(logTrace, "-C->"+text);success(unique) |
| 211 | } . | 216 | } . |
| 212 | 217 | ||
| 213 | Because of attachements, we may have to manipulate very big pieces of text. It would be | 218 | Because of attachements, we may have to manipulate very big pieces of text. It would be |
| @@ -229,32 +234,33 @@ define StringTree [StringTree s . StringTree t] = tree_tree(s,t). | @@ -229,32 +234,33 @@ define StringTree [StringTree s . StringTree t] = tree_tree(s,t). | ||
| 229 | define Reply_Result | 234 | define Reply_Result |
| 230 | send_ehlo | 235 | send_ehlo |
| 231 | ( | 236 | ( |
| 232 | - RWStream conn, | ||
| 233 | - String our_host_name | 237 | + RWStream conn, |
| 238 | + String our_host_name, | ||
| 239 | + (LogLevel, String) -> One logger | ||
| 234 | ) = | 240 | ) = |
| 235 | - if smtp_send_line(conn,"EHLO "+our_host_name) is | 241 | + if smtp_send_line(conn,"EHLO "+our_host_name, logger) is |
| 236 | { | 242 | { |
| 237 | - failure then logError(send_mail_log, "send_ehlo: error sending EHLO"); error, | 243 | + failure then logger(logError, "send_ehlo: error sending EHLO"); error, |
| 238 | success(_) then | 244 | success(_) then |
| 239 | - with rep = if receive_reply(conn) is | 245 | + with rep = if receive_reply(conn, logger) is |
| 240 | { | 246 | { |
| 241 | - error then logError(send_mail_log, "send_ehlo: can't get reply"); error, | ||
| 242 | - timeout then logError(send_mail_log, "send_ehlo: timeout getting reply"); timeout, | 247 | + error then logger(logError, "send_ehlo: can't get reply"); error, |
| 248 | + timeout then logger(logError, "send_ehlo: timeout getting reply"); timeout, | ||
| 243 | reply(code, lines) then | 249 | reply(code, lines) then |
| 244 | //we manage the 500 error, that mean the remote server is not ESMTP | 250 | //we manage the 500 error, that mean the remote server is not ESMTP |
| 245 | //hence we try we with HELO, the old manner RFC 821 | 251 | //hence we try we with HELO, the old manner RFC 821 |
| 246 | if code = 500 | code = 502 then | 252 | if code = 500 | code = 502 then |
| 247 | - if smtp_send_line(conn,"HELO "+our_host_name) is | 253 | + if smtp_send_line(conn,"HELO "+our_host_name, logger) is |
| 248 | { | 254 | { |
| 249 | - failure then logError(send_mail_log, "send_ehlo: error sending HELO"); error, | ||
| 250 | - success(_) then receive_reply(conn) | 255 | + failure then logger(logError, "send_ehlo: error sending HELO"); error, |
| 256 | + success(_) then receive_reply(conn, logger) | ||
| 251 | } | 257 | } |
| 252 | else | 258 | else |
| 253 | reply(code, lines) | 259 | reply(code, lines) |
| 254 | }, | 260 | }, |
| 255 | if rep is reply(code, lines) then | 261 | if rep is reply(code, lines) then |
| 256 | if code = 550 then // some server simply refuse us because it's temporary overloaded (especially try when sending mailings) | 262 | if code = 550 then // some server simply refuse us because it's temporary overloaded (especially try when sending mailings) |
| 257 | - logDebug(send_mail_log, "Converting a 550 error for EHLO to a 432 error as distant server may be temporary overloaded."); | 263 | + logger(logDebug, "Converting a 550 error for EHLO to a 432 error as distant server may be temporary overloaded."); |
| 258 | reply(432, lines) | 264 | reply(432, lines) |
| 259 | else | 265 | else |
| 260 | rep | 266 | rep |
| @@ -281,14 +287,15 @@ define String | @@ -281,14 +287,15 @@ define String | ||
| 281 | define Reply_Result | 287 | define Reply_Result |
| 282 | send_mail_from | 288 | send_mail_from |
| 283 | ( | 289 | ( |
| 284 | - RWStream conn, | ||
| 285 | - String sender | 290 | + RWStream conn, |
| 291 | + String sender, | ||
| 292 | + (LogLevel, String) -> One logger | ||
| 286 | ) = | 293 | ) = |
| 287 | with rfc_sender = check_email_syntax(sender), | 294 | with rfc_sender = check_email_syntax(sender), |
| 288 | - if smtp_send_line(conn,"MAIL FROM:"+rfc_sender) is | 295 | + if smtp_send_line(conn,"MAIL FROM:"+rfc_sender, logger) is |
| 289 | { | 296 | { |
| 290 | - failure then logError(send_mail_log, "error sending 'MAIL FROM:" + rfc_sender + "'"); error, | ||
| 291 | - success(_) then receive_reply(conn) | 297 | + failure then logger(logError, "error sending 'MAIL FROM:" + rfc_sender + "'"); error, |
| 298 | + success(_) then receive_reply(conn, logger) | ||
| 292 | }. | 299 | }. |
| 293 | 300 | ||
| 294 | The same one for 'RCPT TO': | 301 | The same one for 'RCPT TO': |
| @@ -298,12 +305,13 @@ define Reply_Result | @@ -298,12 +305,13 @@ define Reply_Result | ||
| 298 | ( | 305 | ( |
| 299 | RWStream conn, | 306 | RWStream conn, |
| 300 | String recipient, | 307 | String recipient, |
| 308 | + (LogLevel, String) -> One logger | ||
| 301 | ) = | 309 | ) = |
| 302 | with rfc_recipient = check_email_syntax(recipient), | 310 | with rfc_recipient = check_email_syntax(recipient), |
| 303 | - if smtp_send_line(conn,"RCPT TO:"+rfc_recipient) is | 311 | + if smtp_send_line(conn,"RCPT TO:"+rfc_recipient, logger) is |
| 304 | { | 312 | { |
| 305 | - failure then logError(send_mail_log, "error sending 'RCPT TO:"+rfc_recipient+"'"); error, | ||
| 306 | - success(_) then receive_reply(conn) | 313 | + failure then logger(logError, "error sending 'RCPT TO:"+rfc_recipient+"'"); error, |
| 314 | + success(_) then receive_reply(conn, logger) | ||
| 307 | }. | 315 | }. |
| 308 | 316 | ||
| 309 | 317 | ||
| @@ -311,13 +319,14 @@ define Reply_Result | @@ -311,13 +319,14 @@ define Reply_Result | ||
| 311 | 319 | ||
| 312 | define Reply_Result | 320 | define Reply_Result |
| 313 | send_data | 321 | send_data |
| 314 | - ( | ||
| 315 | - RWStream conn | ||
| 316 | - ) = | ||
| 317 | - if smtp_send_line(conn,"DATA") is | 322 | + ( |
| 323 | + RWStream conn, | ||
| 324 | + (LogLevel, String) -> One logger | ||
| 325 | + ) = | ||
| 326 | + if smtp_send_line(conn,"DATA", logger) is | ||
| 318 | { | 327 | { |
| 319 | - failure then logError(send_mail_log, "error sending DATA"); error, | ||
| 320 | - success(_) then receive_reply(conn) | 328 | + failure then logger(logError, "error sending DATA"); error, |
| 329 | + success(_) then receive_reply(conn, logger) | ||
| 321 | }. | 330 | }. |
| 322 | 331 | ||
| 323 | 332 | ||
| @@ -334,40 +343,52 @@ define Maybe(One) | @@ -334,40 +343,52 @@ define Maybe(One) | ||
| 334 | sm_flush | 343 | sm_flush |
| 335 | ( | 344 | ( |
| 336 | ByteArray buffer, | 345 | ByteArray buffer, |
| 337 | - WStream target | 346 | + WStream target, |
| 347 | + Int buffer_start_time, | ||
| 348 | + (LogLevel, String) -> One logger | ||
| 338 | )= | 349 | )= |
| 339 | if write( target , buffer) is | 350 | if write( target , buffer) is |
| 340 | { | 351 | { |
| 341 | failure then failure, | 352 | failure then failure, |
| 342 | success(nb_write) then | 353 | success(nb_write) then |
| 343 | - with buffer_size = length(buffer), | ||
| 344 | - if nb_write = buffer_size then | ||
| 345 | - success(unique) | 354 | + if now - buffer_start_time > 3600 then |
| 355 | + // security to avoid queue blocking | ||
| 356 | + logger(logError, "sm_flush: TIMEOUT sending a 64kb buffer (taking more than 1 hour). SendMail canceled."); | ||
| 357 | + failure | ||
| 346 | else | 358 | else |
| 347 | - with new_buffer = extract(buffer, nb_write, buffer_size), | ||
| 348 | - sm_flush(new_buffer, target) | 359 | + with buffer_size = length(buffer), |
| 360 | + if nb_write = buffer_size then | ||
| 361 | + success(unique) | ||
| 362 | + else | ||
| 363 | + with new_buffer = extract(buffer, nb_write, buffer_size), | ||
| 364 | + sm_flush(new_buffer, target, buffer_start_time, logger) | ||
| 349 | }. | 365 | }. |
| 350 | 366 | ||
| 351 | public define SendContentResult | 367 | public define SendContentResult |
| 352 | sm_copy_Data_IO_to_Stream | 368 | sm_copy_Data_IO_to_Stream |
| 353 | ( | 369 | ( |
| 354 | - Data_IO source, | ||
| 355 | - RWStream target, | ||
| 356 | - Int so_far | 370 | + Data_IO source, |
| 371 | + RWStream target, | ||
| 372 | + Int start_time, | ||
| 373 | + Int so_far, | ||
| 374 | + (Int) -> One progress_report, | ||
| 375 | + (LogLevel, String) -> One logger | ||
| 357 | ) = | 376 | ) = |
| 358 | - if receive_reply(weaken(target), [], 0) is | 377 | + if receive_reply(weaken(target), [], 0, logger) is |
| 359 | { | 378 | { |
| 360 | error then copy_error(so_far), | 379 | error then copy_error(so_far), |
| 361 | timeout then | 380 | timeout then |
| 362 | if read_bytes(source, 65536) is | 381 | if read_bytes(source, 65536) is |
| 363 | { | 382 | { |
| 364 | - failure then logError(send_mail_log, "send_content: failed to read input data_io"); copy_error(so_far), | ||
| 365 | - time_out then logError(send_mail_log, "send_content: timeout reading input data_io"); copy_error(so_far), | 383 | + failure then logger(logError, "send_content: failed to read input data_io"); copy_error(so_far), |
| 384 | + time_out then logger(logError, "send_content: timeout reading input data_io"); copy_error(so_far), | ||
| 366 | success(buffer) then | 385 | success(buffer) then |
| 367 | - if sm_flush( buffer, weaken(target) ) is | 386 | + if sm_flush( buffer, weaken(target), now, logger ) is |
| 368 | { | 387 | { |
| 369 | failure then copy_error(so_far), | 388 | failure then copy_error(so_far), |
| 370 | - success(_) then sm_copy_Data_IO_to_Stream(source, target, so_far + 65536) | 389 | + success(_) then |
| 390 | + progress_report(so_far + 65536); | ||
| 391 | + sm_copy_Data_IO_to_Stream(source, target, start_time, so_far + 65536, progress_report, logger) | ||
| 371 | }, | 392 | }, |
| 372 | 393 | ||
| 373 | truncated(buffer) then | 394 | truncated(buffer) then |
| @@ -375,10 +396,12 @@ public define SendContentResult | @@ -375,10 +396,12 @@ public define SendContentResult | ||
| 375 | if len = 0 then | 396 | if len = 0 then |
| 376 | copy_ok(so_far) | 397 | copy_ok(so_far) |
| 377 | else | 398 | else |
| 378 | - if sm_flush( buffer, weaken(target) ) is | 399 | + if sm_flush( buffer, weaken(target), now, logger ) is |
| 379 | { | 400 | { |
| 380 | failure then copy_error(so_far), | 401 | failure then copy_error(so_far), |
| 381 | - success(_) then copy_ok(so_far + len) | 402 | + success(_) then |
| 403 | + progress_report(so_far + len); | ||
| 404 | + copy_ok(so_far + len) | ||
| 382 | } | 405 | } |
| 383 | }, | 406 | }, |
| 384 | reply(code, lines) then | 407 | reply(code, lines) then |
| @@ -389,17 +412,20 @@ define SendContentResult | @@ -389,17 +412,20 @@ define SendContentResult | ||
| 389 | sm_copy_Data_IO_List_to_Stream | 412 | sm_copy_Data_IO_List_to_Stream |
| 390 | ( | 413 | ( |
| 391 | List(Data_IO) io_list, | 414 | List(Data_IO) io_list, |
| 392 | - RWStream target, | ||
| 393 | - Int so_far | 415 | + RWStream target, |
| 416 | + Int start_time, | ||
| 417 | + Int so_far, | ||
| 418 | + (Int) -> One progress_report, | ||
| 419 | + (LogLevel, String) -> One logger | ||
| 394 | )= | 420 | )= |
| 395 | if io_list is | 421 | if io_list is |
| 396 | { | 422 | { |
| 397 | [] then copy_ok(so_far), | 423 | [] then copy_ok(so_far), |
| 398 | [ h . t ] then | 424 | [ h . t ] then |
| 399 | if rewind(h)(unique) then | 425 | if rewind(h)(unique) then |
| 400 | - with result = sm_copy_Data_IO_to_Stream(h, target, 0), | 426 | + with result = sm_copy_Data_IO_to_Stream(h, target, start_time, 0, progress_report, logger), |
| 401 | if result is copy_ok(written) then | 427 | if result is copy_ok(written) then |
| 402 | - sm_copy_Data_IO_List_to_Stream(t, target, so_far + written) | 428 | + sm_copy_Data_IO_List_to_Stream(t, target, start_time, so_far + written, progress_report, logger) |
| 403 | else | 429 | else |
| 404 | result | 430 | result |
| 405 | else | 431 | else |
| @@ -410,29 +436,31 @@ define Reply_Result | @@ -410,29 +436,31 @@ define Reply_Result | ||
| 410 | send_content | 436 | send_content |
| 411 | ( | 437 | ( |
| 412 | RWStream conn, | 438 | RWStream conn, |
| 413 | - List(Data_IO) mail_part | 439 | + List(Data_IO) mail_part, |
| 440 | + (Int) -> One progress_report, | ||
| 441 | + (LogLevel, String) -> One logger | ||
| 414 | ) = | 442 | ) = |
| 415 | with start_time = now, | 443 | with start_time = now, |
| 416 | - if sm_copy_Data_IO_List_to_Stream(mail_part, conn, 0) is | 444 | + if sm_copy_Data_IO_List_to_Stream(mail_part, conn, now, 0, progress_report, logger) is |
| 417 | { | 445 | { |
| 418 | smtp_reply(reply) then reply | 446 | smtp_reply(reply) then reply |
| 419 | copy_error(written) then | 447 | copy_error(written) then |
| 420 | with finish_time = now, | 448 | with finish_time = now, |
| 421 | - logError(send_mail_log, "send_content: error sending data"); | ||
| 422 | - logTrace(send_mail_log, send_mail_mask, "send_content: "+written+" bytes sent in "+finish_time - start_time+" second(s)"); | 449 | + logger(logError, "send_content: error sending data"); |
| 450 | + logger(logTrace, "send_content: "+written+" bytes sent in "+finish_time - start_time+" second(s)"); | ||
| 423 | if written > 1024000 then | 451 | if written > 1024000 then |
| 424 | - logInfo(send_mail_log, "send_content: may be due to over sized mail. Convert it to 452 error."); | 452 | + logger(logInfo, "send_content: may be due to over sized mail. Convert it to 452 error."); |
| 425 | reply(452, ["Error sending big email (more than 1 Mb)"]) | 453 | reply(452, ["Error sending big email (more than 1 Mb)"]) |
| 426 | else | 454 | else |
| 427 | error, | 455 | error, |
| 428 | copy_ok(size) then | 456 | copy_ok(size) then |
| 429 | if reliable_write(tcp(conn), [crlf_dot_crlf]) is | 457 | if reliable_write(tcp(conn), [crlf_dot_crlf]) is |
| 430 | { | 458 | { |
| 431 | - failure then logError(send_mail_log, "send_content: error writing CRLF.CRLF"); error, | 459 | + failure then logger(logError, "send_content: error writing CRLF.CRLF"); error, |
| 432 | success(_) then | 460 | success(_) then |
| 433 | with finish_time = (Int)now, | 461 | with finish_time = (Int)now, |
| 434 | - logTrace(send_mail_log, send_mail_mask, "mail sent "+size+" bytes in "+finish_time - start_time+" second(s)"); | ||
| 435 | - receive_reply(conn) | 462 | + logger(logTrace, "mail sent "+size+" bytes in "+finish_time - start_time+" second(s)"); |
| 463 | + receive_reply(conn, logger) | ||
| 436 | } | 464 | } |
| 437 | }. | 465 | }. |
| 438 | 466 | ||
| @@ -441,52 +469,55 @@ define Reply_Result | @@ -441,52 +469,55 @@ define Reply_Result | ||
| 441 | 469 | ||
| 442 | define One | 470 | define One |
| 443 | send_quit | 471 | send_quit |
| 444 | - ( | ||
| 445 | - RWStream conn | ||
| 446 | - ) = | ||
| 447 | - if smtp_send_line(conn,"QUIT") is | 472 | + ( |
| 473 | + RWStream conn, | ||
| 474 | + (LogLevel, String) -> One logger | ||
| 475 | + ) = | ||
| 476 | + if smtp_send_line(conn,"QUIT", logger) is | ||
| 448 | { | 477 | { |
| 449 | - failure then logWarning(send_mail_log, "error sending QUIT"), | ||
| 450 | - success(_) then forget(receive_reply(conn)) | 478 | + failure then logger(logWarning, "error sending QUIT"), |
| 479 | + success(_) then forget(receive_reply(conn, logger)) | ||
| 451 | }. | 480 | }. |
| 452 | 481 | ||
| 453 | define SendMailResult | 482 | define SendMailResult |
| 454 | sm_MAIL_FROM | 483 | sm_MAIL_FROM |
| 455 | ( | 484 | ( |
| 456 | - RWStream conn, | ||
| 457 | - Send_Param param, | ||
| 458 | - Send_Mail_Session sm_session | 485 | + RWStream conn, |
| 486 | + Send_Param param, | ||
| 487 | + Send_Mail_Session sm_session, | ||
| 488 | + (Int) -> One progress_report, | ||
| 489 | + (LogLevel, String) -> One logger | ||
| 459 | ) = | 490 | ) = |
| 460 | with enhanced_status = sm_session.enhanced_status, | 491 | with enhanced_status = sm_session.enhanced_status, |
| 461 | //send MAIL FROM | 492 | //send MAIL FROM |
| 462 | - if send_mail_from(conn, param.sender.str) is | 493 | + if send_mail_from(conn, param.sender.str, logger) is |
| 463 | { | 494 | { |
| 464 | error then error, // already logged | 495 | error then error, // already logged |
| 465 | timeout then error, | 496 | timeout then error, |
| 466 | reply(code, lines) then | 497 | reply(code, lines) then |
| 467 | if code = 250 then | 498 | if code = 250 then |
| 468 | //send RCPT TO | 499 | //send RCPT TO |
| 469 | - if send_recipient(conn,param.recipient.str) is | 500 | + if send_recipient(conn,param.recipient.str, logger) is |
| 470 | { | 501 | { |
| 471 | error then error, // already logged | 502 | error then error, // already logged |
| 472 | timeout then error, | 503 | timeout then error, |
| 473 | reply(code, lines) then | 504 | reply(code, lines) then |
| 474 | if code = 250 then | 505 | if code = 250 then |
| 475 | //send DATA | 506 | //send DATA |
| 476 | - if send_data(conn) is | 507 | + if send_data(conn, logger) is |
| 477 | { | 508 | { |
| 478 | error then error, // already logged | 509 | error then error, // already logged |
| 479 | timeout then error, | 510 | timeout then error, |
| 480 | reply(code, lines) then | 511 | reply(code, lines) then |
| 481 | if code = 354 then | 512 | if code = 354 then |
| 482 | - if send_content(conn, param.mail_parts) is | 513 | + if send_content(conn, param.mail_parts, progress_report, logger) is |
| 483 | { | 514 | { |
| 484 | error then error, // already logged | 515 | error then error, // already logged |
| 485 | timeout then error, | 516 | timeout then error, |
| 486 | reply(code, lines) then | 517 | reply(code, lines) then |
| 487 | if code = 250 then | 518 | if code = 250 then |
| 488 | - send_quit(conn); | ||
| 489 | - logTrace(send_mail_log,send_mail_mask,"SENT Mail FROM "+param.sender.str+" TO "+param.recipient.str); | 519 | + send_quit(conn, logger); |
| 520 | + logger(logTrace, "SENT Mail FROM "+param.sender.str+" TO "+param.recipient.str); | ||
| 490 | ok | 521 | ok |
| 491 | else | 522 | else |
| 492 | reply_handling(code, lines, enhanced_status) | 523 | reply_handling(code, lines, enhanced_status) |
| @@ -530,7 +561,8 @@ define SendMailResult | @@ -530,7 +561,8 @@ define SendMailResult | ||
| 530 | RWStream conn, | 561 | RWStream conn, |
| 531 | String login, | 562 | String login, |
| 532 | String password, | 563 | String password, |
| 533 | - Bool enhanced_status | 564 | + Bool enhanced_status, |
| 565 | + (LogLevel, String) -> One logger | ||
| 534 | )= | 566 | )= |
| 535 | 567 | ||
| 536 | with plain_str = "AUTH PLAIN "+ to_string(base64_encode(to_byte_array("")+ | 568 | with plain_str = "AUTH PLAIN "+ to_string(base64_encode(to_byte_array("")+ |
| @@ -538,11 +570,11 @@ define SendMailResult | @@ -538,11 +570,11 @@ define SendMailResult | ||
| 538 | to_byte_array(login)+ | 570 | to_byte_array(login)+ |
| 539 | constant_byte_array(1,0)+ | 571 | constant_byte_array(1,0)+ |
| 540 | to_byte_array(password))), | 572 | to_byte_array(password))), |
| 541 | - if smtp_send_line(conn, plain_str) is | 573 | + if smtp_send_line(conn, plain_str, logger) is |
| 542 | { | 574 | { |
| 543 | failure then error, // already logged | 575 | failure then error, // already logged |
| 544 | success(_) then | 576 | success(_) then |
| 545 | - if receive_reply(conn) is | 577 | + if receive_reply(conn, logger) is |
| 546 | { | 578 | { |
| 547 | error then error // already logged | 579 | error then error // already logged |
| 548 | timeout then error, | 580 | timeout then error, |
| @@ -561,13 +593,14 @@ define SendMailResult | @@ -561,13 +593,14 @@ define SendMailResult | ||
| 561 | List(String) auth_list, //list of available authentication method | 593 | List(String) auth_list, //list of available authentication method |
| 562 | String login, | 594 | String login, |
| 563 | String password, | 595 | String password, |
| 564 | - Bool enhanced_status | 596 | + Bool enhanced_status, |
| 597 | + (LogLevel, String) -> One logger | ||
| 565 | )= | 598 | )= |
| 566 | 599 | ||
| 567 | if member(auth_list, "PLAIN", insensitive_equal) then | 600 | if member(auth_list, "PLAIN", insensitive_equal) then |
| 568 | - do_auth_plain(conn, login, password, enhanced_status) | 601 | + do_auth_plain(conn, login, password, enhanced_status, logger) |
| 569 | else | 602 | else |
| 570 | - logError(send_mail_log, "do_login no PLAIN method available"); error. | 603 | + logger(logError, "do_login no PLAIN method available"); error. |
| 571 | 604 | ||
| 572 | define SendMailResult | 605 | define SendMailResult |
| 573 | do_auth | 606 | do_auth |
| @@ -575,7 +608,8 @@ define SendMailResult | @@ -575,7 +608,8 @@ define SendMailResult | ||
| 575 | RWStream conn, //tcp connection | 608 | RWStream conn, //tcp connection |
| 576 | List(String) lines, //this is the reply lines provided in response to EHLO command | 609 | List(String) lines, //this is the reply lines provided in response to EHLO command |
| 577 | Send_Auth auth, //authentication method to use for that session | 610 | Send_Auth auth, //authentication method to use for that session |
| 578 | - Bool enhanced_status | 611 | + Bool enhanced_status, |
| 612 | + (LogLevel, String) -> One logger | ||
| 579 | )= | 613 | )= |
| 580 | if auth is | 614 | if auth is |
| 581 | { | 615 | { |
| @@ -584,8 +618,8 @@ define SendMailResult | @@ -584,8 +618,8 @@ define SendMailResult | ||
| 584 | with auth_list = get_auth_method(lines,[]), | 618 | with auth_list = get_auth_method(lines,[]), |
| 585 | if auth_list is | 619 | if auth_list is |
| 586 | { | 620 | { |
| 587 | - [] then logError(send_mail_log, "do_auth error");error, | ||
| 588 | - [_ . _] then do_login(conn, auth_list, user, password, enhanced_status) | 621 | + [] then logger(logError, "do_auth error");error, |
| 622 | + [_ . _] then do_login(conn, auth_list, user, password, enhanced_status, logger) | ||
| 589 | } | 623 | } |
| 590 | }. | 624 | }. |
| 591 | 625 | ||
| @@ -596,7 +630,8 @@ define Send_Mail_Session | @@ -596,7 +630,8 @@ define Send_Mail_Session | ||
| 596 | make_sm_session | 630 | make_sm_session |
| 597 | ( | 631 | ( |
| 598 | List(String) lines, //lines given in ehlo stage | 632 | List(String) lines, //lines given in ehlo stage |
| 599 | - Send_Param param | 633 | + Send_Param param, |
| 634 | + (LogLevel, String) -> One logger | ||
| 600 | )= | 635 | )= |
| 601 | //looking for ENHANCEDSTATUSCODES | 636 | //looking for ENHANCEDSTATUSCODES |
| 602 | with session_enhanced_status = has_smtp_extension(lines, enhanced_status_codes), | 637 | with session_enhanced_status = has_smtp_extension(lines, enhanced_status_codes), |
| @@ -609,7 +644,7 @@ define Send_Mail_Session | @@ -609,7 +644,7 @@ define Send_Mail_Session | ||
| 609 | { | 644 | { |
| 610 | failure then 0, | 645 | failure then 0, |
| 611 | success(value) then | 646 | success(value) then |
| 612 | - logTrace(send_mail_log, send_mail_mask, "smtp server with SIZE "+value); | 647 | + logger(logTrace, "smtp server with SIZE "+value); |
| 613 | value | 648 | value |
| 614 | } | 649 | } |
| 615 | }, | 650 | }, |
| @@ -617,41 +652,43 @@ define Send_Mail_Session | @@ -617,41 +652,43 @@ define Send_Mail_Session | ||
| 617 | 652 | ||
| 618 | Apply the whole protocol: | 653 | Apply the whole protocol: |
| 619 | 654 | ||
| 620 | - //TODO we can have a list of part file in param type. This can be very useful when we want | ||
| 621 | - //to send file as mailing. For the mailing, in each mail, only the header is different of the | ||
| 622 | - //other mails. The body part is the same. Then, the mailing sender can generate the header in one | ||
| 623 | - //file and keep the body in other file wich can be given to send_mail function as last file in the list | 655 | + // we can have a list of part file in param type. This can be very useful when we want |
| 656 | + // to send file as mailing. For the mailing, in each mail, only the header is different of the | ||
| 657 | + // other mails. The body part is the same. Then, the mailing sender can generate the header in one | ||
| 658 | + // file and keep the body in other file wich can be given to send_mail function as last file in the list | ||
| 624 | public define SendMailResult | 659 | public define SendMailResult |
| 625 | send_mail | 660 | send_mail |
| 626 | ( | 661 | ( |
| 627 | RWStream conn, | 662 | RWStream conn, |
| 628 | Send_Param param, | 663 | Send_Param param, |
| 629 | (Send_Mail_Session, Send_Param) -> Result(SendMailResult, Send_Param) prepare_mail_callback, | 664 | (Send_Mail_Session, Send_Param) -> Result(SendMailResult, Send_Param) prepare_mail_callback, |
| 665 | + (Int) -> One progress_report, | ||
| 666 | + (LogLevel, String) -> One logger | ||
| 630 | ) = | 667 | ) = |
| 631 | // | 668 | // |
| 632 | // Our connection to the SMTP server is opened. We just have to apply the protocol. | 669 | // Our connection to the SMTP server is opened. We just have to apply the protocol. |
| 633 | // | 670 | // |
| 634 | - if receive_reply(conn) is | 671 | + if receive_reply(conn, logger) is |
| 635 | { | 672 | { |
| 636 | error then error,// already logged | 673 | error then error,// already logged |
| 637 | timeout then error, | 674 | timeout then error, |
| 638 | reply(code, lines) then | 675 | reply(code, lines) then |
| 639 | if code = 220 then | 676 | if code = 220 then |
| 640 | //send EHLO | 677 | //send EHLO |
| 641 | - if send_ehlo(conn, param.host_name.str) is //"mail."+force_Type(get_main_domain(db), "mailfountain.net")) is | 678 | + if send_ehlo(conn, param.host_name.str, logger) is //"mail."+force_Type(get_main_domain(db), "mailfountain.net")) is |
| 642 | { | 679 | { |
| 643 | error then error, // already logged | 680 | error then error, // already logged |
| 644 | timeout then error, | 681 | timeout then error, |
| 645 | reply(code, lines) then | 682 | reply(code, lines) then |
| 646 | if code = 250 then | 683 | if code = 250 then |
| 647 | // parse all available options here, and build a smtp context | 684 | // parse all available options here, and build a smtp context |
| 648 | - with sm_session = make_sm_session(lines, param), | ||
| 649 | - with auth_result = do_auth(conn, lines, param.auth, sm_session.enhanced_status), | 685 | + with sm_session = make_sm_session(lines, param, logger), |
| 686 | + with auth_result = do_auth(conn, lines, param.auth, sm_session.enhanced_status, logger), | ||
| 650 | if auth_result = ok then | 687 | if auth_result = ok then |
| 651 | if prepare_mail_callback(sm_session, param) is | 688 | if prepare_mail_callback(sm_session, param) is |
| 652 | { | 689 | { |
| 653 | error(result) then result, | 690 | error(result) then result, |
| 654 | - ok(new_param) then sm_MAIL_FROM(conn, new_param, sm_session) | 691 | + ok(new_param) then sm_MAIL_FROM(conn, new_param, sm_session, progress_report, logger) |
| 655 | } | 692 | } |
| 656 | else | 693 | else |
| 657 | auth_result | 694 | auth_result |
| @@ -661,7 +698,7 @@ public define SendMailResult | @@ -661,7 +698,7 @@ public define SendMailResult | ||
| 661 | else if code = 550 then | 698 | else if code = 550 then |
| 662 | //some server answer "550 5.7.1 Client host rejected: cannot find your reverse hostname, [88.181.64.17]" | 699 | //some server answer "550 5.7.1 Client host rejected: cannot find your reverse hostname, [88.181.64.17]" |
| 663 | //before anything, then we try to extract the enhanced status if exists for relaying the mail with the ISP | 700 | //before anything, then we try to extract the enhanced status if exists for relaying the mail with the ISP |
| 664 | - logDebug(send_mail_log, "Converting a 550 error for connection to a 432 error as distant server may be temporary overloaded."); | 701 | + logger(logDebug, "Converting a 550 error for connection to a 432 error as distant server may be temporary overloaded."); |
| 665 | reply_handling(432,lines,true) | 702 | reply_handling(432,lines,true) |
| 666 | else | 703 | else |
| 667 | reply_handling(code,lines,true) | 704 | reply_handling(code,lines,true) |
| @@ -672,8 +709,26 @@ public define SendMailResult | @@ -672,8 +709,26 @@ public define SendMailResult | ||
| 672 | ( | 709 | ( |
| 673 | RWStream conn, | 710 | RWStream conn, |
| 674 | Send_Param param, | 711 | Send_Param param, |
| 712 | + (Send_Mail_Session, Send_Param) -> Result(SendMailResult, Send_Param) prepare_mail_callback, | ||
| 713 | + ) = | ||
| 714 | + send_mail(conn, | ||
| 715 | + param, | ||
| 716 | + prepare_mail_callback, | ||
| 717 | + (Int _) |-> unique, | ||
| 718 | + (LogLevel level, String txt) |-> if level is logTrace then logTrace(send_mail_log, send_mail_mask, txt) | ||
| 719 | + else log(level, send_mail_log, txt) | ||
| 720 | + ). | ||
| 721 | + | ||
| 722 | +public define SendMailResult | ||
| 723 | + send_mail | ||
| 724 | + ( | ||
| 725 | + RWStream conn, | ||
| 726 | + Send_Param param, | ||
| 675 | ) = | 727 | ) = |
| 676 | - send_mail(conn, param, (Send_Mail_Session sm_session, Send_Param param) |-> ok(param)). | 728 | + send_mail(conn, |
| 729 | + param, | ||
| 730 | + (Send_Mail_Session sm_session, Send_Param param) |-> ok(param) | ||
| 731 | + ). | ||
| 677 | 732 | ||
| 678 | public define SendMailResult | 733 | public define SendMailResult |
| 679 | send_mail | 734 | send_mail |
calexium_lib/net_services_protocols/logger_service.anubis
| @@ -305,6 +305,14 @@ define Message | @@ -305,6 +305,14 @@ define Message | ||
| 305 | . | 305 | . |
| 306 | 306 | ||
| 307 | public define One | 307 | public define One |
| 308 | + log( | ||
| 309 | + LogLevel level, | ||
| 310 | + String logger_name, | ||
| 311 | + String log_string | ||
| 312 | + )= | ||
| 313 | + local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, get_log_level_value(level))). | ||
| 314 | + | ||
| 315 | +public define One | ||
| 308 | logNone( | 316 | logNone( |
| 309 | String logger_name, | 317 | String logger_name, |
| 310 | String log_string | 318 | String log_string |