summary refs log tree commit diff
path: root/clients/cloud-setup/nm-http-client.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-06-29 22:15:58 +0200
committerMichael Biebl <biebl@debian.org>2020-06-29 22:15:58 +0200
commit10ae7d8cd706062742d0cdb1803d49909aef9e06 (patch)
treecb89e8b475cec18f22b1abfe45f1d63da7e3f440 /clients/cloud-setup/nm-http-client.c
parenta54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (diff)
New upstream version 1.25.91 upstream/1.25.91
Diffstat (limited to 'clients/cloud-setup/nm-http-client.c')
-rw-r--r--clients/cloud-setup/nm-http-client.c63
1 files changed, 51 insertions, 12 deletions
diff --git a/clients/cloud-setup/nm-http-client.c b/clients/cloud-setup/nm-http-client.c
index 94f3fe2b..946ed8ce 100644
--- a/clients/cloud-setup/nm-http-client.c
+++ b/clients/cloud-setup/nm-http-client.c
@@ -16,7 +16,7 @@ typedef struct {
 	GMainContext *context;
 	CURLM *mhandle;
 	GSource *mhandle_source_timeout;
-	GSource *mhandle_source_socket;
+	GHashTable *source_sockets_hashtable;
 } NMHttpClientPrivate;
 
 struct _NMHttpClient {
@@ -119,6 +119,7 @@ typedef struct {
 	CURL *ehandle;
 	char *url;
 	GString *recv_data;
+	struct curl_slist *headers;
 	gssize max_data;
 	gulong cancellable_id;
 } EHandleData;
@@ -145,6 +146,8 @@ _ehandle_free (EHandleData *edata)
 
 	if (edata->recv_data)
 		g_string_free (edata->recv_data, TRUE);
+	if (edata->headers)
+		curl_slist_free_all (edata->headers);
 	g_free (edata->url);
 	nm_g_slice_free (edata);
 }
@@ -159,8 +162,8 @@ _ehandle_complete (EHandleData *edata,
 
 	nm_clear_pointer (&edata->timeout_source, nm_g_source_destroy_and_unref);
 
-	 nm_clear_g_cancellable_disconnect (g_task_get_cancellable (edata->task),
-	                                    &edata->cancellable_id);
+	nm_clear_g_cancellable_disconnect (g_task_get_cancellable (edata->task),
+	                                   &edata->cancellable_id);
 
 	if (error_take) {
 		if (nm_utils_error_is_cancelled (error_take))
@@ -260,12 +263,14 @@ nm_http_client_get (NMHttpClient *self,
                     const char *url,
                     int timeout_msec,
                     gssize max_data,
+                    const char *const *http_headers,
                     GCancellable *cancellable,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
 {
 	NMHttpClientPrivate *priv;
 	EHandleData *edata;
+	guint i;
 
 	g_return_if_fail (NM_IS_HTTP_CLIENT (self));
 	g_return_if_fail (url);
@@ -281,6 +286,7 @@ nm_http_client_get (NMHttpClient *self,
 		.recv_data      = g_string_sized_new (NM_MIN (max_data, 245)),
 		.max_data       = max_data,
 		.url            = g_strdup (url),
+		.headers        = NULL,
 	};
 
 	nmcs_wait_for_objects_register (edata->task);
@@ -302,6 +308,23 @@ nm_http_client_get (NMHttpClient *self,
 	curl_easy_setopt (edata->ehandle, CURLOPT_WRITEDATA, edata);
 	curl_easy_setopt (edata->ehandle, CURLOPT_PRIVATE, edata);
 
+	if (http_headers) {
+		for (i = 0; http_headers[i]; ++i) {
+			struct curl_slist *tmp;
+
+			tmp = curl_slist_append (edata->headers,
+			                         http_headers[i]);
+			if (!tmp) {
+				curl_slist_free_all (tmp);
+				_LOGE ("curl: curl_slist_append() failed adding %s", http_headers[i]);
+				continue;
+			}
+			edata->headers = tmp;
+		}
+
+		curl_easy_setopt (edata->ehandle, CURLOPT_HTTPHEADER, edata->headers);
+	}
+
 	if (timeout_msec > 0) {
 		edata->timeout_source = _source_attach (self,
 		                                        nm_g_timeout_source_new (timeout_msec,
@@ -362,6 +385,7 @@ nm_http_client_get_finish (NMHttpClient *self,
 typedef struct {
 	GTask *task;
 	char *uri;
+	const char *const *http_headers;
 	NMHttpClientPollGetCheckFcn check_fcn;
 	gpointer check_user_data;
 	GBytes *response_data;
@@ -378,6 +402,7 @@ _poll_get_data_free (gpointer data)
 	g_free (poll_get_data->uri);
 
 	nm_clear_pointer (&poll_get_data->response_data, g_bytes_unref);
+	g_strfreev ((char **) poll_get_data->http_headers);
 
 	nm_g_slice_free (poll_get_data);
 }
@@ -397,6 +422,7 @@ _poll_get_probe_start_fcn (GCancellable *cancellable,
 	                    poll_get_data->uri,
 	                    poll_get_data->request_timeout_ms,
 	                    poll_get_data->request_max_data,
+	                    poll_get_data->http_headers,
 	                    cancellable,
 	                    callback,
 	                    user_data);
@@ -476,6 +502,7 @@ nm_http_client_poll_get (NMHttpClient *self,
                          gssize request_max_data,
                          int poll_timeout_ms,
                          int ratelimit_timeout_ms,
+                         const char *const *http_headers,
                          GCancellable *cancellable,
                          NMHttpClientPollGetCheckFcn check_fcn,
                          gpointer check_user_data,
@@ -502,6 +529,7 @@ nm_http_client_poll_get (NMHttpClient *self,
 		.check_fcn          = check_fcn,
 		.check_user_data    = check_user_data,
 		.response_code      = -1,
+		.http_headers       =  NM_CAST_STRV_CC (g_strdupv ((char **) http_headers)),
 	};
 
 	nmcs_wait_for_objects_register (poll_get_data->task);
@@ -615,12 +643,13 @@ _mhandle_socket_cb (int fd,
 static int
 _mhandle_socketfunction_cb (CURL *e_handle, curl_socket_t fd, int what, void *user_data, void *socketp)
 {
+	GSource *source_socket;
 	NMHttpClient *self = user_data;
 	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
 
 	(void) _NM_ENSURE_TYPE (int, fd);
 
-	nm_clear_g_source_inst (&priv->mhandle_source_socket);
+	g_hash_table_remove (priv->source_sockets_hashtable, GINT_TO_POINTER (fd));
 
 	if (what != CURL_POLL_REMOVE) {
 		GIOCondition condition = 0;
@@ -635,13 +664,17 @@ _mhandle_socketfunction_cb (CURL *e_handle, curl_socket_t fd, int what, void *us
 			condition = 0;
 
 		if (condition) {
-			priv->mhandle_source_socket = nm_g_unix_fd_source_new (fd,
-			                                                       condition,
-			                                                       G_PRIORITY_DEFAULT,
-			                                                       _mhandle_socket_cb,
-			                                                       self,
+			source_socket = nm_g_unix_fd_source_new (fd,
+			                                         condition,
+			                                         G_PRIORITY_DEFAULT,
+			                                         _mhandle_socket_cb,
+			                                         self,
 			                                                       NULL);
-			g_source_attach (priv->mhandle_source_socket, priv->context);
+			g_source_attach (source_socket, priv->context);
+
+			g_hash_table_insert (priv->source_sockets_hashtable,
+			                     GINT_TO_POINTER (fd),
+			                     source_socket);
 		}
 	}
 
@@ -652,7 +685,7 @@ static gboolean
 _mhandle_timeout_cb (gpointer user_data)
 {
 	_mhandle_action (user_data, CURL_SOCKET_TIMEOUT, 0);
-	return G_SOURCE_CONTINUE;
+	return G_SOURCE_REMOVE;
 }
 
 static int
@@ -678,6 +711,12 @@ _mhandle_timerfunction_cb (CURLM *multi, long timeout_msec, void *user_data)
 static void
 nm_http_client_init (NMHttpClient *self)
 {
+	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
+
+	priv->source_sockets_hashtable = g_hash_table_new_full (nm_direct_hash,
+	                                                        NULL,
+	                                                        NULL,
+	                                                        (GDestroyNotify) nm_g_source_destroy_and_unref);
 }
 
 static void
@@ -714,9 +753,9 @@ dispose (GObject *object)
 	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
 
 	nm_clear_pointer (&priv->mhandle, curl_multi_cleanup);
+	nm_clear_pointer (&priv->source_sockets_hashtable, g_hash_table_unref);
 
 	nm_clear_g_source_inst (&priv->mhandle_source_timeout);
-	nm_clear_g_source_inst (&priv->mhandle_source_socket);
 
 	G_OBJECT_CLASS (nm_http_client_parent_class)->dispose (object);
 }