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\Action\SendMessage;
|
||||
use Ratchet\Application\WebSocket\Util\HTTP;
|
||||
use Ratchet\Application\WebSocket\Version;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param array of HTTP headers
|
||||
* @param string HTTP handshake request
|
||||
* @return Version\VersionInterface
|
||||
* @throws UnderFlowException If we think the entire header message hasn't been buffered yet
|
||||
* @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) {
|
||||
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);
|
||||
|
||||
if (isset($headers['Sec-Websocket-Version'])) { // HyBi
|
||||
if ((int)$headers['Sec-Websocket-Version'] >= 6) {
|
||||
return $this->versionFactory('HyBi10');
|
||||
foreach ($this->_versions as $name => $instance) {
|
||||
if (null !== $instance) {
|
||||
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');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return the instance of a version class
|
||||
* @return Version\VersionInterface
|
||||
* Disable a version of the WebSocket protocol *cough*Hixie76*cough*
|
||||
* @param string The name of the version to disable
|
||||
* @throws InvalidArgumentException If the given version does not exist
|
||||
*/
|
||||
protected function versionFactory($version) {
|
||||
if (null === $this->_versions[$version]) {
|
||||
$ns = __NAMESPACE__ . "\\Version\\{$version}";
|
||||
$this->_version[$version] = new $ns;
|
||||
public function disableVersion($name) {
|
||||
if (!array_key_exists($name, $this->_versions)) {
|
||||
throw new \InvalidArgumentException("Version {$name} not found");
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
class Hixie76 implements VersionInterface {
|
||||
public static function isProtocol(array $headers) {
|
||||
return isset($headers['Sec-Websocket-Key2']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return string
|
||||
|
@ -10,6 +10,19 @@ use Ratchet\Application\WebSocket\Util\HTTP;
|
||||
class HyBi10 implements VersionInterface {
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* @param string
|
||||
@ -28,6 +36,7 @@ interface VersionInterface {
|
||||
/**
|
||||
* @param string
|
||||
* @return string
|
||||
* @todo Change to use other classes, this will be removed eventually
|
||||
*/
|
||||
function frame($message);
|
||||
}
|
Loading…
Reference in New Issue
Block a user