diff options
author | Yuchen Pei <hi@ypei.me> | 2021-10-14 15:16:42 +1100 |
---|---|---|
committer | Yuchen Pei <hi@ypei.me> | 2021-10-14 15:16:42 +1100 |
commit | 07f5140771388c9e0c8a99b0dd2e5d950bdb173b (patch) | |
tree | 323c00faef1edc7dea2e88ff581cc2258b2b6432 /External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php | |
parent | e119be145500700f3c465e12664403a07530a421 (diff) |
moving h-source subdir out.
Diffstat (limited to 'External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php')
-rwxr-xr-x | External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php b/External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php new file mode 100755 index 0000000..01ae8a5 --- /dev/null +++ b/External/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php @@ -0,0 +1,276 @@ +<?php + +/* + * This file is part of SwiftMailer. + * (c) 2004-2009 Chris Corbyn + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +//@require 'Swift/ByteStream/AbstractFilterableInputStream.php'; +//@require 'Swift/ReplacementFilterFactory.php'; +//@require 'Swift/Transport/IoBuffer.php'; +//@require 'Swift/TransportException.php'; + +/** + * A generic IoBuffer implementation supporting remote sockets and local processes. + * @package Swift + * @subpackage Transport + * @author Chris Corbyn + */ +class Swift_Transport_StreamBuffer + extends Swift_ByteStream_AbstractFilterableInputStream + implements Swift_Transport_IoBuffer +{ + + /** A primary socket */ + private $_stream; + + /** The input stream */ + private $_in; + + /** The output stream */ + private $_out; + + /** Buffer initialization parameters */ + private $_params = array(); + + /** The ReplacementFilterFactory */ + private $_replacementFactory; + + /** Translations performed on data being streamed into the buffer */ + private $_translations = array(); + + /** + * Create a new StreamBuffer using $replacementFactory for transformations. + * @param Swift_ReplacementFilterFactory $replacementFactory + */ + public function __construct( + Swift_ReplacementFilterFactory $replacementFactory) + { + $this->_replacementFactory = $replacementFactory; + } + + /** + * Perform any initialization needed, using the given $params. + * Parameters will vary depending upon the type of IoBuffer used. + * @param array $params + */ + public function initialize(array $params) + { + $this->_params = $params; + switch ($params['type']) + { + case self::TYPE_PROCESS: + $this->_establishProcessConnection(); + break; + case self::TYPE_SOCKET: + default: + $this->_establishSocketConnection(); + break; + } + } + + /** + * Set an individual param on the buffer (e.g. switching to SSL). + * @param string $param + * @param mixed $value + */ + public function setParam($param, $value) + { + if (isset($this->_stream)) + { + switch ($param) + { + case 'protocol': + if (!array_key_exists('protocol', $this->_params) + || $value != $this->_params['protocol']) + { + if ('tls' == $value) + { + stream_socket_enable_crypto( + $this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT + ); + } + } + break; + } + } + $this->_params[$param] = $value; + } + + /** + * Perform any shutdown logic needed. + */ + public function terminate() + { + if (isset($this->_stream)) + { + switch ($this->_params['type']) + { + case self::TYPE_PROCESS: + fclose($this->_in); + fclose($this->_out); + proc_close($this->_stream); + break; + case self::TYPE_SOCKET: + default: + fclose($this->_stream); + break; + } + } + $this->_stream = null; + $this->_out = null; + $this->_in = null; + } + + /** + * Set an array of string replacements which should be made on data written + * to the buffer. This could replace LF with CRLF for example. + * @param string[] $replacements + */ + public function setWriteTranslations(array $replacements) + { + foreach ($this->_translations as $search => $replace) + { + if (!isset($replacements[$search])) + { + $this->removeFilter($search); + unset($this->_translations[$search]); + } + } + + foreach ($replacements as $search => $replace) + { + if (!isset($this->_translations[$search])) + { + $this->addFilter( + $this->_replacementFactory->createFilter($search, $replace), $search + ); + $this->_translations[$search] = true; + } + } + } + + /** + * Get a line of output (including any CRLF). + * The $sequence number comes from any writes and may or may not be used + * depending upon the implementation. + * @param int $sequence of last write to scan from + * @return string + */ + public function readLine($sequence) + { + if (isset($this->_out) && !feof($this->_out)) + { + $line = fgets($this->_out); + return $line; + } + } + + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. If less bytes exist than are requested the + * remaining bytes are given instead. If no bytes are remaining at all, boolean + * false is returned. + * @param int $length + * @return string + */ + public function read($length) + { + if (isset($this->_out) && !feof($this->_out)) + { + $ret = fread($this->_out, $length); + return $ret; + } + } + + /** Not implemented */ + public function setReadPointer($byteOffset) + { + } + + // -- Protected methods + + /** Flush the stream contents */ + protected function _flush() + { + if (isset($this->_in)) + { + fflush($this->_in); + } + } + + /** Write this bytes to the stream */ + protected function _commit($bytes) + { + if (isset($this->_in) + && fwrite($this->_in, $bytes)) + { + return ++$this->_sequence; + } + } + + // -- Private methods + + /** + * Establishes a connection to a remote server. + * @access private + */ + private function _establishSocketConnection() + { + $host = $this->_params['host']; + if (!empty($this->_params['protocol'])) + { + $host = $this->_params['protocol'] . '://' . $host; + } + $timeout = 15; + if (!empty($this->_params['timeout'])) + { + $timeout = $this->_params['timeout']; + } + if (!$this->_stream = fsockopen($host, $this->_params['port'], $errno, $errstr, $timeout)) + { + throw new Swift_TransportException( + 'Connection could not be established with host ' . $this->_params['host'] . + ' [' . $errstr . ' #' . $errno . ']' + ); + } + if (!empty($this->_params['blocking'])) + { + stream_set_blocking($this->_stream, 1); + } + else + { + stream_set_blocking($this->_stream, 0); + } + $this->_in =& $this->_stream; + $this->_out =& $this->_stream; + } + + /** + * Opens a process for input/output. + * @access private + */ + private function _establishProcessConnection() + { + $command = $this->_params['command']; + $descriptorSpec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + $this->_stream = proc_open($command, $descriptorSpec, $pipes); + stream_set_blocking($pipes[2], 0); + if ($err = stream_get_contents($pipes[2])) + { + throw new Swift_TransportException( + 'Process could not be started [' . $err . ']' + ); + } + $this->_in =& $pipes[0]; + $this->_out =& $pipes[1]; + } + +} |