php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39507 concurrent attempts to connect to SMTP relay fail miserably
Submitted: 2006-11-13 23:31 UTC Modified: 2021-07-02 13:59 UTC
From: rherror404 at gmail dot com Assigned: cmb (profile)
Status: Closed Package: *General Issues
PHP Version: 5.2.0 OS: Windows
Private report: No CVE-ID: None
 [2006-11-13 23:31 UTC] rherror404 at gmail dot com
Description:
------------
Hitting this script with two concurrent requests causes a failure of both, each reporting different errors.

$ (curl "http://192.168.1.2/error.php" &); (curl "http://192.168.1.2/error.php" &)

$ 
Warning: mail(): SMTP server response: 503 5.0.0 foo.bar.com Duplicate HELO/EHLO in C:\Program Files\Apache Group\Apache2\htdocs\error.php on line 107
FALSE

Warning: mail(): Failed to Receive in C:\Program Files\Apache Group\Apache2\htdocs\error.php on line 107
FALSE

$ 

Reproduce code:
---------------
<?
define('EXTRAHEADERS', "MIME-Version: 1.0\r\nContent-type: text/html; charset=iso-8859-1\r\nX-Mailer: PHP\r\n");
define('MAILMSG',
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
<html><head><title>foo</title><style type='text/css'>
body {margin: 0; font-size: 10pt; font-family: sans-serif, arial; color: #000000; background-color: #ffffff;}
</style></head><body><div style='font-size: 12pt; background-color: #ffff00;'>" . date("Y-m-d H:i:s") . "</div>
random junk<br />" . str_repeat("afhlkhsad;lfj;lkjsa;lfjasd;lkjf;lkjsad;lkfjsad;lkfjsad;lkfjasd;lfkjasd;lkfjsa;ldf<br />\n", 100) .
"</body></html>");
ini_set('html_errors', FALSE);
ini_set('SMTP', '10.1.2.3'); // valid address for a SMTP relay
ini_set('sendmail_from', 'foo <do_not_reply@foo123.com>'); // fake address
define('MAILTO', 'something@thatworks.com'); // something real
$retval = mail(MAILTO, 'foo', MAILMSG, EXTRAHEADERS);
echo ( $retval ? 'TRUE' : 'FALSE' ). "\n\n\n";
exit();
?>

Expected result:
----------------
If I run multiple concurrent requests, then I expect to get multiple emails, one for each request.

Actual result:
--------------
The little shell command where I run two HTTP requests (using cURL in a Cygwin bash) concurrently causes a failure of both, each reporting different errors.  It runs fine otherwise.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-11-13 23:33 UTC] rherror404 at gmail dot com
s/on line 107/on line 14/g
 [2006-11-14 03:51 UTC] rherror404 at gmail dot com
To clarify, the bash snippet should read like this (see below).  Line 14 contains the call to mail().
========================================
$ (curl "http://192.168.1.2/error.php" &); (curl
"http://192.168.1.2/error.php" &)

$ 
Warning: mail(): SMTP server response: 503 5.0.0 foo.bar.com Duplicate
HELO/EHLO in C:\Program Files\Apache Group\Apache2\htdocs\error.php on
line 14
FALSE

Warning: mail(): Failed to Receive in C:\Program Files\Apache
Group\Apache2\htdocs\error.php on line 14
FALSE

$
 [2006-11-14 03:56 UTC] rherror404 at gmail dot com
Is the mail() function sufficiently thread-safe under the Windows MPM (for Apache)?  I have to wonder if the two concurrent threads are stepping on each other in their efforts to talk to the SMTP box.
 [2006-11-14 04:18 UTC] rherror404 at gmail dot com
<?
/*
Here it is again, edited slightly
to run on a Linux machine so that
it has its local sendmail do the work.
Concurrent requests to the script were
handled quite nicely.  The huge difference
in this case is the Apache prefork MPM.
*/
define('EXTRAHEADERS', "MIME-Version: 1.0\r\nContent-type: text/html; charset=iso-8859-1\r\nX-Mailer: PHP\r\n");
define('MAILMSG',
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
<html><head><title>foo</title><style type='text/css'>
body {margin: 0; font-size: 10pt; font-family: sans-serif, arial; color: #000000; background-color: #ffffff;}
</style></head><body><div style='font-size: 12pt; background-color: #ffff00;'>" . date("Y-m-d H:i:s") . "</div>
random junk<br />" .
str_repeat("afhlkhsad;lfj;lkjsa;lfjasd;lkjf;lkjsad;lkfjsad;lkfjsad;lkfja
sd;lfkjasd;lkfjsa;ldf<br />\n", 100) .
"</body></html>");
ini_set('html_errors', FALSE);
define('MAILTO', 'something@thatworks.com'); // something real
$retval = mail(MAILTO, 'foo', MAILMSG, EXTRAHEADERS);
echo ( $retval ? 'TRUE' : 'FALSE' ) . "\n\n\n";
exit();
?>
 [2006-11-14 16:14 UTC] rherror404 at gmail dot com
I suspect this may be the same bug mentioned in #31676.  My best guess is that this is related to multi-threading.
 [2006-11-20 19:42 UTC] rherror404 at gmail dot com
I have found a work-around (not a fix).

Do not rely upon the current mail() (at least under the Apache WinNT MPM) to be of any use for the case where more than one mod_php script is forwarding a message to an SMTP relay host.

Have the mod_php script spawn a child process that takes a bit of serialized state via its STDIN and let the new process do the mail() work.  See the proc_open() docs.

If you have serious volumes of mail to send, either do it from a Linux box or find some other way to do it from your Windows box.  Calling mail() under Windows/Apache/PHP for anything close to that (as it stands) is not advisable.
 [2007-01-07 05:01 UTC] iliaa@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions.  Due to the volume
of reports we can not explain in detail here why your report is not
a bug.  The support channels will be able to provide an explanation
for you.

Thank you for your interest in PHP.

It sounds like SMTP server flood limiter is being triggered 
here. Not a PHP issue.
 [2007-01-07 05:41 UTC] rherror404 at gmail dot com
> It sounds like SMTP server flood
> limiter is being triggered 
> here. Not a PHP issue.
Nice try, but it is a PHP issue, at least under Apache on win32.  I only tried sending only just a few messages at a time.  My earlier remark about "serious volumes" isn't what this bug report is about, it's about being able to send MORE THAN JUST ONE at a time without it stumbling all over itself.  My testing used EXACTLY TWO concurrent attempts.  Please re-read my remarks about execution under the Apache WinNT MPM.

Is the mail() function thread-safe?
 [2009-07-09 19:39 UTC] php at shitware dot nl
I have a simple test script sending out an e-mail message at exactly the same time. One sends to rob@work.com, other to rob@home.com. 'Sometimes' the two get mixed up completely. This is what I received 'at home':


Date: Thu, 09 Jul 2009 17:48:00 +0200
Subject: parallel test
From: rob@work.org
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx"
To: rob@work.com

--==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

parallel test

--==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx
Content-ID: 91ca2796c5b3542ce33422e15c31414d
Content-Type: application/pdf; name="test.pdf"
Content-Transfer-Encoding: base64

JVBERi0xLjMNJeLjz9MNCjcxOCAwIG9iag08PC9MaW5lYXJpemVkIDEvTCAxNzA1NzMvTyA3MjAv
RSAzMTEzNy9OIDYvVCAxNTYxNjUvSCBbIDkzNCAzMTddPj4NZW5kb2JqDSAgICAgICAgICAgICAg
//snip snip -- up until the next 2.5 lines is only part of the attachment
//see where the new 'header' starts ...
YmoNNzMyIDAgb2JqDTw8L0xlbmd0aCA3NDYvRmlsdGVyL0ZsYXRlRGVjb2RlPj5zdHJlYW0NCkiJ
zFdNj9MwEL33V/gPbOoZexxbqiy1aSqBtCdyQwit+DggQBwWiZ/PxB+xs6Vs8fbAwUrsODOTN+/N
OLvTeDpJidJ7Lw7HQWx2UkLvpy+b8Z5n2ElyQorp4+YtP1FWSqN57D1InpDate: Thu, 09 Jul 2009 17:48:00 +0200
Subject: parallel test to rob@home.com at 17:48:00
From: rob@work.com
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx"
To: rob@home.com

--==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

parallel test

--==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx
Content-ID: 91ca2796c5b3542ce33422e15c31414d
Content-Type: application/pdf; name="test.pdf"
Content-Transfer-Encoding: base64

JVBERi0xLjMNJeLjz9MNCjcxOCAwIG9iag08PC9MaW5lYXJpemVkIDEvTCAxNzA1NzMvTyA3MjAv
RSAzMTEzNy9OIDYvVCAxNTYxNjUvSCBbIDkzNCAzMTddPj4NZW5kb2JqDSAgICAgICAgICAgICAg
//snip snip -- full PDF
MDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwMDAwMDAgNjU1MzUgZg0KdHJhaWxlcg0KPDwvU2l6ZSA3
MTg+Pg0Kc3RhcnR4cmVmDQoxMTYNCiUlRU9GDQo=


--==Multipart_Boundary_x0a08807ab511e1f5db827a961c83fe3cx--


We have this same problem on a production site (WAMP) where 'sometimes' e-mail messages and/or attachments end up in 'the wrong place'.

In short: no, the mail() function is not thread-safe!
 [2021-07-02 13:59 UTC] cmb@php.net
-Status: Open +Status: Closed -Type: Feature/Change Request +Type: Bug -Package: Feature/Change Request +Package: *General Issues -Assigned To: +Assigned To: cmb
 [2021-07-02 13:59 UTC] cmb@php.net
This is fixed[1] as of PHP 7.0.0.

[1] <https://github.com/php/php-src/commit/2841aa95db84f3563c94c90f84bf7f47ba159a2d>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 10:01:30 2024 UTC