static void cockpit_web_response_dispose (GObject *object) { CockpitWebResponse *self = COCKPIT_WEB_RESPONSE (object); if (!self->done) cockpit_web_response_done (self); G_OBJECT_CLASS (cockpit_web_response_parent_class)->dispose (object); }
static void cockpit_web_response_dispose (GObject *object) { CockpitWebResponse *self = COCKPIT_WEB_RESPONSE (object); if (!self->done) cockpit_web_response_done (self); g_list_free_full (self->filters, g_object_unref); self->filters = NULL; G_OBJECT_CLASS (cockpit_web_response_parent_class)->dispose (object); }
/** * cockpit_web_response_abort: * @self: the response * * This function is used when streaming content, and at * some point we can't provide the remainder of the content * * This completes the response and terminates the connection. */ void cockpit_web_response_abort (CockpitWebResponse *self) { g_return_if_fail (self->complete == FALSE); if (self->failed) return; /* Hold a reference until cockpit_web_response_done() */ g_object_ref (self); self->complete = TRUE; self->failed = TRUE; g_debug ("%s: aborted", self->logname); cockpit_web_response_done (self); }
static void on_output_flushed (GObject *stream, GAsyncResult *result, gpointer user_data) { CockpitWebResponse *self = COCKPIT_WEB_RESPONSE (user_data); GOutputStream *output = G_OUTPUT_STREAM (stream); GError *error = NULL; if (g_output_stream_flush_finish (output, result, &error)) { g_debug ("%s: flushed output", self->logname); } else { if (!cockpit_web_should_suppress_output_error (self->logname, error)) g_message ("%s: couldn't flush web output: %s", self->logname, error->message); self->failed = TRUE; g_error_free (error); } cockpit_web_response_done (self); g_object_unref (self); }
static gboolean on_response_output (GObject *pollable, gpointer user_data) { CockpitWebResponse *self = user_data; GError *error = NULL; const guint8 *data; GBytes *block; gssize count; gsize len; block = g_queue_peek_head (self->queue); if (block) { data = g_bytes_get_data (block, &len); g_assert (len == 0 || self->partial_offset < len); data += self->partial_offset; len -= self->partial_offset; if (len > 0) { count = g_pollable_output_stream_write_nonblocking (self->out, data, len, NULL, &error); } else { count = 0; } if (count < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_error_free (error); return TRUE; } if (!cockpit_web_should_suppress_output_error (self->logname, error)) g_message ("%s: couldn't write web output: %s", self->logname, error->message); self->failed = TRUE; cockpit_web_response_done (self); g_error_free (error); return FALSE; } if (count == len) { g_debug ("%s: sent %d bytes", self->logname, (int)len); self->partial_offset = 0; g_queue_pop_head (self->queue); g_bytes_unref (block); } else { g_debug ("%s: sent %d partial", self->logname, (int)count); g_assert (count < len); self->partial_offset += count; } return TRUE; } else { g_source_destroy (self->source); g_source_unref (self->source); self->source = NULL; if (self->complete) { g_debug ("%s: complete flushing output", self->logname); g_output_stream_flush_async (G_OUTPUT_STREAM (self->out), G_PRIORITY_DEFAULT, NULL, on_output_flushed, g_object_ref (self)); } return FALSE; } }