diff options
author | OpenGnSys Support Team <soporte-og@soleta.eu> | 2021-11-10 12:24:30 +0100 |
---|---|---|
committer | Jose M. Guisado <jguisado@soleta.eu> | 2021-11-12 11:06:13 +0100 |
commit | ac3ce22c35db2133816ca30a0a2148ca3dfa6da3 (patch) | |
tree | a7ad17cb6c9b1178f27a303bcfe4297a692f7225 | |
parent | 6fc89cdfc42322899391404ef733185f996c0ce9 (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.c | 84 | ||||
-rw-r--r-- | src/core.c | 3 |
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; @@ -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); |