nmcs-http: fix multiple HTTP request bug

Since just a single pointer is used to store the socket's GSource
if more than 1 consecutive request was done through the same
HTTP provider the 2nd request would clear the GSource associated to
the second request causing the 1st HTTP request to never complete
and end up in a expired timeout.

Use a hashtable instead so we can correctly track all requests.

https://bugzilla.redhat.com/show_bug.cgi?id=1821787

Fixes: 69f048bf0c ('cloud-setup: add tool for automatic IP configuration in cloud')
(cherry picked from commit 427fbc85f0)
(cherry picked from commit f5487645d8)
This commit is contained in:
Antonio Cardace 2020-06-18 18:21:48 +02:00 committed by Thomas Haller
parent 6281e32875
commit fe3ddf3eff
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728

View file

@ -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 {
@ -615,12 +615,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 +636,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);
}
}
@ -678,6 +683,11 @@ _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 +724,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);
}