diff options
author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-11 11:11:44 +0200 |
---|---|---|
committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-11 11:11:44 +0200 |
commit | b44cbae7fb6b7bde948c0f26412e9b2a9ef8f78b (patch) | |
tree | 697b9ec26add5c2dbaa93ca201032d8e91317248 | |
parent | a2ca373e2d6a9903126e152254c83245ad202ff8 (diff) | |
download | monitoring-plugins-b44cbae7fb6b7bde948c0f26412e9b2a9ef8f78b.tar.gz |
check_curl: less global state
-rw-r--r-- | plugins/check_curl.c | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 7bb67645..7755d449 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -131,20 +131,6 @@ typedef struct { | |||
131 | CURL *curl; | 131 | CURL *curl; |
132 | } check_curl_global_state; | 132 | } check_curl_global_state; |
133 | 133 | ||
134 | check_curl_global_state global_state = { | ||
135 | .curl_global_initialized = false, | ||
136 | .curl_easy_initialized = false, | ||
137 | .body_buf_initialized = false, | ||
138 | .body_buf = {}, | ||
139 | .header_buf_initialized = false, | ||
140 | .header_buf = {}, | ||
141 | .status_line_initialized = false, | ||
142 | .status_line = {}, | ||
143 | .put_buf_initialized = false, | ||
144 | .put_buf = {}, | ||
145 | .curl = NULL, | ||
146 | }; | ||
147 | |||
148 | static char errbuf[MAX_INPUT_BUFFER]; | 134 | static char errbuf[MAX_INPUT_BUFFER]; |
149 | static char msg[DEFAULT_BUFFER_SIZE]; | 135 | static char msg[DEFAULT_BUFFER_SIZE]; |
150 | typedef union { | 136 | typedef union { |
@@ -166,15 +152,18 @@ static check_curl_config_wrapper process_arguments(int /*argc*/, char ** /*argv* | |||
166 | 152 | ||
167 | static void handle_curl_option_return_code(CURLcode res, const char *option); | 153 | static void handle_curl_option_return_code(CURLcode res, const char *option); |
168 | static mp_state_enum check_http(check_curl_config /*config*/, check_curl_working_state workingState, | 154 | static mp_state_enum check_http(check_curl_config /*config*/, check_curl_working_state workingState, |
169 | int redir_depth, struct curl_slist *header_list); | 155 | int redir_depth, struct curl_slist *header_list, |
156 | check_curl_global_state global_state); | ||
170 | 157 | ||
171 | typedef struct { | 158 | typedef struct { |
172 | int redir_depth; | 159 | int redir_depth; |
173 | check_curl_working_state working_state; | 160 | check_curl_working_state working_state; |
174 | int error_code; | 161 | int error_code; |
162 | check_curl_global_state curl_state; | ||
175 | } redir_wrapper; | 163 | } redir_wrapper; |
176 | static redir_wrapper redir(curlhelp_write_curlbuf * /*header_buf*/, check_curl_config /*config*/, | 164 | static redir_wrapper redir(curlhelp_write_curlbuf * /*header_buf*/, check_curl_config /*config*/, |
177 | int redir_depth, check_curl_working_state working_state); | 165 | int redir_depth, check_curl_working_state working_state, |
166 | check_curl_global_state global_state); | ||
178 | 167 | ||
179 | static char *perfd_time(double elapsed_time, thresholds * /*thlds*/, long /*socket_timeout*/); | 168 | static char *perfd_time(double elapsed_time, thresholds * /*thlds*/, long /*socket_timeout*/); |
180 | static char *perfd_time_connect(double elapsed_time_connect, long /*socket_timeout*/); | 169 | static char *perfd_time_connect(double elapsed_time_connect, long /*socket_timeout*/); |
@@ -246,12 +235,24 @@ int main(int argc, char **argv) { | |||
246 | config.initial_config.server_url); | 235 | config.initial_config.server_url); |
247 | } | 236 | } |
248 | 237 | ||
249 | int redir_depth = 0; | 238 | check_curl_global_state global_state = { |
239 | .curl_global_initialized = false, | ||
240 | .curl_easy_initialized = false, | ||
241 | .body_buf_initialized = false, | ||
242 | .body_buf = {}, | ||
243 | .header_buf_initialized = false, | ||
244 | .header_buf = {}, | ||
245 | .status_line_initialized = false, | ||
246 | .status_line = {}, | ||
247 | .put_buf_initialized = false, | ||
248 | .put_buf = {}, | ||
249 | .curl = NULL, | ||
250 | }; | ||
250 | 251 | ||
251 | check_curl_working_state working_state = config.initial_config; | 252 | check_curl_working_state working_state = config.initial_config; |
252 | struct curl_slist *header_list = NULL; | 253 | struct curl_slist *header_list = NULL; |
253 | 254 | ||
254 | exit((int)check_http(config, working_state, redir_depth, header_list)); | 255 | exit((int)check_http(config, working_state, 0, header_list, global_state)); |
255 | } | 256 | } |
256 | 257 | ||
257 | #ifdef HAVE_SSL | 258 | #ifdef HAVE_SSL |
@@ -403,7 +404,7 @@ int lookup_host(const char *host, char *buf, size_t buflen, sa_family_t addr_fam | |||
403 | return 0; | 404 | return 0; |
404 | } | 405 | } |
405 | 406 | ||
406 | static void cleanup(void) { | 407 | static void cleanup(check_curl_global_state global_state) { |
407 | if (global_state.status_line_initialized) { | 408 | if (global_state.status_line_initialized) { |
408 | curlhelp_free_statusline(&global_state.status_line); | 409 | curlhelp_free_statusline(&global_state.status_line); |
409 | } | 410 | } |
@@ -436,7 +437,12 @@ static void cleanup(void) { | |||
436 | } | 437 | } |
437 | 438 | ||
438 | mp_state_enum check_http(const check_curl_config config, check_curl_working_state workingState, | 439 | mp_state_enum check_http(const check_curl_config config, check_curl_working_state workingState, |
439 | int redir_depth, struct curl_slist *header_list) { | 440 | int redir_depth, struct curl_slist *header_list, |
441 | check_curl_global_state global_state) { | ||
442 | |||
443 | // ======================= | ||
444 | // Initialisation for curl | ||
445 | // ======================= | ||
440 | /* initialize curl */ | 446 | /* initialize curl */ |
441 | if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { | 447 | if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { |
442 | die(STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); | 448 | die(STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); |
@@ -448,9 +454,6 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
448 | } | 454 | } |
449 | global_state.curl_easy_initialized = true; | 455 | global_state.curl_easy_initialized = true; |
450 | 456 | ||
451 | /* register cleanup function to shut down libcurl properly */ | ||
452 | atexit(cleanup); | ||
453 | |||
454 | if (verbose >= 1) { | 457 | if (verbose >= 1) { |
455 | handle_curl_option_return_code(curl_easy_setopt(global_state.curl, CURLOPT_VERBOSE, 1), | 458 | handle_curl_option_return_code(curl_easy_setopt(global_state.curl, CURLOPT_VERBOSE, 1), |
456 | "CURLOPT_VERBOSE"); | 459 | "CURLOPT_VERBOSE"); |
@@ -651,7 +654,6 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
651 | curl_easy_setopt(global_state.curl, CURLOPT_HTTPHEADER, header_list), "CURLOPT_HTTPHEADER"); | 654 | curl_easy_setopt(global_state.curl, CURLOPT_HTTPHEADER, header_list), "CURLOPT_HTTPHEADER"); |
652 | 655 | ||
653 | #ifdef LIBCURL_FEATURE_SSL | 656 | #ifdef LIBCURL_FEATURE_SSL |
654 | |||
655 | /* set SSL version, warn about insecure or unsupported versions */ | 657 | /* set SSL version, warn about insecure or unsupported versions */ |
656 | if (workingState.use_ssl) { | 658 | if (workingState.use_ssl) { |
657 | handle_curl_option_return_code( | 659 | handle_curl_option_return_code( |
@@ -779,7 +781,6 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
779 | "CURLOPT_SSL_CTX_FUNCTION"); | 781 | "CURLOPT_SSL_CTX_FUNCTION"); |
780 | } | 782 | } |
781 | # endif | 783 | # endif |
782 | |||
783 | #endif /* LIBCURL_FEATURE_SSL */ | 784 | #endif /* LIBCURL_FEATURE_SSL */ |
784 | 785 | ||
785 | /* set default or user-given user agent identification */ | 786 | /* set default or user-given user agent identification */ |
@@ -936,7 +937,9 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
936 | } | 937 | } |
937 | } | 938 | } |
938 | 939 | ||
939 | /* do the request */ | 940 | // ============== |
941 | // do the request | ||
942 | // ============== | ||
940 | CURLcode res = curl_easy_perform(global_state.curl); | 943 | CURLcode res = curl_easy_perform(global_state.curl); |
941 | 944 | ||
942 | if (verbose >= 2 && workingState.http_post_data) { | 945 | if (verbose >= 2 && workingState.http_post_data) { |
@@ -960,6 +963,10 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
960 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 963 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
961 | } | 964 | } |
962 | 965 | ||
966 | // ========== | ||
967 | // Evaluation | ||
968 | // ========== | ||
969 | |||
963 | mp_state_enum result_ssl = STATE_OK; | 970 | mp_state_enum result_ssl = STATE_OK; |
964 | /* certificate checks */ | 971 | /* certificate checks */ |
965 | #ifdef LIBCURL_FEATURE_SSL | 972 | #ifdef LIBCURL_FEATURE_SSL |
@@ -1173,10 +1180,10 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
1173 | * back here, we are in the same status as with | 1180 | * back here, we are in the same status as with |
1174 | * the libcurl method | 1181 | * the libcurl method |
1175 | */ | 1182 | */ |
1176 | redir_wrapper redir_result = | 1183 | redir_wrapper redir_result = redir(&global_state.header_buf, config, |
1177 | redir(&global_state.header_buf, config, redir_depth, workingState); | 1184 | redir_depth, workingState, global_state); |
1178 | check_http(config, redir_result.working_state, redir_result.redir_depth, | 1185 | check_http(config, redir_result.working_state, redir_result.redir_depth, |
1179 | header_list); | 1186 | header_list, redir_result.curl_state); |
1180 | } | 1187 | } |
1181 | } else { | 1188 | } else { |
1182 | /* this is a specific code in the command line to | 1189 | /* this is a specific code in the command line to |
@@ -1195,9 +1202,11 @@ mp_state_enum check_http(const check_curl_config config, check_curl_working_stat | |||
1195 | handle_curl_option_return_code( | 1202 | handle_curl_option_return_code( |
1196 | curl_easy_getinfo(global_state.curl, CURLINFO_REDIRECT_COUNT, &redir_depth), | 1203 | curl_easy_getinfo(global_state.curl, CURLINFO_REDIRECT_COUNT, &redir_depth), |
1197 | "CURLINFO_REDIRECT_COUNT"); | 1204 | "CURLINFO_REDIRECT_COUNT"); |
1205 | |||
1198 | if (verbose >= 2) { | 1206 | if (verbose >= 2) { |
1199 | printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth); | 1207 | printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth); |
1200 | } | 1208 | } |
1209 | |||
1201 | if (redir_depth > config.max_depth) { | 1210 | if (redir_depth > config.max_depth) { |
1202 | snprintf(msg, DEFAULT_BUFFER_SIZE, "maximum redirection depth %d exceeded in libcurl", | 1211 | snprintf(msg, DEFAULT_BUFFER_SIZE, "maximum redirection depth %d exceeded in libcurl", |
1203 | config.max_depth); | 1212 | config.max_depth); |
@@ -1365,7 +1374,8 @@ char *uri_string(const UriTextRangeA range, char *buf, size_t buflen) { | |||
1365 | } | 1374 | } |
1366 | 1375 | ||
1367 | redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config, | 1376 | redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config, |
1368 | int redir_depth, check_curl_working_state working_state) { | 1377 | int redir_depth, check_curl_working_state working_state, |
1378 | check_curl_global_state global_state) { | ||
1369 | curlhelp_statusline status_line; | 1379 | curlhelp_statusline status_line; |
1370 | struct phr_header headers[255]; | 1380 | struct phr_header headers[255]; |
1371 | size_t msglen; | 1381 | size_t msglen; |
@@ -1522,7 +1532,7 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config | |||
1522 | * attached to the URL in Location | 1532 | * attached to the URL in Location |
1523 | */ | 1533 | */ |
1524 | 1534 | ||
1525 | cleanup(); | 1535 | cleanup(global_state); |
1526 | 1536 | ||
1527 | redir_wrapper result = { | 1537 | redir_wrapper result = { |
1528 | .redir_depth = redir_depth, | 1538 | .redir_depth = redir_depth, |