static gboolean on_handle_stream_socket (CockpitWebServer *server, const gchar *path, GIOStream *io_stream, GHashTable *headers, GByteArray *input, guint in_length, gpointer user_data) { CockpitTransport *transport; const gchar *query = NULL; CockpitCreds *creds; CockpitPipe *pipe; gchar *value; gchar **env; if (!g_str_has_prefix (path, "/cockpit/socket")) return FALSE; if (path[15] == '?') query = path + 16; else if (path[15] != '\0') return FALSE; if (service) { g_object_ref (service); } else { value = g_strdup_printf ("%d", server_port); env = g_environ_setenv (g_get_environ (), "COCKPIT_TEST_SERVER_PORT", value, TRUE); creds = cockpit_creds_new (g_get_user_name (), "test", COCKPIT_CRED_CSRF_TOKEN, "myspecialtoken", NULL); pipe = cockpit_pipe_spawn ((const gchar **)bridge_argv, (const gchar **)env, NULL, FALSE); transport = cockpit_pipe_transport_new (pipe); service = cockpit_web_service_new (creds, transport); cockpit_creds_unref (creds); g_object_unref (transport); g_object_unref (pipe); g_free (value); g_strfreev (env); /* Clear the pointer automatically when service is done */ g_object_add_weak_pointer (G_OBJECT (service), (gpointer *)&service); } if (query) cockpit_channel_socket_open (service, "/cockpit/socket", query, io_stream, headers, input); else cockpit_web_service_socket (service, "/cockpit/socket", io_stream, headers, input); /* Keeps ref on itself until it closes */ g_object_unref (service); return TRUE; }
/* Called by @server when handling HTTP requests to /socket - runs in a separate * thread dedicated to the request so it may do blocking I/O */ static gboolean on_handle_stream_socket (CockpitWebServer *server, CockpitWebServerRequestType reqtype, const gchar *resource, GIOStream *io_stream, GHashTable *headers, GByteArray *input, guint in_length, gpointer user_data) { CockpitWebService *service; CockpitCreds *creds; if (!g_str_equal (resource, "/socket")) return FALSE; creds = cockpit_creds_new (g_get_user_name (), NULL); service = cockpit_web_service_new (creds, NULL); cockpit_web_service_socket (service, io_stream, headers, input); /* Keeps ref on itself until it closes */ g_object_unref (service); cockpit_creds_unref (creds); return TRUE; }
/* Called by @server when handling HTTP requests to /cockpit/socket */ gboolean cockpit_handler_socket (CockpitWebServer *server, const gchar *original_path, const gchar *path, const gchar *method, GIOStream *io_stream, GHashTable *headers, GByteArray *input, CockpitHandlerData *ws) { CockpitWebService *service = NULL; const gchar *segment = NULL; /* * Socket requests should come in on /cockpit/socket or /cockpit+app/socket. * However older javascript may connect on /socket, so we continue to support that. */ if (path && path[0]) segment = strchr (path + 1, '/'); if (!segment) segment = path; if (!segment || !g_str_equal (segment, "/socket")) return FALSE; /* don't support HEAD on a socket, it makes little sense */ if (g_strcmp0 (method, "GET") != 0) return FALSE; if (headers) service = cockpit_auth_check_cookie (ws->auth, path, headers); if (service) { cockpit_web_service_socket (service, path, io_stream, headers, input); g_object_unref (service); } else { handle_noauth_socket (io_stream, path, headers, input); } return TRUE; }
/* Called by @server when handling HTTP requests to /socket - runs in a separate * thread dedicated to the request so it may do blocking I/O */ gboolean cockpit_handler_socket (CockpitWebServer *server, const gchar *path, GIOStream *io_stream, GHashTable *headers, GByteArray *input, guint in_length, CockpitHandlerData *ws) { CockpitWebService *service; const gchar *query = NULL; if (!g_str_has_prefix (path, "/socket")) return FALSE; if (path[7] == '?') query = path + 8; else if (path[7] != '\0') return FALSE; service = cockpit_auth_check_cookie (ws->auth, headers); if (service) { if (query) cockpit_web_service_sideband (service, query, io_stream, headers, input); else cockpit_web_service_socket (service, io_stream, headers, input); g_object_unref (service); } else { cockpit_web_service_noauth (io_stream, headers, input); } return TRUE; }
static gboolean on_handle_stream_socket (CockpitWebServer *server, const gchar *path, GIOStream *io_stream, GHashTable *headers, GByteArray *input, gpointer user_data) { CockpitTransport *transport; const gchar *query = NULL; CockpitCreds *creds; int session_stdin = -1; int session_stdout = -1; GError *error = NULL; GPid pid = 0; gchar *value; gchar **env; gchar **argv; if (!g_str_has_prefix (path, "/cockpit/socket")) return FALSE; if (path[15] == '?') { query = path + 16; } else if (path[15] != '\0') { return FALSE; } if (service) { g_object_ref (service); } else { g_clear_object (&bridge); value = g_strdup_printf ("%d", server_port); env = g_environ_setenv (g_get_environ (), "COCKPIT_TEST_SERVER_PORT", value, TRUE); argv = g_strdupv (bridge_argv); if (query) argv[g_strv_length (argv) - 1] = g_strdup (query); g_spawn_async_with_pipes (NULL, argv, env, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &session_stdin, &session_stdout, NULL, &error); g_strfreev (env); g_free (argv); g_free (value); if (error) { g_critical ("couldn't run bridge %s: %s", bridge_argv[0], error->message); return FALSE; } bridge = g_object_new (COCKPIT_TYPE_PIPE, "name", "test-server-bridge", "in-fd", session_stdout, "out-fd", session_stdin, "pid", pid, NULL); creds = cockpit_creds_new (g_get_user_name (), "test", COCKPIT_CRED_CSRF_TOKEN, "myspecialtoken", NULL); transport = cockpit_pipe_transport_new (bridge); service = cockpit_web_service_new (creds, transport); cockpit_creds_unref (creds); g_object_unref (transport); /* Clear the pointer automatically when service is done */ g_object_add_weak_pointer (G_OBJECT (service), (gpointer *)&service); } cockpit_web_service_socket (service, path, io_stream, headers, input); /* Keeps ref on itself until it closes */ g_object_unref (service); return TRUE; }