Buffer headers

WebSocket buffers initial header handshake until it thinks it's complete (TCP was buffering tiny amounts)
This commit is contained in:
Chris Boden 2011-11-15 12:02:57 -05:00
parent e65ecde592
commit 1355e4400b

View File

@ -63,15 +63,21 @@ class App implements ApplicationInterface, ConfiguratorInterface {
public function onOpen(Connection $conn) { public function onOpen(Connection $conn) {
$conn->WebSocket = new \stdClass; $conn->WebSocket = new \stdClass;
$conn->WebSocket->handshake = false; $conn->WebSocket->handshake = false;
$conn->WebSocket->headers = '';
} }
public function onRecv(Connection $from, $msg) { public function onRecv(Connection $from, $msg) {
if (true !== $from->WebSocket->handshake) { if (true !== $from->WebSocket->handshake) {
if (!isset($from->WebSocket->version)) {
try {
$from->WebSocket->headers .= $msg;
$from->WebSocket->version = $this->getVersion($from->WebSocket->headers);
} catch (\UnderflowException $e) {
return;
}
}
// need buffer checks in here $response = $from->WebSocket->version->handshake($from->WebSocket->headers);
$from->WebSocket->version = $this->getVersion($msg);
$response = $from->WebSocket->version->handshake($msg);
$from->WebSocket->handshake = true; $from->WebSocket->handshake = true;
if (is_array($response)) { if (is_array($response)) {
@ -142,19 +148,26 @@ class App implements ApplicationInterface, ConfiguratorInterface {
/** /**
* @param array of HTTP headers * @param array of HTTP headers
* @return Version\VersionInterface * @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) { protected function getVersion($message) {
if (false === strstr($message, "\r\n\r\n")) { // This _could_ fail with Hixie
throw new \UnderflowException;
}
$headers = HTTP::getHeaders($message); $headers = HTTP::getHeaders($message);
if (isset($headers['Sec-Websocket-Version'])) { // HyBi if (isset($headers['Sec-Websocket-Version'])) { // HyBi
if ($headers['Sec-Websocket-Version'] == '8') { if ((int)$headers['Sec-Websocket-Version'] >= 6) {
return $this->versionFactory('HyBi10'); return $this->versionFactory('HyBi10');
} }
} elseif (isset($headers['Sec-Websocket-Key2'])) { // Hixie } elseif (isset($headers['Sec-Websocket-Key2'])) { // Hixie
return $this->versionFactory('Hixie76'); return $this->versionFactory('Hixie76');
} }
throw new \UnexpectedValueException('Could not identify WebSocket protocol'); throw new \InvalidArgumentException('Could not identify WebSocket protocol');
} }
/** /**