-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dev/core#85 On some servers mail() fails when 'Cc' or 'Bcc' headers are defined but empty #12036
Conversation
@mattwire how can make this as specific as possible to keep the risk as low as possible I see in the class this ominous block (which @twomice was last to touch)
I think that is the same mailer & we could possibly do this within that block - which has the added benefit we KNOW empty headers are OK for mail_Mail |
CRM/Utils/Mail.php
Outdated
@@ -289,6 +289,14 @@ public static function send(&$params) { | |||
|
|||
if (is_object($mailer)) { | |||
$errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); | |||
// On some servers mail() fails when 'Cc' or 'Bcc' headers are defined but empty. | |||
// FIXME: Can we unset Cc/Bcc headers for all mail backends if they are empty? | |||
if (empty($headers['Cc'])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mattwire how about moving this code up i.e. point where it is been initialised
- $headers['Cc'] = CRM_Utils_Array::value('cc', $params);
- $headers['Bcc'] = CRM_Utils_Array::value('bcc', $params);
+ foreach (['Cc', 'Bcc'] as $fieldPart) {
+ if (!empty($params[$fieldPart])) {
+ $headers[$fieldPart] = $params[$fieldPart];
+ }
+ }
and then we no longer this code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@monishdeb That makes sense. The only issue, which @eileenmcnaughton has also mentioned, is how we make this low risk as most servers are happy with the empty headers, but clearly some are not! Could we end up in a situation where we apply this patch and find that some servers actually require the empty headers? :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right most conservative possible plse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eileenmcnaughton @mattwire I think it's safe to not set these empty attributes to mail headers. Here's more evidence https://www.drupal.org/project/mimemail/issues/960374 https://stackoverflow.com/questions/44884390/laravel-mail-send-even-if-cc-and-bcc-is-null sendgrid/sendgrid-nodejs#263 where they follow the same logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@monishdeb I think it' safe too - but it still scares me
Also noting some confirmation in the wild - https://issues.civicrm.org/jira/browse/CRM-21801 |
@eileenmcnaughton @monishdeb I've updated this PR with the changes suggested by @monishdeb Will post to dev list for feedback. |
CRM/Utils/Mail.php
Outdated
|
||
// On some servers mail() fails when 'Cc' or 'Bcc' headers are defined but empty. | ||
foreach (['Cc', 'Bcc'] as $optionalHeader) { | ||
if (!empty($params[$optionalHeader])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be:
if (!empty($params[strtolower($optionalHeader]))) {
since it is $params['cc'] lower case in the lines that you are replacing?
I also do not like moving away from the CRM_Utils_Array functions.
How about doing instead:
foreach (['Cc', 'Bcc'] as $optionalHeader) {
$headers[$optionalHeader] = CRM_Utils_Array::value(strtolower($optionalHeader), $params);
if (empty($headers[$optionalHeader])) {
unset($headers[$optionalHeader])
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nganivet do you have any opinion about the safety of the fix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now the fix is non-functional, so needs to be corrected first. Then it would depend on the downstream library's expectations and behavior: does it require $headers['cc'] to be set, even if empty? is it creating the CC header in the outgoing email if the $headers['cc'] is not set? I have not investigated these questions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK @nganivet those questions are the key ones we need to answer. This patch has changed a few times since created & I agree the current iteration needs to do a strtolower comparison - but we really need to answer the bigger question - ie. we know some mail servers fail on an empty cc / bcc but we don't know if any servers REQUIRE cc / bcc to be set EVEN IF EMPTY
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nganivet Thanks for the feedback, I cleaned the patch up and as you spotted it no longer worked because of the lowercase issue. I've now amended it with changes as you suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the final patch and also finds the logic to be safe about not setting cc and bcc attribute. Hence approving this PR
Per @monishdeb comments in gitlab - this seems fairly compelling https://www.drupal.org/project/mimemail/issues/960374 |
Overview
On some servers the PHP mail() function fails to send email if empty 'Cc' or 'Bcc' headers are set.
dev/core#85
Before
Mail cannot be sent, PHP mail() returns false (no error message).
After
Mail is sent, PHP mail() sends.
Technical Details
'Cc' and 'Bcc' headers are optional. Most servers will just ignore them if empty but some seem to fail if they are present but have no email addresses. So we unset them if empty.