debugMode = kUtil::constOn('DBG_CURL'); } /** * Reset connection settings (not results) after connection was closed * * @access protected */ protected function _resetSettings() { $this->timeout = 90; $this->followLocation = false; $this->requestMethod = self::REQUEST_METHOD_GET; $this->requestData = ''; $this->requestHeaders = Array (); $this->options = Array (); } /** * Sets CURL options (adds to options set before) * * @param Array $options_hash * @access public */ public function setOptions($options_hash) { $this->options = kUtil::array_merge_recursive($this->options, $options_hash); } /** * Combines user-defined and default options before setting them to CURL * * @access protected */ protected function prepareOptions() { if ($this->followLocation && ((defined('SAFE_MODE') && SAFE_MODE) || ini_get('open_basedir'))) { // this won't work with such restrictions, so turn it off $this->followLocation = false; } $default_options = Array ( // customizable options CURLOPT_FOLLOWLOCATION => $this->followLocation ? 1 : 0, CURLOPT_TIMEOUT => $this->timeout, // hardcoded options CURLOPT_RETURNTRANSFER => 1, CURLOPT_REFERER => PROTOCOL.SERVER_NAME, // don't verify SSL certificates CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTPHEADER => Array ('Expect:'), ); if ( isset($_SERVER['HTTP_USER_AGENT']) ) { $default_options[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT']; } if ($this->requestHeaders) { $default_options[CURLOPT_HTTPHEADER] = $this->prepareHeaders(); } // if we have post data, then POST else use GET method instead if ($this->requestMethod == self::REQUEST_METHOD_POST) { $default_options[CURLOPT_POST] = 1; $default_options[CURLOPT_POSTFIELDS] = $this->requestData; } // $default_options[CURLOPT_HEADERFUNCTION] = Array(&$this, 'ParseHeader'); $user_options = $this->options; // backup options, that user set directly $this->setOptions($default_options); $this->setOptions($user_options); $this->applyOptions(); } /** * Sets prepared options to CURL * * @access protected */ protected function applyOptions() { foreach ($this->options as $option_name => $option_value) { curl_setopt($this->connectionID, $option_name, $option_value); } } /** * Parses headers from CURL request * * @param resource $ch * @param string $header * @return int * @access protected */ protected function ParseHeader(&$ch, $header) { $this->responceHeaders[] = $header; return strlen($header); } /** * Sets request data for next query * * @param mixed $data Array or string */ public function SetRequestData($data) { if ( is_array($data) ) { $params_str = ''; $data = $this->Application->HttpQuery->_transformArrays($data); foreach ($data as $key => $value) { $params_str .= $key . '=' . urlencode($value) . '&'; } $data = $params_str; } $this->requestData = $data; } /** * Sets request data for next query and switches request method to POST * * @param mixed $data Array or string * @access public */ public function SetPostData($data) { $this->requestMethod = self::REQUEST_METHOD_POST; $this->SetRequestData($data); } /** * Sets request method to be used in next request * * @param int $request_method */ public function SetRequestMethod($request_method) { if ($request_method != self::REQUEST_METHOD_GET || $request_method != self::REQUEST_METHOD_POST) { throw new Exception('Method "' . __METHOD__ . '": Invalid $request_method parameter value'); return ; } $this->requestMethod = $request_method; } /** * Sets headers to be sent along with next query * * @param Array $headers * @access public */ public function SetHeaders($headers) { $this->requestHeaders = array_merge($this->requestHeaders, $headers); } /** * Returns compiled header to be used by curl * * @return Array * @access protected */ protected function prepareHeaders() { $ret = Array (); foreach ($this->requestHeaders as $header_name => $header_value) { $ret[] = is_numeric($header_name) ? $header_value : $header_name . ': ' . $header_value; } return $ret; } /** * Performs CURL request and returns it's result * * @param string $url * @param bool $close_connection * @return string * @access public */ public function Send($url, $close_connection = true, $log_status = null) { if (isset($log_status)) { // override debug mode setting $this->debugMode = $log_status; } if (($this->requestMethod == self::REQUEST_METHOD_GET) && $this->requestData) { // add query to url $url .= (strpos($url, '?') !== false ? '&' : '?') . $this->requestData; } $this->connectionID = curl_init($url); if ($this->debugMode) { kUtil::safeDefine('DBG_CURL_LOGFILE', '/curl.log'); $this->logFilePointer = fopen((defined('RESTRICTED') ? RESTRICTED : FULL_PATH) . DBG_CURL_LOGFILE, 'a'); $user_id = $this->Application->RecallVar('user_id'); $data = $_SERVER['REMOTE_ADDR'] . ' - ['.adodb_date('D M d H:i:s Y').'] ' . $_SERVER['REQUEST_URI'] . '; user_id: '.$user_id.'; sid: '.$this->Application->GetSID(); fwrite($this->logFilePointer, "\n\n" . str_repeat('=', strlen($data)) . "\n"); fwrite($this->logFilePointer, $data); fwrite($this->logFilePointer, "\n" . str_repeat('=', strlen($data)) . "\n"); curl_setopt($this->connectionID, CURLOPT_FILE, $this->logFilePointer); curl_setopt($this->connectionID, CURLOPT_VERBOSE, true); curl_setopt($this->connectionID, CURLOPT_STDERR, $this->logFilePointer); //curl_setopt($this->connectionID, CURLOPT_WRITEHEADER, $this->logFilePointer); } $this->responceHeaders = Array (); $this->prepareOptions(); $this->lastRespoce = curl_exec($this->connectionID); $this->Finalize($close_connection); return $this->lastRespoce; } /** * Returns various info about request made * * @param int $info_type * @return mixed * * @see http://www.php.net/manual/ru/function.curl-getinfo.php * @access public */ public function getInfo($info_type) { return curl_getinfo($this->connectionID, $info_type); } /** * Finalizes curl request and saves some data from curl before closing connection * * @param int $close_connection */ public function Finalize($close_connection = true) { $this->lastErrorCode = curl_errno($this->connectionID); $this->lastErrorMsg = curl_error($this->connectionID); $this->lastHTTPCode = curl_getinfo($this->connectionID, CURLINFO_HTTP_CODE); if ($close_connection) { $this->CloseConnection(); } $this->_resetSettings(); } /** * Closes connection to server * * @access public */ public function CloseConnection() { curl_close($this->connectionID); if ($this->debugMode) { // only close log after curl resource has been terminated fwrite($this->logFilePointer, "\n" . 'LastHTTPCode: ' . $this->lastHTTPCode . '; LastError: #' . $this->lastErrorCode . ' (' . $this->lastErrorMsg . ')' . "\n"); fwrite($this->logFilePointer, 'Respoce:' . "\n" . $this->lastRespoce); fclose($this->logFilePointer); } // restore debug mode setting $this->debugMode = kUtil::constOn('DBG_CURL'); } function isGoodResponceCode() { if ($this->lastErrorCode != 0) { return false; } return ($this->lastHTTPCode == 200) || ($this->lastHTTPCode >= 300 && $this->lastHTTPCode < 310); } }