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) {