diff options
Diffstat (limited to 'src/nm-cloud-setup/nm-http-client.c')
| -rw-r--r-- | src/nm-cloud-setup/nm-http-client.c | 161 |
1 files changed, 87 insertions, 74 deletions
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c index a0964e21..db123f10 100644 --- a/src/nm-cloud-setup/nm-http-client.c +++ b/src/nm-cloud-setup/nm-http-client.c @@ -104,12 +104,12 @@ typedef struct { } GetResult; static void -_get_result_free(gpointer data) +_req_result_free(gpointer data) { - GetResult *get_result = data; + GetResult *req_result = data; - g_bytes_unref(get_result->response_data); - nm_g_slice_free(get_result); + g_bytes_unref(req_result->response_data); + nm_g_slice_free(req_result); } typedef struct { @@ -154,7 +154,7 @@ _ehandle_free(EHandleData *edata) static void _ehandle_complete(EHandleData *edata, GError *error_take) { - GetResult *get_result; + GetResult *req_result; gs_free char *str_tmp_1 = NULL; long response_code = -1; @@ -200,15 +200,15 @@ _ehandle_complete(EHandleData *edata, GError *error_take) _ehandle_free_ehandle(edata); - get_result = g_slice_new(GetResult); - *get_result = (GetResult){ + req_result = g_slice_new(GetResult); + *req_result = (GetResult){ .response_code = response_code, /* This ensures that response_data is always NUL terminated. This is an important guarantee * that NMHttpClient makes. */ .response_data = nm_str_buf_finalize_to_gbytes(&edata->recv_data), }; - g_task_return_pointer(edata->task, get_result, _get_result_free); + g_task_return_pointer(edata->task, req_result, _req_result_free); _ehandle_free(edata); } @@ -256,12 +256,13 @@ _get_cancelled_cb(GObject *object, gpointer user_data) _ehandle_complete(edata, error); } -void -nm_http_client_get(NMHttpClient *self, +static void +nm_http_client_req(NMHttpClient *self, const char *url, int timeout_msec, gssize max_data, const char *const *http_headers, + const char *http_method, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -280,7 +281,7 @@ nm_http_client_get(NMHttpClient *self, edata = g_slice_new(EHandleData); *edata = (EHandleData){ - .task = nm_g_task_new(self, cancellable, nm_http_client_get, callback, user_data), + .task = nm_g_task_new(self, cancellable, nm_http_client_req, callback, user_data), .recv_data = NM_STR_BUF_INIT(0, FALSE), .max_data = max_data, .url = g_strdup(url), @@ -289,7 +290,7 @@ nm_http_client_get(NMHttpClient *self, nmcs_wait_for_objects_register(edata->task); - _LOG2D(edata, "start get ..."); + _LOG2D(edata, "start %s ...", http_method ?: "get"); edata->ehandle = curl_easy_init(); if (!edata->ehandle) { @@ -328,6 +329,9 @@ nm_http_client_get(NMHttpClient *self, curl_easy_setopt(edata->ehandle, CURLOPT_HTTPHEADER, edata->headers); } + if (http_method) + curl_easy_setopt(edata->ehandle, CURLOPT_CUSTOMREQUEST, http_method); + if (timeout_msec > 0) { edata->timeout_source = _source_attach(self, nm_g_timeout_source_new(timeout_msec, @@ -352,7 +356,7 @@ nm_http_client_get(NMHttpClient *self, } /** - * nm_http_client_get_finish: + * nm_http_client_req_finish: * @self: the #NMHttpClient instance * @result: the #GAsyncResult which to complete. * @out_response_code: (allow-none) (out): the HTTP response code or -1 on other error. @@ -366,34 +370,34 @@ nm_http_client_get(NMHttpClient *self, * * Returns: %TRUE on success or %FALSE with an error code. */ -gboolean -nm_http_client_get_finish(NMHttpClient *self, +static gboolean +nm_http_client_req_finish(NMHttpClient *self, GAsyncResult *result, long *out_response_code, GBytes **out_response_data, GError **error) { - GetResult *get_result; + GetResult *req_result; g_return_val_if_fail(NM_IS_HTTP_CLIENT(self), FALSE); - g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_http_client_get), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_http_client_req), FALSE); - get_result = g_task_propagate_pointer(G_TASK(result), error); + req_result = g_task_propagate_pointer(G_TASK(result), error); - nm_assert(!error || (!!get_result) == (!*error)); + nm_assert(!error || (!!req_result) == (!*error)); - if (!get_result) { + if (!req_result) { NM_SET_OUT(out_response_code, -1); NM_SET_OUT(out_response_data, NULL); return FALSE; } - NM_SET_OUT(out_response_code, get_result->response_code); + NM_SET_OUT(out_response_code, req_result->response_code); /* response_data is binary, but is also guaranteed to be NUL terminated! */ - NM_SET_OUT(out_response_data, g_steal_pointer(&get_result->response_data)); + NM_SET_OUT(out_response_data, g_steal_pointer(&req_result->response_data)); - _get_result_free(get_result); + _req_result_free(req_result); return TRUE; } @@ -403,63 +407,65 @@ typedef struct { GTask *task; char *uri; const char *const *http_headers; - NMHttpClientPollGetCheckFcn check_fcn; + const char *http_method; + NMHttpClientPollReqCheckFcn check_fcn; gpointer check_user_data; GBytes *response_data; gsize request_max_data; long response_code; int request_timeout_ms; -} PollGetData; +} PollReqData; static void -_poll_get_data_free(gpointer data) +_poll_req_data_free(gpointer data) { - PollGetData *poll_get_data = data; + PollReqData *poll_req_data = data; - g_free(poll_get_data->uri); + g_free(poll_req_data->uri); - nm_clear_pointer(&poll_get_data->response_data, g_bytes_unref); - g_strfreev((char **) poll_get_data->http_headers); + nm_clear_pointer(&poll_req_data->response_data, g_bytes_unref); + g_free((gpointer) poll_req_data->http_headers); - nm_g_slice_free(poll_get_data); + nm_g_slice_free(poll_req_data); } static void -_poll_get_probe_start_fcn(GCancellable *cancellable, +_poll_req_probe_start_fcn(GCancellable *cancellable, gpointer probe_user_data, GAsyncReadyCallback callback, gpointer user_data) { - PollGetData *poll_get_data = probe_user_data; + PollReqData *poll_req_data = probe_user_data; - /* balanced by _poll_get_probe_finish_fcn() */ - g_object_ref(poll_get_data->task); + /* balanced by _poll_req_probe_finish_fcn() */ + g_object_ref(poll_req_data->task); - nm_http_client_get(g_task_get_source_object(poll_get_data->task), - poll_get_data->uri, - poll_get_data->request_timeout_ms, - poll_get_data->request_max_data, - poll_get_data->http_headers, + nm_http_client_req(g_task_get_source_object(poll_req_data->task), + poll_req_data->uri, + poll_req_data->request_timeout_ms, + poll_req_data->request_max_data, + poll_req_data->http_headers, + poll_req_data->http_method, cancellable, callback, user_data); } static gboolean -_poll_get_probe_finish_fcn(GObject *source, +_poll_req_probe_finish_fcn(GObject *source, GAsyncResult *result, gpointer probe_user_data, GError **error) { - PollGetData *poll_get_data = probe_user_data; + PollReqData *poll_req_data = probe_user_data; _nm_unused gs_unref_object GTask *task = - poll_get_data->task; /* balance ref from _poll_get_probe_start_fcn() */ + poll_req_data->task; /* balance ref from _poll_req_probe_start_fcn() */ gboolean success; gs_free_error GError *local_error = NULL; gs_unref_bytes GBytes *response_data = NULL; long response_code = -1; - success = nm_http_client_get_finish(g_task_get_source_object(poll_get_data->task), + success = nm_http_client_req_finish(g_task_get_source_object(poll_req_data->task), result, &response_code, &response_data, @@ -476,10 +482,10 @@ _poll_get_probe_finish_fcn(GObject *source, return FALSE; } - if (poll_get_data->check_fcn) { - success = poll_get_data->check_fcn(response_code, + if (poll_req_data->check_fcn) { + success = poll_req_data->check_fcn(response_code, response_data, - poll_get_data->check_user_data, + poll_req_data->check_user_data, &local_error); } else success = (response_code == 200); @@ -494,15 +500,15 @@ _poll_get_probe_finish_fcn(GObject *source, return FALSE; } - poll_get_data->response_code = response_code; - poll_get_data->response_data = g_steal_pointer(&response_data); + poll_req_data->response_code = response_code; + poll_req_data->response_data = g_steal_pointer(&response_data); return TRUE; } static void -_poll_get_done_cb(GObject *source, GAsyncResult *result, gpointer user_data) +_poll_req_done_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - PollGetData *poll_get_data = user_data; + PollReqData *poll_req_data = user_data; gs_free_error GError *error = NULL; gboolean success; @@ -511,29 +517,30 @@ _poll_get_done_cb(GObject *source, GAsyncResult *result, gpointer user_data) nm_assert((!!success) == (!error)); if (error) - g_task_return_error(poll_get_data->task, g_steal_pointer(&error)); + g_task_return_error(poll_req_data->task, g_steal_pointer(&error)); else - g_task_return_boolean(poll_get_data->task, TRUE); + g_task_return_boolean(poll_req_data->task, TRUE); - g_object_unref(poll_get_data->task); + g_object_unref(poll_req_data->task); } void -nm_http_client_poll_get(NMHttpClient *self, +nm_http_client_poll_req(NMHttpClient *self, const char *uri, int request_timeout_ms, gssize request_max_data, int poll_timeout_ms, int ratelimit_timeout_ms, const char *const *http_headers, + const char *http_method, GCancellable *cancellable, - NMHttpClientPollGetCheckFcn check_fcn, + NMHttpClientPollReqCheckFcn check_fcn, gpointer check_user_data, GAsyncReadyCallback callback, gpointer user_data) { nm_auto_pop_gmaincontext GMainContext *context = NULL; - PollGetData *poll_get_data; + PollReqData *poll_req_data; g_return_if_fail(NM_IS_HTTP_CLIENT(self)); g_return_if_fail(uri && uri[0]); @@ -543,21 +550,27 @@ nm_http_client_poll_get(NMHttpClient *self, g_return_if_fail(ratelimit_timeout_ms >= -1); g_return_if_fail(!cancellable || G_CANCELLABLE(cancellable)); - poll_get_data = g_slice_new(PollGetData); - *poll_get_data = (PollGetData){ - .task = nm_g_task_new(self, cancellable, nm_http_client_poll_get, callback, user_data), + poll_req_data = g_slice_new(PollReqData); + *poll_req_data = (PollReqData){ + .task = nm_g_task_new(self, cancellable, nm_http_client_poll_req, callback, user_data), .uri = g_strdup(uri), .request_timeout_ms = request_timeout_ms, .request_max_data = request_max_data, .check_fcn = check_fcn, .check_user_data = check_user_data, .response_code = -1, - .http_headers = NM_CAST_STRV_CC(g_strdupv((char **) http_headers)), + .http_headers = NULL, + .http_method = http_method, }; - nmcs_wait_for_objects_register(poll_get_data->task); + if (http_headers) { + poll_req_data->http_headers = + nm_strv_dup_packed(http_headers, -1) ?: g_new(const char *, 1); + } + + nmcs_wait_for_objects_register(poll_req_data->task); - g_task_set_task_data(poll_get_data->task, poll_get_data, _poll_get_data_free); + g_task_set_task_data(poll_req_data->task, poll_req_data, _poll_req_data_free); context = nm_g_main_context_push_thread_default_if_necessary(nm_http_client_get_main_context(self)); @@ -565,28 +578,28 @@ nm_http_client_poll_get(NMHttpClient *self, nmcs_utils_poll(poll_timeout_ms, ratelimit_timeout_ms, 0, - _poll_get_probe_start_fcn, - _poll_get_probe_finish_fcn, - poll_get_data, + _poll_req_probe_start_fcn, + _poll_req_probe_finish_fcn, + poll_req_data, cancellable, - _poll_get_done_cb, - poll_get_data); + _poll_req_done_cb, + poll_req_data); } gboolean -nm_http_client_poll_get_finish(NMHttpClient *self, +nm_http_client_poll_req_finish(NMHttpClient *self, GAsyncResult *result, long *out_response_code, GBytes **out_response_data, GError **error) { - PollGetData *poll_get_data; + PollReqData *poll_req_data; GTask *task; gboolean success; gs_free_error GError *local_error = NULL; g_return_val_if_fail(NM_HTTP_CLIENT(self), FALSE); - g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_http_client_poll_get), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_http_client_poll_req), FALSE); task = G_TASK(result); @@ -601,10 +614,10 @@ nm_http_client_poll_get_finish(NMHttpClient *self, return FALSE; } - poll_get_data = g_task_get_task_data(task); + poll_req_data = g_task_get_task_data(task); - NM_SET_OUT(out_response_code, poll_get_data->response_code); - NM_SET_OUT(out_response_data, g_steal_pointer(&poll_get_data->response_data)); + NM_SET_OUT(out_response_code, poll_req_data->response_code); + NM_SET_OUT(out_response_data, g_steal_pointer(&poll_req_data->response_data)); return TRUE; } |