/** * Get API Details * * Returns the contents of an API url request * * This is needed because of the "XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin" * error that javascript gets when trying to access outside domains sometimes. * * @since 3.1 * @uses GSADMININCPATH * @uses GSCACHEPATH * * @param string $type, default is 'core' * @param array $args, default is empty * * @returns string */ function get_api_details($type = 'core', $args = null) { global $debugApi, $nocache, $nocurl; include GSADMININCPATH . 'configuration.php'; # core api details if ($type == 'core') { # core version request, return status 0-outdated,1-current,2-bleedingedge $fetch_this_api = $api_url . '?v=' . GSVERSION; } else { if ($type == 'plugin' && $args) { # plugin api details. requires a passed plugin i $apiurl = $site_link_back_url . 'api/extend/?file='; $fetch_this_api = $apiurl . $args; } else { if ($type == 'custom' && $args) { # custom api details. requires a passed url $fetch_this_api = $args; } else { return; } } } // get_execution_time(); debug_api_details("type: " . $type . " " . $args); debug_api_details("address: " . $fetch_this_api); # debug_api_details(debug_backtrace()); if (!isset($api_timeout) or (int) $api_timeout < 100) { $api_timeout = 500; } // default and clamp min to 100ms debug_api_details("timeout: " . $api_timeout); # check to see if cache is available for this $cachefile = md5($fetch_this_api) . '.txt'; $cacheExpire = 39600; // 11 minutes if (!$nocache) { debug_api_details('cache check for ' . $fetch_this_api . ' ' . $cachefile); } else { debug_api_details('cache check: disabled'); } $cacheAge = file_exists(GSCACHEPATH . $cachefile) ? filemtime(GSCACHEPATH . $cachefile) : ''; debug_api_details('cache age: ' . output_datetime($cacheAge)); if (!$nocache && !empty($cacheAge) && time() - $cacheExpire < $cacheAge) { # grab the api request from the cache $data = read_file(GSCACHEPATH . $cachefile); debug_api_details('returning api cache ' . GSCACHEPATH . $cachefile); } else { # make the api call if (function_exists('curl_init') && function_exists('curl_exec') && !$nocurl) { // USE CURL $ch = curl_init(); if (!$ch) { debug_api_details("curl init failed"); return; } // define missing curlopts php<5.2.3 if (!defined('CURLOPT_CONNECTTIMEOUT_MS')) { define('CURLOPT_CONNECTTIMEOUT_MS', 156); } if (!defined('CURLOPT_TIMEOUT_MS')) { define('CURLOPT_TIMEOUT_MS', 155); } // min cURL 7.16.2 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $api_timeout); // define the maximum amount of time that cURL can take to connect to the server curl_setopt($ch, CURLOPT_TIMEOUT_MS, $api_timeout); // define the maximum amount of time cURL can execute for. curl_setopt($ch, CURLOPT_NOSIGNAL, 1); // prevents SIGALRM during dns allowing timeouts to work http://us2.php.net/manual/en/function.curl-setopt.php#104597 curl_setopt($ch, CURLOPT_HEADER, false); // ensures header is not in output curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $fetch_this_api); if ($debugApi) { // $verbose = fopen(GSDATAOTHERPATH .'logs/curllog.txt', 'w+'); $verbose = tmpfile(); // curl_setopt($ch, CURLOPT_WRITEHEADER, $verbose ); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_STDERR, $verbose); curl_setopt($ch, CURLINFO_HEADER_OUT, true); } $data = curl_exec($ch); if ($debugApi) { debug_api_details("using curl"); debug_api_details("curl version: "); debug_api_details(print_r(curl_version(), true)); debug_api_details("curl info:"); debug_api_details(print_r(curl_getinfo($ch), true)); if (!$data) { debug_api_details("curl error number:" . curl_errno($ch)); debug_api_details("curl error:" . curl_error($ch)); } debug_api_details("curl Verbose: "); debug_api_details(!rewind($verbose) . nl2br(htmlspecialchars(stream_get_contents($verbose)))); fclose($verbose); // output header and response then remove header from data $dataparts = explode("\r\n", $data); debug_api_details("curl Data: "); debug_api_details($data); $data = end($dataparts); } curl_close($ch); } else { if (ini_get('allow_url_fopen')) { // USE FOPEN debug_api_details("using fopen"); $timeout = $api_timeout / 1000; // ms to float seconds // $context = stream_context_create(); // stream_context_set_option ( $context, array('http' => array('timeout' => $timeout)) ); $context = stream_context_create(array('http' => array('timeout' => $timeout))); $data = read_file($fetch_this_api, false, $context); debug_api_details("fopen data: " . $data); } else { debug_api_details("No api methods available"); return; } } // debug_api_details("Duration: ".get_execution_time()); $response = json_decode($data); debug_api_details('JSON:'); debug_api_details(print_r($response, true), ''); // if response is invalid set status to -1 error // and we pass on our own data, it is also cached to prevent constant rechecking if (!$response) { $data = '{"status":-1}'; } debug_api_details($data); save_file(GSCACHEPATH . $cachefile, $data); return $data; } return $data; }
/** * Get API Details * * Returns the contents of an API url request * * This is needed because of the "XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin" * error that javascript gets when trying to access outside domains sometimes. * * @since 3.1 * @uses GSADMININCPATH * @uses GSCACHEPATH * * @param string $type, default is 'core' * @param array $args, default is empty * * @returns string */ function get_api_details($type = 'core', $args = null) { global $debugApi, $nocache, $nocurl; include GSADMININCPATH . 'configuration.php'; # core api details if ($type == 'core') { $fetch_this_api = $api_url . '?v=' . GSVERSION; } # plugin api details. requires a passed plugin id if ($type == 'plugin' && $args) { $apiurl = $site_link_back_url . 'api/extend/?file='; $fetch_this_api = $apiurl . $args; } # custom api details. requires a passed url if ($type == 'custom' && $args) { $fetch_this_api = $args; } // get_execution_time(); debug_api_details("get_api_details: " . $type . " " . $args); debug_api_details("get_api_details: " . $fetch_this_api); # debug_api_details(debug_backtrace()); if (!isset($api_timeout) or (int) $api_timeout < 100) { $api_timeout = 500; } // default and clamp min to 100ms debug_api_details("API timeout: " . $api_timeout); # check to see if cache is available for this $cachefile = md5($fetch_this_api) . '.txt'; debug_api_details('cache check for ' . $fetch_this_api . ' ' . $cachefile); if (file_exists(GSCACHEPATH . $cachefile) && time() - 40000 < filemtime(GSCACHEPATH . $cachefile) and !$nocache) { # grab the api request from the cache $data = file_get_contents(GSCACHEPATH . $cachefile); debug_api_details('Returning api cache ' . GSCACHEPATH . $cachefile); } else { # make the api call if (function_exists('curl_exec') and !$nocurl) { // USE CURL $ch = curl_init(); // define missing curlopts php<5.2.3 if (!defined('CURLOPT_CONNECTTIMEOUT_MS')) { define('CURLOPT_CONNECTTIMEOUT_MS', 156); } if (!defined('CURLOPT_TIMEOUT_MS')) { define('CURLOPT_TIMEOUT_MS', 155); } // min cURL 7.16.2 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $api_timeout); // define the maximum amount of time that cURL can take to connect to the server curl_setopt($ch, CURLOPT_TIMEOUT_MS, $api_timeout); // define the maximum amount of time cURL can execute for. curl_setopt($ch, CURLOPT_NOSIGNAL, 1); // prevents SIGALRM during dns allowing timeouts to work http://us2.php.net/manual/en/function.curl-setopt.php#104597 curl_setopt($ch, CURLOPT_HEADER, false); // ensures header is not in output curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $fetch_this_api); if ($debugApi) { // $verbose = fopen(GSDATAOTHERPATH .'logs/curllog.txt', 'w+'); $verbose = tmpfile(); // curl_setopt($ch, CURLOPT_WRITEHEADER, $verbose ); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_STDERR, $verbose); curl_setopt($ch, CURLINFO_HEADER_OUT, true); } $data = curl_exec($ch); if ($debugApi) { debug_api_details("API via curl"); debug_api_details("curl version: "); debug_api_details(print_r(curl_version(), true)); debug_api_details("Curl info:"); debug_api_details(print_r(curl_getinfo($ch), true)); if (!$data) { debug_api_details("cURL error number:" . curl_errno($ch)); debug_api_details("cURL error:" . curl_error($ch)); } debug_api_details("Curl Verbose: "); debug_api_details(!rewind($verbose) . nl2br(htmlspecialchars(stream_get_contents($verbose)))); fclose($verbose); // output header and response then remove header from data $dataparts = explode("\r\n", $data); debug_api_details("Curl Data: "); debug_api_details($data); $data = end($dataparts); } curl_close($ch); } else { if (ini_get('allow_url_fopen')) { // USE FOPEN debug_api_details("API via fopen"); $timeout = $api_timeout / 1000; // ms to float seconds // $context = stream_context_create(); // stream_context_set_option ( $context, array('http' => array('timeout' => $timeout)) ); $context = stream_context_create(array('http' => array('timeout' => $timeout))); $data = @file_get_contents($fetch_this_api, false, $context); debug_api_details("fopen data: " . $data); } else { debug_api_details("No api methods available"); return; } } // debug_api_details("Duration: ".get_execution_time()); $response = json_decode($data); debug_api_details('API JSON:'); debug_api_details(print_r($response, true)); // if response is invalid do not write to cache and return false // this keep proxy and malicious responses out of downstream code if ($response) { file_put_contents(GSCACHEPATH . $cachefile, $data); chmod(GSCACHEPATH . $cachefile, 0644); return $data; } else { return; } } return $data; }