static void
on_socket_close (WebSocketConnection *connection,
                 CockpitChannelSocket *chock)
{
  const gchar *problem = NULL;
  GBytes *payload;
  gushort code;

  code = web_socket_connection_get_close_code (chock->socket);
  if (code == WEB_SOCKET_CLOSE_NORMAL)
    {
      payload = cockpit_transport_build_control ("command", "done", "channel", chock->channel, NULL);
      cockpit_transport_send (chock->transport, NULL, payload);
      g_bytes_unref (payload);
    }
  else
    {
      problem = web_socket_connection_get_close_data (chock->socket);
      if (problem == NULL)
        problem = "disconnected";
    }

  payload = cockpit_transport_build_control ("command", "close", "channel", chock->channel, "problem", problem, NULL);
  cockpit_transport_send (chock->transport, NULL, payload);
  g_bytes_unref (payload);

  cockpit_channel_socket_close (chock, problem);
}
static CockpitChannelResponse *
cockpit_channel_response_create (CockpitWebService *service,
                                 CockpitWebResponse *response,
                                 CockpitTransport *transport,
                                 const gchar *logname,
                                 GHashTable *headers,
                                 JsonObject *open)
{
  CockpitChannelResponse *chesp;
  const gchar *payload;
  JsonObject *done;
  GBytes *bytes;

  payload = json_object_get_string_member (open, "payload");

  chesp = g_new0 (CockpitChannelResponse, 1);
  chesp->response = g_object_ref (response);
  chesp->transport = g_object_ref (transport);
  chesp->headers = g_hash_table_ref (headers);
  chesp->channel = cockpit_web_service_unique_channel (service);
  chesp->open = json_object_ref (open);

  if (!cockpit_json_get_string (open, "path", chesp->channel, &chesp->logname))
    chesp->logname = chesp->channel;

  json_object_set_string_member (open, "command", "open");
  json_object_set_string_member (open, "channel", chesp->channel);

  /* Special handling for http-stream1, splice in headers, handle injection */
  if (g_strcmp0 (payload, "http-stream1") == 0)
    chesp->transport_recv = g_signal_connect (transport, "recv", G_CALLBACK (on_httpstream_recv), chesp);
  else
    chesp->transport_recv = g_signal_connect (transport, "recv", G_CALLBACK (on_transport_recv), chesp);

  /* Special handling for http-stream2, splice in headers, handle injection */
  if (g_strcmp0 (payload, "http-stream2") == 0)
    chesp->transport_control = g_signal_connect (transport, "control", G_CALLBACK (on_httpstream_control), chesp);
  else
    chesp->transport_control = g_signal_connect (transport, "control", G_CALLBACK (on_transport_control), chesp);

  chesp->transport_closed = g_signal_connect (transport, "closed", G_CALLBACK (on_transport_closed), chesp);

  bytes = cockpit_json_write_bytes (chesp->open);
  cockpit_transport_send (transport, NULL, bytes);
  g_bytes_unref (bytes);

  done = cockpit_transport_build_json ("command", "done", "channel", chesp->channel, NULL);
  bytes = cockpit_json_write_bytes (done);
  json_object_unref (done);
  cockpit_transport_send (transport, NULL, bytes);
  g_bytes_unref (bytes);

  return chesp;
}
Beispiel #3
0
/**
 * cockpit_channel_control:
 * @self: the channel
 * @command: the control command
 * @options: optional control message or NULL
 *
 * Send a control message to the other side.
 *
 * If @options is not NULL, then it may be modified by this code.
 *
 * With @command of "done" will send an EOF to the other side. This
 * should only be called once. Whether an EOF should be sent or not
 * depends on the payload type.
 */
void
cockpit_channel_control (CockpitChannel *self,
                         const gchar *command,
                         JsonObject *options)
{
  JsonObject *object;
  GBytes *message;

  g_return_if_fail (COCKPIT_IS_CHANNEL (self));
  g_return_if_fail (command != NULL);

  if (g_str_equal (command, "done"))
    {
      g_return_if_fail (self->priv->sent_done == FALSE);
      self->priv->sent_done = TRUE;
    }

  if (options)
    object = json_object_ref (options);
  else
    object = json_object_new ();

  json_object_set_string_member (object, "command", command);
  json_object_set_string_member (object, "channel", self->priv->id);

  message = cockpit_json_write_bytes (object);
  json_object_unref (object);

  cockpit_transport_send (self->priv->transport, NULL, message);
  g_bytes_unref (message);
}
static void
on_helper_read (CockpitPipe *pipe,
                GByteArray *buffer,
                gboolean eof,
                gpointer user_data)
{
  ReauthorizeCaller *caller = user_data;
  JsonObject *object;
  GBytes *bytes;
  guint8 *lf;

  lf = memchr (buffer->data, '\n', buffer->len);
  if (!lf)
    return;

  /* Null terminate the challenge */
  *lf = 0;

  g_debug ("got challenge from helper, will send to cockpit-ws: %s", (gchar *)buffer->data);

  /* send an authorize packet here */
  object = json_object_new ();
  json_object_set_string_member (object, "command", "authorize");
  json_object_set_string_member (object, "cookie", caller->cookie);
  json_object_set_string_member (object, "challenge", (gchar *)buffer->data);
  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  /* Consume from buffer, including null termination */
  cockpit_pipe_skip (buffer, lf - buffer->data);

  cockpit_transport_send (caller->self->transport, NULL, bytes);
  g_bytes_unref (bytes);
}
static void
on_web_socket_message (WebSocketConnection *connection,
                       WebSocketDataType type,
                       GBytes *message,
                       CockpitWebService *self)
{
  CockpitSocket *socket;
  GBytes *payload;
  gchar *channel;

  socket = cockpit_socket_lookup_by_connection (&self->sockets, connection);
  g_return_if_fail (socket != NULL);

  payload = cockpit_transport_parse_frame (message, &channel);
  if (!payload)
    return;

  /* A control channel command */
  if (!channel)
    {
      dispatch_inbound_command (self, socket, payload);
    }

  /* An actual payload message */
  else if (!self->closing)
    {
      if (!self->sent_done)
        cockpit_transport_send (self->transport, channel, payload);
    }

  g_free (channel);
  g_bytes_unref (payload);
}
Beispiel #6
0
static void
send_init_command (CockpitTransport *transport)
{
  const gchar *checksum;
  const gchar *name;
  JsonObject *object;
  GBytes *bytes;

  object = json_object_new ();
  json_object_set_string_member (object, "command", "init");
  json_object_set_int_member (object, "version", 1);

  checksum = cockpit_packages_get_checksum (packages);
  if (checksum)
    json_object_set_string_member (object, "checksum", checksum);

  /* Happens when we're in --interact mode */
  name = cockpit_dbus_internal_name ();
  if (name)
    json_object_set_string_member (object, "bridge-dbus-name", name);

  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  cockpit_transport_send (transport, NULL, bytes);
  g_bytes_unref (bytes);
}
Beispiel #7
0
static void
spawn_portal_bridge (CockpitPortal *self)
{
  CockpitPipe *pipe;
  const gchar *data;
  const gchar **argv;

  g_assert (self->other == NULL);

  argv = current_argv (self);
  g_debug ("launching portal bridge: %s", argv[0]);

  pipe = cockpit_pipe_spawn (argv, NULL, NULL, COCKPIT_PIPE_FLAGS_NONE);
  self->other = cockpit_pipe_transport_new (pipe);
  g_object_unref (pipe);

  self->other_recv_sig = g_signal_connect (self->other, "recv", G_CALLBACK (on_other_recv), self);
  self->other_control_sig = g_signal_connect (self->other, "control", G_CALLBACK (on_other_control), self);
  self->other_closed_sig = g_signal_connect (self->other, "closed", G_CALLBACK (on_other_closed), self);

  if (!self->last_init)
    {
      data = "{\"command\":\"init\",\"version\":1}";
      self->last_init = g_bytes_new_static (data, strlen (data));
    }

  cockpit_transport_send (self->other, NULL, self->last_init);
}
Beispiel #8
0
static gboolean
on_other_control (CockpitTransport *transport,
                  const char *command,
                  const gchar *channel,
                  JsonObject *options,
                  GBytes *payload,
                  gpointer user_data)
{
  CockpitPortal *self = user_data;
  if (g_str_equal (command, "init"))
    {
      if (self->state == PORTAL_OPENING)
        transition_open (self);
    }

  /* Only forward close and done control messages back out */
  else if (g_str_equal (command, "close") ||
           g_str_equal (command, "done"))
    {
      if (self->channels && channel)
        g_hash_table_remove (self->channels, channel);

      g_debug ("portal channel closed: %s", channel);

      if (self->transport)
        cockpit_transport_send (self->transport, NULL, payload);
    }

  return TRUE;
}
static void
on_socket_message (WebSocketConnection *connection,
                   WebSocketDataType type,
                   GBytes *payload,
                   CockpitChannelSocket *chock)
{
  cockpit_transport_send (chock->transport, chock->channel, payload);
}
Beispiel #10
0
/**
 * cockpit_channel_control:
 * @self: the channel
 * @command: the control command
 * @options: optional control message or NULL
 *
 * Send a control message to the other side.
 *
 * If @options is not NULL, then it may be modified by this code.
 *
 * With @command of "done" will send an EOF to the other side. This
 * should only be called once. Whether an EOF should be sent or not
 * depends on the payload type.
 */
void
cockpit_channel_control (CockpitChannel *self,
                         const gchar *command,
                         JsonObject *options)
{
  JsonObject *object;
  GBytes *message;
  const gchar *problem;
  gchar *problem_copy = NULL;

  g_return_if_fail (COCKPIT_IS_CHANNEL (self));
  g_return_if_fail (command != NULL);

  if (g_str_equal (command, "done"))
    {
      g_return_if_fail (self->priv->sent_done == FALSE);
      self->priv->sent_done = TRUE;
    }

  /* If closing save the close options
   * and let close send the message */
  else if (g_str_equal (command, "close"))
    {
      if (!self->priv->close_options)
        {
          /* Ref for close_options, freed in parent */
          self->priv->close_options = json_object_ref (options);
        }

      if (!cockpit_json_get_string (options, "problem", NULL, &problem))
        problem = NULL;

      /* Use a problem copy so it out lasts the value in close_options */
      problem_copy = g_strdup (problem);
      cockpit_channel_close (self, problem_copy);
      goto out;
    }

  if (options)
    object = json_object_ref (options);
  else
    object = json_object_new ();

  json_object_set_string_member (object, "command", command);
  json_object_set_string_member (object, "channel", self->priv->id);

  message = cockpit_json_write_bytes (object);
  json_object_unref (object);

  cockpit_transport_send (self->priv->transport, NULL, message);
  g_bytes_unref (message);

out:
  g_free (problem_copy);
}
static gboolean
process_kill (CockpitWebService *self,
              CockpitSocket *socket,
              JsonObject *options,
              GBytes *payload)
{
  if (!self->sent_done)
    cockpit_transport_send (self->transport, NULL, payload);

  return TRUE;
}
Beispiel #12
0
static void
cockpit_channel_actual_send (CockpitChannel *self,
                             GBytes *payload,
                             gboolean trust_is_utf8)
{
  GBytes *validated = NULL;
  guint64 out_sequence;
  JsonObject *ping;
  gsize size;

  g_return_if_fail (self->priv->out_buffer == NULL);
  g_return_if_fail (self->priv->buffer_timeout == 0);

  if (!trust_is_utf8)
    {
      if (!self->priv->binary_ok)
         payload = validated = cockpit_unicode_force_utf8 (payload);
    }

  cockpit_transport_send (self->priv->transport, self->priv->id, payload);

  /* A wraparound of our gint64 size? */
  if (self->priv->flow_control)
    {
      size = g_bytes_get_size (payload);
      g_return_if_fail (G_MAXINT64 - size > self->priv->out_sequence);

      /* How many bytes have been sent (queued) */
      out_sequence = self->priv->out_sequence + size;

      /* Every CHANNEL_FLOW_PING bytes we send a ping */
      if (out_sequence / CHANNEL_FLOW_PING != self->priv->out_sequence / CHANNEL_FLOW_PING)
        {
          ping = json_object_new ();
          json_object_set_int_member (ping, "sequence", out_sequence);
          cockpit_channel_control (self, "ping", ping);
          g_debug ("%s: sending ping with sequence: %" G_GINT64_FORMAT, self->priv->id, out_sequence);
          json_object_unref (ping);
        }

      /* If we've sent more than the window, apply back pressure */
      self->priv->out_sequence = out_sequence;
      if (self->priv->out_sequence > self->priv->out_window)
        {
          g_debug ("%s: sent too much data without acknowledgement, emitting back pressure until %"
                   G_GINT64_FORMAT, self->priv->id, self->priv->out_window);
          cockpit_flow_emit_pressure (COCKPIT_FLOW (self), TRUE);
        }
    }

  if (validated)
    g_bytes_unref (validated);
}
static gboolean
process_and_relay_close (CockpitWebService *self,
                         CockpitSocket *socket,
                         const gchar *channel,
                         GBytes *payload)
{
  gboolean valid;

  valid = process_close (self, socket, channel);
  if (valid && !self->sent_done)
    cockpit_transport_send (self->transport, NULL, payload);

  return valid;
}
Beispiel #14
0
static void
send_init_command (CockpitTransport *transport)
{
  JsonObject *object;
  GBytes *bytes;

  object = json_object_new ();
  json_object_set_string_member (object, "command", "init");
  json_object_set_int_member (object, "version", 1);

  bytes = cockpit_json_write_bytes (object);
  cockpit_transport_send (transport, NULL, bytes);
  g_bytes_unref (bytes);
}
static void
on_socket_open (WebSocketConnection *connection,
                CockpitChannelSocket *chock)
{
  GBytes *payload;

  /*
   * Actually open the channel. We wait until the WebSocket is open
   * before doing this, so we don't receive messages from the bridge
   * before the websocket is open.
   */

  payload = cockpit_json_write_bytes (chock->open);
  cockpit_transport_send (chock->transport, NULL, payload);
  g_bytes_unref (payload);
}
Beispiel #16
0
static gboolean
on_other_recv (CockpitTransport *transport,
               const gchar *channel,
               GBytes *payload,
               gpointer user_data)
{
  CockpitPortal *self = user_data;

  if (channel)
    {
      if (self->transport)
        cockpit_transport_send (self->transport, channel, payload);
      return TRUE;
    }

  return FALSE;
}
Beispiel #17
0
/**
 * cockpit_channel_send:
 * @self: a pipe
 * @payload: the message payload to send
 * @trust_is_utf8: set to true if sure data is UTF8
 *
 * Called by implementations to send a message over the transport
 * on the right channel.
 *
 * This message is queued, and sent once the transport can.
 */
void
cockpit_channel_send (CockpitChannel *self,
                      GBytes *payload,
                      gboolean trust_is_utf8)
{
  GBytes *validated = NULL;

  if (!trust_is_utf8)
    {
      if (!self->priv->binary_ok)
        payload = validated = cockpit_unicode_force_utf8 (payload);
    }

  cockpit_transport_send (self->priv->transport, self->priv->id, payload);

  if (validated)
    g_bytes_unref (validated);
}
Beispiel #18
0
static gboolean
send_to_portal (CockpitPortal *self,
                const gchar *channel,
                GBytes *payload,
                CockpitPortalFlags flags)
{
  CockpitPortalMessage *message;

  /* What we do here depends on the state */

  switch (self->state)
    {
    case PORTAL_NONE:
      transition_opening (self);
      /* fall through */

    case PORTAL_OPENING:
      if (!self->queue)
        self->queue = g_queue_new ();
      message = cockpit_portal_message_new (intern_string (self, channel), payload, flags);
      g_queue_push_tail (self->queue, message);
      return TRUE;

    case PORTAL_OPEN:
      if (self->transport)
        cockpit_transport_send (self->other, channel, payload);
      return TRUE;

    case PORTAL_FAILED:
      if ((flags & COCKPIT_PORTAL_FALLBACK) == 0)
        {
          if (channel && g_hash_table_contains (self->channels, channel))
            {
              g_hash_table_remove (self->channels, channel);
              send_close_channel (self, channel, self->problem);
            }
          return TRUE;
        }
      return FALSE;
    default:
      g_assert_not_reached ();
    }
}
static gboolean
process_and_relay_open (CockpitWebService *self,
                        CockpitSocket *socket,
                        const gchar *channel,
                        JsonObject *options)
{
  WebSocketDataType data_type = WEB_SOCKET_DATA_TEXT;
  GBytes *payload;

  if (self->closing)
    {
      g_debug ("Ignoring open command while web socket is closing");
      return TRUE;
    }

  if (channel == NULL)
    {
      g_warning ("open command is missing the 'channel' field");
      return FALSE;
    }

  if (cockpit_socket_lookup_by_channel (&self->sockets, channel))
    {
      g_warning ("cannot open a channel %s with the same id as another channel", channel);
      return FALSE;
    }

  if (!cockpit_web_service_parse_binary (options, &data_type))
    return FALSE;

  if (socket)
    cockpit_socket_add_channel (&self->sockets, socket, channel, data_type);

  if (!self->sent_done)
    {
      payload = cockpit_json_write_bytes (options);
      cockpit_transport_send (self->transport, NULL, payload);
      g_bytes_unref (payload);
    }

  return TRUE;
}
Beispiel #20
0
static const gchar *
process_transport_init (CockpitWebService *self,
                        CockpitTransport *transport,
                        JsonObject *options)
{
  JsonObject *object;
  GBytes *payload;
  gint64 version;

  if (!cockpit_json_get_int (options, "version", -1, &version))
    {
      g_warning ("invalid version field in init message");
      return "protocol-error";
    }

  if (version == 1)
    {
      g_debug ("received init message");
      self->init_received = TRUE;
      g_object_set_data_full (G_OBJECT (transport), "init",
                              json_object_ref (options),
                              (GDestroyNotify) json_object_unref);

      /* Always send an init message down the new transport */
      object = cockpit_transport_build_json ("command", "init", NULL);
      json_object_set_int_member (object, "version", 1);
      json_object_set_string_member (object, "host", "localhost");
      payload = cockpit_json_write_bytes (object);
      json_object_unref (object);
      cockpit_transport_send (transport, NULL, payload);
      g_bytes_unref (payload);
    }
  else
    {
      g_message ("unsupported version of cockpit protocol: %" G_GINT64_FORMAT, version);
      return "not-supported";
    }

  g_signal_emit (self, sig_transport_init, 0);
  return NULL;
}
static gboolean
on_web_socket_closing (WebSocketConnection *connection,
                       CockpitWebService *self)
{
  CockpitSocket *socket;
  GHashTable *snapshot;
  GHashTableIter iter;
  const gchar *channel;
  GBytes *payload;

  g_debug ("web socket closing");

  if (self->sent_done)
    return TRUE;

  /* Close any channels that were opened by this web socket */
  snapshot = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  socket = cockpit_socket_lookup_by_connection (&self->sockets, connection);
  if (socket)
    {
      g_hash_table_iter_init (&iter, socket->channels);
      while (g_hash_table_iter_next (&iter, (gpointer *)&channel, NULL))
        {
          g_hash_table_add (snapshot, g_strdup (channel));
        }
    }

  g_hash_table_iter_init (&iter, snapshot);
  while (g_hash_table_iter_next (&iter, (gpointer *)&channel, NULL))
    {
      payload = cockpit_transport_build_control ("command", "close",
                                                 "channel", channel,
                                                 "problem", "disconnected",
                                                 NULL);
      cockpit_transport_send (self->transport, NULL, payload);
      g_bytes_unref (payload);
    }
  g_hash_table_destroy (snapshot);

  return TRUE;
}
Beispiel #22
0
static void
send_init_command (CockpitTransport *transport)
{
  const gchar *checksum;
  JsonObject *object;
  GBytes *bytes;

  object = json_object_new ();
  json_object_set_string_member (object, "command", "init");
  json_object_set_int_member (object, "version", 1);

  checksum = cockpit_packages_get_checksum (packages);
  if (checksum)
    json_object_set_string_member (object, "checksum", checksum);

  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  cockpit_transport_send (transport, NULL, bytes);
  g_bytes_unref (bytes);
}
Beispiel #23
0
/**
 * cockpit_channel_done:
 * @self: the channel
 *
 * Send an EOF to the other side. This should only be called once.
 * Whether an EOF should be sent or not depends on the payload type.
 */
void
cockpit_channel_done (CockpitChannel *self)
{
  JsonObject *object;
  GBytes *message;

  g_return_if_fail (COCKPIT_IS_CHANNEL (self));
  g_return_if_fail (self->priv->sent_done == FALSE);

  self->priv->sent_done = TRUE;

  object = json_object_new ();
  json_object_set_string_member (object, "command", "done");
  json_object_set_string_member (object, "channel", self->priv->id);

  message = cockpit_json_write_bytes (object);
  json_object_unref (object);

  cockpit_transport_send (self->priv->transport, NULL, message);
  g_bytes_unref (message);
}
Beispiel #24
0
static void
cockpit_channel_real_close (CockpitChannel *self,
                            const gchar *problem)
{
  JsonObject *object;
  GBytes *message;

  if (self->priv->sent_close)
    return;

  self->priv->sent_close = TRUE;

  if (!self->priv->transport_closed)
    {
      flush_buffer (self);

      if (self->priv->close_options)
        {
          object = self->priv->close_options;
          self->priv->close_options = NULL;
        }
      else
        {
          object = json_object_new ();
        }

      json_object_set_string_member (object, "command", "close");
      json_object_set_string_member (object, "channel", self->priv->id);
      if (problem)
        json_object_set_string_member (object, "problem", problem);

      message = cockpit_json_write_bytes (object);
      json_object_unref (object);

      cockpit_transport_send (self->priv->transport, NULL, message);
      g_bytes_unref (message);
    }

  g_signal_emit (self, cockpit_channel_sig_closed, 0, problem);
}
Beispiel #25
0
static gboolean
process_ping (CockpitChannel *self,
              JsonObject *ping)
{
  GBytes *payload;

  if (self->priv->throttled)
    {
      g_debug ("%s: received ping while throttled", self->priv->id);
      g_queue_push_tail (self->priv->throttled, json_object_ref (ping));
      return FALSE;
    }
  else
    {
      g_debug ("%s: replying to ping with pong", self->priv->id);
      json_object_set_string_member (ping, "command", "pong");
      payload = cockpit_json_write_bytes (ping);
      cockpit_transport_send (self->priv->transport, NULL, payload);
      g_bytes_unref (payload);
      return TRUE;
    }
}
Beispiel #26
0
static void
send_close_channel (CockpitPortal *self,
                    const gchar *channel_id,
                    const gchar *problem)
{
  JsonObject *object;
  GBytes *bytes;

  g_debug ("sending close for portal channel: %s: %s", channel_id, problem);

  object = json_object_new ();
  json_object_set_string_member (object, "command", "close");
  json_object_set_string_member (object, "channel", channel_id);
  json_object_set_string_member (object, "problem", problem);

  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  if (self->transport)
    cockpit_transport_send (self->transport, NULL, bytes);
  g_bytes_unref (bytes);
}
Beispiel #27
0
static void
cockpit_channel_real_close (CockpitChannel *self,
                            const gchar *problem)
{
  const gchar *reason = problem;
  JsonObject *object;
  GBytes *message;

  if (self->priv->closed)
    return;

  self->priv->closed = TRUE;

  if (reason == NULL)
    reason = "";

  if (self->priv->close_options)
    {
      object = self->priv->close_options;
      self->priv->close_options = NULL;
    }
  else
    {
      object = json_object_new ();
    }

  json_object_set_string_member (object, "command", "close");
  json_object_set_string_member (object, "channel", self->priv->id);
  json_object_set_string_member (object, "reason", reason);

  message = cockpit_json_write_bytes (object);
  json_object_unref (object);

  cockpit_transport_send (self->priv->transport, 0, message);
  g_bytes_unref (message);

  g_signal_emit (self, cockpit_channel_sig_closed, 0, problem);
}
Beispiel #28
0
/**
 * cockpit_channel_send:
 * @self: a pipe
 * @payload: the message payload to send
 * @trust_is_utf8: set to true if sure data is UTF8
 *
 * Called by implementations to send a message over the transport
 * on the right channel.
 *
 * This message is queued, and sent once the transport can.
 */
void
cockpit_channel_send (CockpitChannel *self,
                      GBytes *payload,
                      gboolean trust_is_utf8)
{
  GBytes *encoded = NULL;
  GBytes *validated = NULL;

  if (!trust_is_utf8)
    {
      if (!self->priv->binary_ok)
        payload = validated = check_utf8_and_force_if_necessary (payload);
    }

  if (self->priv->base64_encoding)
    payload = encoded = base64_encode (payload);

  cockpit_transport_send (self->priv->transport, self->priv->id, payload);

  if (encoded)
    g_bytes_unref (encoded);
  if (validated)
    g_bytes_unref (validated);
}
Beispiel #29
0
static void
send_init_command (CockpitTransport *transport,
                   gboolean interactive)
{
  const gchar *checksum;
  JsonObject *object;
  GBytes *bytes;

  object = json_object_new ();
  json_object_set_string_member (object, "command", "init");
  json_object_set_int_member (object, "version", 1);

  /*
   * When in interactive mode pretend we received an init
   * message, and don't print one out.
   */
  if (interactive)
    {
      json_object_set_string_member (object, "host", "localhost");
    }
  else
    {
      checksum = cockpit_packages_get_checksum (packages);
      if (checksum)
        json_object_set_string_member (object, "checksum", checksum);
    }

  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  if (interactive)
    cockpit_transport_emit_recv (transport, NULL, bytes);
  else
    cockpit_transport_send (transport, NULL, bytes);
  g_bytes_unref (bytes);
}
Beispiel #30
0
/**
 * cockpit_channel_send:
 * @self: a pipe
 * @payload: the message payload to send
 *
 * Called by implementations to send a message over the transport
 * on the right channel.
 *
 * This message is queued, and sent once the transport can.
 */
void
cockpit_channel_send (CockpitChannel *self,
                      GBytes *payload)
{
  cockpit_transport_send (self->priv->transport, self->priv->id, payload);
}