<?php
// 封装公共参数并发送请求
function ipmi_req($action = '',$postfields = array(), $params = array(), $timeout = 30){
    $CONFIG = ipmi_GetConfig();
    $host = $params['serverhostname'] ? $params['serverhostname'] : $params['serverip'];  
    $postfields['username'] = $params['serverusername'];
    $postfields['password'] = $params['serverpassword'];
    $postfields['whmcs_version'] = $CONFIG['dcim_edition'];
    $usessl = $params['serversecure'];
    $serverport = $params['serverport'];
    if ($usessl) {
        $urldomain = "https://".$host;
    }
    else {
        $urldomain = "http://".$host;
    }
    if(!empty($serverport)){
        $urldomain .= ":".$serverport;
    }
    $url = $urldomain.'/index.php?m=api&a='.$action;
    # 发送数据
    $results = ipmi_LocalPost($url, $postfields, null, $timeout);
    return $results;
}

// post函数
function ipmi_LocalPost($url, $data, $proxy = null, $timeout = 10,$cookiename="") {
	global $_LANG;
	if (!$url) return false;
    if ($data) {
        $data = http_build_query($data);
    }
    $ssl = substr($url, 0, 8) == 'https://' ? true : false;
    $curl = curl_init();
    if (!is_null($proxy)) curl_setopt ($curl, CURLOPT_PROXY, $proxy); 
    curl_setopt($curl, CURLOPT_URL, $url);  
    if ($ssl) {
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查 
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
    }
    $cookie_file = dirname(__FILE__)."/".$cookiename;
    curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie_file); //连接结束后保存cookie信息的文件。 
    curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_file);//包含cookie数据的文件名，cookie文件的格式可以是Netscape格式，或者只是纯HTTP头部信息存入文件。 
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //在HTTP请求中包含一个"User-Agent: "头的字符串。      
    curl_setopt($curl, CURLOPT_HEADER, 0); //启用时会将头文件的信息作为数据流输出。  
    curl_setopt($curl, CURLOPT_POST, true); //发送一个常规的Post请求
    curl_setopt($curl,  CURLOPT_POSTFIELDS, $data);//Post提交的数据包
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); //启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器，使用CURLOPT_MAXREDIRS可以限定递归返回的数量。   
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //文件流形式       
    curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); //设置cURL允许执行的最长秒数。 
    $results = curl_exec($curl);
    $curl_errno = curl_errno($curl);
    $curl_error = curl_error($curl);
    $HTTP_CODE = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);
    if ($curl_errno > 0) {
        # 开启调试或者有后台的情况
        $errorMsg = "CURL ERRNO: " . $curl_errno . ",CURL ERROR: " . $curl_error . ",HTTP CODE: " . $HTTP_CODE;
        if( ipmi_IsDebug() ){
            $output['status'] = "error";
            $output['msg'] = $errorMsg;
            $logPath = dirname(__FILE__) . "/error.log";
            file_put_contents($logPath, $errorMsg.PHP_EOL, FILE_APPEND);
            return $output;
        }

        $output['status'] = "error";
        $output['msg'] = $_LANG['ipmi_system_curl_error1'];
        return $output;
    }
    $results = json_decode($results, true);
    return $results;
}

function ipmi_httpGetContent($url, $timeout = 30){
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);  
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
    
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); 
    curl_setopt($curl, CURLOPT_HEADER, 0); 
    curl_setopt($curl, CURLOPT_HTTPGET, 1); 
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); 
    $content = curl_exec($curl); 
    curl_close($curl);
    return $content;
}
// 批量执行curl,优化执行速度
function ipmi_batch_curl_post($data, $timeout = 60, $debug = true) {
    global $_LANG;
	$queue = curl_multi_init();
    $map = [];
    foreach($data as $k=>$v){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $v['url']);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($v['data']));
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_NOSIGNAL, true);
 
        curl_multi_add_handle($queue, $ch);
        $map[$k] = $ch;
    }
    $active = null;
 
    // execute the handles
    do {
        $mrc = curl_multi_exec($queue, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
 
    while ($active > 0 && $mrc == CURLM_OK) {
        if (curl_multi_select($queue, 0.5) != -1) {
            do {
                $mrc = curl_multi_exec($queue, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }
    $responses = [];
    foreach ($map as $k=>$ch) {
        $res = curl_multi_getcontent($ch);
        $info = curl_getinfo($ch);
        $error = curl_error($ch);
        $curl_errno = curl_errno($ch);
        if ($curl_errno > 0) {
            # 开启调试或者有后台的情况
            $errorMsg = "CURL ERRNO: " . $curl_errno . ",CURL ERROR: " . $curl_error;
            if($debug){
                $output['status'] = "error";
                $output['msg'] = $errorMsg;
            }else{
                $output['status'] = "error";
                $output['msg'] = $_LANG['ipmi_system_curl_error1'];
            }
            $responses[$k] = $output;
        }else{
            $responses[$k] = json_decode($res, true);
        }
        curl_multi_remove_handle($queue, $ch);
        curl_close($ch);
    }
    curl_multi_close($queue);
    return $responses;
}