public function testParserWillWaitForFullContentLength() { // Make our body and split it up. $body = "Testbody withNULL octets."; $body_parts = str_split($body, 5); // Send our header. $content_length = (string) strlen($body); $this->parser->addData("MESSAGE\ncontent-length:{$content_length}\n\n"); // This should not parse yet. $this->assertFalse($this->parser->parse()); // Remove our last part so we can loop over the rest. $last_body_part = array_pop($body_parts); // Send our parts, checking that we don't parse. foreach ($body_parts as $part) { $this->parser->addData($part); $this->assertFalse($this->parser->parse()); } // Adding our last part should allow it to parse. $this->parser->addData($last_body_part); $this->assertTrue($this->parser->parse()); // Check our frame matches our expectation. $expected = new Frame('MESSAGE', ['content-length' => $content_length], $body); $actual = $this->parser->getFrame(); $this->assertEquals($expected, $actual); }
/** * Try to read a frame from the server. * * @return Frame|false when no frame to read * @throws ConnectionException * @throws ErrorFrameException */ public function readFrame() { if (!$this->hasDataToRead()) { return false; } // See if there are newlines waiting to be processed (some brokers send empty lines as heartbeat) $this->gobbleNewLines(); do { $read = @stream_get_line($this->connection, 8192, Parser::FRAME_END); if ($read === false) { throw new ConnectionException('Was not possible to read data from stream.', $this->activeHost); } $this->parser->addData($read); // Include zero-byte back at the end if (strlen($read) != 8192) { $this->parser->addData(Parser::FRAME_END); } } while (!$this->parser->parse()); // See if there are newlines after the \0 $this->gobbleNewLines(); $frame = $this->parser->getFrame(); if ($frame->isErrorFrame()) { throw new ErrorFrameException($frame); } return $frame; }