@Override
    public void call() throws Exception {

      WebSocketUpgradeHandler handler =
          WebSocketUpgradeHandler.class.cast(future.getAsyncHandler());
      Request request = future.getRequest();

      HttpResponseStatus status =
          new NettyResponseStatus(future.getUri(), config, response, channel);
      HttpResponseHeaders responseHeaders = new NettyResponseHeaders(response.headers());
      Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();

      if (exitAfterProcessingFilters(channel, future, handler, status, responseHeaders)) {
        return;
      }

      future.setHttpHeaders(response.headers());
      if (exitAfterHandlingRedirect(
          channel, future, response, request, response.getStatus().code(), realm)) return;

      boolean validStatus = response.getStatus().equals(SWITCHING_PROTOCOLS);
      boolean validUpgrade = response.headers().get(HttpHeaders.Names.UPGRADE) != null;
      String connection = response.headers().get(HttpHeaders.Names.CONNECTION);
      if (connection == null)
        connection =
            response.headers().get(HttpHeaders.Names.CONNECTION.toLowerCase(Locale.ENGLISH));
      boolean validConnection = HttpHeaders.Values.UPGRADE.equalsIgnoreCase(connection);
      boolean statusReceived = handler.onStatusReceived(status) == State.UPGRADE;

      if (!statusReceived) {
        try {
          handler.onCompleted();
        } finally {
          future.done();
        }
        return;
      }

      final boolean headerOK = handler.onHeadersReceived(responseHeaders) == State.CONTINUE;
      if (!headerOK || !validStatus || !validUpgrade || !validConnection) {
        requestSender.abort(channel, future, new IOException("Invalid handshake response"));
        return;
      }

      String accept = response.headers().get(HttpHeaders.Names.SEC_WEBSOCKET_ACCEPT);
      String key =
          getAcceptKey(
              future
                  .getNettyRequest()
                  .getHttpRequest()
                  .headers()
                  .get(HttpHeaders.Names.SEC_WEBSOCKET_KEY));
      if (accept == null || !accept.equals(key)) {
        requestSender.abort(
            channel,
            future,
            new IOException(
                String.format("Invalid challenge. Actual: %s. Expected: %s", accept, key)));
      }

      channelManager.upgradePipelineForWebSockets(channel.pipeline());

      invokeOnSucces(channel, handler);
      future.done();
      // set back the future so the protocol gets notified of frames
      Channels.setAttribute(channel, future);
    }