Mantis Bugtracker
  

Viewing Issue Advanced Details Jump to Notes ] View Simple ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0003923 [Quercus] minor always 03-03-10 12:42 02-10-11 10:53
Reporter emil View Status public  
Assigned To
Priority normal Resolution open Platform
Status new   OS
Projection none   OS Version
ETA none Fixed in Version Product Version 4.0.5
  Product Build
Summary 0003923: Multipart messages get stuffed into a single mime part by Javamail
Description (rep by michitopf)

In PHP one can easily send Multipart MIME messages. I use the code below to accomplish this. In Quercus this no longer works. It seems that the whole message is wrapped in a single large MIME part of a JavaMail MimeMessage.
How can I then send Multipart MIME messages in Quercus?

/*----------
 * $parts is an array where each entry represents a MIME part and is in turn another array with following entries:
 * $parts[$i]['content-type']
 * $parts[$i]['content-transfer-encoding'] ... 8bit (default), base64
 * $parts[$i]['filename']
 * $parts[$i]['content']
 */
function send_multipart_mail($to, $from, $subject, $parts) {
    global $mail_error;

    $boundary = '=_' . strtoupper(md5(uniqid('', true)));
    $headers = '';
    if ($from)
        $headers .= 'From: ' . $from . CRLF;
    $headers .= 'MIME-Version: 1.0' . CRLF;
    $headers .= 'Date: ' . date('r') . CRLF; // 'r' ... RFC 822
    $headers .= 'Content-Type: multipart/mixed;' . CRLF;
    $headers .= ' boundary="' . $boundary . '"';
    $headers .= 'Content-Transfer-Encoding: 8bit' . CRLF;
    
    $text = 'This is a message with multiple parts in MIME format.' . CRLF;

    foreach ($parts as $part) {
        $text .= '--' . $boundary . CRLF;
        $text .= 'Content-Type: ' . $part['content-type'] . CRLF;
        $content_transfer_encoding = $part['content-transfer-encoding'];
        if (!$content_transfer_encoding)
            $content_transfer_encoding = '8bit';
        $text .= 'Content-Transfer-Encoding: ' . $content_transfer_encoding . CRLF;
        $filename = $part['filename'];
        if ($filename)
            $text .= 'Content-Disposition: attachment; filename="' . $filename . '"' . CRLF;
        $text .= CRLF;
        $content = $part['content'];
        if ($content_transfer_encoding == 'base64')
            $content = trim(chunk_split(base64_encode($content)));
        $text .= $content . CRLF;
    }
    $text .= '--' . $boundary . '--';

    set_error_handler(mail_error_handler);
    $mail_ok = mail($to, $subject, $text, $headers);
    restore_error_handler();
    return $mail_ok;
}

The code can be used like this (also serves as a testcase):

$text = array(
        'content-type' => 'text/plain; charset="ISO-8859-1"',
        'content' => 'Dear recipient,' . CRLF . CRLF . 'attached you will find the requested information' . CRLF . CRLF . 'regards' . CRLF . 'Server' . CRLF . CRLF
    );
    $attachment = array(
        'content-type' => 'text/xml',
        'content-transfer-encoding' => 'base64',
        'filename' => 'info.xml',
        'content' => '<?xml version="1.0" encoding="ISO-8859-1" ?>' . CRLF .
        '<info>Test</info>');
send_multipart_mail('to@recipient.com', 'from@sender.org', 'Subject', array($text, $attachment));
Steps To Reproduce
Additional Information
Attached Files  Main.java [^] (1,384 bytes) 02-10-11 10:53

- Relationships

- Notes
(0004609)
Chris Graham
05-23-10 07:18

If you look at the example code you will see:
    $headers .= ' boundary="' . $boundary . '"';
    $headers .= 'Content-Transfer-Encoding: 8bit' . CRLF;

Notice the missing CRLF on the first line.

That's problem "1".

There are also problems "2" and "3"

2...

If you have the Content-Transfer-Encoding header after the Content-Type header you get a Java stack trace:

java.lang.ArrayIndexOutOfBoundsException: 64
    com.caucho.util.CharBuffer.deleteCharAt(CharBuffer.java:472)
    com.caucho.quercus.lib.mail.MailModule.splitHeaders(MailModule.java:386)
    com.caucho.quercus.lib.mail.MailModule.mail(MailModule.java:76)

3..

Likewise, if you put an unneeded CRLF on the end of $headers you get the same stack trace (i.e. the last header line should not have a CRLF on the end).

----

I have confirmed that generally mail works fine on Quercus, it's just some very specific corner cases that are pulled up in the code here :).
 
(0005042)
doogie
02-10-11 10:53

CharBuffer.deleteCharAt(int) will *always* fail, no matter which char you try to delete. The fix is to change the line:

int tail = _length - index + 1;

to:

int tail = _length - index - 1;

Even deleting the the first char will try to copy 1 more character than is available. When a char is deleted, you actually want to shift 1 less than the length.
 

- Issue History
Date Modified Username Field Change
03-03-10 12:42 emil New Issue
05-22-10 04:19 Chris Graham Issue Monitored: Chris Graham
05-23-10 07:18 Chris Graham Note Added: 0004609
02-10-11 10:53 doogie Note Added: 0005042
02-10-11 10:53 doogie File Added: Main.java
02-18-11 15:00 doogie Issue Monitored: doogie
03-09-11 14:33 kdecherf Issue Monitored: kdecherf
05-14-11 10:19 Chris Graham Issue End Monitor: Chris Graham


Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
38 total queries executed.
29 unique queries executed.
Powered by Mantis Bugtracker