summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Nierlein <sven@nierlein.de>2018-10-25 08:29:48 (GMT)
committerSven Nierlein <sven@nierlein.de>2018-10-25 08:35:06 (GMT)
commit70d36a729e2bc0ecfb24751074663c21160f02f4 (patch)
tree85e7b41ba6f72722bce84a48c2bfb7e953f83449
parentec590af49fa3498db52a118a519d8fcafd0b00ad (diff)
downloadmonitoring-plugins-70d36a7.tar.gz
check_curl: rewrite connect_to / host headers
since CURLOPT_CONNECT_TO is only available in later curl versions, we do it the other way round now and set the url from the address we want to connect to and then set the host header accordingly.
-rw-r--r--plugins/check_curl.c49
-rw-r--r--plugins/t/check_curl.t14
2 files changed, 35 insertions, 28 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 4d37891..7a516a9 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -365,25 +365,22 @@ check_http (void)
365 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout), "CURLOPT_CONNECTTIMEOUT"); 365 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout), "CURLOPT_CONNECTTIMEOUT");
366 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout), "CURLOPT_TIMEOUT"); 366 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout), "CURLOPT_TIMEOUT");
367 367
368 /* compose URL: must be the host_name, only if not given take the IP address. */ 368 /* compose URL: use the address we want to connect to, set Host: header later */
369 if ((use_ssl == FALSE && virtual_port == HTTP_PORT) || 369 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s",
370 (use_ssl == TRUE && virtual_port == HTTPS_PORT)) 370 use_ssl ? "https" : "http",
371 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s%s", use_ssl ? "https" : "http", 371 server_address,
372 host_name ? host_name : server_address, server_url); 372 server_port,
373 else 373 server_url
374 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", use_ssl ? "https" : "http", 374 );
375 host_name ? host_name : server_address, virtual_port, server_url); 375
376 if (verbose>=1)
377 printf ("* curl CURLOPT_URL: %s\n", url);
376 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_URL, url), "CURLOPT_URL"); 378 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_URL, url), "CURLOPT_URL");
377 379
378 /* cURL does certificate checking against the host name from the URL above 380 /* cURL does certificate checking against the host name from the URL above
379 * So we use CURLOPT_CONNECT_TO or CURLOPT_RESOLVE to handle differing 381 * So we use CURLOPT_CONNECT_TO or CURLOPT_RESOLVE to handle differing
380 * host names and/or ports */ 382 * host names and/or ports */
381#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 49, 0) 383#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 3)
382 snprintf (server_ip, DEFAULT_BUFFER_SIZE, "%s:%d:%s:%d", host_name ? host_name : server_address, virtual_port, server_address, server_port);
383 server_ips = curl_slist_append (server_ips, server_ip);
384 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECT_TO, server_ips), "CURLOPT_CONNECT_TO");
385
386#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 3)
387 if (host_name && strcmp (host_name, server_address)) { 384 if (host_name && strcmp (host_name, server_address)) {
388 snprintf (server_ip, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, server_address); 385 snprintf (server_ip, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, server_address);
389 server_ips = curl_slist_append (server_ips, server_ip); 386 server_ips = curl_slist_append (server_ips, server_ip);
@@ -411,8 +408,17 @@ check_http (void)
411 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, http_method), "CURLOPT_CUSTOMREQUEST"); 408 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, http_method), "CURLOPT_CUSTOMREQUEST");
412 } 409 }
413 410
411 /* check if Host header is explicitly set in options */
412 if (http_opt_headers_count) {
413 for (i = 0; i < http_opt_headers_count ; i++) {
414 if (strncmp(http_opt_headers[i], "Host:", 5) == 0) {
415 force_host_header = http_opt_headers[i];
416 }
417 }
418 }
419
414 /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in anyway */ 420 /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in anyway */
415 if(host_name != NULL) { 421 if(host_name != NULL && force_host_header == NULL) {
416 if((virtual_port != HTTP_PORT && !use_ssl) || (virtual_port != HTTPS_PORT && use_ssl)) { 422 if((virtual_port != HTTP_PORT && !use_ssl) || (virtual_port != HTTPS_PORT && use_ssl)) {
417 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", host_name, virtual_port); 423 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", host_name, virtual_port);
418 } else { 424 } else {
@@ -425,22 +431,11 @@ check_http (void)
425 snprintf (http_header, DEFAULT_BUFFER_SIZE, "Connection: close"); 431 snprintf (http_header, DEFAULT_BUFFER_SIZE, "Connection: close");
426 header_list = curl_slist_append (header_list, http_header); 432 header_list = curl_slist_append (header_list, http_header);
427 433
428 /* check if Host header is explicitly set in options */
429 if (http_opt_headers_count) {
430 for (i = 0; i < http_opt_headers_count ; i++) {
431 if (strncmp(http_opt_headers[i], "Host:", 5) == 0) {
432 force_host_header = http_opt_headers[i];
433 }
434 }
435 }
436
437 /* attach additional headers supplied by the user */ 434 /* attach additional headers supplied by the user */
438 /* optionally send any other header tag */ 435 /* optionally send any other header tag */
439 if (http_opt_headers_count) { 436 if (http_opt_headers_count) {
440 for (i = 0; i < http_opt_headers_count ; i++) { 437 for (i = 0; i < http_opt_headers_count ; i++) {
441 if (force_host_header != http_opt_headers[i]) { 438 header_list = curl_slist_append (header_list, http_opt_headers[i]);
442 header_list = curl_slist_append (header_list, http_opt_headers[i]);
443 }
444 } 439 }
445 /* This cannot be free'd here because a redirection will then try to access this and segfault */ 440 /* This cannot be free'd here because a redirection will then try to access this and segfault */
446 /* Covered in a testcase in tests/check_http.t */ 441 /* Covered in a testcase in tests/check_http.t */
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t
index e67fafb..050416c 100644
--- a/plugins/t/check_curl.t
+++ b/plugins/t/check_curl.t
@@ -9,7 +9,7 @@ use Test::More;
9use POSIX qw/mktime strftime/; 9use POSIX qw/mktime strftime/;
10use NPTest; 10use NPTest;
11 11
12plan tests => 49; 12plan tests => 57;
13 13
14my $successOutput = '/OK.*HTTP.*second/'; 14my $successOutput = '/OK.*HTTP.*second/';
15 15
@@ -78,15 +78,27 @@ like( $res->output, "/cURL returned 6 - Couldn't resolve host name/", "Output OK
78# host header checks 78# host header checks
79$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http"); 79$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http");
80like( $res->output, '/^Host: '.$host_tcp_http.'\s*$/ms', "Host Header OK" ); 80like( $res->output, '/^Host: '.$host_tcp_http.'\s*$/ms', "Host Header OK" );
81like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
81 82
82$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http -p 80"); 83$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http -p 80");
83like( $res->output, '/^Host: '.$host_tcp_http.'\s*$/ms', "Host Header OK" ); 84like( $res->output, '/^Host: '.$host_tcp_http.'\s*$/ms', "Host Header OK" );
85like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
84 86
85$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80"); 87$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80");
86like( $res->output, '/^Host: '.$host_tcp_http.':8080\s*$/ms', "Host Header OK" ); 88like( $res->output, '/^Host: '.$host_tcp_http.':8080\s*$/ms', "Host Header OK" );
89like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
87 90
88$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80"); 91$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80");
89like( $res->output, '/^Host: '.$host_tcp_http.':8080\s*$/ms', "Host Header OK" ); 92like( $res->output, '/^Host: '.$host_tcp_http.':8080\s*$/ms', "Host Header OK" );
93like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
94
95$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80 -k 'Host: testhost:8001'");
96like( $res->output, '/^Host: testhost:8001\s*$/ms', "Host Header OK" );
97like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
98
99$res = NPTest->testCmd("./$plugin -v -I $host_tcp_http -p 80 -k 'Host: testhost:8001'");
100like( $res->output, '/^Host: testhost:8001\s*$/ms', "Host Header OK" );
101like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
90 102
91SKIP: { 103SKIP: {
92 skip "No internet access", 3 if $internet_access eq "no"; 104 skip "No internet access", 3 if $internet_access eq "no";