diff mbox series

[v2,09/17] gweb: Add optional OS error status parameter to 'g_web_request_*'.

Message ID 20231119170714.775270-10-gerickson@nuovations.com (mailing list archive)
State Not Applicable, archived
Headers show
Series Address Redundant IPv4 Reachability Checks | expand

Commit Message

Grant Erickson Nov. 19, 2023, 5:07 p.m. UTC
This adds an optional operating system error status parameter to
'g_web_request_{get,post,post_file}' allowing callers, so interested,
to obtain the underlying failure status for a failed GWeb request.
---
 gweb/gweb.c      | 65 ++++++++++++++++++++++++++++++++++--------------
 gweb/gweb.h      |  8 +++---
 src/6to4.c       |  2 +-
 src/wispr.c      |  6 ++---
 tools/web-test.c |  3 ++-
 tools/wispr.c    |  8 +++---
 6 files changed, 62 insertions(+), 30 deletions(-)
diff mbox series

Patch

diff --git a/gweb/gweb.c b/gweb/gweb.c
index 1463b588d411..0270531a982f 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -2255,23 +2255,31 @@  static bool is_ip_address(const char *host)
 static guint do_request(GWeb *web, const char *url,
 				const char *type, GWebInputFunc input,
 				int fd, gsize length, GWebResultFunc func,
-				GWebRouteFunc route, gpointer user_data)
+				GWebRouteFunc route, gpointer user_data,
+				int *err)
 {
 	struct web_session *session;
 	const gchar *host;
+	int request_id = 0;
+	int status = 0;
 
-	if (!web || !url)
-		return 0;
+	if (!web || !url) {
+		status = -EINVAL;
+		goto done;
+	}
 
 	debug(web, "request %s", url);
 
 	session = g_try_new0(struct web_session, 1);
-	if (!session)
-		return 0;
+	if (!session) {
+		status = -ENOMEM;
+		goto done;
+	}
 
-	if (parse_request_and_proxy_urls(session, url, web->proxy) < 0) {
+	status = parse_request_and_proxy_urls(session, url, web->proxy);
+	if (status < 0) {
 		free_session(session);
-		return 0;
+		goto done;
 	}
 
 	debug(web, "proxy host %s", session->address);
@@ -2299,14 +2307,16 @@  static guint do_request(GWeb *web, const char *url,
 	session->receive_buffer = g_try_malloc(DEFAULT_BUFFER_SIZE);
 	if (!session->receive_buffer) {
 		free_session(session);
-		return 0;
+		status = -ENOMEM;
+		goto done;
 	}
 
 	session->result.headers = g_hash_table_new_full(g_str_hash, g_str_equal,
 							g_free, g_free);
 	if (!session->result.headers) {
 		free_session(session);
-		return 0;
+		status = -ENOMEM;
+		goto done;
 	}
 
 	session->receive_space = DEFAULT_BUFFER_SIZE;
@@ -2325,33 +2335,52 @@  static guint do_request(GWeb *web, const char *url,
 	} else {
 		session->resolv_action = g_resolv_lookup_hostname(web->resolv,
 					host, resolv_result, session);
-		if (session->resolv_action == 0) {
+		if (session->resolv_action <= 0) {
 			free_session(session);
-			return 0;
+			/*
+			 * While the return signature of #g_resolv_lookup_hostname
+			 * is 'guint', it overloads this, treating it as 'int' and
+			 * does potentially return -EIO. Consequently, apply the
+			 * 'int' casts to handle these cases.
+			 */
+			status = (int)session->resolv_action < 0 ?
+						(int)session->resolv_action :
+						-ENOENT;
+			goto done;
 		}
 	}
 
 	web->session_list = g_list_append(web->session_list, session);
 
-	return web->next_query_id++;
+	request_id = web->next_query_id++;
+
+done:
+	if (err)
+		*err = status;
+
+	return request_id;
 }
 
 guint g_web_request_get(GWeb *web, const char *url, GWebResultFunc func,
-		GWebRouteFunc route, gpointer user_data)
+		GWebRouteFunc route, gpointer user_data, int *err)
 {
-	return do_request(web, url, NULL, NULL, -1, 0, func, route, user_data);
+	return do_request(web, url, NULL, NULL, -1, 0,
+		func, route, user_data, err);
 }
 
 guint g_web_request_post(GWeb *web, const char *url,
 				const char *type, GWebInputFunc input,
-				GWebResultFunc func, gpointer user_data)
+				GWebResultFunc func, gpointer user_data,
+				int *err)
 {
-	return do_request(web, url, type, input, -1, 0, func, NULL, user_data);
+	return do_request(web, url, type, input, -1, 0,
+		func, NULL, user_data, err);
 }
 
 guint g_web_request_post_file(GWeb *web, const char *url,
 				const char *type, const char *file,
-				GWebResultFunc func, gpointer user_data)
+				GWebResultFunc func, gpointer user_data,
+				int *err)
 {
 	struct stat st;
 	int fd;
@@ -2365,7 +2394,7 @@  guint g_web_request_post_file(GWeb *web, const char *url,
 		return 0;
 
 	ret = do_request(web, url, type, NULL, fd, st.st_size, func, NULL,
-			user_data);
+			user_data, err);
 	if (ret == 0)
 		close(fd);
 
diff --git a/gweb/gweb.h b/gweb/gweb.h
index 3c50979cfd0a..7c65aebf4698 100644
--- a/gweb/gweb.h
+++ b/gweb/gweb.h
@@ -150,13 +150,15 @@  bool g_web_get_close_connection(GWeb *web);
 
 guint g_web_request_get(GWeb *web, const char *url,
 				GWebResultFunc func, GWebRouteFunc route,
-				gpointer user_data);
+				gpointer user_data, int *err);
 guint g_web_request_post(GWeb *web, const char *url,
 				const char *type, GWebInputFunc input,
-				GWebResultFunc func, gpointer user_data);
+				GWebResultFunc func, gpointer user_data,
+				int *err);
 guint g_web_request_post_file(GWeb *web, const char *url,
 				const char *type, const char *file,
-				GWebResultFunc func, gpointer user_data);
+				GWebResultFunc func, gpointer user_data,
+				int *err);
 
 bool g_web_cancel_request(GWeb *web, guint id);
 
diff --git a/src/6to4.c b/src/6to4.c
index 71a288277104..5542b339691a 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -318,7 +318,7 @@  static void tun_newlink(unsigned flags, unsigned change, void *user_data)
 			g_web_set_debug(web, web_debug, "6to4");
 
 		web_request_id = g_web_request_get(web, STATUS_URL,
-				web_result, NULL,  NULL);
+				web_result, NULL,  NULL, NULL);
 
 		newlink_timeout(NULL);
 	}
diff --git a/src/wispr.c b/src/wispr.c
index c15880e9c8a2..1bf63866009a 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -634,7 +634,7 @@  static void wispr_portal_request_portal(
 					wp_context->status_url,
 					wispr_portal_web_result,
 					wispr_route_request,
-					wp_context);
+					wp_context, NULL);
 
 	if (wp_context->request_id == 0) {
 		wp_context->cb(wp_context->service, wp_context->type, false);
@@ -751,7 +751,7 @@  static void wispr_portal_request_wispr_login(struct connman_service *service,
 					wp_context->wispr_msg.login_url,
 					"application/x-www-form-urlencoded",
 					wispr_input, wispr_portal_web_result,
-					wp_context);
+					wp_context, NULL);
 
 	connman_wispr_message_init(&wp_context->wispr_msg);
 }
@@ -906,7 +906,7 @@  static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 		wispr_portal_context_ref(wp_context);
 		wp_context->request_id = g_web_request_get(wp_context->web,
 				redirect, wispr_portal_web_result,
-				wispr_route_request, wp_context);
+				wispr_route_request, wp_context, NULL);
 
 		goto done;
 	case GWEB_HTTP_STATUS_CODE_BAD_REQUEST:
diff --git a/tools/web-test.c b/tools/web-test.c
index 55c58af5a7dc..a65e6c115c41 100644
--- a/tools/web-test.c
+++ b/tools/web-test.c
@@ -150,7 +150,8 @@  int main(int argc, char *argv[])
 
 	timer = g_timer_new();
 
-	if (g_web_request_get(web, argv[1], web_result, NULL,  NULL) == 0) {
+	if (g_web_request_get(web, argv[1], web_result,
+			NULL, NULL, NULL) == 0) {
 		fprintf(stderr, "Failed to start request\n");
 		return 1;
 	}
diff --git a/tools/wispr.c b/tools/wispr.c
index e56dfc169411..ef7b60d3f5ca 100644
--- a/tools/wispr.c
+++ b/tools/wispr.c
@@ -531,7 +531,7 @@  static bool wispr_result(GWebResult *result, gpointer user_data)
 		printf("\n");
 
 		wispr->request = g_web_request_get(wispr->web, redirect,
-				wispr_result, wispr_route, wispr);
+				wispr_result, wispr_route, wispr, NULL);
 
 		return false;
 	}
@@ -591,7 +591,7 @@  static bool wispr_result(GWebResult *result, gpointer user_data)
 		printf("\n");
 
 		wispr->request = g_web_request_get(wispr->web, redirect,
-				wispr_result, NULL, wispr);
+				wispr_result, NULL, wispr, NULL);
 
 		return false;
 	}
@@ -608,7 +608,7 @@  static gboolean execute_login(gpointer user_data)
 
 	wispr->request = g_web_request_post(wispr->web, wispr->msg.login_url,
 					"application/x-www-form-urlencoded",
-					wispr_input, wispr_result, wispr);
+					wispr_input, wispr_result, wispr, NULL);
 
 	wispr_msg_init(&wispr->msg);
 
@@ -694,7 +694,7 @@  int main(int argc, char *argv[])
 						parser_callback, &wispr);
 
 	wispr.request = g_web_request_get(wispr.web, option_url,
-			wispr_result, wispr_route, &wispr);
+			wispr_result, wispr_route, &wispr, NULL);
 
 	if (wispr.request == 0) {
 		fprintf(stderr, "Failed to start request\n");