static void
cockpit_web_socket_stream_dispose (GObject *object)
{
  CockpitWebSocketStream *self = COCKPIT_WEB_SOCKET_STREAM (object);
  GIOStream *io = NULL; // Owned by self->client;

  if (self->client)
    {
      if (web_socket_connection_get_ready_state (self->client) < WEB_SOCKET_STATE_CLOSING)
        web_socket_connection_close (self->client, WEB_SOCKET_CLOSE_GOING_AWAY, "disconnected");
      g_signal_handler_disconnect (self->client, self->sig_open);
      g_signal_handler_disconnect (self->client, self->sig_message);
      g_signal_handler_disconnect (self->client, self->sig_closing);
      g_signal_handler_disconnect (self->client, self->sig_close);
      g_signal_handler_disconnect (self->client, self->sig_error);

      io = web_socket_connection_get_io_stream (self->client);
      if (io != NULL && self->sig_accept_cert)
        g_signal_handler_disconnect (io, self->sig_accept_cert);

      g_object_unref (self->client);
      self->client = NULL;
    }

  G_OBJECT_CLASS (cockpit_web_socket_stream_parent_class)->dispose (object);
}
static void
cockpit_web_socket_stream_close (CockpitChannel *channel,
                                 const gchar *problem)
{
  CockpitWebSocketStream *self = COCKPIT_WEB_SOCKET_STREAM (channel);

  self->closed = TRUE;
  if (self->client && web_socket_connection_get_ready_state (self->client) < WEB_SOCKET_STATE_CLOSING)
    {
      if (problem)
        web_socket_connection_close (self->client, WEB_SOCKET_CLOSE_ABNORMAL, problem);
      else
        web_socket_connection_close (self->client, WEB_SOCKET_CLOSE_NORMAL, "disconnected");
    }
  COCKPIT_CHANNEL_CLASS (cockpit_web_socket_stream_parent_class)->close (channel, problem);
}
static void
cockpit_channel_socket_close (CockpitChannelSocket *chock,
                              const gchar *problem)
{
  gushort code;

  g_free (chock->channel);

  g_signal_handler_disconnect (chock->transport, chock->transport_recv);
  g_signal_handler_disconnect (chock->transport, chock->transport_control);
  g_signal_handler_disconnect (chock->transport, chock->transport_closed);
  json_object_unref (chock->open);
  g_object_unref (chock->transport);

  g_signal_handler_disconnect (chock->socket, chock->socket_open);
  g_signal_handler_disconnect (chock->socket, chock->socket_message);
  g_signal_handler_disconnect (chock->socket, chock->socket_close);
  if (web_socket_connection_get_ready_state (chock->socket) < WEB_SOCKET_STATE_CLOSING)
    {
      if (problem)
        code = WEB_SOCKET_CLOSE_GOING_AWAY;
      else
        code = WEB_SOCKET_CLOSE_NORMAL;
      web_socket_connection_close (chock->socket, code, problem);
    }
  g_object_unref (chock->socket);

  g_free (chock);
}
static gboolean
cockpit_web_socket_stream_control (CockpitChannel *channel,
                                   const gchar *command,
                                   JsonObject *options)
{
  CockpitWebSocketStream *self = COCKPIT_WEB_SOCKET_STREAM (channel);

  if (!g_str_equal (command, "done"))
    return FALSE;

  if (self->client && web_socket_connection_get_ready_state (self->client) == WEB_SOCKET_STATE_OPEN)
    web_socket_connection_close (self->client, WEB_SOCKET_CLOSE_NORMAL, "disconnected");

  return TRUE;
}
static void
cockpit_sockets_close (CockpitSockets *sockets,
                       const gchar *problem)
{
  GHashTableIter iter;
  CockpitSocket *socket;

  if (!problem)
    problem = "terminated";

  g_hash_table_iter_init (&iter, sockets->by_connection);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&socket))
    {
      if (web_socket_connection_get_ready_state (socket->connection) < WEB_SOCKET_STATE_CLOSING)
        web_socket_connection_close (socket->connection, WEB_SOCKET_CLOSE_GOING_AWAY, problem);
    }
}
Beispiel #6
0
static void
on_web_socket_noauth (WebSocketConnection *connection,
                      gpointer data)
{
  GBytes *payload;
  GBytes *prefix;

  g_debug ("closing unauthenticated web socket");

  payload = cockpit_transport_build_control ("command", "init", "problem", "no-session", NULL);
  prefix = g_bytes_new_static ("\n", 1);

  web_socket_connection_send (connection, WEB_SOCKET_DATA_TEXT, prefix, payload);
  web_socket_connection_close (connection, WEB_SOCKET_CLOSE_GOING_AWAY, "no-session");

  g_bytes_unref (prefix);
  g_bytes_unref (payload);
}
static void
cockpit_channel_socket_close (CockpitChannel *channel,
                              const gchar *problem)
{
  CockpitChannelSocket *self = COCKPIT_CHANNEL_SOCKET (channel);
  gushort code;

  self->closed = TRUE;

  if (web_socket_connection_get_ready_state (self->socket) < WEB_SOCKET_STATE_CLOSING)
    {
      if (problem)
        code = WEB_SOCKET_CLOSE_GOING_AWAY;
      else
        code = WEB_SOCKET_CLOSE_NORMAL;
      web_socket_connection_close (self->socket, code, problem);
    }
}
static void
inbound_protocol_error (CockpitWebService *self,
                        WebSocketConnection *connection,
                        const gchar *problem)
{
  GBytes *payload;

  if (problem == NULL)
    problem = "protocol-error";

  if (web_socket_connection_get_ready_state (connection) == WEB_SOCKET_STATE_OPEN)
    {
      payload = cockpit_transport_build_control ("command", "close", "problem", problem, NULL);
      web_socket_connection_send (connection, WEB_SOCKET_DATA_TEXT, self->control_prefix, payload);
      g_bytes_unref (payload);
      web_socket_connection_close (connection, WEB_SOCKET_CLOSE_SERVER_ERROR, problem);
    }
}