Reputation: 136
I'm using CodeIgniter's email library to send a mail to myself for testing. This email should have an attachment, so I use the following code for sending the mail:
$this->load->library('colorparser');
$this->load->library('email');
$config = array();
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from('...', '...');
$this->email->to('...');
$this->email->subject('A user sent in a map for your Trackmania tournament');
$this->email->message("some HTML code");
$this->email->attach("/www/htdocs/.../dev/tournois/uploads/tm2/57e30c92aaa65393755646.gif", 'attachment');
$this->email->send();
What makes me curious is that after execution I receive a mail with an attachment. The name is correct and Thunderbird tries to show the gif, but the attachment is empty, 0 bytes.
Then I tried to get the output via print_debugger() which worked just fine. I can't see any error in the information shown by the debugger, even the base64 encoded stuff is there.
Do you've any idea why this is a thing?
Upvotes: 4
Views: 1234
Reputation: 136
I reanalyzed the mail headers & bodies and discovered a missing blank line, which is the problem:
Content-Type: image/gif; name="57e30c92aaa65393755646.gif"
Content-Disposition: attachment;
Content-Transfer-Encoding: base64
R0lGODlhLAGoAPcAADwkGEAnHEMpIEQsIEQtJEgxJks1K082KVM4KVQ9KlQ8Lk85MVI9NFQ/N1JA...
But normally it has to be with two line breaks:
Content-Type: image/gif; name="57e30c92aaa65393755646.gif"
Content-Disposition: attachment;
Content-Transfer-Encoding: base64
R0lGODlhLAGoAPcAADwkGEAnHEMpIEQsIEQtJEgxJks1K082KVM4KVQ9KlQ8Lk85MVI9NFQ/N1JA...
I don't know if this is already fixed in a newer CodeIgniter build, but for everyone having the same problem, you can fix it by editing the Email library by yourself. The library is located in /system/libraries
folder. You can overwrite it too (with MY_...), but for short fixing it I just added a second "new line" to the code in the CI library.
This is the original function where CodeIgniter adds attachments to the mail:
protected function _append_attachments(&$body, $boundary, $multipart = null)
{
for ($i = 0, $c = count($this->_attachments); $i < $c; $i++)
{
if (isset($multipart) && $this->_attachments[$i]['multipart'] !== $multipart)
{
continue;
}
$name = isset($this->_attachments[$i]['name'][1])
? $this->_attachments[$i]['name'][1]
: basename($this->_attachments[$i]['name'][0]);
$body .= '--'.$boundary.$this->newline
.'Content-Type: '.$this->_attachments[$i]['type'].'; name="'.$name.'"'.$this->newline
.'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline
.'Content-Transfer-Encoding: base64'.$this->newline
.(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline.$this->newline)
.$this->_attachments[$i]['content'].$this->newline;
}
// $name won't be set if no attachments were appended,
// and therefore a boundary wouldn't be necessary
empty($name) OR $body .= '--'.$boundary.'--';
}
Now, to solve the problem, just replace the ''
of the Content ID string part with a new line, so if there is no Content ID, there will be the missing new line.
$body .= '--'.$boundary.$this->newline
.'Content-Type: '.$this->_attachments[$i]['type'].'; name="'.$name.'"'.$this->newline
.'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline
.'Content-Transfer-Encoding: base64'.$this->newline
.(empty($this->_attachments[$i]['cid']) ? $this->newline : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline.$this->newline)
.$this->_attachments[$i]['content'].$this->newline;
Hope this helps someone!
Upvotes: 2
Reputation: 1171
It all looks good so a couple of things to double check that might help.
If you are creating the file on the fly or with a file upload then the error might be occurring there, and not in the email.
Hope that helps.
Upvotes: 1