static void process_open (CockpitRouter *self, CockpitTransport *transport, const gchar *channel, JsonObject *options, GBytes *data) { GList *l; GBytes *new_payload = NULL; if (!channel) { g_warning ("Caller tried to open channel with invalid id"); cockpit_transport_close (transport, "protocol-error"); } /* Check that this isn't a local channel */ else if (g_hash_table_lookup (self->channels, channel)) { g_warning ("%s: caller tried to reuse a channel that's already in use", channel); cockpit_transport_close (self->transport, "protocol-error"); return; } /* Request that this channel is frozen, and requeue its open message for later */ else if (g_hash_table_size (self->fences) > 0 && !g_hash_table_lookup (self->fences, channel)) { if (!self->fenced) self->fenced = g_queue_new (); g_queue_push_tail (self->fenced, g_strdup (channel)); cockpit_transport_freeze (self->transport, channel); cockpit_transport_emit_control (self->transport, "open", channel, options, data); } else if (!cockpit_router_normalize_host (self, options)) { g_warning ("%s: caller specified invalid 'host' field in open message", channel); process_open_not_supported (self, channel, options, data, NULL); } /* Now go throgh the rules */ else { cockpit_router_normalize_host_params (options); new_payload = cockpit_json_write_bytes (options); for (l = self->rules; l != NULL; l = g_list_next (l)) { if (router_rule_match (l->data, options) && router_rule_invoke (l->data, self, channel, options, new_payload)) { break; } } } if (new_payload) g_bytes_unref (new_payload); }
static void cockpit_channel_constructed (GObject *object) { CockpitChannel *self = COCKPIT_CHANNEL (object); G_OBJECT_CLASS (cockpit_channel_parent_class)->constructed (object); g_return_if_fail (self->priv->id != NULL); g_return_if_fail (self->priv->transport != NULL); self->priv->capabilities = NULL; self->priv->recv_sig = g_signal_connect (self->priv->transport, "recv", G_CALLBACK (on_transport_recv), self); self->priv->control_sig = g_signal_connect (self->priv->transport, "control", G_CALLBACK (on_transport_control), self); self->priv->close_sig = g_signal_connect (self->priv->transport, "closed", G_CALLBACK (on_transport_closed), self); /* Freeze this channel's messages until ready */ cockpit_transport_freeze (self->priv->transport, self->priv->id); self->priv->prepare_tag = g_idle_add_full (G_PRIORITY_HIGH, on_idle_prepare, self, NULL); }