homepage Welcome to WebmasterWorld Guest from 54.237.184.242
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
"\r\n" In Headers Killling Email Attachments
An on-going battle
neophyte




msg:3900102
 12:47 am on Apr 25, 2009 (gmt 0)

Hello All -

I've got a script that will send a plain text email with one or more attachments which works. But part of the spec for this script is that a bunch of different headers need to be included as well (i.e. Reply To: Reply Path: X-MSmail-Priority: High, and others - see script below).

If I send an email with this script that DOESN'T have an attachment, all is well - all required headers are included and the email is received by the recepiant.

HOWEVER, everytime I send an email that has an attachment AND includes any header data other than "From:", the attachment - as well as the attachment mime headers - ends up IN THE BODY of the email as a mile-long list of garbage characters.

After much testing, this attachment problem "seems" to be caused by by EOL characters "\r\n" at the end of basic email headers.

PROBLEM RECAP:
- Plain Text email WITHOUT attachments: all headers can be included without problem
- Plain text email WITH attachment(s): all headers except for From: need to be stripped, INCLUDING the "\r\n" characters at the end of the the From: header.

Has anyone else had this problem?

I've included my script below in hopes that someone can guide me as to how to I can include all client-required email headers ALONG WITH an email attachment.

Note: As seen below, all additional general email headers have been commented out.

Great appreciation in advance for any assistance!

Neophyte

*********************************************

function send_mail($fName, $fAdd, $tName, $tAdd, $subj, $body, $cName, $cAdd, $bName, $bAdd, $eType, $attach)
{

# TRANSFER $body VAR INTO $message VAR
$message = $body;

//$headers .= 'To: '. $tName . '<' . $tAdd . '>'. "\r\n";
$headers .= 'From: '. $fName . '<' . $fAdd . '>';
//$headers .= 'Reply-To: '. $fName . '<' . $fAdd . '>'. "\r\n";
//$headers .= 'Return-Path: '. $fName . '<' . $fAdd . '>'. "\r\n";
//$headers .= 'Message-ID: <'. time() . '-' . $fAdd . '>'. "\r\n";
//$headers .= 'X-Mailer: PHP v'. phpversion(). "\r\n";
//$headers .= 'X-Priority: 1'. "\r\n";
//$headers .= 'X-MSmail-Priority: High'. "\r\n";

#INCLUDE CC AND BCC IF REQUIRED
//if($cName) $headers .= 'Cc: ' . $cName . '<' . $cAdd . '>'. "\r\n";
//if($bName) $headers .= 'Bcc: '. $bName . '<' . $bAdd . '>'. "\r\n";

#CHECK IF ATTACHMENT IS REQUIRED
#IF TRUE, TRANSFER VARS FROM $_FILES INTO LOCAL COUNTERPARTS
if($attach)
{
$fileatt = $_FILES['UpLoad']['tmp_name'][0];
$fileatt_type = $_FILES['UpLoad']['type'][0];
$fileatt_name = $_FILES['UpLoad']['name'][0];
}

# CHECK IF FILE UPLOAD IS TRUE
if(is_uploaded_file($fileatt))
{
# READ THE FILE TO BE ATTACHED
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);

# GENERATE BOUNDARY STRING
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

# ADD FILE ATTACHMENT HEADERS
$headers .= "\r\nMIME-Version: 1.0\r\n" .
"Content-Type: multipart/mixed;\r\n" .
" boundary=\"{$mime_boundary}\"";

# ADD MULTIPART BOUNDARY ABOVE PLAIN MESSAGE
$message = "This is a multi-part message in MIME format.\r\n\r\n" .
"--{$mime_boundary}\r\n" .
"Content-Type: text/plain; charset=\"iso-8859-1\"\r\n" .
"Content-Transfer-Encoding: 7bit\r\n\r\n" .
$message . "\r\n\r\n";

# BASE64 ENCODE ATTACHMENT FILE DATA
$data = chunk_split(base64_encode($data));

# ADD FILE ATTACHMENT TO THE MESSAGE
$message .= "--{$mime_boundary}\r\n" .
"Content-Type: {$fileatt_type};\n" .
" name=\"{$fileatt_name}\"\r\n" .
"Content-Disposition: attachment;\r\n" .
" filename=\"{$fileatt_name}\"\r\n" .
"Content-Transfer-Encoding: base64\r\n\r\n" .
$data . "\r\n\r\n" .
"--{$mime_boundary}--\r\n";
}

# MAKE SURE EMAIL USES THE FROM ADDRESS
ini_set('sendmail_from', $fAdd);

# SEND THE EMAIL
mail($tAdd, $subj, $message, $headers);

# RESTORE INITIAL STATE OF INI/SENDMAIL_FROM
ini_restore('sendmail_from');

# IF ATTACHMENT IS TRUE, UNLINK ATTACHMENT
if($attach) unlink($filePath);

}

 

rocknbil




msg:3900154
 2:22 am on Apr 25, 2009 (gmt 0)

May be off base, but have experienced this a LOT with perl - on some systems, it doesn't need both an \r and an \n, have you tried a version of your script with just \n in the headers variable? Worth a shot . . .

vincevincevince




msg:3900164
 3:27 am on Apr 25, 2009 (gmt 0)

Save yourself a LOT of time and use PHPMailer

pinterface




msg:3901326
 5:31 am on Apr 27, 2009 (gmt 0)

I notice that the first thing you do when printing headers for an attachment is add an "\r\n" before the MIME-version field.
$headers .= "\r\nMIME-Version: 1.0\r\n" .

Given that all your commented-out code includes "\r\n"s at the end of the lines, you're surely ending up with something like:
X-MSmail-Priority: High<CR><LF> 
<CR><LF>
MIME-Version: 1.0<CR><LF>

If you aren't familiar with SMTP, "\r\n\r\n" marks the end of the headers, and so causes mail programs to think everything from "MIME-Version" on down is the e-mail. Outputting a single end-of-line (e.g., always at the end of a line, or always at the beginning of a line) will probably fix your problem.

However, as vincevincevince mentioned, there already exist PHP classes to do all this grunt work for you. That's almost certainly the easiest way to go.

rocknbil: "\n" is perl's "logical newline", and so follows the convention of the underlying system for line separator. E.g., on Windows "\n" really means "\r\n", which means "\r\n" is really "\r\r\n". see perlport Newlines [perldoc.perl.org] for the gory details. (Of course, if you're just shelling out to sendmail, single LFs should be fine.)

neophyte




msg:3901394
 9:08 am on Apr 27, 2009 (gmt 0)

PrinterFace -

>>Outputting a single end-of-line (e.g., always at the end of a line, or always at the beginning of a line) will probably fix your problem.<<

I took out the leading EOL in front of the MIME version line and that did the trick. THANKS!

Neophyte

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved