WebSocket versions
Allowed user to disable WebSocket versions Change how versions are detected, responsibility is on the concrete version class instead of factory
This commit is contained in:
parent
4da707b653
commit
d75113ec5e
@ -7,6 +7,7 @@ use Ratchet\Resource\Command\Factory;
|
|||||||
use Ratchet\Resource\Command\CommandInterface;
|
use Ratchet\Resource\Command\CommandInterface;
|
||||||
use Ratchet\Resource\Command\Action\SendMessage;
|
use Ratchet\Resource\Command\Action\SendMessage;
|
||||||
use Ratchet\Application\WebSocket\Util\HTTP;
|
use Ratchet\Application\WebSocket\Util\HTTP;
|
||||||
|
use Ratchet\Application\WebSocket\Version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The adapter to handle WebSocket requests/responses
|
* The adapter to handle WebSocket requests/responses
|
||||||
@ -185,11 +186,10 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect the WebSocket protocol version a client is using based on the HTTP header request
|
* Detect the WebSocket protocol version a client is using based on the HTTP header request
|
||||||
* @param array of HTTP headers
|
* @param string HTTP handshake request
|
||||||
* @return Version\VersionInterface
|
* @return Version\VersionInterface
|
||||||
* @throws UnderFlowException If we think the entire header message hasn't been buffered yet
|
* @throws UnderFlowException If we think the entire header message hasn't been buffered yet
|
||||||
* @throws InvalidArgumentException If we can't understand protocol version request
|
* @throws InvalidArgumentException If we can't understand protocol version request
|
||||||
* @todo Can/will add more versions later, but perhaps a chain of responsibility, ask each version if they want to handle the request
|
|
||||||
*/
|
*/
|
||||||
protected function getVersion($message) {
|
protected function getVersion($message) {
|
||||||
if (false === strstr($message, "\r\n\r\n")) { // This CAN fail with Hixie, depending on the TCP buffer in between
|
if (false === strstr($message, "\r\n\r\n")) { // This CAN fail with Hixie, depending on the TCP buffer in between
|
||||||
@ -198,27 +198,33 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
|
|
||||||
$headers = HTTP::getHeaders($message);
|
$headers = HTTP::getHeaders($message);
|
||||||
|
|
||||||
if (isset($headers['Sec-Websocket-Version'])) { // HyBi
|
foreach ($this->_versions as $name => $instance) {
|
||||||
if ((int)$headers['Sec-Websocket-Version'] >= 6) {
|
if (null !== $instance) {
|
||||||
return $this->versionFactory('HyBi10');
|
if ($instance::isProtocol($headers)) {
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ns = __NAMESPACE__ . "\\Version\\{$name}";
|
||||||
|
if ($ns::isProtocol($headers)) {
|
||||||
|
$this->_version[$name] = new $ns;
|
||||||
|
return $this->_version[$name];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif (isset($headers['Sec-Websocket-Key2'])) { // Hixie
|
|
||||||
return $this->versionFactory('Hixie76');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException('Could not identify WebSocket protocol');
|
throw new \InvalidArgumentException('Could not identify WebSocket protocol');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return the instance of a version class
|
* Disable a version of the WebSocket protocol *cough*Hixie76*cough*
|
||||||
* @return Version\VersionInterface
|
* @param string The name of the version to disable
|
||||||
|
* @throws InvalidArgumentException If the given version does not exist
|
||||||
*/
|
*/
|
||||||
protected function versionFactory($version) {
|
public function disableVersion($name) {
|
||||||
if (null === $this->_versions[$version]) {
|
if (!array_key_exists($name, $this->_versions)) {
|
||||||
$ns = __NAMESPACE__ . "\\Version\\{$version}";
|
throw new \InvalidArgumentException("Version {$name} not found");
|
||||||
$this->_version[$version] = new $ns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_version[$version];
|
unset($this->_versions[$name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,6 +14,10 @@ namespace Ratchet\Application\WebSocket\Version;
|
|||||||
* @link http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
|
* @link http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
|
||||||
*/
|
*/
|
||||||
class Hixie76 implements VersionInterface {
|
class Hixie76 implements VersionInterface {
|
||||||
|
public static function isProtocol(array $headers) {
|
||||||
|
return isset($headers['Sec-Websocket-Key2']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string
|
* @param string
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -10,6 +10,19 @@ use Ratchet\Application\WebSocket\Util\HTTP;
|
|||||||
class HyBi10 implements VersionInterface {
|
class HyBi10 implements VersionInterface {
|
||||||
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo When I support later version (that implement extension) change >= 6 to 6 through 10 (or w/e #)
|
||||||
|
*/
|
||||||
|
public static function isProtocol(array $headers) {
|
||||||
|
if (isset($headers['Sec-Websocket-Version'])) {
|
||||||
|
if ((int)$headers['Sec-Websocket-Version'] >= 6) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
* I kept this as an array and combined in App for future considerations...easier to add a subprotol as a key value than edit a string
|
* I kept this as an array and combined in App for future considerations...easier to add a subprotol as a key value than edit a string
|
||||||
|
@ -8,6 +8,14 @@ namespace Ratchet\Application\WebSocket\Version;
|
|||||||
* The current method names suggest you could create a new message/frame to send, which they can not do
|
* The current method names suggest you could create a new message/frame to send, which they can not do
|
||||||
*/
|
*/
|
||||||
interface VersionInterface {
|
interface VersionInterface {
|
||||||
|
/**
|
||||||
|
* Given an HTTP header, determine if this version should handle the protocol
|
||||||
|
* @param array
|
||||||
|
* @return bool
|
||||||
|
* @throws UnderflowException If the protocol thinks the headers are still fragmented
|
||||||
|
*/
|
||||||
|
static function isProtocol(array $headers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the handshake and return the response headers
|
* Perform the handshake and return the response headers
|
||||||
* @param string
|
* @param string
|
||||||
@ -28,6 +36,7 @@ interface VersionInterface {
|
|||||||
/**
|
/**
|
||||||
* @param string
|
* @param string
|
||||||
* @return string
|
* @return string
|
||||||
|
* @todo Change to use other classes, this will be removed eventually
|
||||||
*/
|
*/
|
||||||
function frame($message);
|
function frame($message);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user