Example #1
0
 public function __invoke(Request $request, Response $response, ...$args)
 {
     if ($request->getMethod() !== "GET") {
         $response->setStatus(HTTP_STATUS["METHOD_NOT_ALLOWED"]);
         $response->setHeader("Allow", "GET");
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     if ($request->getProtocolVersion() !== "1.1") {
         $response->setStatus(HTTP_STATUS["HTTP_VERSION_NOT_SUPPORTED"]);
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     $body = $request->getBody();
     if (!$body instanceof NullBody) {
         $response->setStatus(HTTP_STATUS["BAD_REQUEST"]);
         $response->setReason("Bad Request: Entity body disallowed for websocket endpoint");
         $response->setHeader("Connection", "close");
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     $hasUpgradeWebsocket = false;
     foreach ($request->getHeaderArray("Upgrade") as $value) {
         if (strcasecmp($value, "websocket") === 0) {
             $hasUpgradeWebsocket = true;
             break;
         }
     }
     if (empty($hasUpgradeWebsocket)) {
         $response->setStatus(HTTP_STATUS["UPGRADE_REQUIRED"]);
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     $hasConnectionUpgrade = false;
     foreach ($request->getHeaderArray("Connection") as $value) {
         $values = array_map("trim", explode(",", $value));
         foreach ($values as $token) {
             if (strcasecmp($token, "Upgrade") === 0) {
                 $hasConnectionUpgrade = true;
                 break;
             }
         }
     }
     if (empty($hasConnectionUpgrade)) {
         $response->setStatus(HTTP_STATUS["UPGRADE_REQUIRED"]);
         $response->setReason("Bad Request: \"Connection: Upgrade\" header required");
         $response->setHeader("Upgrade", "websocket");
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     if (!($acceptKey = $request->getHeader("Sec-Websocket-Key"))) {
         $response->setStatus(HTTP_STATUS["BAD_REQUEST"]);
         $response->setReason("Bad Request: \"Sec-Websocket-Key\" header required");
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     if (!in_array("13", $request->getHeaderArray("Sec-Websocket-Version"))) {
         $response->setStatus(HTTP_STATUS["BAD_REQUEST"]);
         $response->setReason("Bad Request: Requested Websocket version unavailable");
         $response->setHeader("Sec-WebSocket-Version", "13");
         $response->setHeader("Aerys-Generic-Response", "enable");
         $response->end();
         return;
     }
     $handshaker = new Handshake($response, $acceptKey);
     $onHandshakeResult = $this->application->onHandshake($request, $handshaker, ...$args);
     if ($onHandshakeResult instanceof \Generator) {
         $onHandshakeResult = (yield from $onHandshakeResult);
     }
     $request->setLocalVar("aerys.websocket", $onHandshakeResult);
     $handshaker->end();
 }