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 | 88 | RStream conn, |
| 89 | 89 | List(Word8) so_far, |
| 90 | 90 | Word8 previous, |
| 91 | - Int time_out | |
| 91 | + Int time_out, | |
| 92 | + (LogLevel, String) -> One logger | |
| 92 | 93 | ) = |
| 93 | 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 | 98 | success(c) then |
| 98 | 99 | if c = 10 & previous = 13 then // <LF> |
| 99 | 100 | with result = implode(reverse(so_far)), |
| 100 | - logTrace(send_mail_log, send_mail_mask,"<-S-"+result); | |
| 101 | + logger(logTrace, "<-S-"+result); | |
| 101 | 102 | success(result) |
| 102 | 103 | else |
| 103 | 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 | 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 | 110 | define Command_Result |
| ... | ... | @@ -111,13 +112,14 @@ define Command_Result |
| 111 | 112 | ( |
| 112 | 113 | RStream conn, |
| 113 | 114 | List(Word8) so_far, |
| 114 | - Int time_out | |
| 115 | + Int time_out, | |
| 116 | + (LogLevel, String) -> One logger | |
| 115 | 117 | ) = |
| 116 | 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 | 152 | ( |
| 151 | 153 | RStream conn, |
| 152 | 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 | 162 | success(line) then |
| 160 | 163 | //check if we must read another line by presence of hyphen after the reply code |
| 161 | 164 | //220-bla bla bla |
| ... | ... | @@ -163,24 +166,24 @@ define Reply_Result |
| 163 | 166 | if length(line) =< 3 then |
| 164 | 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 | 170 | success(code) then reply(code, reverse(so_far)) |
| 168 | 171 | } |
| 169 | 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 | 175 | success(char) then |
| 173 | 176 | if char = '-' then |
| 174 | - receive_reply(conn, [line . so_far], time_out) | |
| 177 | + receive_reply(conn, [line . so_far], time_out, logger) | |
| 175 | 178 | else |
| 176 | 179 | //decode the code |
| 177 | 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 | 183 | success(code_str) then |
| 181 | 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 | 187 | success(code) then reply(code , reverse([line . so_far])) |
| 185 | 188 | } |
| 186 | 189 | } |
| ... | ... | @@ -191,23 +194,25 @@ define Reply_Result |
| 191 | 194 | receive_reply |
| 192 | 195 | ( |
| 193 | 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 | 202 | Sending a piece of text (String) from the begining. |
| 199 | 203 | |
| 200 | 204 | define Maybe(One) |
| 201 | 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 | 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 | 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 | 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 | 234 | define Reply_Result |
| 230 | 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 | 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 | 249 | reply(code, lines) then |
| 244 | 250 | //we manage the 500 error, that mean the remote server is not ESMTP |
| 245 | 251 | //hence we try we with HELO, the old manner RFC 821 |
| 246 | 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 | 258 | else |
| 253 | 259 | reply(code, lines) |
| 254 | 260 | }, |
| 255 | 261 | if rep is reply(code, lines) then |
| 256 | 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 | 264 | reply(432, lines) |
| 259 | 265 | else |
| 260 | 266 | rep |
| ... | ... | @@ -281,14 +287,15 @@ define String |
| 281 | 287 | define Reply_Result |
| 282 | 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 | 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 | 301 | The same one for 'RCPT TO': |
| ... | ... | @@ -298,12 +305,13 @@ define Reply_Result |
| 298 | 305 | ( |
| 299 | 306 | RWStream conn, |
| 300 | 307 | String recipient, |
| 308 | + (LogLevel, String) -> One logger | |
| 301 | 309 | ) = |
| 302 | 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 | 319 | |
| 312 | 320 | define Reply_Result |
| 313 | 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 | 343 | sm_flush |
| 335 | 344 | ( |
| 336 | 345 | ByteArray buffer, |
| 337 | - WStream target | |
| 346 | + WStream target, | |
| 347 | + Int buffer_start_time, | |
| 348 | + (LogLevel, String) -> One logger | |
| 338 | 349 | )= |
| 339 | 350 | if write( target , buffer) is |
| 340 | 351 | { |
| 341 | 352 | failure then failure, |
| 342 | 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 | 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 | 367 | public define SendContentResult |
| 352 | 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 | 379 | error then copy_error(so_far), |
| 361 | 380 | timeout then |
| 362 | 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 | 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 | 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 | 394 | truncated(buffer) then |
| ... | ... | @@ -375,10 +396,12 @@ public define SendContentResult |
| 375 | 396 | if len = 0 then |
| 376 | 397 | copy_ok(so_far) |
| 377 | 398 | else |
| 378 | - if sm_flush( buffer, weaken(target) ) is | |
| 399 | + if sm_flush( buffer, weaken(target), now, logger ) is | |
| 379 | 400 | { |
| 380 | 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 | 407 | reply(code, lines) then |
| ... | ... | @@ -389,17 +412,20 @@ define SendContentResult |
| 389 | 412 | sm_copy_Data_IO_List_to_Stream |
| 390 | 413 | ( |
| 391 | 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 | 421 | if io_list is |
| 396 | 422 | { |
| 397 | 423 | [] then copy_ok(so_far), |
| 398 | 424 | [ h . t ] then |
| 399 | 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 | 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 | 429 | else |
| 404 | 430 | result |
| 405 | 431 | else |
| ... | ... | @@ -410,29 +436,31 @@ define Reply_Result |
| 410 | 436 | send_content |
| 411 | 437 | ( |
| 412 | 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 | 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 | 446 | smtp_reply(reply) then reply |
| 419 | 447 | copy_error(written) then |
| 420 | 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 | 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 | 453 | reply(452, ["Error sending big email (more than 1 Mb)"]) |
| 426 | 454 | else |
| 427 | 455 | error, |
| 428 | 456 | copy_ok(size) then |
| 429 | 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 | 460 | success(_) then |
| 433 | 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 | 469 | |
| 442 | 470 | define One |
| 443 | 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 | 482 | define SendMailResult |
| 454 | 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 | 491 | with enhanced_status = sm_session.enhanced_status, |
| 461 | 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 | 495 | error then error, // already logged |
| 465 | 496 | timeout then error, |
| 466 | 497 | reply(code, lines) then |
| 467 | 498 | if code = 250 then |
| 468 | 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 | 502 | error then error, // already logged |
| 472 | 503 | timeout then error, |
| 473 | 504 | reply(code, lines) then |
| 474 | 505 | if code = 250 then |
| 475 | 506 | //send DATA |
| 476 | - if send_data(conn) is | |
| 507 | + if send_data(conn, logger) is | |
| 477 | 508 | { |
| 478 | 509 | error then error, // already logged |
| 479 | 510 | timeout then error, |
| 480 | 511 | reply(code, lines) then |
| 481 | 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 | 515 | error then error, // already logged |
| 485 | 516 | timeout then error, |
| 486 | 517 | reply(code, lines) then |
| 487 | 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 | 521 | ok |
| 491 | 522 | else |
| 492 | 523 | reply_handling(code, lines, enhanced_status) |
| ... | ... | @@ -530,7 +561,8 @@ define SendMailResult |
| 530 | 561 | RWStream conn, |
| 531 | 562 | String login, |
| 532 | 563 | String password, |
| 533 | - Bool enhanced_status | |
| 564 | + Bool enhanced_status, | |
| 565 | + (LogLevel, String) -> One logger | |
| 534 | 566 | )= |
| 535 | 567 | |
| 536 | 568 | with plain_str = "AUTH PLAIN "+ to_string(base64_encode(to_byte_array("")+ |
| ... | ... | @@ -538,11 +570,11 @@ define SendMailResult |
| 538 | 570 | to_byte_array(login)+ |
| 539 | 571 | constant_byte_array(1,0)+ |
| 540 | 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 | 575 | failure then error, // already logged |
| 544 | 576 | success(_) then |
| 545 | - if receive_reply(conn) is | |
| 577 | + if receive_reply(conn, logger) is | |
| 546 | 578 | { |
| 547 | 579 | error then error // already logged |
| 548 | 580 | timeout then error, |
| ... | ... | @@ -561,13 +593,14 @@ define SendMailResult |
| 561 | 593 | List(String) auth_list, //list of available authentication method |
| 562 | 594 | String login, |
| 563 | 595 | String password, |
| 564 | - Bool enhanced_status | |
| 596 | + Bool enhanced_status, | |
| 597 | + (LogLevel, String) -> One logger | |
| 565 | 598 | )= |
| 566 | 599 | |
| 567 | 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 | 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 | 605 | define SendMailResult |
| 573 | 606 | do_auth |
| ... | ... | @@ -575,7 +608,8 @@ define SendMailResult |
| 575 | 608 | RWStream conn, //tcp connection |
| 576 | 609 | List(String) lines, //this is the reply lines provided in response to EHLO command |
| 577 | 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 | 614 | if auth is |
| 581 | 615 | { |
| ... | ... | @@ -584,8 +618,8 @@ define SendMailResult |
| 584 | 618 | with auth_list = get_auth_method(lines,[]), |
| 585 | 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 | 630 | make_sm_session |
| 597 | 631 | ( |
| 598 | 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 | 636 | //looking for ENHANCEDSTATUSCODES |
| 602 | 637 | with session_enhanced_status = has_smtp_extension(lines, enhanced_status_codes), |
| ... | ... | @@ -609,7 +644,7 @@ define Send_Mail_Session |
| 609 | 644 | { |
| 610 | 645 | failure then 0, |
| 611 | 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 | 648 | value |
| 614 | 649 | } |
| 615 | 650 | }, |
| ... | ... | @@ -617,41 +652,43 @@ define Send_Mail_Session |
| 617 | 652 | |
| 618 | 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 | 659 | public define SendMailResult |
| 625 | 660 | send_mail |
| 626 | 661 | ( |
| 627 | 662 | RWStream conn, |
| 628 | 663 | Send_Param param, |
| 629 | 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 | 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 | 673 | error then error,// already logged |
| 637 | 674 | timeout then error, |
| 638 | 675 | reply(code, lines) then |
| 639 | 676 | if code = 220 then |
| 640 | 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 | 680 | error then error, // already logged |
| 644 | 681 | timeout then error, |
| 645 | 682 | reply(code, lines) then |
| 646 | 683 | if code = 250 then |
| 647 | 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 | 687 | if auth_result = ok then |
| 651 | 688 | if prepare_mail_callback(sm_session, param) is |
| 652 | 689 | { |
| 653 | 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 | 693 | else |
| 657 | 694 | auth_result |
| ... | ... | @@ -661,7 +698,7 @@ public define SendMailResult |
| 661 | 698 | else if code = 550 then |
| 662 | 699 | //some server answer "550 5.7.1 Client host rejected: cannot find your reverse hostname, [88.181.64.17]" |
| 663 | 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 | 702 | reply_handling(432,lines,true) |
| 666 | 703 | else |
| 667 | 704 | reply_handling(code,lines,true) |
| ... | ... | @@ -672,8 +709,26 @@ public define SendMailResult |
| 672 | 709 | ( |
| 673 | 710 | RWStream conn, |
| 674 | 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 | 733 | public define SendMailResult |
| 679 | 734 | send_mail | ... | ... |
calexium_lib/net_services_protocols/logger_service.anubis
| ... | ... | @@ -305,6 +305,14 @@ define Message |
| 305 | 305 | . |
| 306 | 306 | |
| 307 | 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 | 316 | logNone( |
| 309 | 317 | String logger_name, |
| 310 | 318 | String log_string | ... | ... |