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 GBytes * build_environment (GHashTable *os_release) { /* * We don't include entirety of os-release into the * environment for the login.html page. There could * be unexpected things in here. * * However since we are displaying branding based on * the OS name variant flavor and version, including * the corresponding information is not a leak. */ static const gchar *release_fields[] = { "NAME", "ID", "PRETTY_NAME", "VARIANT", "VARIANT_ID", "CPE_NAME", }; static const gchar *prefix = "\n <script>\nvar environment = "; static const gchar *suffix = ";\n </script>"; GByteArray *buffer; GBytes *bytes; JsonObject *object; const gchar *value; gchar *hostname; JsonObject *osr; gint i; object = json_object_new (); add_page_to_environment (object); hostname = g_malloc0 (HOST_NAME_MAX + 1); gethostname (hostname, HOST_NAME_MAX); hostname[HOST_NAME_MAX] = '\0'; json_object_set_string_member (object, "hostname", hostname); g_free (hostname); if (os_release) { osr = json_object_new (); for (i = 0; i < G_N_ELEMENTS (release_fields); i++) { value = g_hash_table_lookup (os_release, release_fields[i]); if (value) json_object_set_string_member (osr, release_fields[i], value); } json_object_set_object_member (object, "os-release", osr); } add_oauth_to_environment (object); bytes = cockpit_json_write_bytes (object); json_object_unref (object); buffer = g_bytes_unref_to_array (bytes); g_byte_array_prepend (buffer, (const guint8 *)prefix, strlen (prefix)); g_byte_array_append (buffer, (const guint8 *)suffix, strlen (suffix)); return g_byte_array_free_to_bytes (buffer); }
static void byte_array_ensure_gbytes (ByteArrayInstance *priv) { if (priv->array) { priv->bytes = g_byte_array_free_to_bytes(priv->array); priv->array = NULL; } else { g_assert(priv->bytes); } }
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); }
static GBytes * build_environment (GHashTable *os_release) { static const gchar *prefix = "\n <script>\nvar environment = "; static const gchar *suffix = ";\n </script>"; GByteArray *buffer; GHashTableIter iter; GBytes *bytes; JsonObject *object; const gchar *title; gchar *hostname; gpointer key, value; JsonObject *osr; object = json_object_new (); title = cockpit_conf_string ("WebService", "LoginTitle"); if (title) json_object_set_string_member (object, "title", title); hostname = g_malloc0 (HOST_NAME_MAX + 1); gethostname (hostname, HOST_NAME_MAX); hostname[HOST_NAME_MAX] = '\0'; json_object_set_string_member (object, "hostname", hostname); g_free (hostname); if (os_release) { osr = json_object_new (); g_hash_table_iter_init (&iter, os_release); while (g_hash_table_iter_next (&iter, &key, &value)) json_object_set_string_member (osr, key, value); json_object_set_object_member (object, "os-release", osr); } add_oauth_to_environment (object); bytes = cockpit_json_write_bytes (object); json_object_unref (object); buffer = g_bytes_unref_to_array (bytes); g_byte_array_prepend (buffer, (const guint8 *)prefix, strlen (prefix)); g_byte_array_append (buffer, (const guint8 *)suffix, strlen (suffix)); return g_byte_array_free_to_bytes (buffer); }
static void on_echo_socket_message (WebSocketConnection *self, WebSocketDataType type, GBytes *message, gpointer user_data) { GByteArray *array = g_bytes_unref_to_array (g_bytes_ref (message)); GBytes *payload; guint i; /* Capitalize and relay back */ for (i = 0; i < array->len; i++) array->data[i] = g_ascii_toupper (array->data[i]); payload = g_byte_array_free_to_bytes (array); web_socket_connection_send (self, type, NULL, payload); g_bytes_unref (payload); }
/** * cockpit_web_response_gunzip: * @bytes: the compressed bytes * @error: place to put an error * * Perform gzip decompression on the @bytes. * * Returns: the uncompressed bytes, caller owns return value. */ GBytes * cockpit_web_response_gunzip (GBytes *bytes, GError **error) { GConverter *converter; GConverterResult result; const guint8 *in; gsize inl, outl, read, written; GByteArray *out; converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP)); in = g_bytes_get_data (bytes, &inl); out = g_byte_array_new (); do { outl = out->len; g_byte_array_set_size (out, outl + inl); result = g_converter_convert (converter, in, inl, out->data + outl, inl, G_CONVERTER_INPUT_AT_END, &read, &written, error); if (result == G_CONVERTER_ERROR) break; g_byte_array_set_size (out, outl + written); in += read; inl -= read; } while (result != G_CONVERTER_FINISHED); g_object_unref (converter); if (result != G_CONVERTER_FINISHED) { g_byte_array_unref (out); return NULL; } else { return g_byte_array_free_to_bytes (out); } }
/** * 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) { const guint8 *data; gsize length; GBytes *send_data = payload; GByteArray *combined; if (self->priv->buffer_timeout) g_source_remove(self->priv->buffer_timeout); self->priv->buffer_timeout = 0; if (self->priv->out_buffer) { combined = g_bytes_unref_to_array (self->priv->out_buffer); self->priv->out_buffer = NULL; data = g_bytes_get_data (payload, &length); g_byte_array_append (combined, data, length); send_data = g_byte_array_free_to_bytes (combined); trust_is_utf8 = FALSE; } if (!trust_is_utf8 && !self->priv->binary_ok) { if (cockpit_unicode_has_incomplete_ending (send_data)) { self->priv->out_buffer = g_bytes_ref (send_data); self->priv->buffer_timeout = g_timeout_add (500, flush_buffer, self); } } if (!self->priv->buffer_timeout) cockpit_channel_actual_send (self, send_data, trust_is_utf8); if (send_data != payload) g_bytes_unref (send_data); }