From 70d36a729e2bc0ecfb24751074663c21160f02f4 Mon Sep 17 00:00:00 2001 From: Sven Nierlein Date: Thu, 25 Oct 2018 10:29:48 +0200 Subject: 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. --- plugins/check_curl.c | 49 ++++++++++++++++++++++--------------------------- plugins/t/check_curl.t | 14 +++++++++++++- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 4d378916..7a516a9e 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -365,25 +365,22 @@ check_http (void) handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout), "CURLOPT_CONNECTTIMEOUT"); handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout), "CURLOPT_TIMEOUT"); - /* compose URL: must be the host_name, only if not given take the IP address. */ - if ((use_ssl == FALSE && virtual_port == HTTP_PORT) || - (use_ssl == TRUE && virtual_port == HTTPS_PORT)) - snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s%s", use_ssl ? "https" : "http", - host_name ? host_name : server_address, server_url); - else - snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", use_ssl ? "https" : "http", - host_name ? host_name : server_address, virtual_port, server_url); + /* compose URL: use the address we want to connect to, set Host: header later */ + snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", + use_ssl ? "https" : "http", + server_address, + server_port, + server_url + ); + + if (verbose>=1) + printf ("* curl CURLOPT_URL: %s\n", url); handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_URL, url), "CURLOPT_URL"); /* cURL does certificate checking against the host name from the URL above * So we use CURLOPT_CONNECT_TO or CURLOPT_RESOLVE to handle differing * host names and/or ports */ -#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 49, 0) - snprintf (server_ip, DEFAULT_BUFFER_SIZE, "%s:%d:%s:%d", host_name ? host_name : server_address, virtual_port, server_address, server_port); - server_ips = curl_slist_append (server_ips, server_ip); - handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECT_TO, server_ips), "CURLOPT_CONNECT_TO"); - -#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 3) +#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 3) if (host_name && strcmp (host_name, server_address)) { snprintf (server_ip, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, server_address); server_ips = curl_slist_append (server_ips, server_ip); @@ -411,8 +408,17 @@ check_http (void) handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, http_method), "CURLOPT_CUSTOMREQUEST"); } + /* check if Host header is explicitly set in options */ + if (http_opt_headers_count) { + for (i = 0; i < http_opt_headers_count ; i++) { + if (strncmp(http_opt_headers[i], "Host:", 5) == 0) { + force_host_header = http_opt_headers[i]; + } + } + } + /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in anyway */ - if(host_name != NULL) { + if(host_name != NULL && force_host_header == NULL) { if((virtual_port != HTTP_PORT && !use_ssl) || (virtual_port != HTTPS_PORT && use_ssl)) { snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", host_name, virtual_port); } else { @@ -425,22 +431,11 @@ check_http (void) snprintf (http_header, DEFAULT_BUFFER_SIZE, "Connection: close"); header_list = curl_slist_append (header_list, http_header); - /* check if Host header is explicitly set in options */ - if (http_opt_headers_count) { - for (i = 0; i < http_opt_headers_count ; i++) { - if (strncmp(http_opt_headers[i], "Host:", 5) == 0) { - force_host_header = http_opt_headers[i]; - } - } - } - /* attach additional headers supplied by the user */ /* optionally send any other header tag */ if (http_opt_headers_count) { for (i = 0; i < http_opt_headers_count ; i++) { - if (force_host_header != http_opt_headers[i]) { - header_list = curl_slist_append (header_list, http_opt_headers[i]); - } + header_list = curl_slist_append (header_list, http_opt_headers[i]); } /* This cannot be free'd here because a redirection will then try to access this and segfault */ /* Covered in a testcase in tests/check_http.t */ diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index e67fafb6..050416cb 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t @@ -9,7 +9,7 @@ use Test::More; use POSIX qw/mktime strftime/; use NPTest; -plan tests => 49; +plan tests => 57; my $successOutput = '/OK.*HTTP.*second/'; @@ -78,15 +78,27 @@ like( $res->output, "/cURL returned 6 - Couldn't resolve host name/", "Output OK # host header checks $res = NPTest->testCmd("./$plugin -v -H $host_tcp_http"); like( $res->output, '/^Host: '.$host_tcp_http.'\s*$/ms', "Host Header OK" ); +like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); $res = NPTest->testCmd("./$plugin -v -H $host_tcp_http -p 80"); like( $res->output, '/^Host: '.$host_tcp_http.'\s*$/ms', "Host Header OK" ); +like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); $res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80"); like( $res->output, '/^Host: '.$host_tcp_http.':8080\s*$/ms', "Host Header OK" ); +like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); $res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80"); like( $res->output, '/^Host: '.$host_tcp_http.':8080\s*$/ms', "Host Header OK" ); +like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); + +$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http:8080 -p 80 -k 'Host: testhost:8001'"); +like( $res->output, '/^Host: testhost:8001\s*$/ms', "Host Header OK" ); +like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); + +$res = NPTest->testCmd("./$plugin -v -I $host_tcp_http -p 80 -k 'Host: testhost:8001'"); +like( $res->output, '/^Host: testhost:8001\s*$/ms', "Host Header OK" ); +like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); SKIP: { skip "No internet access", 3 if $internet_access eq "no"; -- cgit v1.2.3-74-g34f1