如何使用PHP curl(HTTPS)的“后备”方法?

问题描述 投票:-1回答:1

情况:我在基于PHP的监控Web应用程序上改进了一些代码,用于检查其他Web应用程序/服务的运行状况。

目标:我们使用CURL作为获取标头的主要方法,以确保通过HTTP返回代码访问受监控的应用程序。这在目前很有用。但是,我们正在尝试构建一个“后备”方法,其中来自受监视应用程序的CURL HTTP代码响应在我们定义的变量之外(即http代码404),PHP将使用类似PING的函数来检查是否在同一地址有任何响应(例如,webserver仍在“运行”(占用给定端口)但不提供正确的标头)。

问题:我们的回退方法(stream_socket_client)适用于非安全站点,因为我们可以简单地定义“主机名:端口”,它可以使用两个curl和stream_socket_client。但是,如果我们要监视安全站点(HTTPS),curl需要在主机之前定义HTTPS协议 - 这将使我们的回退方法(stream_socket_client)功能失败,因为它只使用host:port格式。

所以,例如:

$ URL:https://example.com:443(这会转换为“GOOD”CURL响应,但是转换为stream_socket_client响应)

$ URL:example.com:443(这将返回“UP”stream_socket_client响应,但是“DOWN”CURL响应)

因此,如果我们使用https://example.com:443作为我们的URL,并且Web服务器变得没有响应,但仍在该端口上运行,则两者都会失败,因为HTTPs已定义。

这是我们当前代码的简化版本:

<?php

    $url = "example.com:80";

    function curl($url) {



        $handle = curl_init($url);
        curl_setopt($handle,  CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($handle, CURLOPT_HEADER, true);
        curl_setopt($handle, CURLOPT_NOBODY, true);
        curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($handle, CURLOPT_URL, $url);

        $response = curl_exec($handle);
        $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);


        if($httpCode >= 200 && $httpCode < 400 || $httpCode == 401 || $httpCode == 405) {

                echo "CURL GOOD, $httpCode";
                echo "STATUS: GREEN";
            } 

            else {

                $fp = stream_socket_client("$url", $errno, $errstr);

                if (!$fp) {
                    echo "CURL BAD, PING DOWN";
                    echo "STATUS: RED";
                } 

                else {
                    echo "CURL BAD PING UP";
                    echo "STATUS: YELLOW";
                }
            }

        curl_close($handle);

    };
?>

任何想法如何使用回退方法来检查端口是否打开?我不必坚持使用PHP,可以使用一些JS,但更喜欢PHP。

编辑1:

感谢@ drew010,我知道我最终需要使用fsockopen。但是,我需要使用parse_url(),然后可以将“无效”URL传递给fsockopen以进行后备“ping”检查。

但是,我不确定如何仅剥离协议并离开端口和子路径(如果已定义)。我也不确定如何将无菌URL传递给fsockeopn函数以用于检查。到目前为止,我有下面的代码,但我知道我错过了一些代码。

下面的代码将http://example.com解析为example.com

function parseurl($url) {
    $url = 'http://example.com:80';
    $host = parse_url($url, PHP_URL_HOST);

    //this works for stripping protocol and "wwww" but need to leave port and sub path if defined.

    if (!$host)
        $host = $url;

    if (substr($host, 0, 4) == "www.")
        $host = substr($host, 4);
    if (strlen($host) > 50)
        $host = substr($host, 0, 47) . '...';
    return $host;
}


  // How to pass steril URL to PING function??

function ping($host, $timeout = 1) {

    if (!fsockopen($host, $port, $errno, $errstr, $timeout)) {
        return false;
        echo "OPEN";
    }

    else {
        echo "CLOSED";
    }
 }
php curl monitoring ping fsockopen
1个回答
0
投票

找到答案:

此脚本使用CURL检查给定的HOST是否正在为网页提供服务。如果不是,请使用PING函数检查是否有任何内容在侦听给定端口。

<?php

     * This script uses CURL to check if given HOST is serving a webpage. 
     * If NOT, use a PING function to check if anything is listening on given port.
    //* URL MUST contain a PORT after HOST
    //* URL CAN include any protocol or sub-path


    // sanitizes URL to host:port:path ONLY. (if PORT, PATH don't exist, it is ignored):

    function url_to_domain($url) {

        $url = 'http://google.com:80';

        echo "Input URL ..... $url<br />\n";

        $host = parse_url($url, PHP_URL_HOST);
        $port = parse_url($url, PHP_URL_PORT);
        $path = parse_url($url, PHP_URL_PATH);

        // If the URL can't be parsed, use the original URL
        // Change to "return false" if you don't want that

        if (!$host)
            echo "fail";
            // $host = $url;

            // remove "http/s" and "www" :

        if (substr($host, 0, 4) == "www.")
            $host = substr($host, 4);
        if (strlen($host) > 50)
            $host = substr($host, 0, 47) . '...';

        // contruct sanitized URL, add ":port/path" to HOST:

        return $host . ":" . $port . $path;

 }


     // pings "sanitized" URL:

    $url = (url_to_domain($url));

    $fp = pfsockopen($url, $errno, $errstr, $timeout = 5);
    if (!$fp) {

        echo "Ping URL ...... $url <br />\n ";
        echo "URL status ..... CLOSED <br />\n";
        echo "Error ............... $errstr ($errno)<br />\n";

     } 

    else {
        // $out = "GET / HTTP/1.1\r\n";
        // $out .= "$url\r\n";
        // $out .= "Connection: Close\r\n\r\n";
        //fwrite ($fp, $out);
        //displays header: 
           /*    
            while (!feof($fp)) {
                echo fgets($fp, 128);
             } 
        */
        // fclose($fp);

       echo "Ping URL ...... $url <br />\n  ";
        echo "URL status .... OPEN";

    }


 ?> 
© www.soinside.com 2019 - 2024. All rights reserved.