function init(cowboy_request $req, array $opts)
 {
     $handler = ranch_utils::config($opts, 'handler');
     if (!$handler) {
         $req->reply(500);
     } else {
         return new $handler();
     }
 }
 public function upgrade(cowboy_request $req, cowboy_protocol_env $env)
 {
     $this->env = $env;
     $this->req = $req;
     if (strtolower($req->method()) != "get") {
         $req->reply(400);
         return;
     }
     if (!$req->headerContains("connection", "upgrade") || !$req->headerContains("upgrade", "websocket")) {
         $req->reply(400);
         return;
     }
     $version = (int) $req->header("sec-websocket-version");
     $key = $req->header("sec-websocket-key");
     if ($version != 13 || !$key) {
         $req->reply(400);
         return;
     }
     $req->setMeta("websocketVersion", $version);
     $req->setMeta("websocketCompress", false);
     if ($req->headerContains("sec-websocket-extensions", "permessage-deflate") || $req->headerContains("sec-websocket-extensions", "x-webkit-deflate-frame")) {
         $req->setMeta("websocketCompress", true);
     }
     $challenge = base64_encode(sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
     $this->handshake($req);
     if ($req->respState() != "waiting") {
         return;
     }
     $this->init($req);
     $req->setRespHeader("connection", "upgrade");
     $req->setRespHeader("upgrade", "websocket");
     $req->setRespHeader("sec-websocket-accept", $challenge);
     $req->reply(101);
     $this->setUpWaitRecvCb();
 }