Skip to content

Commit

Permalink
[mms] Add support for BINARYMIME extension (RFC 3030).
Browse files Browse the repository at this point in the history
  • Loading branch information
slusarz committed Oct 13, 2014
1 parent 57e4b68 commit afabd9d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 24 deletions.
10 changes: 9 additions & 1 deletion framework/Smtp/doc/Horde/Smtp/UPGRADING
Expand Up @@ -16,17 +16,25 @@ Upgrading to 1.7.0

- Horde_Smtp

Added the $data_binary property.

- Constructor

Added the 'chunk_size' parameter.

- send()

Added the 'body' option.
Deprecated the '8bit' option. Use 'body' with Horde_Smtp::BODY_8BIT
argument instead.


Upgrading to 1.6.0
==================

- Horde_Smtp

Added the $data_intl parameter.
Added the $data_intl property.

- send()

Expand Down
90 changes: 67 additions & 23 deletions framework/Smtp/lib/Horde/Smtp.php
Expand Up @@ -22,7 +22,8 @@
* - RFC 2595/4616: TLS & PLAIN (SASL Authentication)
* - RFC 2831: DIGEST-MD5 authentication mechanism (obsoleted by RFC 6331)
* - RFC 2920/STD 60: Pipelining
* - RFC 3030: CHUNKING
* - RFC 3030: SMTP Service Extensions for Transmission of Large and Binary
* MIME Messages
* - RFC 3207: Secure SMTP over TLS
* - RFC 3463: Enhanced Mail System Status Codes
* - RFC 4422: SASL Authentication (for DIGEST-MD5)
Expand All @@ -39,7 +40,6 @@
* <pre>
* - RFC 1845: CHECKPOINT
* - RFC 2852: DELIVERYBY
* - RFC 3030: BINARYMIME
* - RFC 3461: DSN
* - RFC 3865: NO-SOLICITING
* - RFC 3885: MTRK
Expand All @@ -59,6 +59,8 @@
*
* @property-read boolean $data_8bit Does server support sending 8-bit MIME
* data?
* @property-read boolean $data_binary Does server support sending binary
* MIME data? (@since 1.7.0)
* @property-read boolean $data_intl Does server support sending
* internationalized (UTF-8) header data?
* (@since 1.6.0)
Expand All @@ -67,6 +69,12 @@
*/
class Horde_Smtp implements Serializable
{
const BODY_7BIT = 1;
const BODY_8BIT = 2;
const BODY_BINARY = 3;

const CHUNK_DEFAULT = 1048576;

/**
* Connection to the SMTP server.
*
Expand Down Expand Up @@ -174,7 +182,7 @@ public function __construct(array $params = array())
{
// Default values.
$params = array_merge(array(
'chunk_size' => 1048576,
'chunk_size' => self::CHUNK_DEFAULT,
'host' => 'localhost',
'port' => 587,
'secure' => true,
Expand Down Expand Up @@ -255,6 +263,10 @@ public function __get($name)
// RFC 6152
return $this->queryExtension('8BITMIME');

case 'data_binary':
// RFC 3030
return $this->queryExtension('BINARYMIME');

case 'data_intl':
// RFC 6531
return $this->queryExtension('SMTPUTF8');
Expand Down Expand Up @@ -492,9 +504,11 @@ public function logout()
* @param mixed $data The data to send. Either a stream or a string.
* @param array $opts Additional options:
* <pre>
* - 8bit: (boolean) If true, $data is a MIME message with arbitrary
* octet content (i.e. 8-bit encoding).
* DEFAULT: false
* - body: (integer) The encoding type of the message data. (@since
* 1.7.0) One of:
* - Horde_Smtp::BODY_7BIT (Default)
* - Horde_Smtp::BODY_8BIT
* - Horde_Smtp::BODY_BINARY
* - intl: (boolean) If true, $data contains internationalized header
* content (UTF-8). (@since 1.6.0)
* DEFAULT: false
Expand All @@ -512,6 +526,13 @@ public function logout()
*/
public function send($from, $to, $data, array $opts = array())
{
/* BC: support '8bit' option. */
if (!isset($opts['body'])) {
$opts['body'] = empty($opts['8bit'])
? self::BODY_7BIT
: self::BODY_8BIT;
}

$this->login();

if (!($from instanceof Horde_Mail_Rfc822_Address)) {
Expand All @@ -527,22 +548,18 @@ public function send($from, $to, $data, array $opts = array())
}

/* RFC 6531[1.2] requires 8BITMIME to be available. */
$opts['8bit'] = true;
}

/* RFC 6152[3] */
if (!empty($opts['8bit']) && !$this->data_8bit) {
throw new InvalidArgumentException(
'Server does not support sending 8-bit data.'
);
$opts['body'] = self::BODY_8BIT;
}

$mailcmd = 'MAIL FROM:<' .
(empty($opts['intl']) ? $from->bare_address_idn : $from->bare_address) .
'>';

$size = $this->queryExtension('SIZE');

$chunking = $this->queryExtension('CHUNKING');
$chunk_force = false;
$chunk_size = $this->getParam('chunk_size');

// RFC 1870[6]
if ($size || $chunking) {
Expand All @@ -563,13 +580,41 @@ public function send($from, $to, $data, array $opts = array())
$mailcmd .= ' SMTPUTF8';
}

// RFC 6152[3]
if (!empty($opts['8bit'])) {
switch ($opts['body']) {
case self::BODY_BINARY:
// RFC 3030[3]
if (!$this->data_binary) {
throw new InvalidArgumentException(
'Server does not support binary message data.'
);
}
$mailcmd .= ' BODY=BINARYMIME';

/* BINARYMIME requires CHUNKING. */
$chunking = $chunk_force = true;
if (!$chunk_size) {
$chunk_size = self::CHUNK_DEFAULT;
}
break;

case self::BODY_8BIT:
// RFC 6152[3]
if (!$this->data_8bit) {
throw new InvalidArgumentException(
'Server does not support 8-bit message data.'
);
}
$mailcmd .= ' BODY=8BITMIME';
} elseif ($this->_debug->active && $this->data_8bit) {
/* Only output extended 7bit command if debug is active (it is
* default and does not need to be explicitly declared). */
$mailcmd .= ' BODY=7BIT';
break;

case self::BODY_7BIT:
default:
if ($this->_debug->active && $this->data_8bit) {
/* Only output extended 7bit command if debug is active (it is
* default and does not need to be explicitly declared). */
$mailcmd .= ' BODY=7BIT';
}
break;
}

$cmds = array($mailcmd);
Expand Down Expand Up @@ -613,9 +658,8 @@ public function send($from, $to, $data, array $opts = array())
}

/* CHUNKING support. RFC 3030[2] */
if ($chunking &&
($chunk_size = $this->getParam('chunk_size')) &&
($size > $chunk_size)) {
if ($chunking && $chunk_size &&
($chunk_force || ($size > $chunk_size))) {
list($data2, $res) = $this->_prepareData($data);

/* Since we need exact size for chunking purposes, we need to
Expand Down
2 changes: 2 additions & 0 deletions framework/Smtp/package.xml
Expand Up @@ -21,6 +21,7 @@
</stability>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
* [mms] Add support for BINARYMIME extension (RFC 3030).
* [mms] Add support for CHUNKING extension (RFC 3030).
</notes>
<contents>
Expand Down Expand Up @@ -444,6 +445,7 @@
<date>2014-08-04</date>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
* [mms] Add support for BINARYMIME extension (RFC 3030).
* [mms] Add support for CHUNKING extension (RFC 3030).
</notes>
</release>
Expand Down

0 comments on commit afabd9d

Please sign in to comment.