@@ -75,6 +75,8 @@ public class SendEmailFunction extends BasicFunction {
75
75
76
76
static final String ERROR_MSG_NON_MIME_CLIENT = "Error your mail client is not MIME Compatible" ;
77
77
78
+ private static final Random RANDOM = new Random ();
79
+
78
80
public final static FunctionSignature deprecated = new FunctionSignature (
79
81
new QName ("send-email" , MailModule .NAMESPACE_URI , MailModule .PREFIX ),
80
82
"Sends an email through the SMTP Server." ,
@@ -482,38 +484,42 @@ static void writeMessage(final PrintWriter out, final Mail aMail, final boolean
482
484
483
485
484
486
boolean multipartAlternative = false ;
485
- String multipartBoundary = null ;
487
+ int multipartInstanceCount = 0 ;
488
+ final Deque <String > multipartBoundary = new ArrayDeque <>();
486
489
487
490
if (aMail .attachmentIterator ().hasNext ()) {
488
491
// we have an attachment as well as text and/or html, so we need a multipart/mixed message
489
- multipartBoundary = multipartBoundary (1 );
492
+ multipartBoundary . addFirst ( multipartBoundary (++ multipartInstanceCount ) );
490
493
} else if (nonEmpty (aMail .getText ()) && nonEmpty (aMail .getXHTML ())) {
491
494
// we have text and html, so we need a multipart/alternative message and no attachment
492
495
multipartAlternative = true ;
493
- multipartBoundary = multipartBoundary (1 ) + "_alt" ;
496
+ multipartBoundary . addFirst ( multipartBoundary (++ multipartInstanceCount )) ;
494
497
}
495
498
// else {
496
499
// // we have either text or html and no attachment this message is not multipart
497
500
// }
498
501
499
502
//content type
500
- if (multipartBoundary != null ) {
503
+ if (! multipartBoundary . isEmpty () ) {
501
504
//multipart message
502
505
503
- out .print ("Content-Type: " + (multipartAlternative ? "multipart/alternative" : "multipart/mixed" ) + "; boundary=" + parameterValue (multipartBoundary ) + eol );
506
+ out .print ("Content-Type: " + (multipartAlternative ? "multipart/alternative" : "multipart/mixed" ) + "; boundary=" + parameterValue (multipartBoundary . peekFirst () ) + eol );
504
507
505
508
//Mime warning
506
509
out .print (eol );
507
510
out .print (ERROR_MSG_NON_MIME_CLIENT + eol );
508
511
out .print (eol );
509
512
510
- out .print ("--" + multipartBoundary + eol );
513
+ out .print ("--" + multipartBoundary . peekFirst () + eol );
511
514
}
512
515
513
516
if (nonEmpty (aMail .getText ()) && nonEmpty (aMail .getXHTML ()) && aMail .attachmentIterator ().hasNext ()) {
514
- out .print ("Content-Type: multipart/alternative; boundary=" + parameterValue (multipartBoundary (1 ) + "_alt" ) + eol );
517
+ // we are a multipart inside a multipart
518
+ multipartBoundary .addFirst (multipartBoundary (++multipartInstanceCount ));
519
+
520
+ out .print ("Content-Type: multipart/alternative; boundary=" + parameterValue (multipartBoundary .peekFirst ()) + eol );
515
521
out .print (eol );
516
- out .print ("--" + multipartBoundary ( 1 ) + "_alt" + eol );
522
+ out .print ("--" + multipartBoundary . peekFirst () + eol );
517
523
}
518
524
519
525
//text email
@@ -525,19 +531,13 @@ static void writeMessage(final PrintWriter out, final Mail aMail, final boolean
525
531
out .print (eol );
526
532
out .print (aMail .getText () + eol );
527
533
528
- if (multipartBoundary != null ) {
534
+ if (! multipartBoundary . isEmpty () ) {
529
535
if (nonEmpty (aMail .getXHTML ()) || aMail .attachmentIterator ().hasNext ()) {
530
- if (nonEmpty (aMail .getText ()) && nonEmpty (aMail .getXHTML ()) && aMail .attachmentIterator ().hasNext ()) {
531
- out .print ("--" + multipartBoundary (1 ) + "_alt" + eol );
532
- } else {
533
- out .print ("--" + multipartBoundary + eol );
534
- }
536
+ out .print ("--" + multipartBoundary .peekFirst () + eol );
535
537
} else {
536
- if (nonEmpty (aMail .getText ()) && nonEmpty (aMail .getXHTML ()) && aMail .attachmentIterator ().hasNext ()) {
537
- out .print ("--" + multipartBoundary (1 ) + "_alt--" + eol );
538
- } else {
539
- out .print ("--" + multipartBoundary + "--" + eol );
540
- }
538
+ // End multipart message
539
+ out .print ("--" + multipartBoundary .peekFirst () + "--" + eol );
540
+ multipartBoundary .removeFirst ();
541
541
}
542
542
}
543
543
}
@@ -552,20 +552,20 @@ static void writeMessage(final PrintWriter out, final Mail aMail, final boolean
552
552
out .print ("<!DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.1//EN\" \" http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\" >" + eol );
553
553
out .print (aMail .getXHTML () + eol );
554
554
555
- if (multipartBoundary != null ) {
555
+ if (! multipartBoundary . isEmpty () ) {
556
556
if (aMail .attachmentIterator ().hasNext ()) {
557
557
if (nonEmpty (aMail .getText ()) && nonEmpty (aMail .getXHTML ()) && aMail .attachmentIterator ().hasNext ()) {
558
- out .print ("--" + multipartBoundary (1 ) + "_alt--" + eol );
559
- out .print ("--" + multipartBoundary + eol );
560
- } else {
561
- out .print ("--" + multipartBoundary + eol );
558
+ // End multipart message
559
+ out .print ("--" + multipartBoundary .peekFirst () + "--" + eol );
560
+ multipartBoundary .removeFirst ();
562
561
}
562
+
563
+ out .print ("--" + multipartBoundary .peekFirst () + eol );
564
+
563
565
} else {
564
- if (nonEmpty (aMail .getText ()) && nonEmpty (aMail .getXHTML ()) && aMail .attachmentIterator ().hasNext ()) {
565
- out .print ("--" + multipartBoundary (1 ) + "_alt--" + eol );
566
- } else {
567
- out .print ("--" + multipartBoundary + "--" + eol );
568
- }
566
+ // End multipart message
567
+ out .print ("--" + multipartBoundary .peekFirst () + "--" + eol );
568
+ multipartBoundary .removeFirst ();
569
569
}
570
570
}
571
571
}
@@ -591,12 +591,13 @@ static void writeMessage(final PrintWriter out, final Mail aMail, final boolean
591
591
}
592
592
593
593
if (itAttachment .hasNext ()) {
594
- out .print ("--" + multipartBoundary + eol );
594
+ out .print ("--" + multipartBoundary . peekFirst () + eol );
595
595
}
596
596
}
597
597
598
- //Emd multipart message
599
- out .print ("--" + multipartBoundary + "--" + eol );
598
+ // End multipart message
599
+ out .print ("--" + multipartBoundary .peekFirst () + "--" + eol );
600
+ multipartBoundary .removeFirst ();
600
601
}
601
602
602
603
//end the message, <cr><lf>.<cr><lf>
@@ -1382,9 +1383,29 @@ private static boolean isNonToken(final String str) {
1382
1383
*
1383
1384
* @return the multi-part boundary string.
1384
1385
*/
1385
- static String multipartBoundary (final int multipartInstance ) {
1386
- // Get the version of eXist-db
1387
- final String version = Version .getVersion ();
1388
- return "eXist-db.multipart." + version + "_multipart_" + multipartInstance ;
1386
+ private static String multipartBoundary (final int multipartInstance ) {
1387
+ return multipartBoundaryPrefix (multipartInstance ) + "_" + nextRandomPositiveInteger () + "." + System .currentTimeMillis ();
1388
+ }
1389
+
1390
+ /**
1391
+ * Produce the prefix of a multi-part boundary string.
1392
+ *
1393
+ * Access is package-private for unit testing purposes.
1394
+ *
1395
+ * @param multipartInstance the number of this multipart instance.
1396
+ *
1397
+ * @return the multi-part boundary string prefix.
1398
+ */
1399
+ static String multipartBoundaryPrefix (final int multipartInstance ) {
1400
+ return "----=_mail.mime.boundary_" + multipartInstance ;
1401
+ }
1402
+
1403
+ /**
1404
+ * Generates a positive random integer.
1405
+ *
1406
+ * @return the integer
1407
+ */
1408
+ private static int nextRandomPositiveInteger () {
1409
+ return RANDOM .nextInt () & Integer .MAX_VALUE ;
1389
1410
}
1390
1411
}
0 commit comments