diff --git a/system/autoload/PEAR2/Net/RouterOS/Client.php b/system/autoload/PEAR2/Net/RouterOS/Client.php index 0747e675..eb75caf5 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Client.php +++ b/system/autoload/PEAR2/Net/RouterOS/Client.php @@ -19,21 +19,25 @@ /** * The namespace declaration. */ + namespace PEAR2\Net\RouterOS; /** * Refers to transmitter direction constants. */ + use PEAR2\Net\Transmitter\Stream as S; /** * Refers to the cryptography constants. */ + use PEAR2\Net\Transmitter\NetworkStream as N; /** * Catches arbitrary exceptions at some points. */ + use Exception as E; /** @@ -108,11 +112,12 @@ class Client protected $registry = null; /** - * Whether to stream future responses. + * Stream response words that are above this many bytes. + * NULL to disable streaming completely. * - * @var bool + * @var int|null */ - private $_streamingResponses = false; + private $_streamingResponses = null; /** * Creates a new instance of a RouterOS API client. @@ -167,7 +172,7 @@ class Client : (int) $timeout; //Login the user if necessary if ((!$persist - || !($old = $this->com->getTransmitter()->lock(S::DIRECTION_ALL))) + || !($old = $this->com->getTransmitter()->lock(S::DIRECTION_ALL))) && $this->com->getTransmitter()->isFresh() ) { if (!static::login($this->com, $username, $password, $timeout)) { @@ -233,7 +238,8 @@ class Client $password = '', $timeout = null ) { - if (null !== ($remoteCharset = $com->getCharset($com::CHARSET_REMOTE)) + if ( + null !== ($remoteCharset = $com->getCharset($com::CHARSET_REMOTE)) && null !== ($localCharset = $com->getCharset($com::CHARSET_LOCAL)) ) { $password = iconv( @@ -256,8 +262,8 @@ class Client $com->getTransmitter()->lock($old, true); } throw ($e instanceof NotSupportedException - || $e instanceof UnexpectedValueException - || !$com->getTransmitter()->isDataAwaiting()) ? new SocketException( + || $e instanceof UnexpectedValueException + || !$com->getTransmitter()->isDataAwaiting()) ? new SocketException( 'This is not a compatible RouterOS service', SocketException::CODE_SERVICE_INCOMPATIBLE, $e @@ -287,30 +293,47 @@ class Client $timeout = null ) { $request = new Request('/login'); - $request->send($com); - $response = new Response($com, false, $timeout); $request->setArgument('name', $username); $request->setArgument('password', $password); - // $request->setArgument( - // 'response', - // '00' . md5( - // chr(0) . $password - // . pack('H*', $response->getProperty('ret')) - // ) - // ); + $oldCharset = $com->getCharset($com::CHARSET_ALL); + $com->setCharset(null, $com::CHARSET_ALL); $request->verify($com)->send($com); - + $com->setCharset($oldCharset, $com::CHARSET_ALL); $response = new Response($com, false, $timeout); - if ($response->getType() === Response::TYPE_FINAL) { - return null === $response->getProperty('ret'); - } else { - while ($response->getType() !== Response::TYPE_FINAL - && $response->getType() !== Response::TYPE_FATAL - ) { - $response = new Response($com, false, $timeout); + if ( + $response->getType() === Response::TYPE_FINAL + && null === $response->getProperty('ret') + ) { + // version >= 6.43 + return null === $response->getProperty('message'); + } elseif ($response->getType() === Response::TYPE_FINAL) { + // version < 6.43 + $request->setArgument('password', ''); + $request->setArgument( + 'response', + '00' . md5( + chr(0) . $password + . pack( + 'H*', + is_string($response->getProperty('ret')) + ? $response->getProperty('ret') + : stream_get_contents($response->getProperty('ret')) + ) + ) + ); + $request->verify($com)->send($com); + $response = new Response($com, false, $timeout); + if ($response->getType() === Response::TYPE_FINAL) { + return null === $response->getProperty('ret'); } - return false; } + while ( + $response->getType() !== Response::TYPE_FINAL + && $response->getType() !== Response::TYPE_FATAL + ) { + $response = new Response($com, false, $timeout); + } + return false; } /** @@ -322,7 +345,7 @@ class Client * {@link Communicator::CHARSET_REMOTE}, and when receiving, * {@link Communicator::CHARSET_REMOTE} is converted to * {@link Communicator::CHARSET_LOCAL}. Setting NULL to either charset will - * disable charset convertion, and data will be both sent and received "as + * disable charset conversion, and data will be both sent and received "as * is". * * @param mixed $charset The charset to set. If $charsetType is @@ -387,7 +410,7 @@ class Client { //Error checking $tag = $request->getTag(); - if ('' == $tag) { + if ('' === (string)$tag) { throw new DataFlowException( 'Asynchonous commands must have a tag.', DataFlowException::CODE_TAG_REQUIRED @@ -487,7 +510,7 @@ class Client $result = $hasNoTag ? array() : $this->extractNewResponses($tag)->toArray(); while ((!$hasNoTag && $this->isRequestActive($tag)) - || ($hasNoTag && 0 !== $this->getPendingRequestsCount()) + || ($hasNoTag && 0 !== $this->getPendingRequestsCount()) ) { $newReply = $this->dispatchNextResponse(null); if ($newReply->getTag() === $tag) { @@ -499,8 +522,8 @@ class Client $result = array_merge( $result, $this->isRequestActive($tag) - ? $this->extractNewResponses($tag)->toArray() - : array() + ? $this->extractNewResponses($tag)->toArray() + : array() ); } break; @@ -582,7 +605,8 @@ class Client } } else { list($usStart, $sStart) = explode(' ', microtime()); - while ($this->getPendingRequestsCount() !== 0 + while ( + $this->getPendingRequestsCount() !== 0 && ($sTimeout >= 0 || $usTimeout >= 0) ) { $this->dispatchNextResponse($sTimeout, $usTimeout); @@ -647,7 +671,7 @@ class Client public function cancelRequest($tag = null) { $cancelRequest = new Request('/cancel'); - $hasTag = !('' == $tag); + $hasTag = !('' === (string)$tag); $hasReg = null !== $this->registry; if ($hasReg && !$hasTag) { $tags = array_merge( @@ -703,34 +727,39 @@ class Client /** * Sets response streaming setting. * - * Sets whether future responses are streamed. If responses are streamed, - * the argument values are returned as streams instead of strings. This is - * particularly useful if you expect a response that may contain one or more - * very large words. + * Sets when future response words are streamed. If a word is streamed, + * the property value is returned a stream instead of a string, and + * unrecognized words are returned entirely as streams instead of strings. + * This is particularly useful if you expect a response that may contain + * one or more very large words. * - * @param bool $streamingResponses Whether to stream future responses. + * @param int|null $threshold Threshold after which to stream + * a word. That is, a word less than this length will not be streamed. + * If set to 0, effectively all words are streamed. + * NULL to disable streaming altogether. * - * @return bool The previous value of the setting. + * @return $this The client object. * - * @see isStreamingResponses() + * @see getStreamingResponses() */ - public function setStreamingResponses($streamingResponses) + public function setStreamingResponses($threshold) { - $oldValue = $this->_streamingResponses; - $this->_streamingResponses = (bool) $streamingResponses; - return $oldValue; + $this->_streamingResponses = $threshold === null + ? null + : (int) $threshold; + return $this; } /** * Gets response streaming setting. * - * Gets whether future responses are streamed. + * Gets when future response words are streamed. * - * @return bool The value of the setting. + * @return int|null The value of the setting. * * @see setStreamingResponses() */ - public function isStreamingResponses() + public function getStreamingResponses() { return $this->_streamingResponses; } @@ -822,8 +851,8 @@ class Client * If NULL, wait indefinitely. * @param int $usTimeout Microseconds to add to the waiting time. * + * @return Response The dispatched response. * @throws SocketException When there's no response within the time limit. - * @return Response The dispatched response. */ protected function dispatchNextResponse($sTimeout = 0, $usTimeout = 0) { @@ -846,13 +875,14 @@ class Client $this->pendingRequestsCount--; } - if ('' != $tag) { + if ('' !== (string)$tag) { if ($this->isRequestActive($tag, self::FILTER_CALLBACK)) { if ($this->callbacks[$tag]($response, $this)) { try { $this->cancelRequest($tag); } catch (DataFlowException $e) { - if ($e->getCode() !== DataFlowException::CODE_UNKNOWN_REQUEST + if ( + $e->getCode() !== $e::CODE_UNKNOWN_REQUEST ) { throw $e; }