Branch for testing SMTP message limit patch by Carl Corliss
This commit is contained in:
parent
5aeead7e70
commit
76a3eb79b1
|
|
@ -527,6 +527,41 @@ class PHPMailer {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends out the list of recipients to the smtp server, checking
|
||||
* for a 45X failure while doing so.
|
||||
*
|
||||
* @param Array $recipients List of recipients to set up
|
||||
* @param Array &$bad_recipients Reference to an array that will be filled with the list of recipients who failed during this run
|
||||
* @param Bool &$was_throttled Reference to a boolean that will bet set based on whether or not the connection appeared to be throttled
|
||||
* @param Integer &$throttle_total Reference to a total that will be set to the total recipients that were successfully added if throttling happened
|
||||
* @access public
|
||||
* @return Bool
|
||||
* Carl Corliss <rabbitt at users.sourceforge.net>
|
||||
*/
|
||||
function SmtpSend_AddRecipients($recipients, &$bad_recipients = array(), &$was_throttled = false, &$throttle_total = -1) {
|
||||
|
||||
$total_recipients = count($recipients);
|
||||
$return_value = true;
|
||||
|
||||
for ($i = 0; $i < $total_recipients; $i++) {
|
||||
if (!$this->smtp->Recipient($recipients[$i])) {
|
||||
$error = $this->smtp->getLastError();
|
||||
if (isset($error['smtp_code']) &&
|
||||
($error['smtp_code'] == 451 || $error['smtp_code'] == 452)) {
|
||||
$was_throttled = true;
|
||||
$throttle_total = ($i - 1);
|
||||
$return_value = false;
|
||||
break;
|
||||
} else {
|
||||
$bad_recipients[] = $recipients[$i];
|
||||
$return_value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends mail via SMTP using PhpSMTP
|
||||
* Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
|
||||
|
|
@ -537,7 +572,6 @@ class PHPMailer {
|
|||
*/
|
||||
public function SmtpSend($header, $body) {
|
||||
include_once($this->PluginDir . 'class.smtp.php');
|
||||
$error = '';
|
||||
$bad_rcpt = array();
|
||||
|
||||
if(!$this->SmtpConnect()) {
|
||||
|
|
@ -546,55 +580,86 @@ class PHPMailer {
|
|||
|
||||
$smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
|
||||
if(!$this->smtp->Mail($smtp_from)) {
|
||||
$error = $this->Lang('from_failed') . $smtp_from;
|
||||
$this->SetError($error);
|
||||
$this->SetError($this->Lang('from_failed') . $smtp_from);
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Attempt to send attach all recipients */
|
||||
for($i = 0; $i < count($this->to); $i++) {
|
||||
if(!$this->smtp->Recipient($this->to[$i][0])) {
|
||||
$bad_rcpt[] = $this->to[$i][0];
|
||||
}
|
||||
}
|
||||
for($i = 0; $i < count($this->cc); $i++) {
|
||||
if(!$this->smtp->Recipient($this->cc[$i][0])) {
|
||||
$bad_rcpt[] = $this->cc[$i][0];
|
||||
}
|
||||
}
|
||||
for($i = 0; $i < count($this->bcc); $i++) {
|
||||
if(!$this->smtp->Recipient($this->bcc[$i][0])) {
|
||||
$bad_rcpt[] = $this->bcc[$i][0];
|
||||
/* Build recipient list */
|
||||
$all_recipients = array_map(
|
||||
create_function('$a', 'return $a[0];'),
|
||||
array_merge($this->to, $this->cc, $this->bcc)
|
||||
);
|
||||
|
||||
/* Attempt to add all recipients (to, cc, and bcc) */
|
||||
$this->SmtpSend_AddRecipients($all_recipients, $bad_rcpt, $was_throttled, $throttle_total);
|
||||
|
||||
// If the attempt failed and it looked like a throttle, split the list into smaller 'buckets'
|
||||
// and then send each bucket individually. We figure out the size of each bucket based on the
|
||||
// number of recipients that were accepted before we recieved the throttle 45X error.
|
||||
if ($was_throttled && $this->smtp->Reset()) {
|
||||
// Split recipients into roughly equal buckets
|
||||
for ($i = 0; $i < count($all_recipients); $i++) {
|
||||
$buckets[$i] = array_splice($all_recipients, 0, $throttle_total);
|
||||
}
|
||||
|
||||
foreach ($buckets as $bucket) {
|
||||
if (!$this->smtp->Mail($smtp_from)) {
|
||||
$this->SetError($this->Lang('from_failed') . $smtp_from);
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(count($bad_rcpt) > 0) { // Create error message
|
||||
for($i = 0; $i < count($bad_rcpt); $i++) {
|
||||
if($i != 0) {
|
||||
$error .= ', ';
|
||||
if (!$this->SmtpSend_AddRecipients($bucket, $bad_rcpt, $was_throttled)) {
|
||||
if (!$was_throttled && !count($bad_rcpt)) {
|
||||
$this->SetError($this->Lang('recipients_failed') . join(', ', $bucket));
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($bad_rcpt) > 0) { // Create error message
|
||||
$this->SetError('Error Unknown: ' . $this->Lang('recipients_failed') . join(', ', $bad_rcpt));
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->smtp->Data($header . $body)) {
|
||||
$this->SetError($this->Lang('data_not_accepted'));
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->smtp->Reset();
|
||||
}
|
||||
$error .= $bad_rcpt[$i];
|
||||
|
||||
if ($this->SMTPKeepAlive == true) {
|
||||
$this->smtp->Reset();
|
||||
} else {
|
||||
$this->SmtpClose();
|
||||
}
|
||||
$error = $this->Lang('recipients_failed') . $error;
|
||||
$this->SetError($error);
|
||||
|
||||
} else { // No problems adding recipients - proceed normally
|
||||
if (count($bad_rcpt) > 0) { // Create error message
|
||||
$this->SetError('Unknown Error: ' . $this->Lang('recipients_failed') . join(', ', $bad_rcpt));
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->smtp->Data($header . $body)) {
|
||||
if (!$this->smtp->Data($header . $body)) {
|
||||
$this->SetError($this->Lang('data_not_accepted'));
|
||||
$this->smtp->Reset();
|
||||
return false;
|
||||
}
|
||||
if($this->SMTPKeepAlive == true) {
|
||||
|
||||
if ($this->SMTPKeepAlive == true) {
|
||||
$this->smtp->Reset();
|
||||
} else {
|
||||
$this->SmtpClose();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a connection to an SMTP server.
|
||||
|
|
|
|||
|
|
@ -90,6 +90,17 @@ class SMTP {
|
|||
$this->do_debug = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last error emitted by the SMTP server. This
|
||||
* is reset to null on each new command call.
|
||||
*
|
||||
* @access public
|
||||
* @return Array containing error message and code or NULL
|
||||
*/
|
||||
public function getLastError() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* CONNECTION FUNCTIONS *
|
||||
***********************************************************/
|
||||
|
|
@ -181,7 +192,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
|
||||
$this->client_send("STARTTLS" . $extra . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -217,7 +228,7 @@ class SMTP {
|
|||
*/
|
||||
public function Authenticate($username, $password) {
|
||||
// Start authentication
|
||||
fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
|
||||
$this->client_send("AUTH LOGIN" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -235,7 +246,7 @@ class SMTP {
|
|||
}
|
||||
|
||||
// Send encoded username
|
||||
fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
|
||||
$this->client_send(base64_encode($username) . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -253,7 +264,7 @@ class SMTP {
|
|||
}
|
||||
|
||||
// Send encoded password
|
||||
fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
|
||||
$this->client_send(base64_encode($password) . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -345,7 +356,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"DATA" . $this->CRLF);
|
||||
$this->client_send("DATA" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -435,13 +446,13 @@ class SMTP {
|
|||
$line_out = "." . $line_out;
|
||||
}
|
||||
}
|
||||
fputs($this->smtp_conn,$line_out . $this->CRLF);
|
||||
$this->client_send($line_out . $this->CRLF);
|
||||
}
|
||||
}
|
||||
|
||||
// ok all the message data has been sent so lets get this
|
||||
// over with aleady
|
||||
fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
|
||||
$this->client_send($this->CRLF . "." . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -489,7 +500,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
|
||||
$this->client_send("EXPN " . $name . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -564,7 +575,7 @@ class SMTP {
|
|||
* @return bool
|
||||
*/
|
||||
private function SendHello($hello, $host) {
|
||||
fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
|
||||
$this->client_send($hello . " " . $host . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -619,7 +630,7 @@ class SMTP {
|
|||
$extra = " " . $keyword;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
|
||||
$this->client_send("HELP" . $extra . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -667,7 +678,7 @@ class SMTP {
|
|||
}
|
||||
|
||||
$useVerp = ($this->do_verp ? "XVERP" : "");
|
||||
fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
|
||||
$this->client_send("MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -709,7 +720,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"NOOP" . $this->CRLF);
|
||||
$this->client_send("NOOP" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -753,7 +764,7 @@ class SMTP {
|
|||
}
|
||||
|
||||
// send the quit command to the server
|
||||
fputs($this->smtp_conn,"quit" . $this->CRLF);
|
||||
$this->client_send("quit" . $this->CRLF);
|
||||
|
||||
// get any good-bye messages
|
||||
$byemsg = $this->get_lines();
|
||||
|
|
@ -806,7 +817,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
|
||||
$this->client_send("RCPT TO:<" . $to . ">" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -850,7 +861,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"RSET" . $this->CRLF);
|
||||
$this->client_send("RSET" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -899,7 +910,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
|
||||
$this->client_send("SEND FROM:" . $from . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -947,7 +958,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
|
||||
$this->client_send("SAML FROM:" . $from . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -995,7 +1006,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
|
||||
$this->client_send("SOML FROM:" . $from . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -1062,7 +1073,7 @@ class SMTP {
|
|||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
|
||||
$this->client_send("VRFY " . $name . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
|
@ -1085,6 +1096,19 @@ class SMTP {
|
|||
return $rply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends data to the server
|
||||
*
|
||||
* @access public
|
||||
* @return Integer number of bytes sent to the server or FALSE on error
|
||||
*/
|
||||
public function client_send($data) {
|
||||
if ($this->do_debug >= 1) {
|
||||
echo "CLIENT -> SMTP: $data";
|
||||
}
|
||||
return fputs($this->smtp_conn, $data);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* INTERNAL FUNCTIONS *
|
||||
******************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue