Changeset 2109459
- Timestamp:
- 06/20/2019 11:38:46 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
finteza-analytics/trunk/lib/finteza-analytics.php
r2071245 r2109459 40 40 * Used if url did not specified in functions call 41 41 * 42 * @ @const string42 * @const string 43 43 */ 44 44 const DEFAULT_URL = "https://content.mql5.com"; 45 46 /** 47 * Default user-agent for server-side events 48 * 49 * @const string 50 */ 51 const DEFAULT_USER_AGENT = 'FintezaPHP/1.0'; 45 52 46 53 /** … … 105 112 $path, 106 113 $websiteId, 107 $referer = null,108 $token = null114 $referer, 115 $token 109 116 ) { 110 $this->_url = (is_null($url) || empty($url)) ? self::DEFAULT_URL : $url; 111 $this->_token = $token; 117 118 // default values 119 $url = (is_null($url) || empty($url)) ? self::DEFAULT_URL : $url; 120 $path = (is_null($path) || empty($path)) ? '/' : $path; 121 $websiteId = (is_null($websiteId) || empty($websiteId)) ? '' : $websiteId; 122 123 // check referer 124 if (is_null($referer) || empty($referer)) { 125 $is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'; 126 $referer = $is_ssl ? 'https' : 'http'; 127 $referer .= "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; 128 } 129 130 // check path 131 if (substr($path, 0, 1) != '/') { 132 $path = '/' . $path; 133 } 134 135 // save options 136 $this->_url = $url; 112 137 $this->_path = $path; 113 138 $this->_websiteId = $websiteId; 114 139 $this->_referer = $referer; 140 $this->_token = $token; 141 } 142 143 /** 144 * Send server event to Finteza 145 * 146 * @param array $options Event options 147 * 148 * @return bool True if request was sent successfully; otherwise False; 149 * 150 * @see https://www.finteza.com/en/integrations/php-sdk/php-sdk-events 151 */ 152 public static function event($options) 153 { 154 if (is_null($options)) { 155 return false; 156 } 157 158 $fsdk = new self( 159 $options['url'], 160 null, 161 $options['websiteId'], 162 $options['referer'], 163 $options['token'] 164 ); 165 166 return $fsdk->_sendEvent( 167 isset($options['name']) ? $options['name'] : null, 168 isset($options['backReferer']) ? $options['backReferer'] : null, 169 isset($options['userIp']) ? $options['userIp'] : null, 170 isset($options['userAgent']) 171 ? $options['userAgent'] 172 : DEFAULT_USER_AGENT, 173 isset($options['value']) ? $options['value'] : null, 174 isset($options['unit']) ? $options['unit'] : null 175 ); 176 } 177 178 /** 179 * Send event to Finteza 180 * 181 * @param string $name Event name 182 * @param string|null $backReferer Back referer for event 183 * @param string|null $userIp User client ip for event 184 * @param string|null $userAgent User-Agent for event 185 * @param string|null $value Value param 186 * @param string|null $unit Unit for value param 187 * 188 * @return bool True if event was sent successfully; otherwise, False 189 */ 190 private function _sendEvent( 191 $name, 192 $backReferer, 193 $userIp, 194 $userAgent, 195 $value, 196 $unit 197 ) { 198 // check event name 199 if (empty($name)) { 200 return false; 201 } 202 203 // replace spaces 204 $name = str_replace(' ', '+', $name); 205 206 // add path 207 $path = '/tr?'; 208 209 // add params 210 $path .= 'id=' . urlencode($this->_websiteId); 211 $path .= '&event=' . urlencode($name); 212 $path .= '&ref=' . urlencode($this->_referer); 213 214 if (!is_null($backReferer) && !empty($backReferer)) { 215 $path .= '&back_ref=' . urlencode($backReferer); 216 } 217 if (!is_null($value) && !empty($value)) { 218 $path .= '&value=' . urlencode($value); 219 } 220 if (!is_null($unit) && !empty($unit)) { 221 $path .= '&unit=' . urlencode($unit); 222 } 223 224 // send request 225 try 226 { 227 // get host 228 $host = parse_url($this->_url)['host']; 229 230 // create connect 231 $errno = ''; 232 $errstr = ''; 233 $fp = stream_socket_client('ssl://'. $host . ':443', $errno, $errstr, 5); 234 if ($fp === false) { 235 return false; 236 } 237 238 // build headers 239 $out = "GET " . $path . " HTTP/1.1\r\n"; 240 $out .= "Host: " . $host . "\r\n"; 241 242 if (!is_null($userIp) && !empty($userIp)) { 243 $out .= "X-Forwarded-For: " . $userIp . "\r\n"; 244 $out .= "X-Forwarded-For-Sign: " 245 . md5($userIp . ':' . $this->_token) 246 . "\r\n"; 247 } 248 249 if (!is_null($userAgent) && !empty($userAgent)) { 250 $out .= "User-Agent: " . $userAgent . "\r\n"; 251 } 252 253 $out .= "Connection: Close\r\n\r\n"; 254 255 // connect and close 256 fwrite($fp, $out); 257 fclose($fp); 258 return true; 259 } 260 catch (Exception $ex) 261 { 262 return false; 263 } 115 264 } 116 265 … … 122 271 * @return null Nothing 123 272 * 124 * @see https://www.finteza.com/ developer/sdks/php/273 * @see https://www.finteza.com/en/integrations/php-sdk/php-sdk-proxy 125 274 */ 126 275 public static function proxy($options) … … 138 287 ); 139 288 140 $fsdk->_proxyTrack(); 141 } 142 143 /** 144 * Send server event to Finteza 145 * 146 * @param array $options Event options 147 * 148 * @return bool True if request was sent successfully; otherwise False; 149 * 150 * @see https://www.finteza.com/developer/sdks/php/ 151 */ 152 public static function event($options) 289 $fsdk->_proxyRequest(); 290 } 291 292 /** 293 * Set headers and outputs proxy content 294 * 295 * @return null Nothing 296 */ 297 private function _proxyRequest() 153 298 { 154 if (is_null($options)) { 155 return false; 156 } 157 158 $fsdk = new self( 159 isset($options['url']) ? $options['url'] : null, 160 null, 161 isset($options['websiteId']) ? $options['websiteId'] : null, 162 isset($options['referer']) ? $options['referer'] : null, 163 isset($options['token']) ? $options['token'] : null 299 // get request properties 300 $request_method = $_SERVER['REQUEST_METHOD']; 301 $request_host = $_SERVER['HTTP_HOST']; 302 $request_uri = $_SERVER['REQUEST_URI']; 303 $request_port = $_SERVER['SERVER_PORT']; 304 $request_params = $_GET; 305 $request_body = file_get_contents('php://input'); 306 307 // create proxy headers 308 $proxy_headers = $this->_getProxyHeaders(); 309 310 // create proxy URI (without domain and params) 311 $proxy_uri = $request_uri; 312 if (substr($proxy_uri, 0, strlen($this->_path)) == $this->_path) { 313 $proxy_uri = substr($proxy_uri, strlen($this->_path)); 314 } 315 316 // counter scripts handler 317 $has_corejs = preg_match('/core\.js$/', $proxy_uri) === 1; 318 $has_ampjs = preg_match('/amp\.js$/', $proxy_uri) === 1; 319 320 if ($has_corejs || $has_ampjs) { 321 $proxy_host = '//' . $request_host; 322 if ($request_port != 443 && $request_port != 80) { 323 $proxy_host .= ':' . $request_port; 324 } 325 326 $has_params = strpos($proxy_uri, '?') !== false; 327 $proxy_uri .= ($has_params ? '&' : '?'); 328 $proxy_uri .= 'host=' . urlencode($proxy_host) . $this->_path; 329 } 330 331 // execute request 332 $response = $this->_sendProxyRequest( 333 $request_method, 334 $proxy_uri, 335 $proxy_headers, 336 $request_body 164 337 ); 165 338 166 return $fsdk->_sendEvent( 167 isset($options['name']) ? $options['name'] : null, 168 isset($options['backReferer']) ? $options['backReferer'] : null, 169 isset($options['userIp']) ? $options['userIp'] : null, 170 isset($options['userAgent']) ? $options['userAgent'] : null, 171 isset($options['value']) ? $options['value'] : null, 172 isset($options['unit']) ? $options['unit'] : null 173 ); 174 } 175 176 /** 177 * Set headers and outputs proxy content 178 * 179 * @return null Nothing 180 */ 181 private function _proxyTrack() 182 { 183 $method = $_SERVER['REQUEST_METHOD']; 184 $headers = $this->_createRequestHeaders(); 185 $params = $this->_createRequestParams($method); 186 $url = $this->_createRequestUrl(); 187 $parsedUrl = parse_url($url); 188 189 $path = $this->_path; 190 $protocol = $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://"; 191 $port = ''; 192 if ($_SERVER['SERVER_PORT'] != 443 && $_SERVER['SERVER_PORT'] != 80) { 193 $port = ':'.$_SERVER['SERVER_PORT']; 194 } 195 196 if (substr($path, 0, 1) != '/') { 197 $path = '/' . $path; 198 } 199 // Handle core.js 200 if (preg_match('/core\.js$/', $url) !== false 201 && preg_match('/core\.js$/', $url) !== 0 202 ) { 203 $params['host'] = $protocol . $_SERVER['SERVER_NAME'] . $port . $path; 204 } 205 // Handle amp.js 206 if (preg_match('/amp\.js$/', $url) !== false 207 && preg_match('/amp\.js$/', $url) !== 0 208 ) { 209 $params['host'] = $protocol . $_SERVER['SERVER_NAME'] . $port . $path; 210 } 211 // Append query string for GET requests 212 if ($method == 'GET' 213 && count($params) > 0 214 && (!array_key_exists('query', $parsedUrl) || empty($parsedUrl['query'])) 215 ) { 216 $url .= '?' . http_build_query($params); 217 } 218 // Send request 219 $response = $this->_sendRequest($url, $headers, $params, $method); 220 $responseContent = $this->_processResponse($response); 221 222 // Remove headers 339 // parse response 340 $responseContent = $this->_parseProxyResponse($request_method, $response); 341 342 // remove headers 223 343 header_remove('X-Powered-By'); 224 header_remove('Server'); 225 226 // Output result 344 345 // return response 227 346 print($responseContent); 228 347 exit; … … 230 349 231 350 /** 232 * Send event to Finteza233 *234 * @param string $name Event name235 * @param string|null $backReferer Back referer for event236 * @param string|null $userIp User client ip for event237 * @param string|null $userAgent User-Agent for event238 * @param string|null $value Value param239 * @param string|null $unit Unit for value param240 *241 * @return bool True if event was sent successfully; otherwise, False242 */243 private function _sendEvent(244 $name,245 $backReferer = null,246 $userIp = null,247 $userAgent = null,248 $value = null,249 $unit = null250 ) {251 if (empty($name)) {252 return false;253 }254 255 $name = str_replace(' ', '+', $name);256 257 $url = $this->_url;258 if (!preg_match('/\/$/', $url)) {259 $url .= '/';260 }261 262 $url .= 'tr?';263 $query = 'id=' . urlencode($this->_websiteId);264 $query .= '&event=' . urlencode($name);265 $query .= '&ref=' . urlencode($this->_referer);266 if (!is_null($backReferer) && !empty($backReferer)) {267 $query .= '&back_ref=' . urlencode($backReferer);268 }269 if (!is_null($value) && !empty($value)) {270 $query .= '&value=' . urlencode($value);271 }272 if (!is_null($unit) && !empty($unit)) {273 $query .= '&unit=' . urlencode($unit);274 }275 276 $parts = parse_url($url);277 $parts['path'] .= '?'.$query;278 279 try {280 $fp = stream_socket_client(281 'ssl://'.$parts['host'].':443',282 $errno,283 $errstr,284 5285 );286 $parts['path'] .= '?'.$query;287 $out = "GET ".$parts['path']." HTTP/1.1\r\n";288 $out.= "Host: ".$parts['host']."\r\n";289 if (!is_null($userIp) && !empty($userIp)) {290 $out.= "X-Forwarded-For: ".$userIp."\r\n";291 $out.= "X-Forwarded-For-Sign: "292 .md5($userIp . ':' . $this->_token)293 ."\r\n";294 }295 if (!is_null($userAgent) && !empty($userAgent)) {296 $out.= "User-Agent: ".$userAgent."\r\n";297 }298 $out.= "Connection: Close\r\n\r\n";299 fwrite($fp, $out);300 fclose($fp);301 return true;302 } catch (Exception $ex) {303 return false;304 }305 }306 307 /**308 351 * Create request headers array for request to finteza server 309 352 * 310 353 * @return array Headers for request 311 354 */ 312 private function _ createRequestHeaders()355 private function _getProxyHeaders() 313 356 { 314 357 // Identify request headers … … 358 401 359 402 /** 360 * Create request params array for request to finteza server 361 * 362 * @param string $method Request method 363 * 364 * @return string|null Request params array or query string 365 */ 366 private function _createRequestParams($method) 403 * Sends request to finteza server 404 * 405 * @param string $method Request method 406 * @param string $uri Request URI 407 * @param array $headers Request headers 408 * @param string $body Request body 409 * 410 * @return string 411 */ 412 private function _sendProxyRequest($method, $uri, $headers, $body) 367 413 { 368 if ('GET' == $method) { 369 $params = $_GET; 370 } elseif ('POST' == $method) { 371 $params = $_POST; 372 if (empty($params)) { 373 $data = file_get_contents('php://input'); 374 if (!empty($data)) { 375 $params = $data; 376 } 377 } 378 } else { 379 $params = null; 380 } 381 382 return $params; 383 } 384 385 /** 386 * Create request URL to finteza server 387 * 388 * @return string 389 */ 390 private function _createRequestUrl() 391 { 392 $currentUri = parse_url($_SERVER['REQUEST_URI']); 393 $requestUrl = ''; 394 $cPath = $currentUri['path']; 395 396 if (substr($cPath, 0, strlen($this->_path)) == $this->_path) { 397 $requestUrl = $this->_url . substr($cPath, strlen($this->_path)); 398 } 399 400 return $requestUrl; 401 } 402 403 /** 404 * Sends request to finteza server 405 * 406 * @param string $url Request URL 407 * @param array $headers Request headers string 408 * @param array|string $params Request params array or query string 409 * @param string $method Request method 410 * 411 * @return string 412 */ 413 private function _sendRequest($url, $headers, $params, $method) 414 { 414 415 415 // let the request begin 416 $request = curl_init($ url);416 $request = curl_init($this->_url . $uri); 417 417 418 418 // (re-)send headers … … 425 425 curl_setopt($request, CURLOPT_HEADER, true); 426 426 427 // add data for POST, PUT or DELETE requests 428 if ('POST' == $method) { 429 $postData = is_array($params) ? http_build_query($params) : $params; 427 // set timeout 428 curl_setopt($request, CURLOPT_CONNECTTIMEOUT, 5); 429 curl_setopt($request, CURLOPT_TIMEOUT, 10); 430 431 // add data for POST-request 432 if ($method == 'POST') { 430 433 curl_setopt($request, CURLOPT_POST, true); 431 curl_setopt($request, CURLOPT_POSTFIELDS, $postData); 432 } 433 434 curl_setopt($request, CURLOPT_POSTFIELDS, $body); 435 curl_setopt($request, CURLOPT_HTTPHEADER, array("Expect:")); 436 } 437 434 438 // retrieve response (headers and content) 435 439 $response = curl_exec($request); 440 441 // check errors 436 442 if (curl_errno($request)) { 437 443 return ''; 438 444 } 445 446 // close connect 439 447 curl_close($request); 440 if (false === $response) { 448 449 // check response 450 if ($response == false) { 441 451 $response = ''; 442 452 } 453 443 454 return $response; 444 455 } … … 447 458 * Sets response headers and returns response content 448 459 * 460 * @param object $method Request method 449 461 * @param object $response Response handle object 450 462 * 451 463 * @return string Response content 452 464 */ 453 private function _p rocessResponse($response)465 private function _parseProxyResponse($method, $response) 454 466 { 455 467 // split response to header and content 456 468 list($headers, $content) = preg_split('/(\r\n){2}/', $response, 2); 457 469 470 // no parse POST-requests 471 if ($method == 'POST') { 472 return $content; 473 } 474 458 475 // (re-)send the headers 459 476 $headers = preg_split('/(\r\n){1}/', $headers); … … 463 480 if (substr($header, 0, strlen('Set-Cookie:')) !== 'Set-Cookie:') { 464 481 if (!preg_match('/^(Transfer-Encoding):/', $header)) { 465 header($header, false);482 header($header, true); 466 483 } 467 484 continue; … … 473 490 $cookies = ''; 474 491 foreach ($matches[1] as $item) { 475 476 492 if (!in_array($item, $this->_proxyCookies)) { 477 493 continue; … … 484 500 $paramLen = strlen('domain='); 485 501 if (substr($matches[3][0], 0, $paramLen) === 'domain=') { 486 $cookies .= 'domain=' . $_SERVER[' SERVER_NAME'];502 $cookies .= 'domain=' . $_SERVER['HTTP_HOST']; 487 503 } 488 504 } … … 496 512 497 513 if (!empty($cookies)) { 498 header('Set-Cookie:' . $cookies, false);514 header('Set-Cookie:' . $cookies, true); 499 515 } 500 516
Note: See TracChangeset
for help on using the changeset viewer.