Sicher HTML Mails versenden / Header Layout!?

Mik3e

Erfahrenes Mitglied
Hi zusammen,

ich muss via Mail eine HTML Mail versenden. Prinzipiell eine simple Sache, wenn da die Header nicht wären.
Damit das Teil wirklich wasserdicht ist, muss der Header natürlich korrekt sein. Leider ist es so, dass ich mir ca. 10 Tutorials durchgelesen habe und der Header immer anders definiert wird....

Daher hab ich mir mal HTML Mails von eBay geschnappt und den Header analysiert.
Bei einer eBay Mail ist der Header folgendermaßen aufgebaut (nur der interessante Teil):

Code:
From: Gebotbestaetigt@ebay.at
To: test@test.com
Subject: =?ISO-8859-1?Q?eBay_-_Gebot_best=E4tigt:_***GTA_VICE_CITY***CU?=
 =?ISO-8859-1?Q?LT_GAME_f=FCr_PS2***_(Artikelnummer_8112092025)?=
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=1955588816.1088079721449.JavaMail.ebayapp.rc-v3offer32
X-eBay-MailTracker: 10003.355.16.12021

Nachdem eBay nicht irgendein Bastelverein ist, gehe ich mal davon aus, dass dieser Header eigentlich die perfekte Vorlage sein muss.

Aber hier tun sich gleich die ersten Fragen auf:
1. Was macht diese ISO Codierung im Betreff?
2. Content-Type: multipart/alternative (warum nicht text/html) - Es ist kein File angefügt

Weiters gibt es eine PEAR Klasse für MIME Codierte Mails (http://pear.php.net/package/Mail_Mime). Hat jemand damit zufällig Erfahrung Ich verwenden bisher nur die DB Klasse von PEAR.

Danke & LG
Mike
 
Okay okay, ich bin ueberzeigt: Ich mach demnaechst mal mein Mailscript als Tutorial fertig.
Solange gibt's das hier. Unbearbeitet und unzensiert.
Wird aber so nicht gleich laufen, da es Teil meines (noch in Produktion befindlichen) WebMailers ist.
PHP:
<?php
if ((empty($_SESSION['username'])) || (empty($_SESSION['password'])))
	{
		header("Location:index.php");
	}
$attachedfiles=array();
$mailto="";
$subject="";
$message="";
if (!empty($_POST))
	{
		$keys=array_keys($_POST);
		for ($count=0;$count<count($keys);$count++)
			{
				if (substr($keys[$count],0,10)=="attachment")
					{
						$attachedfiles[]=$_POST[$keys[$count]];
					}
			}
	}
if ((isset($_POST['attachfile'])) || (isset($_POST['removeattachment'])))
	{
		if (!empty($_POST['mailto']))
			{
				$mailto=$_POST['mailto'];
			}
		if (!empty($_POST['subject']))
			{
				$subject=$_POST['subject'];
			}
		if (!empty($_POST['message']))
			{
				$message=$_POST['message'];
			}
		if (isset($_POST['attachfile']))
			{
				$tmpname=$_FILES["uploadfile"]["tmp_name"];
				$filename=$_FILES["uploadfile"]["name"];
				$filesize=$_FILES["uploadfile"]["size"];
				if ($filesize>0)
					{
						move_uploaded_file($tmpname,"mailtemp/".$filename);
						$attachedfiles[]=$filename;
					}
			}
		if (isset($_POST['removeattachment']))
			{
				for ($count=0;$count<count($keys);$count++)
					{
						if (substr($keys[$count],0,13)=="delattachment")
							{
								$filename=$_POST[$keys[$count]];
								$delpositions[]=substr($keys[$count],13,1);
								unlink("mailtemp/".$filename);
							}
					}
				$newattachedfiles=array();
				for ($count=0;$count<count($attachedfiles);$count++)
					{
						if (!in_array($count,$delpositions))
							{
								$newattachedfiles[]=$attachedfiles[$count];
							}
					}
				$attachedfiles=$newattachedfiles;
				unset($newattachedfiles);
			}
	}
if (((isset($_POST['sendmail'])) || (isset($_POST['savedraft']))) && ((!empty($_POST['mailto'])) && (!empty($_POST['subject'])) && (!empty($_POST['message']))))
	{
		$message=imap_8bit($_POST['message']);
		$message.="\n\n";
		/*for ($attachment=0;$attachment<count($attachedfiles);$attachment++)
			{
				$message.="\t".imap_8bit("<<".$attachedfiles[$attachment].">>");
			}*/
		$boundary="----".md5(uniqid());
		$email="";
		$email.="Content-class: urn:content-classes:message";
		$email.="\nUser-Agent: reptilers lustiges Mailscript";
		$email.="\nMIME-Version: 1.0";
		if (!empty($attachedfiles))
			{
				$email.="\nContent-Type: multipart/mixed;\n\tboundary=\"".$boundary."\"";
			}
		$email.="\nFrom: ".$_SESSION['username']."@".$host;
		$email.="\nX-Priority: 3 (Normal)";
		$email.="\nImportance: Normal";
		if (!empty($attachedfiles))
			{
				$email.="\n\n--".$boundary;
			}
		$email.="\nContent-Type: text/plain;\n\tcharset=\"iso-8859-1\"";
		$email.="\nContent-Transfer-Encoding: quoted-printable";
		$email.="\nContent-Disposition: inline";
		$email.="\n\n".$message;
		if (!empty($attachedfiles))
			{
				$email.="\n\n--".$boundary;
			}
		for ($attachment=0;$attachment<count($attachedfiles);$attachment++)
			{
				$file=fopen("mailtemp/".$attachedfiles[$attachment],"r");
				$content=fread($file,filesize("mailtemp/".$attachedfiles[$attachment]));
				fclose($file);
				$encodedfile=chunk_split(base64_encode($content));
				$email.="\nContent-Type: application/octet-stream;\n\tname=\"".$attachedfiles[$attachment]."\"";
				$email.="\nContent-Transfer-Encoding: base64";
				$email.="\nContent-Description: ".$attachedfiles[$attachment];
				$email.="\nContent-Disposition: attachment;\n\tfilename=\"".$attachedfiles[$attachment]."\"";
				$email.="\n\n".$encodedfile."\n\n--".$boundary;
				unlink("mailtemp/".$attachedfiles[$attachment]);
			}
		if (!empty($attachedfiles))
			{
				$email.="--";
			}
		$mbox=imap_open("{".$host."/norsh}",$_SESSION['username'],$_SESSION['password']);
		if ((isset($_POST['sendmail'])) && (isset($_POST['savesent'])))
			{
				imap_append($mbox,"{".$host."}".$sentfolder,"To: ".$_POST['mailto']."\nSubject: ".$_POST['subject']."\n".$email);
			}
		elseif (isset($_POST['savedraft']))
			{
				imap_append($mbox,"{".$host."}".$draftfolder,"To: ".$_POST['mailto']."\nSubject: ".$_POST['subject']."\n".$email);
			}
		imap_close($mbox);
		if (isset($_POST['sendmail']))
			{
				imap_mail($_POST['mailto'],$_POST['subject'],"",$email);
			}
		unset($body);
		unset($message);
		unset($attachedfiles);
		$message="";
		$attachedfiles=array();
	}
echo '<html>';
echo '<body>';
echo '<form method="post" action="webmail.php?subsite=sendmail.php" enctype="multipart/form-data">';
echo gettext("Recipient");
echo ':<input type="text" name="mailto" value="'.$mailto.'"><br>';
echo gettext("Subject");
echo ':<input type="text" name="subject" value="'.$subject.'"><br>';
echo '<textarea name="message">'.$message.'</textarea><br>';
for ($attachment=0;$attachment<count($attachedfiles);$attachment++)
	{
		echo '<input type="hidden" name="attachment'.$attachment.'" value="'.$attachedfiles[$attachment].'">';
		echo '<input type="checkbox" name="delattachment'.$attachment.'" value="'.$attachedfiles[$attachment].'">'.$attachedfiles[$attachment].'<br>';
	}
if (count($attachedfiles)>0)
	{
		echo '<input type="submit" name="removeattachment" value="';
		echo gettext("Remove selected attachments");
		echo '"><br>';
	}
echo '<input type="file" name="uploadfile">';
echo '<input type="submit" name="attachfile" value="';
echo gettext("Attach file");
echo '"><br>';
echo '<input type="checkbox" name="savesent" value="savesent" checked>';
echo gettext("Save copy in sent eMails folder");
echo '<br>';
echo '<input type="submit" name="sendmail" value="';
echo gettext("Send eMail");
echo '">';
echo '<input type="submit" name="savedraft" value="';
echo gettext("Save as Draft");
echo '">';
echo '</form>';
echo '</body>';
echo '</html>';
?>
 
Wenn Du daraus ein Tutorial machen willst, würde ich diesen Spaghetti Code noch in Klassen und ein schönes Package umbaun ;-)

Hilft mir an der Stelle leider nicht sehr viel, da ich ja sehr wohl weiß, wie MIME Mail funktioniert, meine eigentlichen Fragen damit aber nicht beantwortet sind.

Danke trotzdem,
LG
Mike
 
Das stimmt, aber Du verwendest auch "Content-Type: text/plain;\n\tcharset=\"iso-8859-1\""
Ich hab das ganze jetzt mit PEAR realisiert, dort wird ebenfalls multipater/alternative verwendet...

Wenn das ein Webmailer wird, warum verwendest Du eigentlich nicht auch die PEAR Klassen Ist doch wesentlich eleganter und bequemer...
 
Wenn ich die PEAR-Klassen verwende lerne ich daraus nicht wirklich viel.
Wenn ich mir jedoch die Doku zu den IMAP-Funktionen reinzieh und damit arbeite ist der Lernfaktor wesentlich hoeher.
Was meinst Du warum ich mir die Arbeit gemacht habe Tar-Archive zu analysieren um dann im Endeffekt dieses Script daraus zu erstellen? ;)

Multipart/Alternative hab ich mir auch angesehen.
Als das Mail-Script entstand hab ich mir mit verschiedenen Mail-Programmen selbst Mails zugeschickt um die Header zu analysieren.
Da ich aber persoenlich nichts von HTML-Mails halte ist halt mein Script fuer PLAIN vorgesehen.
Ein grosses Problem dies in HTML-Mails zu aendern sollte es aber nicht darstellen.
 
Alles klar... Ich hab das nur gesagt, da ich in den letzten 3 jahren alle Mailer auch selbst gebaut habe. Spannend ist vor allem das attachen von Files wenn Du alles selbst entwickelst. (echt mühsam). Da ist ein Framework schon gemütlicher:

Mit Pear:
PHP:
$file = 'classes/xmail.dtd';
$mime->addAttachment($file, 'text/plain');
Fertig! :)

Und Du brauchst Dich nicht mit dem öffnen der Files, Streams, fehlerabfragen oder ähnlichem rumschlagen.

Aber wenn Du es nur zwecks Lernübung entwickelst, dann ist es ohne Pear natürlich besser...
 
Naja, es soll nicht nur zum lernen sein.
Im Endeffekt soll es auch eingesetzt werden, jedoch lerne ich auf dem Weg zum fertigen Produkt gerne neue Dinge.
Auch wenn die Entwicklung dadurch evtl. etwas laenger dauert. Dafuer ist das Erfolgsgefuehl am Ende groesser.
Natuerlich geb ich ein Script mit neu angelernte Sachen nicht gleich nach Fertigstellung frei sondern teste es ausgiebig. Das muss aber auch gemacht werden wenn man sich auf Fremdkomponenten verlaessst.

Mit den Anhaengen kann ich Dir nur Recht geben, das war schon ein Kreuz. Jedoch funktioniert es jetzt wunderbar, ich kann so viele Dateien anhaengen wie ich lustig bin. Und manchmal bin ich sehr lustig. ;)
 
Mal schauen.
Bisher bin ich immer ganz gut um PEAR herum gekommen und konnte am Ende doch was funktionierendes auf die Beine stellen.
 
Zurück