CockpitStream * cockpit_stream_connect (const gchar *name, CockpitConnectable *connectable) { CockpitStream *self; g_return_val_if_fail (connectable != NULL, NULL); self = g_object_new (COCKPIT_TYPE_STREAM, "io-stream", NULL, "name", name, NULL); self->priv->connecting = cockpit_connectable_ref (connectable); cockpit_connect_stream_full (self->priv->connecting, NULL, on_connect_stream, g_object_ref (self)); return self; }
static void cockpit_http_stream_prepare (CockpitChannel *channel) { CockpitHttpStream *self = COCKPIT_HTTP_STREAM (channel); CockpitConnectable *connectable = NULL; const gchar *payload; const gchar *connection; JsonObject *options; const gchar *path; COCKPIT_CHANNEL_CLASS (cockpit_http_stream_parent_class)->prepare (channel); if (self->failed) goto out; options = cockpit_channel_get_options (channel); if (!cockpit_json_get_string (options, "connection", NULL, &connection)) { cockpit_channel_fail (channel, "protocol-error", "bad \"connection\" field in HTTP stream request"); goto out; } if (!cockpit_json_get_string (options, "path", "/", &path)) { cockpit_channel_fail (channel, "protocol-error", "bad \"path\" field in HTTP stream request"); goto out; } /* * In http-stream1 the headers are sent as first message. * In http-stream2 the headers are in a control message. */ if (cockpit_json_get_string (options, "payload", NULL, &payload) && payload && g_str_equal (payload, "http-stream1")) { self->headers_inline = TRUE; } self->client = cockpit_http_client_ensure (connection); if (!self->client->connectable || json_object_has_member (options, "unix") || json_object_has_member (options, "port") || json_object_has_member (options, "internal") || json_object_has_member (options, "tls") || json_object_has_member (options, "address")) { connectable = cockpit_connect_parse_stream (channel); if (!connectable) goto out; if (self->client->connectable) cockpit_connectable_unref (self->client->connectable); self->client->connectable = cockpit_connectable_ref (connectable); } self->name = g_strdup_printf ("%s://%s%s", self->client->connectable->tls ? "https" : "http", self->client->connectable->name, path); self->stream = cockpit_http_client_checkout (self->client); if (!self->stream) { self->stream = cockpit_stream_connect (self->name, self->client->connectable); self->sig_open = g_signal_connect (self->stream, "open", G_CALLBACK (on_stream_open), self); } /* Parsed elsewhere */ self->binary = json_object_has_member (options, "binary"); self->sig_read = g_signal_connect (self->stream, "read", G_CALLBACK (on_stream_read), self); self->sig_close = g_signal_connect (self->stream, "close", G_CALLBACK (on_stream_close), self); self->sig_rejected_cert = g_signal_connect (self->stream, "rejected-cert", G_CALLBACK (on_rejected_cert), self); /* Let the channel throttle the stream's input flow*/ cockpit_flow_throttle (COCKPIT_FLOW (self->stream), COCKPIT_FLOW (self)); /* Let the stream throtlte the channel peer's output flow */ cockpit_flow_throttle (COCKPIT_FLOW (channel), COCKPIT_FLOW (self->stream)); /* If not waiting for open */ if (!self->sig_open) cockpit_channel_ready (channel, NULL); out: if (connectable) cockpit_connectable_unref (connectable); }