Beispiel #1
0
static GBytes *
download_uri (const char *url,
              BuilderContext *context,
              GError **error)
{
  SoupSession *session;
  g_autoptr(SoupRequest) req = NULL;
  g_autoptr(GInputStream) input = NULL;
  g_autoptr(GOutputStream) out = NULL;

  session = builder_context_get_soup_session (context);

  req = soup_session_request (session, url, error);
  if (req == NULL)
    return NULL;

  input = soup_request_send (req, NULL, error);
  if (input == NULL)
    return NULL;

  out = g_memory_output_stream_new_resizable ();
  if (!g_output_stream_splice  (out,
                                input,
                                G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
                                NULL,
                                error))
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out));
}
Beispiel #2
0
static GBytes *
download_uri (SoupURI  *uri,
              GError  **error)
{
  g_autoptr(SoupSession) session = NULL;
  g_autoptr(SoupRequest) req = NULL;
  g_autoptr(GInputStream) input = NULL;
  g_autoptr(GOutputStream) out = NULL;

  g_assert (uri != NULL);

  session = get_soup_session ();

  req = soup_session_request_uri (session, uri, error);
  if (req == NULL)
    return NULL;

  input = soup_request_send (req, NULL, error);
  if (input == NULL)
    return NULL;

  out = g_memory_output_stream_new_resizable ();
  if (!g_output_stream_splice (out,
                               input,
                               G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
                               NULL,
                               error))
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out));
}
Beispiel #3
0
/* Default implementation: assume the sync implementation doesn't block */
static void
soup_request_default_send_async (SoupRequest          *request,
				 GCancellable         *cancellable,
				 GAsyncReadyCallback   callback,
				 gpointer              user_data)
{
	GTask *task;
	GInputStream *stream;
	GError *error = NULL;

	task = g_task_new (request, cancellable, callback, user_data);

	stream = soup_request_send (request, cancellable, &error);
	if (stream)
		g_task_return_pointer (task, stream, g_object_unref);
	else
		g_task_return_error (task, error);
	g_object_unref (task);
}
Beispiel #4
0
static gboolean
myopen(FetchData *fetch_data, GError **error)
{
    g_return_val_if_fail(fetch_data != NULL, FALSE);
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
    SoupRequest *request;

    GError *tmp_error = NULL;

    request = (SoupRequest *)soup_session_request_http_uri (session, "GET", fetch_data->url, NULL);
    fetch_data->istream = soup_request_send (request, NULL, &tmp_error);

    if (tmp_error != NULL) {
        gchar *url = soup_uri_to_string (fetch_data->url, TRUE);
        g_propagate_prefixed_error(error, tmp_error,
                "While connecting to %s: ", url);
        g_free (url);
        return FALSE;
    }

    return TRUE;
}
Beispiel #5
0
GInputStream *
soup_test_request_send (SoupRequest   *req,
			GCancellable  *cancellable,
			GError       **error)
{
	AsyncAsSyncData data;
	GInputStream *stream;

	if (SOUP_IS_SESSION_SYNC (soup_request_get_session (req)))
		return soup_request_send (req, cancellable, error);

	data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);

	soup_request_send_async (req, cancellable, async_as_sync_callback, &data);
	g_main_loop_run (data.loop);

	stream = soup_request_send_finish (req, data.result, error);

	g_main_loop_unref (data.loop);
	g_object_unref (data.result);

	return stream;
}
static gboolean
do_one_attempt (gpointer user_data)
{
  GError *local_error = NULL;
  MinCloudAgentApp *self = user_data;
  gs_free char *uri_str = NULL;
  gs_unref_object SoupRequest *request = NULL;
  gs_unref_object GInputStream *instream = NULL;
  gs_unref_object GFileOutputStream *outstream = NULL;
  gs_unref_object GFile *authorized_keys_path = NULL;
  gs_unref_object SoupMessage *msg = NULL;
  SoupURI *uri = NULL;
  const int max_request_failures = 5;
  const char *state_description = NULL;

  /* Skip over already completed states */
 again:
  switch (self->state)
    {
    case MCA_STATE_USER_DATA:
      if (g_file_query_exists (self->userdata_done_stamp, NULL))
        {
          self->state++;
          goto again;
        }
      break;
    case MCA_STATE_OPENSSH_KEY:
      if (g_file_query_exists (self->authorized_keys_path, NULL))
        {
          self->state++;
          goto again;
        }
      break;
    case MCA_STATE_DONE:
      goto out;
    }

  uri = soup_uri_new (NULL);
  soup_uri_set_scheme (uri, "http");
  {
    gs_free char *addr_str = g_inet_address_to_string (self->addr);
    soup_uri_set_host (uri, addr_str);
  }
  soup_uri_set_port (uri, g_inet_socket_address_get_port (self->addr_port));
  switch (self->state)
    {
    case MCA_STATE_USER_DATA:
      soup_uri_set_path (uri, "/2009-04-04/user-data");
      state_description = "user-data";
      break;
    case MCA_STATE_OPENSSH_KEY:
      soup_uri_set_path (uri, "/2009-04-04/meta-data/public-keys/0/openssh-key");
      state_description = "openssh-key";
      break;
    case MCA_STATE_DONE:
      g_assert_not_reached ();
    }

  uri_str = soup_uri_to_string (uri, FALSE);
  g_print ("Requesting '%s'...\n", uri_str);

  request = soup_session_request_uri (self->session, uri, &local_error);
  soup_uri_free (uri);
  if (!request)
    goto out;

  instream = soup_request_send (request, NULL, &local_error);
  if (!instream)
    goto out;

  msg = soup_request_http_get_message ((SoupRequestHTTP*) request);
  if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
    {
      switch (msg->status_code)
        {
        case 404:
        case 410:
          {
            gs_log_structured_print_id_v (MCA_NOT_FOUND_ID, "No %s found", state_description);
            g_clear_error (&local_error);
            /* Note fallthrough to out, where we'll advance to the
               next state */
            goto out;
          }
        default:
          /* Don't actually set the error, we will just continue to
           * the next phase.
           */
          gs_log_structured_print_id_v (MCA_TIMEOUT_ID,
                                        "Error fetching %s: %u %s",
                                        uri_str,
                                        msg->status_code,
                                        soup_status_get_phrase (msg->status_code));
          goto out;
        }
    }

  switch (self->state)
    {
    case MCA_STATE_USER_DATA:
      if (!handle_userdata_script (self, instream, self->cancellable,
                                   &local_error))
        goto out;
      break;
    case MCA_STATE_OPENSSH_KEY:
      if (!handle_install_authorized_keys (self, instream, self->cancellable,
                                           &local_error))
        goto out;
      break;
    default:
      g_assert_not_reached ();
    }

  g_assert (self->state != MCA_STATE_DONE);
  self->state++;
  self->request_failure_count = 0;

 out:
  if (local_error)
    {
      self->request_failure_count++;
      if (self->request_failure_count >= max_request_failures)
        {
          g_error_free (local_error);
          gs_log_structured_print_id_v (MCA_TIMEOUT_ID,
                                        "Reached maximum failed attempts (%u) to fetch metadata",
                                        self->request_failure_count);
          self->do_one_attempt_id = 0;
          self->running = FALSE;
        }
      else
        {
          gs_log_structured_print_id_v (MCA_REQUEST_FAILED_ID,
                                        "Request failed (count: %u): %s", self->request_failure_count,
                                        local_error->message);
          g_error_free (local_error);
          self->do_one_attempt_id = g_timeout_add_seconds (self->request_failure_count,
                                                           do_one_attempt, self);
        }
    }
  else
    {
      /* If we advanced in state, schedule the next callback in an
       * idle so we're consistently scheduled out of an idle.
       */
      if (self->state != MCA_STATE_DONE)
        self->do_one_attempt_id = g_idle_add (do_one_attempt, self);
      else
        {
          self->do_one_attempt_id = 0;
          self->running = FALSE;
        }
    }

  return FALSE;
}