Merge branch '0.4-merge-0.3.4' into 0.4
This commit is contained in:
commit
e463de0c6b
@ -4,6 +4,8 @@ php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7
|
||||
- hhvm
|
||||
|
||||
before_script:
|
||||
|
15
CHANGELOG.md
15
CHANGELOG.md
@ -8,6 +8,21 @@ CHANGELOG
|
||||
|
||||
---
|
||||
|
||||
* 0.3.4 (2015-12-23)
|
||||
|
||||
* BF: Edge case where version check wasn't run on message coalesce
|
||||
* BF: Session didn't start when using pdo_sqlite
|
||||
* BF: WAMP currie prefix check when using '#'
|
||||
* Compatibility with Symfony 3
|
||||
|
||||
* 0.3.3 (2015-05-26)
|
||||
|
||||
* BF: Framing bug on large messages upon TCP fragmentation
|
||||
* BF: Symfony Router query parameter defaults applied to Request
|
||||
* BF: WAMP CURIE on all URIs
|
||||
* OriginCheck rules applied to FlashPolicy
|
||||
* Switched from PSR-0 to PSR-4
|
||||
|
||||
* 0.3.2 (2014-06-08)
|
||||
|
||||
* BF: No messages after closing handshake (fixed rare race condition causing 100% CPU)
|
||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2011-2014 Chris Boden
|
||||
Copyright (c) 2011-2016 Chris Boden
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -1,7 +1,7 @@
|
||||
#Ratchet
|
||||
|
||||
[](http://travis-ci.org/cboden/Ratchet)
|
||||
[](https://packagist.org/packages/cboden/Ratchet)
|
||||
[](http://travis-ci.org/ratchetphp/Ratchet)
|
||||
[](https://packagist.org/packages/cboden/ratchet)
|
||||
|
||||
A PHP 5.3 library for asynchronously serving WebSockets.
|
||||
Build up your application through simple interfaces and re-use your application without changing any of its code just by combining different components.
|
||||
|
@ -14,19 +14,19 @@
|
||||
]
|
||||
, "support": {
|
||||
"forum": "https://groups.google.com/forum/#!forum/ratchet-php"
|
||||
, "issues": "https://github.com/cboden/Ratchet/issues"
|
||||
, "issues": "https://github.com/ratchetphp/Ratchet/issues"
|
||||
, "irc": "irc://irc.freenode.org/reactphp"
|
||||
}
|
||||
, "autoload": {
|
||||
"psr-0": {
|
||||
"Ratchet": "src"
|
||||
"psr-4": {
|
||||
"Ratchet\\": "src/Ratchet"
|
||||
}
|
||||
}
|
||||
, "require": {
|
||||
"php": ">=5.3.9"
|
||||
, "react/socket": "0.3.*|0.4.*"
|
||||
, "guzzle/http": "~3.6"
|
||||
, "symfony/http-foundation": "~2.2"
|
||||
, "symfony/routing": "~2.2"
|
||||
, "react/socket": "^0.3 || ^0.4"
|
||||
, "guzzle/http": "^3.6"
|
||||
, "symfony/http-foundation": "^2.2|^3.0"
|
||||
, "symfony/routing": "^2.2|^3.0"
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,12 @@ class App {
|
||||
*/
|
||||
protected $httpHost;
|
||||
|
||||
/***
|
||||
* The port the socket is listening
|
||||
* @var int
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
@ -56,7 +62,7 @@ class App {
|
||||
*/
|
||||
public function __construct($httpHost = 'localhost', $port = 8080, $address = '127.0.0.1', LoopInterface $loop = null) {
|
||||
if (extension_loaded('xdebug')) {
|
||||
trigger_error("XDebug extension detected. Remember to disable this if performance testing or going live!", E_USER_WARNING);
|
||||
trigger_error('XDebug extension detected. Remember to disable this if performance testing or going live!', E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (3 !== strlen('✓')) {
|
||||
@ -68,6 +74,7 @@ class App {
|
||||
}
|
||||
|
||||
$this->httpHost = $httpHost;
|
||||
$this->port = $port;
|
||||
|
||||
$socket = new Reactor($loop);
|
||||
$socket->listen($port, $address);
|
||||
@ -80,7 +87,6 @@ class App {
|
||||
$policy->addAllowedAccess($httpHost, $port);
|
||||
$flashSock = new Reactor($loop);
|
||||
$this->flashServer = new IoServer($policy, $flashSock);
|
||||
|
||||
if (80 == $port) {
|
||||
$flashSock->listen(843, '0.0.0.0');
|
||||
} else {
|
||||
@ -89,7 +95,7 @@ class App {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an endpiont/application to the server
|
||||
* Add an endpoint/application to the server
|
||||
* @param string $path The URI the client will connect to
|
||||
* @param ComponentInterface $controller Your application to server for the route. If not specified, assumed to be for a WebSocket
|
||||
* @param array $allowedOrigins An array of hosts allowed to connect (same host by default), ['*'] for any
|
||||
@ -119,6 +125,13 @@ class App {
|
||||
$decorated = new OriginCheck($decorated, $allowedOrigins);
|
||||
}
|
||||
|
||||
//allow origins in flash policy server
|
||||
if(empty($this->flashServer) === false) {
|
||||
foreach($allowedOrigins as $allowedOrgin) {
|
||||
$this->flashServer->app->addAllowedAccess($allowedOrgin, $this->port);
|
||||
}
|
||||
}
|
||||
|
||||
$this->routes->add('rr-' . ++$this->_routeCounter, new Route($path, array('_controller' => $decorated), array('Origin' => $this->httpHost), array(), $httpHost));
|
||||
|
||||
return $decorated;
|
||||
|
@ -5,7 +5,7 @@ namespace Ratchet;
|
||||
* The version of Ratchet being used
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = 'Ratchet/0.3.2';
|
||||
const VERSION = 'Ratchet/0.3.4';
|
||||
|
||||
/**
|
||||
* A proxy object representing a connection to the application
|
||||
|
@ -53,6 +53,8 @@ class Router implements HttpServerInterface {
|
||||
$parameters[$key] = $value;
|
||||
}
|
||||
}
|
||||
$parameters = array_merge($parameters, $request->getQuery()->getAll());
|
||||
|
||||
$url = Url::factory($request->getPath());
|
||||
$url->setQuery($parameters);
|
||||
$request->setUrl($url);
|
||||
|
@ -30,6 +30,12 @@ class VirtualSessionStorage extends NativeSessionStorage {
|
||||
return true;
|
||||
}
|
||||
|
||||
// You have to call Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::open() to use
|
||||
// pdo_sqlite (and possible pdo_*) as session storage, if you are using a DSN string instead of a \PDO object
|
||||
// in the constructor. The method arguments are filled with the values, which are also used by the symfony
|
||||
// framework in this case. This must not be the best choice, but it works.
|
||||
$this->saveHandler->open(session_save_path(), session_name());
|
||||
|
||||
$rawData = $this->saveHandler->read($this->saveHandler->getId());
|
||||
$sessionData = $this->_serializer->unserialize($rawData);
|
||||
|
||||
|
@ -107,7 +107,7 @@ class ServerProtocol implements MessageComponentInterface, WsServerInterface {
|
||||
$json = $json[0];
|
||||
}
|
||||
|
||||
$this->_decorating->onCall($from, $callID, $procURI, $json);
|
||||
$this->_decorating->onCall($from, $callID, $from->getUri($procURI), $json);
|
||||
break;
|
||||
|
||||
case static::MSG_SUBSCRIBE:
|
||||
|
@ -17,7 +17,7 @@ class WampConnection extends AbstractConnectionDecorator {
|
||||
parent::__construct($conn);
|
||||
|
||||
$this->WAMP = new \StdClass;
|
||||
$this->WAMP->sessionId = uniqid();
|
||||
$this->WAMP->sessionId = str_replace('.', '', uniqid(mt_rand(), true));
|
||||
$this->WAMP->prefixes = array();
|
||||
|
||||
$this->send(json_encode(array(WAMP::MSG_WELCOME, $this->WAMP->sessionId, 1, \Ratchet\VERSION)));
|
||||
@ -26,10 +26,10 @@ class WampConnection extends AbstractConnectionDecorator {
|
||||
/**
|
||||
* Successfully respond to a call made by the client
|
||||
* @param string $id The unique ID given by the client to respond to
|
||||
* @param array $data An array of data to return to the client
|
||||
* @param array $data an object or array
|
||||
* @return WampConnection
|
||||
*/
|
||||
public function callResult($id, array $data = array()) {
|
||||
public function callResult($id, $data = array()) {
|
||||
return $this->send(json_encode(array(WAMP::MSG_CALL_RESULT, $id, $data)));
|
||||
}
|
||||
|
||||
@ -81,7 +81,19 @@ class WampConnection extends AbstractConnectionDecorator {
|
||||
* @return string
|
||||
*/
|
||||
public function getUri($uri) {
|
||||
return (array_key_exists($uri, $this->WAMP->prefixes) ? $this->WAMP->prefixes[$uri] : $uri);
|
||||
$curieSeperator = ':';
|
||||
|
||||
if (preg_match('/http(s*)\:\/\//', $uri) == false) {
|
||||
if (strpos($uri, $curieSeperator) !== false) {
|
||||
list($prefix, $action) = explode($curieSeperator, $uri);
|
||||
|
||||
if(isset($this->WAMP->prefixes[$prefix]) === true){
|
||||
return $this->WAMP->prefixes[$prefix] . '#' . $action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ class WampServer implements MessageComponentInterface, WsServerInterface {
|
||||
/**
|
||||
* @var ServerProtocol
|
||||
*/
|
||||
private $wampProtocol;
|
||||
protected $wampProtocol;
|
||||
|
||||
/**
|
||||
* This class just makes it 1 step easier to use Topic objects in WAMP
|
||||
@ -41,8 +41,6 @@ class WampServer implements MessageComponentInterface, WsServerInterface {
|
||||
$this->wampProtocol->onMessage($conn, $msg);
|
||||
} catch (Exception $we) {
|
||||
$conn->close(1007);
|
||||
} catch (JsonException $je) {
|
||||
$conn->close(1007);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,6 +379,7 @@ class Frame implements FrameInterface {
|
||||
|
||||
$byte_length = $this->getNumPayloadBytes();
|
||||
if ($this->bytesRecvd < 1 + $byte_length) {
|
||||
$this->defPayLen = -1;
|
||||
throw new \UnderflowException('Not enough data buffered to determine payload length');
|
||||
}
|
||||
|
||||
|
@ -102,13 +102,13 @@ class WsServer implements HttpServerInterface {
|
||||
protected function attemptUpgrade(ConnectionInterface $conn, $data = '') {
|
||||
if ('' !== $data) {
|
||||
$conn->WebSocket->request->getBody()->write($data);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!$this->versioner->isVersionEnabled($conn->WebSocket->request)) {
|
||||
return $this->close($conn);
|
||||
}
|
||||
|
||||
$conn->WebSocket->version = $this->versioner->getVersion($conn->WebSocket->request);
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $conn->WebSocket->version->handshake($conn->WebSocket->request);
|
||||
|
@ -8,7 +8,7 @@ interface WsServerInterface {
|
||||
/**
|
||||
* If any component in a stack supports a WebSocket sub-protocol return each supported in an array
|
||||
* @return array
|
||||
* @temporary This method may be removed in future version (note that will not break code, just make some code obsolete)
|
||||
* @todo This method may be removed in future version (note that will not break code, just make some code obsolete)
|
||||
*/
|
||||
function getSubProtocols();
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
$loader = require __DIR__ . '/../vendor/autoload.php';
|
||||
$loader->add('Ratchet', __DIR__ . '/helpers');
|
||||
$loader->register();
|
||||
$loader->addPsr4('Ratchet\\', __DIR__ . '/helpers/Ratchet');
|
||||
|
@ -15,8 +15,18 @@ class RouterTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $_req;
|
||||
|
||||
public function setUp() {
|
||||
$queryMock = $this->getMock('Guzzle\Http\QueryString');
|
||||
$queryMock
|
||||
->expects($this->any())
|
||||
->method('getAll')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
$this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->_req = $this->getMock('\Guzzle\Http\Message\RequestInterface');
|
||||
$this->_req
|
||||
->expects($this->any())
|
||||
->method('getQuery')
|
||||
->will($this->returnValue($queryMock));
|
||||
$this->_matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
|
||||
$this->_matcher
|
||||
->expects($this->any())
|
||||
@ -88,8 +98,7 @@ class RouterTest extends \PHPUnit_Framework_TestCase {
|
||||
$this->_router->onError($this->_conn, $e);
|
||||
}
|
||||
|
||||
public function testRouterGeneratesRouteParameters()
|
||||
{
|
||||
public function testRouterGeneratesRouteParameters() {
|
||||
/** @var $controller WsServerInterface */
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
/** @var $matcher UrlMatcherInterface */
|
||||
@ -110,4 +119,22 @@ class RouterTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
$this->assertEquals(array('foo' => 'bar', 'baz' => 'qux'), $request->getQuery()->getAll());
|
||||
}
|
||||
|
||||
public function testQueryParams() {
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
$this->_matcher->expects($this->any())->method('match')->will(
|
||||
$this->returnValue(array('_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'))
|
||||
);
|
||||
|
||||
$conn = $this->getMock('Ratchet\Mock\Connection');
|
||||
$request = $this->getMock('Guzzle\Http\Message\Request', array('getPath'), array('GET', ''), '', false);
|
||||
|
||||
$request->setHeaderFactory($this->getMock('Guzzle\Http\Message\Header\HeaderFactoryInterface'));
|
||||
$request->setUrl('ws://doesnt.matter?hello=world&foo=nope');
|
||||
|
||||
$router = new Router($this->_matcher);
|
||||
$router->onOpen($conn, $request);
|
||||
|
||||
$this->assertEquals(array('foo' => 'nope', 'baz' => 'qux', 'hello' => 'world'), $request->getQuery()->getAll());
|
||||
}
|
||||
}
|
||||
|
@ -70,14 +70,17 @@ class SessionProviderTest extends AbstractMessageComponentTestCase {
|
||||
, 'db_id_col' => 'sess_id'
|
||||
, 'db_data_col' => 'sess_data'
|
||||
, 'db_time_col' => 'sess_time'
|
||||
, 'db_lifetime_col' => 'sess_lifetime'
|
||||
);
|
||||
|
||||
$pdo = new \PDO("sqlite::memory:");
|
||||
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->exec(vsprintf("CREATE TABLE %s (%s VARCHAR(255) PRIMARY KEY, %s TEXT, %s INTEGER)", $dbOptions));
|
||||
$pdo->prepare(vsprintf("INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)", $dbOptions))->execute(array($sessionId, base64_encode('_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}'), time()));
|
||||
$pdo->exec(vsprintf("CREATE TABLE %s (%s TEXT NOT NULL PRIMARY KEY, %s BLOB NOT NULL, %s INTEGER NOT NULL, %s INTEGER)", $dbOptions));
|
||||
|
||||
$component = new SessionProvider($this->getMock($this->getComponentClassString()), new PdoSessionHandler($pdo, $dbOptions), array('auto_start' => 1));
|
||||
$pdoHandler = new PdoSessionHandler($pdo, $dbOptions);
|
||||
$pdoHandler->write($sessionId, '_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}');
|
||||
|
||||
$component = new SessionProvider($this->getMock($this->getComponentClassString()), $pdoHandler, array('auto_start' => 1));
|
||||
$connection = $this->getMock('Ratchet\\ConnectionInterface');
|
||||
|
||||
$headers = $this->getMock('Guzzle\\Http\\Message\\Request', array('getCookie'), array('POST', '/', array()));
|
||||
|
53
tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
Normal file
53
tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace Ratchet\Session\Storage;
|
||||
use Ratchet\Session\Serialize\PhpHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
|
||||
|
||||
class VirtualSessionStoragePDOTest extends \PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* @var VirtualSessionStorage
|
||||
*/
|
||||
protected $_virtualSessionStorage;
|
||||
|
||||
protected $_pathToDB;
|
||||
|
||||
public function setUp() {
|
||||
if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
|
||||
return $this->markTestSkipped('Session test requires PDO and pdo_sqlite');
|
||||
}
|
||||
|
||||
$schema = <<<SQL
|
||||
CREATE TABLE `sessions` (
|
||||
`sess_id` VARBINARY(128) NOT NULL PRIMARY KEY,
|
||||
`sess_data` BLOB NOT NULL,
|
||||
`sess_time` INTEGER UNSIGNED NOT NULL,
|
||||
`sess_lifetime` MEDIUMINT NOT NULL
|
||||
);
|
||||
SQL;
|
||||
$this->_pathToDB = tempnam(sys_get_temp_dir(), 'SQ3');;
|
||||
$dsn = 'sqlite:' . $this->_pathToDB;
|
||||
|
||||
$pdo = new \PDO($dsn);
|
||||
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->exec($schema);
|
||||
$pdo = null;
|
||||
|
||||
$sessionHandler = new PdoSessionHandler($dsn);
|
||||
$serializer = new PhpHandler();
|
||||
$this->_virtualSessionStorage = new VirtualSessionStorage($sessionHandler, 'foobar', $serializer);
|
||||
$this->_virtualSessionStorage->registerBag(new FlashBag());
|
||||
$this->_virtualSessionStorage->registerBag(new AttributeBag());
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
unlink($this->_pathToDB);
|
||||
}
|
||||
|
||||
public function testStartWithDSN() {
|
||||
$this->_virtualSessionStorage->start();
|
||||
|
||||
$this->assertTrue($this->_virtualSessionStorage->isStarted());
|
||||
}
|
||||
}
|
@ -211,13 +211,14 @@ class ServerProtocolTest extends \PHPUnit_Framework_TestCase {
|
||||
$conn = new WampConnection($this->newConn());
|
||||
$this->_comp->onOpen($conn);
|
||||
|
||||
$shortIn = 'incoming';
|
||||
$longIn = 'http://example.com/incoming/';
|
||||
$prefix = 'incoming';
|
||||
$fullURI = "http://example.com/$prefix";
|
||||
$method = 'call';
|
||||
|
||||
$this->_comp->onMessage($conn, json_encode(array(1, $shortIn, $longIn)));
|
||||
$this->_comp->onMessage($conn, json_encode(array(1, $prefix, $fullURI)));
|
||||
|
||||
$this->assertEquals($longIn, $conn->WAMP->prefixes[$shortIn]);
|
||||
$this->assertEquals($longIn, $conn->getUri($shortIn));
|
||||
$this->assertEquals($fullURI, $conn->WAMP->prefixes[$prefix]);
|
||||
$this->assertEquals("$fullURI#$method", $conn->getUri("$prefix:$method"));
|
||||
}
|
||||
|
||||
public function testMessageMustBeJson() {
|
||||
|
@ -80,4 +80,24 @@ class Hixie76Test extends \PHPUnit_Framework_TestCase {
|
||||
$mockApp->expects($this->once())->method('onOpen');
|
||||
$server->onMessage($mockConn, $body . $this->_crlf . $this->_crlf);
|
||||
}
|
||||
|
||||
public function testTcpFragmentedBodyUpgrade() {
|
||||
$headers = $this->headerProvider();
|
||||
$body = base64_decode($this->_body);
|
||||
$body1 = substr($body, 0, 4);
|
||||
$body2 = substr($body, 4);
|
||||
|
||||
$mockConn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$mockApp = $this->getMock('\Ratchet\MessageComponentInterface');
|
||||
|
||||
$server = new HttpServer(new WsServer($mockApp));
|
||||
$server->onOpen($mockConn);
|
||||
$server->onMessage($mockConn, $headers);
|
||||
|
||||
$mockApp->expects($this->once())->method('onOpen');
|
||||
|
||||
$server->onMessage($mockConn, $body1);
|
||||
$server->onMessage($mockConn, $body2);
|
||||
$server->onMessage($mockConn, $this->_crlf . $this->_crlf);
|
||||
}
|
||||
}
|
||||
|
@ -500,4 +500,44 @@ class FrameTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
/**
|
||||
* There was a frame boundary issue when the first 3 bytes of a frame with a payload greater than
|
||||
* 126 was added to the frame buffer and then Frame::getPayloadLength was called. It would cause the frame
|
||||
* to set the payload length to 126 and then not recalculate it once the full length information was available.
|
||||
*
|
||||
* This is fixed by setting the defPayLen back to -1 before the underflow exception is thrown.
|
||||
*
|
||||
* @covers Ratchet\WebSocket\Version\RFC6455\Frame::getPayloadLength
|
||||
* @covers Ratchet\WebSocket\Version\RFC6455\Frame::extractOverflow
|
||||
*/
|
||||
public function testFrameDeliveredOneByteAtATime() {
|
||||
$startHeader = "\x01\x7e\x01\x00"; // header for a text frame of 256 - non-final
|
||||
$framePayload = str_repeat("*", 256);
|
||||
$rawOverflow = "xyz";
|
||||
$rawFrame = $startHeader . $framePayload . $rawOverflow;
|
||||
|
||||
$frame = new Frame();
|
||||
$payloadLen = 256;
|
||||
|
||||
for ($i = 0; $i < strlen($rawFrame); $i++) {
|
||||
$frame->addBuffer($rawFrame[$i]);
|
||||
|
||||
try {
|
||||
// payloadLen will
|
||||
$payloadLen = $frame->getPayloadLength();
|
||||
} catch (\UnderflowException $e) {
|
||||
if ($i > 2) { // we should get an underflow on 0,1,2
|
||||
$this->fail("Underflow exception when the frame length should be available");
|
||||
}
|
||||
}
|
||||
|
||||
if ($payloadLen !== 256) {
|
||||
$this->fail("Payload length of " . $payloadLen . " should have been 256.");
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the overflow is good
|
||||
$this->assertEquals($rawOverflow, $frame->extractOverflow());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user