Page 1 of 2
[BUGFIX] Browser hanging when testing e-mail connections
Posted: Fri Apr 13, 2007 10:45 am
by chazter6
I have uploaded my script to my isp and I am using their sendmail function.
When I use this code for my file
testEmail1.php:
Code: Select all
require_once ("swift/lib/Swift.php");
require_once ("swift/lib/Swift/Connection/Sendmail.php");
$swift =& new Swift(new Swift_Connection_NativeMail());
//Create the message
$message =& new Swift_Message("My subject Native", "My body");
//Now check if Swift actually sends it
if ($swift->send($message, "Address@Todomain.com", "Address@Fromdomain.com")) echo "Sent";
else echo "Failed";
..the browser will return with my page saying it was
Sent. I do receive this e-mail in my test recepient.
Now when I use this code for my file
testEmail2.php
Code: Select all
require_once ("swift/lib/Swift.php");
require_once ("swift/lib/Swift/Connection/Sendmail.php");
//Start Swift
$swift =& new Swift(new Swift_Connection_Sendmail(SWIFT_SENDMAIL_AUTO_DETECT));
//Create the message
$message =& new Swift_Message("My subject", "My body");
//Now check if Swift actually sends it
if ($swift->send($message, "im_chaz@rocketmail.com", "webmaster@isceca.com")) echo "Sent";
else echo "Failed";
...Both browsers FireFox and I.E. hangs, like it is trying to load the page. I dont get and indication that its been sent per my echo statement,
BUT when I check my test e-mail account, I do receive the test e-mails (Successful). Though, my browser just keeps hanging. I have used the connection timeout setting per
http://www.swiftmailer.org/wikidocs/v3/ ... s/sendmail
..and my test script
testEmail2.php is still reacts the same. Any ideas? The browsers does not timeout it continues to act like its loading the page or awaiting a response somehow and I have to manually stop the page.
Thanks.
Posted: Fri Apr 13, 2007 11:17 am
by Chris Corbyn
You're the second person to tell me of this issue I cannot reproduce (it's the check for the executable). Can I ask if your MTA is postfix? If you don't know, you can check by running this command on the server:
That wil print a line starting with 220. If that line has "postfix" in it then you use postfix which is the same as the other bug-reporter and helps me to narrow this down
The ad-hoc fix (I haven't found an alternative bit of code that doesn't have other drawbacks) is this:
Open Sendmail.php and change the function start() to comment out the following:
Code: Select all
// $test = popen($this->getCommand() . " 2>&1", "r");
// $read = fread($test, 4);
// fclose($test);
// if ((strpos($this->getFlags(), "t") !== false && !empty($read))
// && (substr($read, 0, 4) != "220 "))
// {
// throw new Swift_Connection_Exception(
// "Sendmail cannot be started. The command given [" . $this->getCommand() . "] does not appear to be valid.");
// }
That code is superfluosu anyway if you already know the binary is there.
I am looking into another approach though. I had a simple is_executable() before but a problem was brought to light with this approach.
Posted: Fri Apr 13, 2007 12:06 pm
by chazter6
d11wtq wrote:You're the second person to tell me of this issue I cannot reproduce (it's the check for the executable). Can I ask if your MTA is postfix? If you don't know, you can check by running this command on the server:
That wil print a line starting with 220. If that line has "postfix" in it then you use postfix which is the same as the other bug-reporter and helps me to narrow this down
I dont have command line access to the ISP server but I did call them and they indicated they were using QMAIL as the MTA.
d11wtq wrote:
The ad-hoc fix (I haven't found an alternative bit of code that doesn't have other drawbacks) is this:
Open Sendmail.php and change the function start() to comment out the following:
Code: Select all
// $test = popen($this->getCommand() . " 2>&1", "r");
// $read = fread($test, 4);
// fclose($test);
// if ((strpos($this->getFlags(), "t") !== false && !empty($read))
// && (substr($read, 0, 4) != "220 "))
// {
// throw new Swift_Connection_Exception(
// "Sendmail cannot be started. The command given [" . $this->getCommand() . "] does not appear to be valid.");
// }
That code is superfluosu anyway if you already know the binary is there.
I am looking into another approach though. I had a simple is_executable() before but a problem was brought to light with this approach.
My sendmail.php file has this...It looks a bit different. Is this the same? I am using your version for php4.
Code: Select all
$test = popen($this->getCommand() . " 2>&1", "r");
$read = fread($test, 4);
fclose($test);
if ((strpos($this->getFlags(), "t") !== false && !empty($read))
&& (substr($read, 0, 4) != "220 "))
{
Swift_Errors::trigger(new Swift_Connection_Exception(
"Sendmail cannot be started. The command given [" . $this->getCommand() . "] does not appear to be valid."));
return;
}
UPDATE: I went ahead and commented the php code I had in my sendmail.php out and still go the same result. The browser just hangs.
Posted: Fri Apr 13, 2007 1:29 pm
by Chris Corbyn
What happens if you change this:
Code: Select all
$swift =& new Swift(new Swift_Connection_Sendmail(SWIFT_SENDMAIL_AUTO_DETECT));
To this:
Code: Select all
$swift =& new Swift(new Swift_Connection_Sendmail());
If you can post a phpinfo() showing the value of sendmail_path that would be HUGELY useful

Posted: Fri Apr 13, 2007 2:14 pm
by chazter6
d11wtq wrote:What happens if you change this:
Code: Select all
$swift =& new Swift(new Swift_Connection_Sendmail(SWIFT_SENDMAIL_AUTO_DETECT));
To this:
Code: Select all
$swift =& new Swift(new Swift_Connection_Sendmail());
If you can post a phpinfo() showing the value of sendmail_path that would be HUGELY useful

Sorry, I was out on a lunch...I changed to what you suggested but still the same problem. I am able to receive my test e-mail, but the browser still hangs.
I am going to PM you my link for the PHP Info.
Thanks.
Posted: Thu Apr 19, 2007 11:03 am
by stonedyak
I am having the same problem with the sendmail connection hanging. Commenting out that bit of code did work for me, so I tried testing the popen code on its own:
Code: Select all
$test = popen("/usr/sbin/sendmail -bs 2>&1", "r");
echo "opened connection\n";
$read = fread($test, 4); // this never returns
fclose($test);
echo $read;
The 'hang' occurs on the fread call. If I replace the command with "/bin/echo hello 2>&1", it works perfectly. If I run ps aux | grep sendmail while that script is hanging, I get:
Code: Select all
paul 51960 1.0 0.5 3436 2400 pv S+ 5:02PM 0:00.02 sendmail: server paul@localhost cmd read (sendmail)
paul 51959 0.0 0.2 1632 1048 pv S+ 5:02PM 0:00.00 sh -c /usr/libexec/sendmail/sendmail -bs 2>&1
Running sendmail on the commandline:
Code: Select all
[paul@ra][~] $ /usr/sbin/sendmail -bs 2>&1
220 ra.example.net ESMTP Sendmail 8.13.6/8.13.6/Submit; Thu, 19 Apr 2007 16:53:24 +0100 (BST)
QUIT
221 2.0.0 ra.example.net closing connection
sendmail_path in php.ini is /usr/sbin/sendmail -t -i. I'm running on FreeBSD 6.1
Posted: Thu Apr 19, 2007 11:10 am
by stonedyak
Actually, my previous post is incorrect. I assumed the hang was happening on the fread - actually it was happening on fclose. However, if I remove the fread, and just close the connection without reading anything then it works ok.
Posted: Thu Apr 19, 2007 11:53 am
by Chris Corbyn
stonedyak wrote:Actually, my previous post is incorrect. I assumed the hang was happening on the fread - actually it was happening on fclose. However, if I remove the fread, and just close the connection without reading anything then it works ok.
That's useful to me, thank you

I`m reluctant to go back to the obvious is_executable() check because some servers were reporitng FALSE even when they could successuflly start the process. Maybe some fseek()/fflush() trickery or something will help fix this.
Posted: Fri Apr 20, 2007 3:31 am
by stonedyak
No luck with fflush before or after the fread. Using fseek results in a warning that the 'stream does not support seeking'.
Do you have any other suggestions?
Posted: Fri Apr 20, 2007 6:23 am
by Chris Corbyn
I'll have to have a snoop around the stream functions. Maybe a simple unset() will work. I believe unsetting a resource closes it.
Posted: Fri Apr 20, 2007 6:52 am
by stonedyak
unset() hangs, and so does exit().
Posted: Fri Apr 20, 2007 8:44 am
by stonedyak
Silly question, but why is the popen needed at all? Couldn't you just read from the proc_open pipe and throw an error if you don't get anything?
Posted: Fri Apr 20, 2007 3:08 pm
by Chris Corbyn
stonedyak wrote:Silly question, but why is the popen needed at all? Couldn't you just read from the proc_open pipe and throw an error if you don't get anything?
Not a silly question at all. proc_open() hangs even beyond the 30 second time limit if you try reading from a non-existing process. Reason: it's tryng to read the bash shell. proc_open() *always* returns a process because it uses bash (or sh, or DOS) to launch the process. It sucks.
Posted: Fri Apr 20, 2007 3:10 pm
by Chris Corbyn
Here's a couple of threads I've had here regarding proc_open in the past if it helps with any background info:
viewtopic.php?t=63602&highlight=procopen
viewtopic.php?t=64654&highlight=procopen
Posted: Sat Apr 21, 2007 3:50 pm
by Chris Corbyn
I think I have an inexpensive solution to this and my testing on my server setting all kinds of restrictive permissions (i.e. nothing but execute, no read or write) and using symlinks etc still works.
Simple:
Code: Select all
if (!@stat($this->getPath()))
{
//No use
}
The @ is needed though since it throws a warning without it. Worth a shot
