/** * Read frame * @return bool|Frame */ public function read($timeout = 0) { $this->setTimeout($timeout); $this->isConnected(); // as per protocol COMMAND is 1st \n terminated then headers also \n terminated // COMMAND and header block are seperated by a blank line. $headers_rows = array(); // read command and headers while (($line = @fgets($this->_socket)) !== false) { $headers_rows[] = $line; if (rtrim($line) === '') { break; } } if (count($headers_rows) > 0) { $command = trim($headers_rows[0]); unset($headers_rows[0]); $headers = Frame::extractHeaders($headers_rows); $response = ''; if (!isset($headers[Frame::CONTENT_LENGTH])) { // read till we hit the end of frame marker do { $chunk = @fgets($this->_socket); if ($chunk === false || strlen($chunk) === 0) { $this->_checkSocketReadTimeout(); break; } if (substr($chunk, -2) === Frame::END_OF_FRAME) { // add the chunk above to the result before returning $response .= $chunk; break; } $response .= $chunk; } while (feof($this->_socket) === false); } else { // we have a content-length header set $contentLength = $headers[Frame::CONTENT_LENGTH] + 2; $current_pos = ftell($this->_socket); $chunk = ''; for ($read_to = $current_pos + $contentLength; $read_to > $current_pos; $current_pos = ftell($this->_socket)) { $chunk = fread($this->_socket, $read_to - $current_pos); if ($chunk === false || strlen($chunk) === 0) { $this->_checkSocketReadTimeout(); break; } $response .= $chunk; // Break if the connection ended prematurely if (feof($this->_socket)) { break; } } } return new Frame($command, substr($response, 0, -2), $headers); } else { return false; } }
public function testParseHeaders() { $this->assertEquals(array('version' => '1.0'), \Stomp\Frame::extractHeaders(array('version:1.0'))); $this->assertEquals(array('server' => 'apache-apollo/1.5'), \Stomp\Frame::extractHeaders(array('server:apache-apollo/1.5'))); $this->assertEquals(array('destination' => '/queue/a', 'content-type' => 'text/plain'), \Stomp\Frame::extractHeaders(array('destination:/queue/a', 'content-type:text/plain'))); }