summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOpenGnSys Support Team <soporte-og@soleta.eu>2021-11-10 12:24:30 +0100
committerJose M. Guisado <jguisado@soleta.eu>2021-11-12 11:06:13 +0100
commitac3ce22c35db2133816ca30a0a2148ca3dfa6da3 (patch)
treea7ad17cb6c9b1178f27a303bcfe4297a692f7225
parent6fc89cdfc42322899391404ef733185f996c0ce9 (diff)
#1064 revisit error handling from ogClient
200 => successful command, run next pending command 202 => successful command in progress, do not run next pending command 403 => server sent a malformed HTTP header, should not ever happen, close connection (server is buggy?). 500 => client fails to run command, report error and run next pending command 503 => client is busy, report error and do not run next pending command Anything else, should not ever happen (client is buggy?), close connection with client. On error, when processing response from ogClient, do not close the connection, instead annotate in the database that command was not successful and run next pending command. *Only* if client replies status code 500 set last_cmd to UNSPEC so its state is not BSY as reported by og_client_status function and pending cmds can be sent.
-rw-r--r--src/client.c84
-rw-r--r--src/core.c3
2 files changed, 73 insertions, 14 deletions
diff --git a/src/client.c b/src/client.c
index 44e7c1b..f6de95e 100644
--- a/src/client.c
+++ b/src/client.c
@@ -610,29 +610,82 @@ static int og_resp_image_restore(json_t *data, struct og_client *cli)
return 0;
}
+static int og_agent_http_response_code(const char *buf)
+{
+ if (!strncmp(buf, "HTTP/1.0 200 OK", strlen("HTTP/1.0 200 OK"))) {
+ return 200;
+ } else if (!strncmp(buf, "HTTP/1.0 202 Accepted",
+ strlen("HTTP/1.0 202 Accepted"))) {
+ return 202;
+ } else if (!strncmp(buf, "HTTP/1.0 400 Bad Request",
+ strlen("HTTP/1.0 400 Bad Request"))) {
+ return 400;
+ } else if (!strncmp(buf, "HTTP/1.0 500 Internal Server Error",
+ strlen("HTTP/1.0 500 Internal Server Error"))) {
+ return 500;
+ } else if (!strncmp(buf, "HTTP/1.0 503 Service Unavailable",
+ strlen("HTTP/1.0 503 Service Unavailable"))) {
+ return 503;
+ }
+
+ return -1;
+}
+
int og_agent_state_process_response(struct og_client *cli)
{
+ int ret, err = -1, code;
json_error_t json_err;
+ bool success;
json_t *root;
- int err = -1;
char *body;
- if (!strncmp(cli->buf, "HTTP/1.0 202 Accepted",
- strlen("HTTP/1.0 202 Accepted"))) {
- og_dbi_update_action(cli->last_cmd_id, true);
- cli->last_cmd_id = 0;
- return 1;
+ code = og_agent_http_response_code(cli->buf);
+ switch (code) {
+ case 200:
+ ret = 0;
+ success = true;
+ break;
+ case 202:
+ ret = 1;
+ success = true;
+ break;
+ case 400:
+ ret = -1;
+ success = false;
+ syslog(LOG_ERR, "Client %s:%hu reports malformed HTTP request from server\n",
+ inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
+ break;
+ case 500:
+ ret = 0;
+ success = false;
+ cli->last_cmd = OG_CMD_UNSPEC;
+ syslog(LOG_ERR, "Client %s:%hu reports failure to process command\n",
+ inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
+ /* ... cancel pending actions related to this task for this client here */
+ break;
+ case 503:
+ ret = 1;
+ success = false;
+ syslog(LOG_ERR, "Client %s:%hu is busy to process command\n",
+ inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
+ break;
+ default:
+ ret = -1;
+ success = false;
+ syslog(LOG_ERR, "Client %s:%hu reports unknown HTTP response code\n",
+ inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
+ break;
}
- if (strncmp(cli->buf, "HTTP/1.0 200 OK", strlen("HTTP/1.0 200 OK"))) {
- og_dbi_update_action(cli->last_cmd_id, false);
+ if (code != 200) {
+ og_dbi_update_action(cli->last_cmd_id, success);
cli->last_cmd_id = 0;
- return -1;
+ return ret;
}
- og_dbi_update_action(cli->last_cmd_id, true);
- cli->last_cmd_id = 0;
if (!cli->content_length) {
+ og_dbi_update_action(cli->last_cmd_id, true);
+ cli->last_cmd_id = 0;
cli->last_cmd = OG_CMD_UNSPEC;
return 0;
}
@@ -677,6 +730,15 @@ int og_agent_state_process_response(struct og_client *cli)
}
json_decref(root);
+
+ if (err < 0) {
+ err = 0;
+ success = false;
+ /* ... cancel pending actions related to this task for this client here */
+ }
+
+ og_dbi_update_action(cli->last_cmd_id, success);
+ cli->last_cmd_id = 0;
cli->last_cmd = OG_CMD_UNSPEC;
return err;
diff --git a/src/core.c b/src/core.c
index 9fe83bf..cc523c6 100644
--- a/src/core.c
+++ b/src/core.c
@@ -251,9 +251,6 @@ static void og_agent_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
case OG_AGENT_PROCESSING_RESPONSE:
ret = og_agent_state_process_response(cli);
if (ret < 0) {
- syslog(LOG_ERR, "Failed to process HTTP request from %s:%hu\n",
- inet_ntoa(cli->addr.sin_addr),
- ntohs(cli->addr.sin_port));
goto close;
} else if (ret == 0) {
og_agent_deliver_pending_cmd(cli);