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)); }
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)); }
/* 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); }
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; }
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; }