Merge branch 'refs/heads/guzzle' into guzzle-refactor
* refs/heads/guzzle: [HIXIE] Reverting back to the proper response code. [TESTS] Fixing unit tests for versions [REFACTOR] Fixing some code based on unit tests [REFACTOR] Changing the handshake to return a guzzle object
This commit is contained in:
commit
8a2b9153ab
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Ratchet\Component\WebSocket\Version;
|
namespace Ratchet\Component\WebSocket\Version;
|
||||||
use Guzzle\Http\Message\RequestInterface;
|
use Guzzle\Http\Message\RequestInterface;
|
||||||
|
use Guzzle\Http\Message\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FOR THE LOVE OF BEER, PLEASE PLEASE PLEASE DON'T allow the use of this in your application!
|
* FOR THE LOVE OF BEER, PLEASE PLEASE PLEASE DON'T allow the use of this in your application!
|
||||||
@ -25,26 +26,20 @@ class Hixie76 implements VersionInterface {
|
|||||||
* @todo Unhack this mess...or wait for Hixie to die (HURRY UP APPLE)
|
* @todo Unhack this mess...or wait for Hixie to die (HURRY UP APPLE)
|
||||||
*/
|
*/
|
||||||
public function handshake(RequestInterface $request) {
|
public function handshake(RequestInterface $request) {
|
||||||
$buffer = $request->getRawHeaders() . "\r\n\r\n" . $request->getBody();
|
$body = $this->sign($request->getHeader('Sec-WebSocket-Key1'), $request->getHeader('Sec-WebSocket-Key2'), $request->getBody());
|
||||||
$resource = $host = $origin = $key1 = $key2 = $protocol = $code = $handshake = null;
|
|
||||||
|
$headers = array(
|
||||||
preg_match('#GET (.*?) HTTP#', $buffer, $match) && $resource = $match[1];
|
'Upgrade' => 'WebSocket'
|
||||||
preg_match("#Host: (.*?)\r\n#", $buffer, $match) && $host = $match[1];
|
, 'Connection' => 'Upgrade'
|
||||||
preg_match("#Sec-WebSocket-Key1: (.*?)\r\n#", $buffer, $match) && $key1 = $match[1];
|
, 'Sec-WebSocket-Origin' => $request->getHeader('Origin')
|
||||||
preg_match("#Sec-WebSocket-Key2: (.*?)\r\n#", $buffer, $match) && $key2 = $match[1];
|
, 'Sec-WebSocket-Location' => 'ws://' . $request->getHeader('Host') . $request->getPath()
|
||||||
preg_match("#Sec-WebSocket-Protocol: (.*?)\r\n#", $buffer, $match) && $protocol = $match[1];
|
);
|
||||||
preg_match("#Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1];
|
if ($request->getHeader('Sec-WebSocket-Protocol')) {
|
||||||
preg_match("#\r\n(.*?)\$#", $buffer, $match) && $code = $match[1];
|
$headers['Sec-WebSocket-Protocol'] = $request->getHeader('Sec-WebSocket-Protocol');
|
||||||
|
}
|
||||||
return "HTTP/1.1 101 WebSocket Protocol Handshake\r\n".
|
|
||||||
"Upgrade: WebSocket\r\n"
|
$response = new \Guzzle\Http\Message\Response('101', $headers, $body);
|
||||||
. "Connection: Upgrade\r\n"
|
return $response;
|
||||||
. "Sec-WebSocket-Origin: {$origin}\r\n"
|
|
||||||
. "Sec-WebSocket-Location: ws://{$host}{$resource}\r\n"
|
|
||||||
. ($protocol ? "Sec-WebSocket-Protocol: {$protocol}\r\n" : "")
|
|
||||||
. "\r\n"
|
|
||||||
. $this->_createHandshakeThingy($key1, $key2, $code)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function newMessage() {
|
public function newMessage() {
|
||||||
@ -59,17 +54,22 @@ class Hixie76 implements VersionInterface {
|
|||||||
return chr(0) . $message . chr(255);
|
return chr(0) . $message . chr(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _doStuffToObtainAnInt32($key) {
|
public function generateKeyNumber($key) {
|
||||||
return preg_match_all('#[0-9]#', $key, $number) && preg_match_all('# #', $key, $space) ?
|
|
||||||
implode('', $number[0]) / count($space[0]) :
|
if (substr_count($key, ' ') == 0) {
|
||||||
''
|
return '';
|
||||||
;
|
}
|
||||||
|
$int = preg_replace('[\D]', '', $key) / substr_count($key, ' ');
|
||||||
|
return (is_int($int)) ? $int : '';
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _createHandshakeThingy($key1, $key2, $code) {
|
protected function sign($key1, $key2, $code) {
|
||||||
|
|
||||||
return md5(
|
return md5(
|
||||||
pack('N', $this->_doStuffToObtainAnInt32($key1))
|
pack('N', $this->generateKeyNumber($key1))
|
||||||
. pack('N', $this->_doStuffToObtainAnInt32($key2))
|
. pack('N', $this->generateKeyNumber($key2))
|
||||||
. $code
|
. $code
|
||||||
, true);
|
, true);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
namespace Ratchet\Component\WebSocket\Version;
|
namespace Ratchet\Component\WebSocket\Version;
|
||||||
use Ratchet\Component\WebSocket\Version\RFC6455\HandshakeVerifier;
|
use Ratchet\Component\WebSocket\Version\RFC6455\HandshakeVerifier;
|
||||||
use Guzzle\Http\Message\RequestInterface;
|
use Guzzle\Http\Message\RequestInterface;
|
||||||
|
use Guzzle\Http\Message\Response;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @link http://tools.ietf.org/html/rfc6455
|
* @link http://tools.ietf.org/html/rfc6455
|
||||||
@ -33,13 +35,17 @@ class RFC6455 implements VersionInterface {
|
|||||||
throw new \InvalidArgumentException('Invalid HTTP header');
|
throw new \InvalidArgumentException('Invalid HTTP header');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
$headers = array(
|
||||||
'' => 'HTTP/1.1 101 Switching Protocols'
|
'Upgrade' => 'websocket'
|
||||||
, 'Upgrade' => 'websocket'
|
|
||||||
, 'Connection' => 'Upgrade'
|
, 'Connection' => 'Upgrade'
|
||||||
, 'Sec-WebSocket-Accept' => $this->sign($request->getHeader('Sec-WebSocket-Key'))
|
, 'Sec-WebSocket-Accept' => $this->sign($request->getHeader('Sec-WebSocket-Key'))
|
||||||
// , 'Sec-WebSocket-Protocol' => ''
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$response = new \Guzzle\Http\Message\Response(101, $headers);
|
||||||
|
return $response;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,33 +78,9 @@ class WebSocketComponent implements MessageComponentInterface {
|
|||||||
|
|
||||||
$response = $from->WebSocket->version->handshake($from->WebSocket->headers);
|
$response = $from->WebSocket->version->handshake($from->WebSocket->headers);
|
||||||
$from->WebSocket->handshake = true;
|
$from->WebSocket->handshake = true;
|
||||||
|
|
||||||
if (is_array($response)) {
|
$header = (string)$response;
|
||||||
// This block is to be moved/changed later
|
|
||||||
$agreed_protocols = array();
|
|
||||||
$requested_protocols = $from->WebSocket->headers->getTokenizedHeader('Sec-WebSocket-Protocol', ',');
|
|
||||||
foreach ($this->accepted_subprotocols as $sub_protocol) {
|
|
||||||
if (false !== $requested_protocols->hasValue($sub_protocol)) {
|
|
||||||
$agreed_protocols[] = $sub_protocol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count($agreed_protocols) > 0) {
|
|
||||||
$response['Sec-WebSocket-Protocol'] = implode(',', $agreed_protocols);
|
|
||||||
}
|
|
||||||
|
|
||||||
$header = '';
|
|
||||||
foreach ($response as $key => $val) {
|
|
||||||
if (!empty($key)) {
|
|
||||||
$header .= "{$key}: ";
|
|
||||||
}
|
|
||||||
|
|
||||||
$header .= "{$val}\r\n";
|
|
||||||
}
|
|
||||||
$header .= "\r\n";
|
|
||||||
} else {
|
|
||||||
$header = $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$comp = $this->_factory->newComposite();
|
$comp = $this->_factory->newComposite();
|
||||||
$comp->enqueue($this->_factory->newCommand('SendMessage', $from)->setMessage($header));
|
$comp->enqueue($this->_factory->newCommand('SendMessage', $from)->setMessage($header));
|
||||||
$comp->enqueue($this->prepareCommand($this->_decorating->onOpen($from, $msg))); // Need to send headers/handshake to application, let it have the cookies, etc
|
$comp->enqueue($this->prepareCommand($this->_decorating->onOpen($from, $msg))); // Need to send headers/handshake to application, let it have the cookies, etc
|
||||||
|
@ -30,4 +30,23 @@ class Hixie76Test extends \PHPUnit_Framework_TestCase {
|
|||||||
, array('', '')
|
, array('', '')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider KeyProvider
|
||||||
|
*/
|
||||||
|
public function testKeySigningForHandshake($accept, $key) {
|
||||||
|
$this->assertEquals($accept, $this->_version->generateKeyNumber($key));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function KeyProvider() {
|
||||||
|
return array(
|
||||||
|
array('179922739', '17 9 G`ZD9 2 2b 7X 3 /r90')
|
||||||
|
, array('', '17 9 G`ZD9 2 2b 7X 3 /r91')
|
||||||
|
, array('906585445', '3e6b263 4 17 80')
|
||||||
|
, array('', '3e6b263 4 17 80')
|
||||||
|
, array('', '3e6b63 4 17 80')
|
||||||
|
, array('', '3e6b6341780')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
@ -119,7 +119,7 @@ class RFC6455Test extends \PHPUnit_Framework_TestCase {
|
|||||||
$request = RequestFactory::fromMessage($header);
|
$request = RequestFactory::fromMessage($header);
|
||||||
|
|
||||||
if ($pass) {
|
if ($pass) {
|
||||||
$this->assertTrue(is_array($this->_version->handshake($request)));
|
$this->assertInstanceOf('\\Guzzle\\Http\\Message\\Response', $this->_version->handshake($request));
|
||||||
} else {
|
} else {
|
||||||
$this->setExpectedException('InvalidArgumentException');
|
$this->setExpectedException('InvalidArgumentException');
|
||||||
$this->_version->handshake($request);
|
$this->_version->handshake($request);
|
||||||
|
Loading…
Reference in New Issue
Block a user