#!/usr/bin/perl -w
# Version:      0.2
# Date:         Sept 15, 2022
# Author:       ivan.stetka@live.com
# Summary:      This is a nagios plugin to check web page over proxy.
#
# Nagios example:
# ./check_proxy_web.pl -P "proxysrv.xyz.com" -p 9876 -W "https://wwww.servertocheck.com"
#

use strict;
use Getopt::Long qw(:config no_ignore_case bundling);

use POSIX qw(strftime);

my %STATES = (
    OK       => 0,
    WARNING  => 1,
    CRITICAL => 2,
    UNKNOWN  => 3
);

my @curl = ();
my $textConnProxy = "";
my $counConnProxy = 0;
my $textProxyEsta = "";
my $countProxyEsta = 0;
my $textProxyConn = "";
my $countProxyConn = 0;
my $textSSL = "";
my $countSSL = 0;
my $textHttp = "";
my $countHttp = 0;
my $textHttpErr = "";
my $countHttpErr = 0;
my $numbHttpErr = 0;
my $longOutputText = "";
my $printArrayCurl = "";
my $proxy = "";
my $port = 0;
my $web = "";
my $verbose = 0;
my $help = 0;

GetOptions(
    'P|proxy:s'    => \$proxy,
    'p|port:s'     => \$port,
    'W|web:s'      => \$web,
    'v|verbose'    => \$verbose,
    'h|help'       => \$help
);

if ($help) {
    help();
    exit($STATES{OK});
}

@curl = `curl -s -m 3 -x $proxy:$port -vI $web 2>&1`;

if (!@curl) {
    print "CRITICAL: curl timeout exceeded, maybe problem with proxy.\n";
    print @curl;
    help();
    perf ("0");
    exit($STATES{CRITICAL});
}

foreach my $curl (@curl) {
    if ($curl=~ /^\* (Could not resolve proxy.*)/) {
        print "CRITICAL: $1\n";
        perf ("0");
        exit($STATES{CRITICAL}); }
    if ($curl=~ /^\* (Connected to $proxy .*)/) {
        $textConnProxy = "$1\n";
        $counConnProxy++;
    } elsif ($curl=~ /^\* (Establish HTTP proxy tunnel to .*)/) {
        $textProxyEsta = "$1\n";
        $countProxyEsta++;
    } elsif ($curl=~ /^\* (Proxy replied 200 to CONNECT request.*)/) {
        $textProxyConn = "$1\n";
        $countProxyConn++;
    } elsif ($curl=~ /^\*  (SSL certificate verify ok.*)/) {
        $textSSL = "$1\n";
        $countSSL++;
    } elsif ($curl=~ /^(HTTP\/1\.[0-1] 2[0-9][0-9] OK)/ || $curl=~ /^(HTTP\/2 2[0-9][0-9])/) {
        $textHttp = "$1\n";
        $countHttp++;
    } elsif ($curl=~ /^(HTTP\/1\.[0-1] ([3-9][0-9][0-9]).*)/) {
        $textHttpErr = "$1\n";
        $numbHttpErr = "$2";
        $countHttpErr++;
    }
}

if ($verbose) {
    $printArrayCurl = "\nVERBOSE: \n @curl"
}

$longOutputText = "$textConnProxy$textProxyEsta$textProxyConn$textSSL$textHttp$textHttpErr\n" .
                   "ConnProxy: $counConnProxy\nProxyEsta: $countProxyEsta \nProxyConn200: $countProxyConn \nSSL: $countSSL \nHTTP 200: $countHttp \nHTTP ERR: $countHttpErr \n$printArrayCurl";

if ($counConnProxy == 1 && $countProxyEsta == 1 && $countProxyConn == 1 && $countSSL == 1  && $countHttp == 1 ) {
    print "OK: test webpage $web over proxy $proxy is without problems.\n$longOutputText";
    perf ("1");
    exit($STATES{OK});
} elsif ($numbHttpErr >= 300 && $numbHttpErr < 400  && $counConnProxy == 1 && $countProxyEsta == 1 && $countProxyConn == 1 && $countSSL == 1 ) {
    print "OK: connection to webpage $web over proxy $proxy has only redirection message, HTTP code: $numbHttpErr.\n$longOutputText";
    perf ("1");
    exit($STATES{OK});
} elsif ($numbHttpErr > 400 && $counConnProxy == 1 && $countProxyEsta == 1 ) {
    print "CRITICAL: connection to webpage $web over proxy $proxy has problem, HTTP code: $numbHttpErr.\n$longOutputText";
    perf ("0");
    exit($STATES{CRITICAL});
} elsif ($counConnProxy == 1 && $countProxyEsta == 0 && $countProxyConn == 0 ) {
    print "CRITICAL: webpage $web not allowed in proxy $proxy or does not exist, HTTP code: $numbHttpErr. \n$longOutputText";
    perf ("0");
    exit($STATES{CRITICAL});
} else {
    print "CRITICAL: unexpected plugin error.\n$longOutputText\n$printArrayCurl";
    perf ("2");
    exit($STATES{CRITICAL});
}

# # # SUBROUTINES # # #

#   PERF
sub perf {
    my $state = shift;
    print "|'state'=$state;;0;\n";
}

#   HELP
sub help {
    print <<HELP;

H E L P:
This is a nagios plugin to check webservers over proxy,

-P, --proxy          # proxy server url
                     # example proxy: "proxysrv.xyz.com"
-p, --port           # proxy port
                     # example port: 9876
-W, --web            # web page to check
                     # example web: "https.servertocheck.com"
-v, --verbose       # show details for command-line debugging
-h, --help           # print this help

HELP
}
