public function testHexDump() { $htmlOutput = false; $uppercase = false; $return = true; $res = MiscHelper::hexdump('FM', $htmlOutput, $uppercase, $return); $this->assertRegExp('/000\\s+46 4d\\s+FM/', $res); $uppercase = true; $res = MiscHelper::hexdump('FM', $htmlOutput, $uppercase, $return); $this->assertRegExp('/000\\s+46 4D\\s+FM/', $res); }
public function __construct($reply_code, $reply_text, $method_sig) { parent::__construct($reply_text, $reply_code); $this->amqp_reply_code = $reply_code; // redundant, but kept for BC $this->amqp_reply_text = $reply_text; // redundant, but kept for BC $this->amqp_method_sig = $method_sig; $ms = MiscHelper::methodSig($method_sig); $mn = isset(AbstractChannel::$GLOBAL_METHOD_NAMES[$ms]) ? AbstractChannel::$GLOBAL_METHOD_NAMES[$ms] : ($mn = ""); $this->args = array($reply_code, $reply_text, $method_sig, $mn); }
/** * @param string $reply_code * @param int $reply_text * @param array $method_sig */ public function __construct($reply_code, $reply_text, $method_sig) { parent::__construct($reply_text, $reply_code); $this->amqp_reply_code = $reply_code; // redundant, but kept for BC $this->amqp_reply_text = $reply_text; // redundant, but kept for BC $this->amqp_method_sig = $method_sig; $ms = MiscHelper::methodSig($method_sig); $protocolClass = AbstractChannel::$PROTOCOL_CONSTANTS_CLASS; $mn = isset($protocolClass::$GLOBAL_METHOD_NAMES[$ms]) ? $protocolClass::$GLOBAL_METHOD_NAMES[$ms] : ($mn = ''); $this->args = array($reply_code, $reply_text, $method_sig, $mn); }
/** * Sets up the socket connection * * @throws \Exception */ public function connect() { $this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); list($sec, $uSec) = MiscHelper::splitSecondsMicroseconds($this->timeout); socket_set_option($this->sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $sec, 'usec' => $uSec)); socket_set_option($this->sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $sec, 'usec' => $uSec)); if (!socket_connect($this->sock, $this->host, $this->port)) { $errno = socket_last_error($this->sock); $errstr = socket_strerror($errno); throw new AMQPIOException(sprintf('Error Connecting to server (%s): %s', $errno, $errstr), $errno); } socket_set_block($this->sock); socket_set_option($this->sock, SOL_TCP, TCP_NODELAY, 1); if ($this->keepalive) { $this->enable_keepalive(); } }
/** * Setup the stream connection * * @throws \PhpAmqpLib\Exception\AMQPRuntimeException * @throws \Exception */ public function connect() { $errstr = $errno = null; if ($this->context) { $remote = sprintf('ssl://%s:%s', $this->host, $this->port); $this->sock = @stream_socket_client($remote, $errno, $errstr, $this->connection_timeout, STREAM_CLIENT_CONNECT, $this->context); } else { $remote = sprintf('tcp://%s:%s', $this->host, $this->port); $this->sock = @stream_socket_client($remote, $errno, $errstr, $this->connection_timeout, STREAM_CLIENT_CONNECT); } if (!$this->sock) { throw new AMQPRuntimeException("Error Connecting to server({$errno}): {$errstr} "); } list($sec, $uSec) = MiscHelper::splitSecondsMicroseconds($this->read_write_timeout); if (!stream_set_timeout($this->sock, $sec, $uSec)) { throw new AMQPIOException("Timeout could not be set"); } stream_set_blocking($this->sock, 1); if ($this->keepalive) { $this->enable_keepalive(); } }
/** * return a failed message */ protected function basic_return($args, $msg) { $reply_code = $args->read_short(); $reply_text = $args->read_shortstr(); $exchange = $args->read_shortstr(); $routing_key = $args->read_shortstr(); if (!is_null($this->basic_return_callback)) { call_user_func_array($this->basic_return_callback, array($reply_code, $reply_text, $exchange, $routing_key, $msg)); } elseif ($this->debug) { MiscHelper::debug_msg("Skipping unhandled basic_return message"); } }
/** * start connection negotiation * * @param AMQPReader $args */ protected function connection_start($args) { $this->version_major = $args->read_octet(); $this->version_minor = $args->read_octet(); $this->server_properties = $args->read_table(); $this->mechanisms = explode(" ", $args->read_longstr()); $this->locales = explode(" ", $args->read_longstr()); if ($this->debug) { MiscHelper::debug_msg(sprintf("Start from server, version: %d.%d, properties: %s, mechanisms: %s, locales: %s", $this->version_major, $this->version_minor, self::dump_table($this->server_properties), implode(', ', $this->mechanisms), implode(', ', $this->locales))); } }
/** * Sets up the stream connection * * @throws \PhpAmqpLib\Exception\AMQPRuntimeException * @throws \Exception */ public function connect() { $errstr = $errno = null; $remote = sprintf('%s://%s:%s', $this->protocol, $this->host, $this->port); set_error_handler(array($this, 'error_handler')); $this->sock = stream_socket_client($remote, $errno, $errstr, $this->connection_timeout, STREAM_CLIENT_CONNECT, $this->context); restore_error_handler(); if (false === $this->sock) { throw new AMQPRuntimeException(sprintf('Error Connecting to server(%s): %s ', $errno, $errstr), $errno); } if (false === stream_socket_get_name($this->sock, true)) { throw new AMQPRuntimeException(sprintf('Connection refused: %s ', $remote)); } list($sec, $uSec) = MiscHelper::splitSecondsMicroseconds($this->read_write_timeout); if (!stream_set_timeout($this->sock, $sec, $uSec)) { throw new AMQPIOException('Timeout could not be set'); } // php cannot capture signals while streams are blocking if ($this->canDispatchPcntlSignal) { stream_set_blocking($this->sock, 0); stream_set_write_buffer($this->sock, 0); if (function_exists('stream_set_read_buffer')) { stream_set_read_buffer($this->sock, 0); } } else { stream_set_blocking($this->sock, 1); } if ($this->keepalive) { $this->enable_keepalive(); } }
/** * Wait for some expected AMQP methods and dispatch to them. * Unexpected methods are queued up for later calls to this PHP * method. * * @param array $allowed_methods * @param bool $non_blocking * @param int $timeout * @return mixed */ public function wait($allowed_methods = null, $non_blocking = false, $timeout = 0) { $PROTOCOL_CONSTANTS_CLASS = self::$PROTOCOL_CONSTANTS_CLASS; if ($allowed_methods && $this->debug) { MiscHelper::debug_msg("waiting for " . implode(", ", $allowed_methods)); } elseif ($this->debug) { MiscHelper::debug_msg("waiting for any method"); } //Process deferred methods foreach ($this->method_queue as $qk => $queued_method) { if ($this->debug) { MiscHelper::debug_msg("checking queue method " . $qk); } $method_sig = $queued_method[0]; if ($allowed_methods == null || in_array($method_sig, $allowed_methods)) { unset($this->method_queue[$qk]); if ($this->debug) { MiscHelper::debug_msg("Executing queued method: {$method_sig}: " . $PROTOCOL_CONSTANTS_CLASS::$GLOBAL_METHOD_NAMES[MiscHelper::methodSig($method_sig)]); } return $this->dispatch($queued_method[0], $queued_method[1], $queued_method[2]); } } // No deferred methods? wait for new ones while (true) { $frm = $this->next_frame($timeout); $frame_type = $frm[0]; $payload = $frm[1]; if ($frame_type != 1) { throw new AMQPRuntimeException("Expecting AMQP method, received frame type: {$frame_type} (" . $PROTOCOL_CONSTANTS_CLASS::$FRAME_TYPES[$frame_type] . ")"); } if (mb_strlen($payload, 'ASCII') < 4) { throw new AMQPOutOfBoundsException("Method frame too short"); } $method_sig_array = unpack("n2", mb_substr($payload, 0, 4, 'ASCII')); $method_sig = "" . $method_sig_array[1] . "," . $method_sig_array[2]; $args = mb_substr($payload, 4, mb_strlen($payload, 'ASCII') - 4, 'ASCII'); if ($this->debug) { MiscHelper::debug_msg("> {$method_sig}: " . $PROTOCOL_CONSTANTS_CLASS::$GLOBAL_METHOD_NAMES[MiscHelper::methodSig($method_sig)]); } if (in_array($method_sig, $PROTOCOL_CONSTANTS_CLASS::$CONTENT_METHODS)) { $content = $this->wait_content(); } else { $content = null; } if ($allowed_methods == null || in_array($method_sig, $allowed_methods) || in_array($method_sig, $PROTOCOL_CONSTANTS_CLASS::$CLOSE_METHODS)) { return $this->dispatch($method_sig, $args, $content); } // Wasn't what we were looking for? save it for later if ($this->debug) { MiscHelper::debug_msg("Queueing for later: {$method_sig}: " . $PROTOCOL_CONSTANTS_CLASS::$GLOBAL_METHOD_NAMES[MiscHelper::methodSig($method_sig)]); } $this->method_queue[] = array($method_sig, $args, $content); if ($non_blocking) { break; } } }
/** * Overrides parent method and creates messages of type \Mopsy\Message * instead of AMQPMessage to gain extra functionality * * (non-PHPdoc) * @see \PhpAmqpLib\Channel\AbstractChannel::wait_content() * * @return Message|\PhpAmqpLib\Message\AMQPMessage * * @throws \PhpAmqpLib\Exception\AMQPRuntimeException */ public function wait_content() { $frame = $this->next_frame(); $frame_type = $frame[0]; $payload = $frame[1]; if ($frame_type != 2) { throw new AMQPRuntimeException("Expecting Content header"); } /* @var $payload_reader \PhpAmqpLib\Wire\AMQPReader */ $payload_reader = $this->container->newInstance('PhpAmqpLib\\Wire\\AMQPReader', array(substr($payload, 0, 12))); // read_short() is like readline // calls must be made - but assignment is not used $payload_reader->read_short(); // $class_id = $payload_reader->read_short(); // $weight = $body_size = $payload_reader->read_longlong(); /* @var $msg Message */ $msg = $this->container->newInstance('Mopsy\\Message', array(array())); $msg->load_properties(substr($payload, 12)); $body_parts = array(); $body_received = 0; while (bccomp($body_size, $body_received) == 1) { $frame = $this->next_frame(); $frame_type = $frame[0]; $payload = $frame[1]; if ($frame_type != 3) { throw new AMQPRuntimeException("Expecting Content body, received frame type {$frame_type} (" . self::$FRAME_TYPES[$frame_type] . ")"); } $body_parts[] = $payload; $body_received = bcadd($body_received, strlen($payload)); } $msg->body = implode("", $body_parts); if ($this->auto_decode && isset($msg->content_encoding)) { try { $msg->body = $msg->body->decode($msg->content_encoding); } catch (\Exception $e) { if ($this->debug) { MiscHelper::debug_msg("Ignoring body decoding exception: " . $e->getMessage()); } } } return $msg; }
/** * Wait until some data is retrieved from the socket. * * AMQPTimeoutException can be raised if the timeout is set * * @throws \PhpAmqpLib\Exception\AMQPTimeoutException */ protected function wait() { if ($this->timeout == 0) { return; } // wait .. list($sec, $usec) = MiscHelper::splitSecondsMicroseconds($this->timeout); $result = $this->io->select($sec, $usec); if ($result === false) { throw new AMQPRuntimeException(sprintf("An error occurs", $this->timeout)); } if ($result === 0) { throw new AMQPTimeoutException(sprintf("A timeout of %ds occurs while waiting for incoming data", $this->timeout)); } }
/** * Waits until some data is retrieved from the socket. * * AMQPTimeoutException can be raised if the timeout is set * * @throws \PhpAmqpLib\Exception\AMQPTimeoutException */ protected function wait() { if ($this->timeout == 0) { return; } // wait .. list($sec, $usec) = MiscHelper::splitSecondsMicroseconds($this->timeout); $result = $this->io->select($sec, $usec); if ($result === false) { throw new AMQPRuntimeException('A network error occured while awaiting for incoming data'); } if ($result === 0) { throw new AMQPTimeoutException(sprintf('The connection timed out after %s sec while awaiting incoming data', $this->getTimeout())); } }
/** * @dataProvider getInputOutputForSplitSecondsMicroseconds * @param mixed $input * @param array $expected */ public function testSplitSecondsMicroseconds($input, $expected) { $this->assertEquals($expected, MiscHelper::splitSecondsMicroseconds($input)); }