/lib/horde/framework/Horde/Imap/Client/Socket/Connection/Socket.php

https://github.com/markn86/moodle · PHP · 222 lines · 126 code · 29 blank · 67 comment · 27 complexity · 0d9080c3a4f459bf813bb6be0b760c46 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright 2013-2017 Horde LLC (http://www.horde.org/)
  4. *
  5. * See the enclosed file LICENSE for license information (LGPL). If you
  6. * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  7. *
  8. * @category Horde
  9. * @copyright 2013-2017 Horde LLC
  10. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11. * @package Imap_Client
  12. */
  13. /**
  14. * PHP stream connection to the IMAP server.
  15. *
  16. * NOTE: This class is NOT intended to be accessed outside of the package.
  17. * There is NO guarantees that the API of this class will not change across
  18. * versions.
  19. *
  20. * @author Michael Slusarz <slusarz@horde.org>
  21. * @category Horde
  22. * @copyright 2013-2017 Horde LLC
  23. * @internal
  24. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  25. * @package Imap_Client
  26. */
  27. class Horde_Imap_Client_Socket_Connection_Socket
  28. extends Horde_Imap_Client_Socket_Connection_Base
  29. {
  30. /**
  31. * If false, does not outpt the current line of client output to debug.
  32. *
  33. * @var boolean
  34. */
  35. public $client_debug = true;
  36. /**
  37. * Sending buffer.
  38. *
  39. * @var string
  40. */
  41. protected $_buffer = '';
  42. /**
  43. * Writes data to the IMAP output stream.
  44. *
  45. * @param string $data String data.
  46. * @param boolean $eol Append EOL?
  47. *
  48. * @throws Horde_Imap_Client_Exception
  49. */
  50. public function write($data, $eol = false)
  51. {
  52. if ($eol) {
  53. $buffer = $this->_buffer;
  54. $debug = $this->client_debug;
  55. $this->_buffer = '';
  56. $this->client_debug = true;
  57. if (fwrite($this->_stream, $buffer . $data . ($eol ? "\r\n" : '')) === false) {
  58. throw new Horde_Imap_Client_Exception(
  59. Horde_Imap_Client_Translation::r("Server write error."),
  60. Horde_Imap_Client_Exception::SERVER_WRITEERROR
  61. );
  62. }
  63. if ($debug) {
  64. $this->_params['debug']->client($buffer . $data);
  65. }
  66. } else {
  67. $this->_buffer .= $data;
  68. }
  69. }
  70. /**
  71. * Writes literal data to the IMAP output stream.
  72. *
  73. * @param mixed $data Either a stream resource, or Horde_Stream
  74. * object.
  75. * @param integer $length The literal length.
  76. * @param boolean $binary If true, this is binary data.
  77. *
  78. * @throws Horde_Imap_Client_Exception
  79. */
  80. public function writeLiteral($data, $length, $binary = false)
  81. {
  82. $this->_buffer = '';
  83. $success = false;
  84. if ($data instanceof Horde_Stream) {
  85. $data = $data->stream;
  86. }
  87. if (rewind($data)) {
  88. $success = true;
  89. while (!feof($data)) {
  90. if ((($read_data = fread($data, 8192)) === false) ||
  91. (fwrite($this->_stream, $read_data) === false)) {
  92. $success = false;
  93. break;
  94. }
  95. }
  96. }
  97. if (!$success) {
  98. $this->client_debug = true;
  99. throw new Horde_Imap_Client_Exception(
  100. Horde_Imap_Client_Translation::r("Server write error."),
  101. Horde_Imap_Client_Exception::SERVER_WRITEERROR
  102. );
  103. }
  104. if ($this->client_debug && !empty($this->_params['debugliteral'])) {
  105. rewind($data);
  106. while (!feof($data)) {
  107. $this->_params['debug']->raw(fread($data, 8192));
  108. }
  109. } else {
  110. $this->_params['debug']->client('[' . ($binary ? 'BINARY' : 'LITERAL') . ' DATA: ' . $length . ' bytes]');
  111. }
  112. }
  113. /**
  114. * Read data from incoming IMAP stream.
  115. *
  116. * @param integer $size UNUSED: The number of bytes to read from the
  117. * socket.
  118. *
  119. * @return Horde_Imap_Client_Tokenize The tokenized data.
  120. *
  121. * @throws Horde_Imap_Client_Exception
  122. */
  123. public function read($size = null)
  124. {
  125. $got_data = false;
  126. $literal_len = null;
  127. $token = new Horde_Imap_Client_Tokenize();
  128. do {
  129. if (feof($this->_stream)) {
  130. $this->close();
  131. $this->_params['debug']->info(
  132. 'ERROR: Server closed the connection.'
  133. );
  134. throw new Horde_Imap_Client_Exception(
  135. Horde_Imap_Client_Translation::r("Mail server closed the connection unexpectedly."),
  136. Horde_Imap_Client_Exception::DISCONNECT
  137. );
  138. }
  139. if (is_null($literal_len)) {
  140. $buffer = '';
  141. while (($in = fgets($this->_stream)) !== false) {
  142. $got_data = true;
  143. if (substr($in, -1) === "\n") {
  144. $in = rtrim($in);
  145. $this->_params['debug']->server($buffer . $in);
  146. $token->add($in);
  147. break;
  148. }
  149. $buffer .= $in;
  150. $token->add($in);
  151. }
  152. /* Check for literal data. */
  153. if (is_null($len = $token->getLiteralLength())) {
  154. break;
  155. }
  156. // Skip 0-length literal data.
  157. if ($len['length']) {
  158. $binary = $len['binary'];
  159. $literal_len = $len['length'];
  160. }
  161. continue;
  162. }
  163. $old_len = $literal_len;
  164. while (($literal_len > 0) && !feof($this->_stream)) {
  165. $in = fread($this->_stream, min($literal_len, 8192));
  166. /* Only store in stream if this is something more than a
  167. * nominal number of bytes. */
  168. if ($old_len > 256) {
  169. $token->addLiteralStream($in);
  170. } else {
  171. $token->add($in);
  172. }
  173. if (!empty($this->_params['debugliteral'])) {
  174. $this->_params['debug']->raw($in);
  175. }
  176. $got_data = true;
  177. $literal_len -= strlen($in);
  178. }
  179. $literal_len = null;
  180. if (empty($this->_params['debugliteral'])) {
  181. $this->_params['debug']->server('[' . ($binary ? 'BINARY' : 'LITERAL') . ' DATA: ' . $old_len . ' bytes]');
  182. }
  183. } while (true);
  184. if (!$got_data) {
  185. $this->_params['debug']->info('ERROR: read/timeout error.');
  186. throw new Horde_Imap_Client_Exception(
  187. Horde_Imap_Client_Translation::r("Error when communicating with the mail server."),
  188. Horde_Imap_Client_Exception::SERVER_READERROR
  189. );
  190. }
  191. return $token;
  192. }
  193. }