Example #1
0
static void
relay_data (CockpitChannel *channel,
            GBytes *data)
{
  GBytes *block;
  gsize size;
  gsize offset;
  gsize length;

  size = g_bytes_get_size (data);
  if (size < 8192)
    {
      cockpit_channel_send (channel, data, FALSE);
    }
  else
    {
      for (offset = 0; offset < size; offset += 4096)
        {
          length = MIN (4096, size - offset);
          block = g_bytes_new_from_bytes (data, offset, length);
          cockpit_channel_send (channel, block, FALSE);
          g_bytes_unref (block);
        }
    }
}
static void
cockpit_echo_channel_recv (CockpitChannel *channel,
                           GBytes *message)
{
  g_debug ("received echo channel payload");
  cockpit_channel_send (channel, message, FALSE);
}
Example #3
0
static void
on_pipe_read (CockpitPipe *pipe,
              GByteArray *data,
              gboolean end_of_data,
              gpointer user_data)
{
  CockpitTextStream *self = user_data;
  CockpitChannel *channel = user_data;
  GBytes *message;
  GBytes *clean;

  if (data->len || !end_of_data)
    {
      /* When array is reffed, this just clears byte array */
      g_byte_array_ref (data);
      message = g_byte_array_free_to_bytes (data);
      clean = check_utf8_and_force_if_necessary (message);
      cockpit_channel_send (channel, clean);
      g_bytes_unref (message);
      g_bytes_unref (clean);
    }

  /* Close the pipe when writing is done */
  if (end_of_data && self->open)
    {
      g_debug ("%s: end of data, closing pipe", self->name);
      cockpit_pipe_close (pipe, NULL);
    }
}
static void
on_socket_message (WebSocketConnection *connection,
                   WebSocketDataType data_type,
                   GBytes *payload,
                   gpointer user_data)
{
  CockpitChannel *channel = COCKPIT_CHANNEL (user_data);
  cockpit_channel_send (channel, payload, data_type == WEB_SOCKET_DATA_TEXT);
}
Example #5
0
static void
write_builder (CockpitDBusJson1 *self,
               JsonBuilder *builder)
{
  GBytes *bytes;

  json_builder_end_object (builder);
  bytes = _json_builder_to_bytes (self, builder);
  cockpit_channel_send (COCKPIT_CHANNEL (self), bytes, TRUE);
  g_bytes_unref (bytes);
}
Example #6
0
void
cockpit_fswatch_emit_event (CockpitChannel    *channel,
                            GFile             *file,
                            GFile             *other_file,
                            GFileMonitorEvent  event_type)
{
  JsonObject *msg;
  GBytes *msg_bytes;

  msg = json_object_new ();
  json_object_set_string_member (msg, "event", event_type_to_string (event_type));
  if (file)
    {
      char *p = g_file_get_path (file);
      char *t = cockpit_get_file_tag (p);
      json_object_set_string_member (msg, "path", p);
      json_object_set_string_member (msg, "tag", t);
      if (event_type == G_FILE_MONITOR_EVENT_CREATED)
        {
          GError *error = NULL;
          GFileInfo *info = g_file_query_info (file,
                                               G_FILE_ATTRIBUTE_STANDARD_TYPE,
                                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                               NULL, &error);
          if (info)
            {
              json_object_set_string_member
                (msg, "type", cockpit_file_type_to_string (g_file_info_get_file_type (info)));
              g_object_unref (info);
            }

          g_clear_error (&error);
      }

      g_free (p);
      g_free (t);
    }
  if (other_file)
    {
      char *p = g_file_get_path (other_file);
      json_object_set_string_member (msg, "other", p);
      g_free (p);
    }
  msg_bytes = cockpit_json_write_bytes (msg);
  json_object_unref (msg);
  cockpit_channel_send (channel, msg_bytes, TRUE);
  g_bytes_unref (msg_bytes);
}
Example #7
0
static void
mock_case_channel_recv (CockpitChannel *channel,
                        GBytes *message)
{
  MockCaseChannel *self = (MockCaseChannel *)channel;
  GByteArray *array = g_bytes_unref_to_array (g_bytes_ref (message));
  GBytes *bytes;
  gsize i;

  for (i = 0; i < array->len; i++)
    array->data[i] = self->function(array->data[i]);

  bytes = g_byte_array_free_to_bytes (array);
  cockpit_channel_send (channel, bytes, FALSE);
  g_bytes_unref (bytes);
}
Example #8
0
static void
write_builder (CockpitDBusJson *self,
               JsonBuilder *builder)
{
  GBytes *bytes;
  JsonNode *root;
  gsize length;
  gchar *ret;

  json_builder_end_object (builder);

  root = json_builder_get_root (builder);
  ret = cockpit_json_write (root, &length);
  json_node_free (root);

  bytes = g_bytes_new_take (ret, length);
  cockpit_channel_send (COCKPIT_CHANNEL (self), bytes);
  g_bytes_unref (bytes);
}
Example #9
0
static void
on_files_listed (GObject *source_object,
                 GAsyncResult *res,
                 gpointer user_data)
{
  GError *error = NULL;
  JsonObject *options;
  GList *files;

  files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source_object), res, &error);
  if (error)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          CockpitFslist *self = COCKPIT_FSLIST (user_data);
          g_message ("%s: couldn't process files %s", COCKPIT_FSLIST(user_data)->path, error->message);
          options = cockpit_channel_close_options (COCKPIT_CHANNEL (self));
          json_object_set_string_member (options, "message", error->message);
          cockpit_channel_close (COCKPIT_CHANNEL (self), "internal-error");
        }
      g_clear_error (&error);
      return;
    }

  CockpitFslist *self = COCKPIT_FSLIST (user_data);

  if (files == NULL)
    {
      JsonObject *msg;
      GBytes *msg_bytes;

      msg = json_object_new ();
      json_object_set_string_member (msg, "event", "present-done");
      msg_bytes = cockpit_json_write_bytes (msg);
      json_object_unref (msg);
      cockpit_channel_send (COCKPIT_CHANNEL(self), msg_bytes, FALSE);
      g_bytes_unref (msg_bytes);

      g_clear_object (&self->cancellable);
      g_object_unref (source_object);

      if (self->monitor == NULL)
        {
          cockpit_channel_done (COCKPIT_CHANNEL (self));
          cockpit_channel_close (COCKPIT_CHANNEL (self), NULL);
        }
      return;
    }

  for (GList *l = files; l; l = l->next)
    {
      GFileInfo *info = G_FILE_INFO (l->data);
      JsonObject *msg;
      GBytes *msg_bytes;

      msg = json_object_new ();
      json_object_set_string_member (msg, "event", "present");
      json_object_set_string_member
        (msg, "path", g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME));
      json_object_set_string_member
        (msg, "type", cockpit_file_type_to_string (g_file_info_get_file_type (info)));
      msg_bytes = cockpit_json_write_bytes (msg);
      json_object_unref (msg);
      cockpit_channel_send (COCKPIT_CHANNEL(self), msg_bytes, FALSE);
      g_bytes_unref (msg_bytes);
    }

  g_list_free_full (files, g_object_unref);

  g_file_enumerator_next_files_async (G_FILE_ENUMERATOR (source_object),
                                      10,
                                      G_PRIORITY_DEFAULT,
                                      self->cancellable,
                                      on_files_listed,
                                      self);
}
Example #10
0
static void
mock_echo_channel_recv (CockpitChannel *channel,
                        GBytes *message)
{
  cockpit_channel_send (channel, message, FALSE);
}
Example #11
0
static gboolean
relay_headers (CockpitHttpStream *self,
               CockpitChannel *channel,
               GByteArray *buffer)
{
  GHashTable *headers = NULL;
  gchar *version = NULL;
  gchar *reason = NULL;
  JsonObject *object;
  const gchar *data;
  JsonObject *heads;
  GHashTableIter iter;
  GBytes *message;
  gpointer key;
  gpointer value;
  guint status;
  gsize length;
  gssize offset;
  gssize offset2;

  data = (const gchar *)buffer->data;
  length = buffer->len;

  offset = web_socket_util_parse_status_line (data, length, &version, &status, &reason);
  if (offset == 0)
    return FALSE; /* want more data */

  if (offset < 0)
    {
      cockpit_channel_fail (channel, "protocol-error",
                            "%s: received response with bad HTTP status line", self->name);
      goto out;
    }

  offset2 = web_socket_util_parse_headers (data + offset, length - offset, &headers);
  if (offset2 == 0)
    return FALSE; /* want more data */

  if (offset2 < 0)
    {
      cockpit_channel_fail (channel, "protocol-error",
                            "%s: received response with bad HTTP headers", self->name);
      goto out;
    }

  g_debug ("%s: response: %u %s", self->name, status, reason);
  g_hash_table_iter_init (&iter, headers);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_debug ("%s: header: %s %s", self->name, (gchar *)key, (gchar *)value);

  if (!parse_transfer_encoding (self, channel, headers) ||
      !parse_content_length (self, channel, status, headers) ||
      !parse_keep_alive (self, channel, version, headers))
    goto out;

  cockpit_pipe_skip (buffer, offset + offset2);

  if (!self->binary)
    {
      g_hash_table_remove (headers, "Content-Length");
      g_hash_table_remove (headers, "Range");
    }
  g_hash_table_remove (headers, "Connection");
  g_hash_table_remove (headers, "Transfer-Encoding");

  /* Now serialize all the rest of this into JSON */
  object = json_object_new ();
  json_object_set_int_member (object, "status", status);
  json_object_set_string_member (object, "reason", reason);

  heads = json_object_new();
  g_hash_table_iter_init (&iter, headers);
  while (g_hash_table_iter_next (&iter, &key, &value))
    json_object_set_string_member (heads, key, value);

  json_object_set_object_member (object, "headers", heads);

  if (self->headers_inline)
    {
      message = cockpit_json_write_bytes (object);
      cockpit_channel_send (channel, message, TRUE);
      g_bytes_unref (message);
    }
  else
    {
      cockpit_channel_control (channel, "response", object);
    }

  json_object_unref (object);

out:
  if (headers)
    g_hash_table_unref (headers);
  g_free (version);
  g_free (reason);

  return TRUE;
}