Forum Moderators: coopster
In my world, I rock ;)
Now, recently, I had someone contact me because they installed the form on their site, and it was doing odd things. Everything they had done to the form *should* have worked, and in all test environments I had available to me, it did. But on her live site, it was showing odd behavior.
Basically, you'd fill out the form. All fields worked and checked things as they should. The user clicks "submit", and the end user was taken immediately to a "500 Internal server error".
Funnily enough, the email would come through to the mailbox just fine.
I originally thought that there was something wrong with the coding for the "thank you" page that was included with the script, and all efforts to alter it didn't resolve the problem. I changed permissions (spent a good hour + changing permissions to every combination imaginable, with no effect), renamed the file, checked the code 5 gazillion times, and nothing worked. At one point, I even made the form - upon successful submission - return to the contact form from whence it came - even *that* returned the error.
Finally, I just deleted the call for the thank-you page altogether. In a perfect world, this means that, upon submitting the form, the end user would just stay on the contact page, looking at everything in utter confusion wondering why it didn't work.
Amazingly, it returned a 500 internal server error. So now I had it down to "the submit action is what's doing it" However, the submit was coded properly.
For the record, before you say "why didn't you check the error logs?" - it was hosted on GoDaddy.com, PHP running as CGI (GoDaddy uses IIS servers). The person who was using my form did not pay the extra fee to have access to her error logs (yes, you have to do that with GoDaddy - upgrade your account to get your error logs). So it all had to be via trial and error.
Anyway, I Googled the issue with the sumbit button, and discovered that, when PHP is run as CGI, it needs further "new line" code. The explanation given went right over my head, but I tried the solution because I was desperate. To my utter amazement, it worked. The solution makes *absolutely* no sense to me, but it worked.
Basically, the line of code that was causing the error was this:
$mailheader = "From: $name <$email>\nContent-Type: text/html";
When I changed it to this:
$mailheader = "From: $name <$email>\n\nContent-Type: text/html";
It worked (note the extra "\n" there before the "Content Type").
What I want to know is, WHY? The fact that this *did* work is great, but I guess I'm looking a gift horse in the mouth, because I want to understand WHY it works. In all reality, it shouldn't, because new lines are how mail servers determine when headers end and the message begins. The fact is, this *should* fail utterly, and it *shouldn't* be sending the email through. But it is.
So would anyone know *why* this is working? (For the record, I found the solution from a thread on another forum where the guy was having the same problem with a script he wrote - he was also using GoDaddy with PHP run as CGI, and the solution worked for him as well.)
If anyone has any insight, I'd *love* to hear it, because although I'm glad it works, the solution confounds me.
Also, CGI scripts have to send Content-Type: text/html in the HTTP response header. That's the major cause of 500 server errors when you're writing CGI code. PHP normally does that for you, but maybe the way it's configured, it doesn't know that it's running under a Web server.
I'd try changing the mail header back the way it was, and add
print "Content-Type: text/html\n\n";
I suspect that the SMTP (mail) server that is being used by the IIS server is pickier than the one used in LAMP systems.
MIME encoding is a HUGE pain in the butt. Just a few weeks ago, I had to work for a couple of hours to get an email sender formatted so I could send attachments to our bug reporting system. Both the server and the client kept puking on the silliest little things.
The extra newline probably won't hurt your LAMP server (test it out and see), but you should definitely put that Content-Type in there. You should probably format the message as a MIME type with all the separators and whatnot. This will make it a lot easier to make changes in the future.
This can be further complicated by the choice of mail server installed.
As far as <CRLF>s are concerned:
Windows requires \r\n
Unix/Linux requires \n
Mac requires \r
In PHP, for portability, you could try using the PHP constant PHP_EOL which should return the correct <CRLF> for the OS that it's installed on.
If PHP_EOL isn't defined on your system for some reason you can use the following to set it.
if (!defined('PHP_EOL')) {
switch (strtoupper(substr(PHP_OS, 0, 3))) {
// Windows
case 'WIN':
define('PHP_EOL', "\r\n");
break;
// Mac
case 'DAR':
define('PHP_EOL', "\r");
break;
// Unix
default:
define('PHP_EOL', "\n");
}
}