tUse GError for curl error handling - vaccinewars - be a doctor and try to vaccinate the world (HTM) git clone git://src.adamsgaard.dk/vaccinewars (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit 826c6ac4c313c45fad652728ea9002483507ef9a (DIR) parent a2b557a74595793a733876f6164e1cce5df1e3a2 (HTM) Author: Ben Webb <ben@salilab.org> Date: Mon, 2 Nov 2020 23:11:28 -0800 Use GError for curl error handling Diffstat: M src/curses_client/curses_client.c | 14 +++++++------- M src/gui_client/newgamedia.c | 23 ++++++----------------- M src/message.c | 8 ++++---- M src/message.h | 2 +- M src/network.c | 86 ++++++++++++++++++++----------- M src/network.h | 12 ++++++++++-- M src/serverside.c | 29 ++++++++++++----------------- 7 files changed, 97 insertions(+), 77 deletions(-) --- (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c t@@ -367,7 +367,7 @@ static void SelectServerManually(void) static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr) { int c; - const char *merr; + GError *tmp_error = NULL; GSList *ListPt; ServerData *ThisServer; GString *text; t@@ -381,8 +381,9 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr) mvaddstr(top + 1, 1, _("Please wait... attempting to contact metaserver...")); refresh(); - if ((merr = OpenMetaHttpConnection(&MetaConn))) { - g_string_assign(errstr, merr); + if (!OpenMetaHttpConnection(&MetaConn, &tmp_error)) { + g_string_assign(errstr, tmp_error->message); + g_error_free(tmp_error); return FALSE; } t@@ -416,12 +417,11 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr) if (c == '\f') wrefresh(curscr); } - merr = CurlConnectionPerform(&MetaConn, &still_running); - if (merr) { - g_string_assign(errstr, merr); + if (!CurlConnectionPerform(&MetaConn, &still_running, &tmp_error)) { + g_string_assign(errstr, tmp_error->message); + g_error_free(tmp_error); return FALSE; } else if (still_running == 0) { - GError *tmp_error = NULL; if (!HandleWaitingMetaServerData(&MetaConn, &ServerList, &tmp_error)) { CloseCurlConnection(&MetaConn); g_string_assign(errstr, tmp_error->message); (DIR) diff --git a/src/gui_client/newgamedia.c b/src/gui_client/newgamedia.c t@@ -498,7 +498,7 @@ static void UpdateMetaServerList(GtkWidget *widget) { GtkWidget *metaserv; gchar *text; - const char *merr; + GError *tmp_error = NULL; /* Terminate any existing connection attempts */ ShutdownNetworkBuffer(&stgam.play->NetBuf); t@@ -514,23 +514,12 @@ static void UpdateMetaServerList(GtkWidget *widget) SetStartGameStatus(text); g_free(text); - if ((merr = OpenMetaHttpConnection(stgam.MetaConn))) { - ConnectError(TRUE); - } else { + if (!OpenMetaHttpConnection(stgam.MetaConn, &tmp_error)) { + text = g_strdup_printf(_("Status: ERROR: %s"), tmp_error->message); + g_error_free(tmp_error); + SetStartGameStatus(text); + g_free(text); } - /* - if (OpenMetaHttpConnection(&stgam.MetaConn)) { - metaserv = stgam.metaserv; - SetHttpAuthFunc(stgam.MetaConn, AuthDialog, NULL); - SetNetworkBufferUserPasswdFunc(&stgam.MetaConn->NetBuf, - MetaSocksAuthDialog, NULL); - SetNetworkBufferCallBack(&stgam.MetaConn->NetBuf, - MetaSocketStatus, NULL); - } else { - ConnectError(TRUE); - CloseHttpConnection(stgam.MetaConn); - stgam.MetaConn = NULL; - }*/ } static void MetaServerConnect(GtkWidget *widget, gpointer data) (DIR) diff --git a/src/message.c b/src/message.c t@@ -427,16 +427,16 @@ static void MetaAppendError(GString *str, LastError *error) } } -const char *OpenMetaHttpConnection(CurlConnection *conn) +gboolean OpenMetaHttpConnection(CurlConnection *conn, GError **err) { - const char *errstr; + gboolean ret; gchar *url; url = g_strdup_printf("%s?output=text&getlist=%d", MetaServer.URL, METAVERSION); - errstr = OpenCurlConnection(conn, url, NULL); + ret = OpenCurlConnection(conn, url, NULL, err); g_free(url); - return errstr; + return ret; } GQuark dope_meta_error_quark(void) (DIR) diff --git a/src/message.h b/src/message.h t@@ -93,7 +93,7 @@ void QueuePlayerMessageForSend(Player *Play, gchar *data); gboolean WritePlayerDataToWire(Player *Play); gchar *GetWaitingPlayerMessage(Player *Play); -const char *OpenMetaHttpConnection(CurlConnection *conn); +gboolean OpenMetaHttpConnection(CurlConnection *conn, GError **err); gboolean HandleWaitingMetaServerData(CurlConnection *conn, GSList **listpt, GError **err); void ClearServerList(GSList **listpt); (DIR) diff --git a/src/network.c b/src/network.c t@@ -1257,15 +1257,14 @@ void CurlCleanup(CurlConnection *conn) curl_global_cleanup(); } -const char *CurlConnectionPerform(CurlConnection *conn, int *still_running) +gboolean HandleCurlMultiReturn(CurlConnection *conn, CURLMcode mres, + GError **err) { - CURLMcode mres; struct CURLMsg *m; - - mres = curl_multi_perform(conn->multi, still_running); if (mres != CURLM_OK && mres != CURLM_CALL_MULTI_PERFORM) { CloseCurlConnection(conn); - return curl_multi_strerror(mres); + g_set_error_literal(err, DOPE_CURLM_ERROR, mres, curl_multi_strerror(mres)); + return FALSE; } do { t@@ -1273,14 +1272,45 @@ const char *CurlConnectionPerform(CurlConnection *conn, int *still_running) m = curl_multi_info_read(conn->multi, &msgq); if (m && m->msg == CURLMSG_DONE && m->data.result != CURLE_OK) { CloseCurlConnection(conn); - return curl_easy_strerror(m->data.result); + g_set_error_literal(err, DOPE_CURL_ERROR, m->data.result, + curl_easy_strerror(m->data.result)); + return FALSE; } } while(m); - return NULL; + return TRUE; } -const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body) +gboolean CurlConnectionPerform(CurlConnection *conn, int *still_running, + GError **err) +{ + CURLMcode mres = curl_multi_perform(conn->multi, still_running); + return HandleCurlMultiReturn(conn, mres, err); +} + +GQuark dope_curl_error_quark(void) +{ + return g_quark_from_static_string("dope-curl-error-quark"); +} + +GQuark dope_curlm_error_quark(void) +{ + return g_quark_from_static_string("dope-curlm-error-quark"); +} + +gboolean CurlEasySetopt1(CURL *curl, CURLoption option, void *arg, GError **err) +{ + CURLcode res = curl_easy_setopt(curl, option, arg); + if (res == CURLE_OK) { + return TRUE; + } else { + g_set_error_literal(err, DOPE_CURL_ERROR, res, curl_easy_strerror(res)); + return FALSE; + } +} + +gboolean OpenCurlConnection(CurlConnection *conn, char *URL, char *body, + GError **err) { /* If the previous connect hung for so long that it's still active, then * break the connection before we start a new one */ t@@ -1291,39 +1321,37 @@ const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body) if (conn->h) { const char *errstr; int still_running; - CURLcode res; CURLMcode mres; - if (body) { - res = curl_easy_setopt(conn->h, CURLOPT_COPYPOSTFIELDS, body); - if (res != CURLE_OK) return curl_easy_strerror(res); + if (body && !CurlEasySetopt1(conn->h, CURLOPT_COPYPOSTFIELDS, body, err)) { + return FALSE; + } + + if (!CurlEasySetopt1(conn->h, CURLOPT_URL, URL, err) + || !CurlEasySetopt1(conn->h, CURLOPT_WRITEFUNCTION, MetaConnWriteFunc, + err) + || !CurlEasySetopt1(conn->h, CURLOPT_WRITEDATA, conn, err) + || !CurlEasySetopt1(conn->h, CURLOPT_HEADERFUNCTION, + MetaConnHeaderFunc, err) + || !CurlEasySetopt1(conn->h, CURLOPT_HEADERDATA, conn, err)) { + return FALSE; } - res = curl_easy_setopt(conn->h, CURLOPT_URL, URL); - if (res != CURLE_OK) return curl_easy_strerror(res); - res = curl_easy_setopt(conn->h, CURLOPT_WRITEFUNCTION, MetaConnWriteFunc); - if (res != CURLE_OK) return curl_easy_strerror(res); - res = curl_easy_setopt(conn->h, CURLOPT_WRITEDATA, conn); - if (res != CURLE_OK) return curl_easy_strerror(res); - res = curl_easy_setopt(conn->h, CURLOPT_HEADERFUNCTION, MetaConnHeaderFunc); - if (res != CURLE_OK) return curl_easy_strerror(res); - res = curl_easy_setopt(conn->h, CURLOPT_HEADERDATA, conn); - if (res != CURLE_OK) return curl_easy_strerror(res); mres = curl_multi_add_handle(conn->multi, conn->h); if (mres != CURLM_OK && mres != CURLM_CALL_MULTI_PERFORM) { - return curl_multi_strerror(mres); + g_set_error_literal(err, DOPE_CURLM_ERROR, mres, + curl_multi_strerror(mres)); + return FALSE; } conn->data = g_malloc(1); conn->data_size = 0; conn->headers = g_ptr_array_new_with_free_func(g_free); conn->running = TRUE; - errstr = CurlConnectionPerform(conn, &still_running); - if (errstr) { - return errstr; - } - return NULL; + return CurlConnectionPerform(conn, &still_running, err); } else { - return "Could not init curl"; + g_set_error_literal(err, DOPE_CURLM_ERROR, 0, _("Could not init curl")); + return FALSE; } + return TRUE; } char *CurlNextLine(CurlConnection *conn, char *ch) (DIR) diff --git a/src/network.h b/src/network.h t@@ -226,11 +226,19 @@ gchar *ExpandWriteBuffer(ConnBuf *conn, int numbytes, LastError **error); void CommitWriteBuffer(NetworkBuffer *NetBuf, ConnBuf *conn, gchar *addpt, guint addlen); +#define DOPE_CURL_ERROR dope_curl_error_quark() +GQuark dope_curl_error_quark(void); + +#define DOPE_CURLM_ERROR dope_curlm_error_quark() +GQuark dope_curlm_error_quark(void); + void CurlInit(CurlConnection *conn); void CurlCleanup(CurlConnection *conn); -const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body); +gboolean OpenCurlConnection(CurlConnection *conn, char *URL, char *body, + GError **err); void CloseCurlConnection(CurlConnection *conn); -const char *CurlConnectionPerform(CurlConnection *conn, int *still_running); +gboolean CurlConnectionPerform(CurlConnection *conn, int *still_running, + GError **err); char *CurlNextLine(CurlConnection *conn, char *ch); gboolean OpenHttpConnection(HttpConnection **conn, gchar *HostName, (DIR) diff --git a/src/serverside.c b/src/serverside.c t@@ -156,10 +156,10 @@ static void MetaSocketStatus(NetworkBuffer *NetBuf, #endif #ifdef NETWORKING -static void MetaConnectError(CurlConnection *conn, const char *errstr) +static void MetaConnectError(CurlConnection *conn, GError *err) { dopelog(1, LF_SERVER, _("Failed to connect to metaserver at %s (%s)"), - MetaServer.URL, errstr); + MetaServer.URL, err->message); } void log_meta_headers(gpointer data, gpointer user_data) t@@ -229,7 +229,8 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData, struct HISCORE MultiScore[NUMHISCORE], AntiqueScore[NUMHISCORE]; GString *body; gchar *prstr; - const char *errstr; + gboolean ret; + GError *tmp_error = NULL; int i; if (!MetaServer.Active || WantQuit || !Server) { t@@ -278,21 +279,15 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData, } } - errstr = OpenCurlConnection(&MetaConn, MetaServer.URL, body->str); + ret = OpenCurlConnection(&MetaConn, MetaServer.URL, body->str, &tmp_error); dopelog(2, LF_SERVER, _("Waiting for connect to metaserver at %s..."), MetaServer.URL); g_string_free(body, TRUE); - if (errstr) { - MetaConnectError(&MetaConn, errstr); + if (!ret) { + MetaConnectError(&MetaConn, tmp_error); + g_error_free(tmp_error); } -/*SetHttpAuthFunc(MetaConn, ServerHttpAuth, NULL); - - if (Socks.authuser && Socks.authuser[0] && - Socks.authpassword && Socks.authpassword[0]) { - SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, ServerNetBufAuth, - NULL); - }*/ #ifdef GUI_SERVER SetNetworkBufferCallBack(&MetaConn->NetBuf, MetaSocketStatus, NULL); #endif t@@ -1291,11 +1286,11 @@ void ServerLoop(struct CMDLINE *cmdline) break; #endif if (MetaConn.running) { + GError *tmp_error = NULL; int still_running; - const char *errstr; - errstr = CurlConnectionPerform(&MetaConn, &still_running); - if (errstr) { - MetaConnectError(&MetaConn, errstr); + if (!CurlConnectionPerform(&MetaConn, &still_running, &tmp_error)) { + MetaConnectError(&MetaConn, tmp_error); + g_error_free(tmp_error); if (IsServerShutdown()) break; } else if (still_running == 0) {