Пример #1
0
static void
cockpit_web_server_set_property (GObject *object,
                                 guint prop_id,
                                 const GValue *value,
                                 GParamSpec *pspec)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (object);

  switch (prop_id)
    {
    case PROP_PORT:
      server->port = g_value_get_int (value);
      break;

    case PROP_CERTIFICATE:
      server->certificate = g_value_dup_object (value);
      break;

    case PROP_DOCUMENT_ROOTS:
      server->document_roots = filter_document_roots (g_value_get_boxed (value));
      break;

    case PROP_SSL_EXCEPTION_PREFIX:
      g_string_assign (server->ssl_exception_prefix, g_value_get_string (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
Пример #2
0
static void
cockpit_web_server_get_property (GObject *object,
                                 guint prop_id,
                                 GValue *value,
                                 GParamSpec *pspec)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (object);

  switch (prop_id)
    {
    case PROP_PORT:
      g_value_set_int (value, cockpit_web_server_get_port (server));
      break;

    case PROP_CERTIFICATE:
      g_value_set_object (value, server->certificate);
      break;

    case PROP_DOCUMENT_ROOTS:
      g_value_set_boxed (value, cockpit_web_server_get_document_roots (server));
      break;

    case PROP_SSL_EXCEPTION_PREFIX:
      g_value_set_string (value, server->ssl_exception_prefix->str);

    case PROP_SOCKET_ACTIVATED:
      g_value_set_boolean (value, server->socket_activated);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
Пример #3
0
static void
on_local_ready (GObject *object,
                GAsyncResult *result,
                gpointer data)
{
  cockpit_web_server_start (COCKPIT_WEB_SERVER (data));
  g_object_unref (data);
}
Пример #4
0
static void
cockpit_web_server_dispose (GObject *object)
{
  CockpitWebServer *self = COCKPIT_WEB_SERVER (object);

  g_hash_table_remove_all (self->requests);

  G_OBJECT_CLASS (cockpit_web_server_parent_class)->dispose (object);
}
Пример #5
0
static void
cockpit_web_server_constructed (GObject *object)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (object);
  static gchar *default_roots[] = { ".", NULL };

  G_OBJECT_CLASS (cockpit_web_server_parent_class)->constructed (object);

  if (server->document_roots == NULL)
    server->document_roots = g_strdupv (default_roots);
}
Пример #6
0
static gboolean
on_incoming (GSocketService *service,
             GSocketConnection *connection,
             GObject *source_object,
             gpointer user_data)
{
  CockpitWebServer *self = COCKPIT_WEB_SERVER (user_data);
  cockpit_request_start (self, G_IO_STREAM (connection), TRUE);

  /* handled */
  return TRUE;
}
Пример #7
0
static void
cockpit_web_server_finalize (GObject *object)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (object);

  g_clear_object (&server->certificate);
  g_strfreev (server->document_roots);
  g_hash_table_destroy (server->requests);
  if (server->main_context)
    g_main_context_unref (server->main_context);
  g_string_free (server->ssl_exception_prefix, TRUE);
  g_clear_object (&server->socket_service);

  G_OBJECT_CLASS (cockpit_web_server_parent_class)->finalize (object);
}
Пример #8
0
CockpitWebServer *
cockpit_web_server_new (gint port,
                        GTlsCertificate *certificate,
                        const gchar **document_roots,
                        GCancellable *cancellable,
                        GError **error)
{
  GInitable *initable;
  initable = g_initable_new (COCKPIT_TYPE_WEB_SERVER,
                             cancellable,
                             error,
                             "port", port,
                             "certificate", certificate,
                             "document-roots", document_roots,
                             NULL);
  if (initable != NULL)
    return COCKPIT_WEB_SERVER (initable);
  else
    return NULL;
}
Пример #9
0
static gboolean
cockpit_web_server_initable_init (GInitable *initable,
                                  GCancellable *cancellable,
                                  GError **error)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (initable);
  gboolean ret = FALSE;
  gboolean failed = FALSE;
  int n, fd;

  server->socket_service = g_socket_service_new ();

  n = sd_listen_fds (0);
  if (n > 0)
    {
      /* We got file descriptors passed in, use those. */

      for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++)
        {
          GSocket *s = NULL;
          gboolean b;
          int type;
          socklen_t l = sizeof (type);

          /*
           * HACK: Workaround g_error() happy code in GSocket
           * https://bugzilla.gnome.org/show_bug.cgi?id=746339
           */
          if (getsockopt (fd, SOL_SOCKET, SO_TYPE, &type, &l) < 0)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "invalid socket passed via systemd activation: %d: %s", fd, g_strerror (errno));
              goto out;
            }

          s = g_socket_new_from_fd (fd, error);
          if (s == NULL)
            {
              g_prefix_error (error, "Failed to acquire passed socket %i: ", fd);
              goto out;
            }

          b = cockpit_web_server_add_socket (server, s, error);
          g_object_unref (s);

          if (!b)
            {
              g_prefix_error (error, "Failed to add listener for socket %i: ", fd);
              goto out;
            }
        }

      server->socket_activated = TRUE;
    }
  else
    {
      /* No fds passed in, let's listen on our own. */
      if (server->port == 0)
        {
          server->port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (server->socket_service),
                                                              NULL, error);
          failed = (server->port == 0);
        }
      else if (server->port > 0)
        {
          failed = !g_socket_listener_add_inet_port (G_SOCKET_LISTENER (server->socket_service),
                                                     server->port, NULL, error);
        }
      if (failed)
        {
          g_prefix_error (error, "Failed to bind to port %d: ", server->port);
          goto out;
        }
    }

  g_signal_connect (server->socket_service,
                    "incoming",
                    G_CALLBACK (on_incoming),
                    server);

  ret = TRUE;

out:
  return ret;
}
Пример #10
0
static void
cockpit_web_server_set_property (GObject *object,
                                 guint prop_id,
                                 const GValue *value,
                                 GParamSpec *pspec)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (object);
  GString *str;
  const gchar *address = NULL;

  switch (prop_id)
    {
    case PROP_PORT:
      server->port = g_value_get_int (value);
      break;

    case PROP_ADDRESS:
      address = g_value_get_string (value);
      if (address)
        {
          server->address = g_inet_address_new_from_string (address);
          if (!server->address)
            g_warning ("Couldn't parse IP address from: %s", address);
        }
      break;

    case PROP_CERTIFICATE:
      server->certificate = g_value_dup_object (value);
      break;

    case PROP_DOCUMENT_ROOTS:
      server->document_roots = cockpit_web_server_resolve_roots (g_value_get_boxed (value));
      break;

    case PROP_SSL_EXCEPTION_PREFIX:
      g_string_assign (server->ssl_exception_prefix, g_value_get_string (value));
      break;

    case PROP_URL_ROOT:
      str = g_string_new (g_value_get_string (value));

      while (str->str[0] == '/')
        g_string_erase (str, 0, 1);

      if (str->len)
        {
          while (str->str[str->len - 1] == '/')
            g_string_truncate (str, str->len - 1);
        }

      if (str->len)
        g_string_printf (server->url_root, "/%s", str->str);
      else
        g_string_assign (server->url_root, str->str);

      g_string_free (str, TRUE);
      break;

    case PROP_REDIRECT_TLS:
      server->redirect_tls = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
Пример #11
0
static gboolean
cockpit_web_server_initable_init (GInitable *initable,
                                  GCancellable *cancellable,
                                  GError **error)
{
  CockpitWebServer *server = COCKPIT_WEB_SERVER (initable);
  gboolean ret = FALSE;
  gboolean failed;
  int n, fd;

  server->socket_service = g_socket_service_new ();

  n = sd_listen_fds (0);
  if (n > 0)
    {
      /* We got file descriptors passed in, use those. */

      for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++)
        {
          GSocket *s = NULL;
          gboolean b;

          s = g_socket_new_from_fd (fd, error);
          if (s == NULL)
            {
              g_prefix_error (error, "Failed to acquire passed socket %i: ", fd);
              goto out;
            }

          b = g_socket_listener_add_socket (G_SOCKET_LISTENER (server->socket_service),
                                            s,
                                            NULL,
                                            error);

          g_object_unref (s);

          if (!b)
            {
              g_prefix_error (error, "Failed to add listener for socket %i: ", fd);
              goto out;
            }
        }

      server->socket_activated = TRUE;
    }
  else
    {
      /* No fds passed in, let's listen on our own. */
      if (server->port == 0)
        {
          server->port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (server->socket_service),
                                                              NULL, error);
          failed = (server->port == 0);
        }
      else
        {
          failed = !g_socket_listener_add_inet_port (G_SOCKET_LISTENER (server->socket_service),
                                                     server->port, NULL, error);
        }
      if (failed)
        {
          g_prefix_error (error, "Failed to bind to port %d: ", server->port);
          goto out;
        }
    }

  g_signal_connect (server->socket_service,
                    "incoming",
                    G_CALLBACK (on_incoming),
                    server);

  ret = TRUE;

out:
  return ret;
}