Commit 65f1d1f2 65f1d1f2ae3781d1b1839a2aace81d79422bff1a by Sergey Poznyakoff

spamd sieve test: bugfix.

* libmu_sieve/extensions/spamd.c (get_real_message_size): New function.
(spamd_test): Use get_real_message_size instead of mu_message_size.
1 parent 61bccb10
...@@ -87,7 +87,7 @@ spamd_send_command (mu_stream_t stream, const char *fmt, ...) ...@@ -87,7 +87,7 @@ spamd_send_command (mu_stream_t stream, const char *fmt, ...)
87 } 87 }
88 88
89 static int 89 static int
90 spamd_send_message (mu_stream_t stream, mu_message_t msg) 90 spamd_send_message (mu_stream_t stream, mu_message_t msg, int dbg)
91 { 91 {
92 int rc; 92 int rc;
93 mu_stream_t mstr, flt; 93 mu_stream_t mstr, flt;
...@@ -120,7 +120,8 @@ spamd_send_message (mu_stream_t stream, mu_message_t msg) ...@@ -120,7 +120,8 @@ spamd_send_message (mu_stream_t stream, mu_message_t msg)
120 bufchg = 1; 120 bufchg = 1;
121 } 121 }
122 122
123 if (mu_debug_category_level ("sieve", 5, &dlev) == 0 && 123 if (dbg &&
124 mu_debug_category_level ("sieve", 5, &dlev) == 0 &&
124 !(dlev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE9))) 125 !(dlev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE9)))
125 { 126 {
126 /* Mark out the following data as payload */ 127 /* Mark out the following data as payload */
...@@ -296,6 +297,35 @@ parse_response_line (mu_sieve_machine_t mach, const char *buffer) ...@@ -296,6 +297,35 @@ parse_response_line (mu_sieve_machine_t mach, const char *buffer)
296 return 0; 297 return 0;
297 } 298 }
298 299
300 /* Compute the "real" size of the message. This takes into account filtering
301 applied by spamd_send_message (LF->CRLF transcription).
302
303 FIXME: Previous versions used mu_message_size, but it turned out to be
304 unreliable, because it sometimes returns a "normalized" size, which differs
305 from the real one. This happens when the underlying implementation does
306 not provide a _get_size method, so that the size is computed as a sum of
307 message body and header sizes. This latter is returned by mu_header_size,
308 which ignores extra whitespace around each semicolon (see header_parse in
309 libmailutils/mailbox/header.c).
310 */
311 static int
312 get_real_message_size (mu_message_t msg, size_t *psize)
313 {
314 mu_stream_t null;
315 mu_stream_stat_buffer stat;
316 int rc;
317
318 rc = mu_nullstream_create (&null, MU_STREAM_WRITE);
319 if (rc)
320 return rc;
321 mu_stream_set_stat (null, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), stat);
322 rc = spamd_send_message (null, msg, 0);
323 mu_stream_destroy (&null);
324 if (rc == 0)
325 *psize = stat[MU_STREAM_STAT_OUT];
326 return rc;
327 }
328
299 /* The test proper */ 329 /* The test proper */
300 330
301 /* Syntax: spamd [":host" <tcp-host: string>] 331 /* Syntax: spamd [":host" <tcp-host: string>]
...@@ -326,7 +356,7 @@ static int ...@@ -326,7 +356,7 @@ static int
326 spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) 356 spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
327 { 357 {
328 char *buffer = NULL; 358 char *buffer = NULL;
329 size_t size = 0; 359 size_t size;
330 char spam_str[6], score_str[21], threshold_str[21]; 360 char spam_str[6], score_str[21], threshold_str[21];
331 int rc; 361 int rc;
332 int result; 362 int result;
...@@ -334,7 +364,6 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -334,7 +364,6 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
334 mu_stream_t stream = NULL, null; 364 mu_stream_t stream = NULL, null;
335 mu_sieve_value_t *arg; 365 mu_sieve_value_t *arg;
336 mu_message_t msg; 366 mu_message_t msg;
337 size_t m_size, m_lines;
338 char *host; 367 char *host;
339 mu_header_t hdr; 368 mu_header_t hdr;
340 mu_debug_handle_t lev = 0; 369 mu_debug_handle_t lev = 0;
...@@ -348,6 +377,15 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -348,6 +377,15 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
348 if (mu_sieve_is_dry_run (mach)) 377 if (mu_sieve_is_dry_run (mach))
349 return 0; 378 return 0;
350 379
380 msg = mu_sieve_get_message (mach);
381 rc = get_real_message_size (msg, &size);
382 if (rc)
383 {
384 mu_sieve_error (mach, _("cannot get real message size: %s"),
385 mu_strerror (rc));
386 mu_sieve_abort (mach);
387 }
388
351 if (mu_sieve_tag_lookup (tags, "host", &arg)) 389 if (mu_sieve_tag_lookup (tags, "host", &arg))
352 host = arg->v.string; 390 host = arg->v.string;
353 else 391 else
...@@ -387,14 +425,9 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -387,14 +425,9 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
387 } 425 }
388 } 426 }
389 427
390 msg = mu_sieve_get_message (mach);
391 mu_message_size (msg, &m_size);
392 mu_message_lines (msg, &m_lines);
393
394 spamd_send_command (stream, "SYMBOLS SPAMC/1.2"); 428 spamd_send_command (stream, "SYMBOLS SPAMC/1.2");
395 429
396 spamd_send_command (stream, "Content-length: %lu", 430 spamd_send_command (stream, "Content-length: %lu", (u_long) size);
397 (u_long) (m_size + m_lines));
398 if (mu_sieve_tag_lookup (tags, "user", &arg)) 431 if (mu_sieve_tag_lookup (tags, "user", &arg))
399 spamd_send_command (stream, "User: %s", arg); 432 spamd_send_command (stream, "User: %s", arg);
400 else 433 else
...@@ -408,7 +441,7 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -408,7 +441,7 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
408 handler = set_signal_handler (SIGPIPE, sigpipe_handler); 441 handler = set_signal_handler (SIGPIPE, sigpipe_handler);
409 442
410 spamd_send_command (stream, ""); 443 spamd_send_command (stream, "");
411 spamd_send_message (stream, msg); 444 spamd_send_message (stream, msg, 1);
412 mu_stream_shutdown (stream, MU_STREAM_WRITE); 445 mu_stream_shutdown (stream, MU_STREAM_WRITE);
413 446
414 spamd_read_line (mach, stream, &buffer, &size); 447 spamd_read_line (mach, stream, &buffer, &size);
......