142 lines
4.2 KiB
PHP
142 lines
4.2 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (LGPL). If you
|
|
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
|
|
*
|
|
* @category Horde
|
|
* @copyright 2013-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
|
|
* @package Smtp
|
|
*/
|
|
|
|
/**
|
|
* PHP stream connection to a SMTP server.
|
|
*
|
|
* NOTE: This class is NOT intended to be accessed outside of the package.
|
|
* There is NO guarantees that the API of this class will not change across
|
|
* versions.
|
|
*
|
|
* @author Michael Slusarz <slusarz@horde.org>
|
|
* @category Horde
|
|
* @copyright 2013-2017 Horde LLC
|
|
* @internal
|
|
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
|
|
* @package Smtp
|
|
*/
|
|
class Horde_Smtp_Connection extends Horde\Socket\Client
|
|
{
|
|
/**
|
|
* Writes data to the output stream.
|
|
*
|
|
* @param mixed $data String data (or array of string data), or a
|
|
* resource.
|
|
* @param mixed $size If set, the maximum number of octets to send.
|
|
*
|
|
* @throws Horde_Smtp_Exception
|
|
*/
|
|
public function write($data, $size = null)
|
|
{
|
|
if (is_resource($data)) {
|
|
$this->_params['debug']->client('', false);
|
|
$max_size = $size;
|
|
while (!feof($data) && (is_null($size) || ($size > 0))) {
|
|
if (is_null($size)) {
|
|
$c_size = 65536;
|
|
} else {
|
|
$c_size = min($size, 65536);
|
|
$size -= $c_size;
|
|
}
|
|
|
|
$chunk = fread($data, $c_size);
|
|
$this->_params['debug']->raw($chunk);
|
|
|
|
try {
|
|
$this->_write($chunk);
|
|
} catch (Horde_Smtp_Exception $e) {
|
|
$this->_params['debug']->raw("\n");
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
// If we are chunking with BDAT (RFC 3030),
|
|
// we can't send any additional data after
|
|
// the binary data since the server expects
|
|
// the next command immediately after the
|
|
// end of data.
|
|
if (!$max_size) {
|
|
$this->_write("\r\n");
|
|
}
|
|
$this->_params['debug']->raw("\n");
|
|
} else {
|
|
if (!is_array($data)) {
|
|
$data = array($data);
|
|
}
|
|
|
|
foreach ($data as $val) {
|
|
$this->_params['debug']->client($val);
|
|
}
|
|
|
|
$chunk = implode("\r\n", $data);
|
|
if (!is_null($size)) {
|
|
$chunk = substr($chunk, 0, $size);
|
|
}
|
|
|
|
$this->_write($chunk . "\r\n");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes data to the output stream.
|
|
*
|
|
* @param string $data String data.
|
|
*
|
|
* @throws Horde_Smtp_Exception
|
|
*/
|
|
protected function _write($data)
|
|
{
|
|
if (fwrite($this->_stream, $data) === false) {
|
|
throw new Horde_Smtp_Exception(
|
|
Horde_Smtp_Translation::r("Server write error."),
|
|
Horde_Smtp_Exception::SERVER_WRITEERROR
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read data from incoming stream.
|
|
*
|
|
* @param integer $size UNUSED: The number of bytes to read from the
|
|
* socket.
|
|
*
|
|
* @return string Line of data.
|
|
*
|
|
* @throws Horde_Smtp_Exception
|
|
*/
|
|
public function read($size = null)
|
|
{
|
|
if (feof($this->_stream)) {
|
|
$this->close();
|
|
$this->_params['debug']->info("ERROR: Server closed the connection.");
|
|
throw new Horde_Smtp_Exception(
|
|
Horde_Smtp_Translation::r("Server closed the connection unexpectedly."),
|
|
Horde_Smtp_Exception::DISCONNECT
|
|
);
|
|
}
|
|
|
|
if (($read = fgets($this->_stream)) === false) {
|
|
$this->_params['debug']->info("ERROR: Server read/timeout error.");
|
|
throw new Horde_Smtp_Exception(
|
|
Horde_Smtp_Translation::r("Error when communicating with the server."),
|
|
Horde_Smtp_Exception::SERVER_READERROR
|
|
);
|
|
}
|
|
|
|
$this->_params['debug']->server(rtrim($read, "\r\n"));
|
|
|
|
return $read;
|
|
}
|
|
|
|
}
|