1<?php 2 3/* 4 * This file is part of MailSo. 5 * 6 * (c) 2014 Usenko Timur 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace MailSo\Base; 13 14/** 15 * @category MailSo 16 * @package Base 17 */ 18class Http 19{ 20 /** 21 * @var bool 22 */ 23 private $bIsMagicQuotesOn; 24 25 /** 26 * @access private 27 */ 28 private function __construct() 29 { 30 $this->bIsMagicQuotesOn = (bool) @\ini_get('magic_quotes_gpc'); 31 } 32 33 /** 34 * @return \MailSo\Base\Http 35 */ 36 public static function NewInstance() 37 { 38 return new self(); 39 } 40 41 /** 42 * @staticvar \MailSo\Base\Http $oInstance; 43 * 44 * @return \MailSo\Base\Http 45 */ 46 public static function SingletonInstance() 47 { 48 static $oInstance = null; 49 if (null === $oInstance) 50 { 51 $oInstance = self::NewInstance(); 52 } 53 54 return $oInstance; 55 } 56 57 /** 58 * @param string $sKey 59 * 60 * @return bool 61 */ 62 public function HasQuery($sKey) 63 { 64 return isset($_GET[$sKey]); 65 } 66 67 /** 68 * @param string $sKey 69 * @param mixed $mDefault = null 70 * @param bool $bClearPercZeroZero = true 71 * 72 * @return mixed 73 */ 74 public function GetQuery($sKey, $mDefault = null, $bClearPercZeroZero = true) 75 { 76 return isset($_GET[$sKey]) ? \MailSo\Base\Utils::StripSlashesValue($_GET[$sKey], $bClearPercZeroZero) : $mDefault; 77 } 78 79 /** 80 * @return array|null 81 */ 82 public function GetQueryAsArray() 83 { 84 return isset($_GET) && \is_array($_GET) ? \MailSo\Base\Utils::StripSlashesValue($_GET, true) : null; 85 } 86 87 /** 88 * @param string $sKey 89 * 90 * @return bool 91 */ 92 public function HasPost($sKey) 93 { 94 return isset($_POST[$sKey]); 95 } 96 97 /** 98 * @param string $sKey 99 * @param mixed $mDefault = null 100 * @param bool $bClearPercZeroZero = false 101 * 102 * @return mixed 103 */ 104 public function GetPost($sKey, $mDefault = null, $bClearPercZeroZero = false) 105 { 106 return isset($_POST[$sKey]) ? \MailSo\Base\Utils::StripSlashesValue($_POST[$sKey], $bClearPercZeroZero) : $mDefault; 107 } 108 109 /** 110 * @return array|null 111 */ 112 public function GetPostAsArray() 113 { 114 return isset($_POST) && \is_array($_POST) ? \MailSo\Base\Utils::StripSlashesValue($_POST, false) : null; 115 } 116 117 /** 118 * @param string $sKey 119 * 120 * @return bool 121 */ 122 public function HasRequest($sKey) 123 { 124 return isset($_REQUEST[$sKey]); 125 } 126 127 /** 128 * @param string $sKey 129 * @param mixed $mDefault = null 130 * 131 * @return mixed 132 */ 133 public function GetRequest($sKey, $mDefault = null) 134 { 135 return isset($_REQUEST[$sKey]) ? \MailSo\Base\Utils::StripSlashesValue($_REQUEST[$sKey]) : $mDefault; 136 } 137 138 /** 139 * @param string $sKey 140 * 141 * @return bool 142 */ 143 public function HasServer($sKey) 144 { 145 return isset($_SERVER[$sKey]); 146 } 147 148 /** 149 * @param string $sKey 150 * @param mixed $mDefault = null 151 * 152 * @return mixed 153 */ 154 public function GetServer($sKey, $mDefault = null) 155 { 156 return isset($_SERVER[$sKey]) ? $_SERVER[$sKey] : $mDefault; 157 } 158 159 /** 160 * @param string $sKey 161 * 162 * @return bool 163 */ 164 public function HasEnv($sKey) 165 { 166 return isset($_ENV[$sKey]); 167 } 168 169 /** 170 * @param string $sKey 171 * @param mixed $mDefault = null 172 * 173 * @return mixed 174 */ 175 public function GetEnv($sKey, $mDefault = null) 176 { 177 return isset($_ENV[$sKey]) ? $_ENV[$sKey] : $mDefault; 178 } 179 180 /** 181 * @return string 182 */ 183 public function ServerProtocol() 184 { 185 return $this->GetServer('SERVER_PROTOCOL', 'HTTP/1.0'); 186 } 187 188 /** 189 * @return string 190 */ 191 public function GetMethod() 192 { 193 return $this->GetServer('REQUEST_METHOD', ''); 194 } 195 196 /** 197 * @return bool 198 */ 199 public function IsPost() 200 { 201 return ('POST' === $this->GetMethod()); 202 } 203 204 /** 205 * @return bool 206 */ 207 public function IsGet() 208 { 209 return ('GET' === $this->GetMethod()); 210 } 211 212 /** 213 * @return string 214 */ 215 public function GetQueryString() 216 { 217 return $this->GetServer('QUERY_STRING', ''); 218 } 219 220 /** 221 * @return bool 222 */ 223 public function CheckLocalhost($sServer) 224 { 225 return \in_array(\strtolower(\trim($sServer)), array( 226 'localhost', '127.0.0.1', '::1', '::1/128', '0:0:0:0:0:0:0:1' 227 )); 228 } 229 230 /** 231 * @param string $sValueToCheck = '' 232 * 233 * @return bool 234 */ 235 public function IsLocalhost($sValueToCheck = '') 236 { 237 if (empty($sValueToCheck)) 238 { 239 $sValueToCheck = $this->GetServer('REMOTE_ADDR', ''); 240 } 241 242 return $this->CheckLocalhost($sValueToCheck); 243 } 244 245 /** 246 * @return string 247 */ 248 public function GetRawBody() 249 { 250 static $sRawBody = null; 251 if (null === $sRawBody) 252 { 253 $sBody = @\file_get_contents('php://input'); 254 $sRawBody = (false !== $sBody) ? $sBody : ''; 255 } 256 return $sRawBody; 257 } 258 259 /** 260 * @param string $sHeader 261 * 262 * @return string 263 */ 264 public function GetHeader($sHeader) 265 { 266 $sServerKey = 'HTTP_'.\strtoupper(\str_replace('-', '_', $sHeader)); 267 $sResultHeader = $this->GetServer($sServerKey, ''); 268 269 if (0 === \strlen($sResultHeader) && 270 \MailSo\Base\Utils::FunctionExistsAndEnabled('apache_request_headers')) 271 { 272 $sHeaders = \apache_request_headers(); 273 if (isset($sHeaders[$sHeader])) 274 { 275 $sResultHeader = $sHeaders[$sHeader]; 276 } 277 } 278 279 return $sResultHeader; 280 } 281 282 /** 283 * @param bool $bCheckProxy = true 284 * 285 * @return string 286 */ 287 public function GetScheme($bCheckProxy = true) 288 { 289 return $this->IsSecure($bCheckProxy) ? 'https' : 'http'; 290 } 291 292 /** 293 * @param bool $bCheckProxy = true 294 * 295 * @return bool 296 */ 297 public function IsSecure($bCheckProxy = true) 298 { 299 $sHttps = \strtolower($this->GetServer('HTTPS', '')); 300 if ('on' === $sHttps || ('' === $sHttps && '443' === (string) $this->GetServer('SERVER_PORT', ''))) 301 { 302 return true; 303 } 304 305 if ($bCheckProxy && ( 306 ('https' === \strtolower($this->GetServer('HTTP_X_FORWARDED_PROTO', ''))) || 307 ('on' === \strtolower($this->GetServer('HTTP_X_FORWARDED_SSL', ''))) 308 )) 309 { 310 return true; 311 } 312 313 return false; 314 } 315 316 /** 317 * @param bool $bWithRemoteUserData = false 318 * @param bool $bWithoutWWW = true 319 * @param bool $bWithoutPort = false 320 * 321 * @return string 322 */ 323 public function GetHost($bWithRemoteUserData = false, $bWithoutWWW = true, $bWithoutPort = false) 324 { 325 $sHost = $this->GetServer('HTTP_HOST', ''); 326 if (0 === \strlen($sHost)) 327 { 328 $sName = $this->GetServer('SERVER_NAME'); 329 $iPort = (int) $this->GetServer('SERVER_PORT', 80); 330 331 $sHost = (\in_array($iPort, array(80, 433))) ? $sName : $sName.':'.$iPort; 332 } 333 334 if ($bWithoutWWW) 335 { 336 $sHost = 'www.' === \substr(\strtolower($sHost), 0, 4) ? \substr($sHost, 4) : $sHost; 337 } 338 339 if ($bWithRemoteUserData) 340 { 341 $sUser = \trim($this->HasServer('REMOTE_USER') ? $this->GetServer('REMOTE_USER', '') : ''); 342 $sHost = (0 < \strlen($sUser) ? $sUser.'@' : '').$sHost; 343 } 344 345 if ($bWithoutPort) 346 { 347 $sHost = \preg_replace('/:[\d]+$/', '', $sHost); 348 } 349 350 return $sHost; 351 } 352 353 /** 354 * @param bool $bCheckProxy = false 355 * 356 * @return string 357 */ 358 public function GetClientIp($bCheckProxy = false) 359 { 360 $sIp = ''; 361 if ($bCheckProxy && null !== $this->GetServer('HTTP_CLIENT_IP', null)) 362 { 363 $sIp = $this->GetServer('HTTP_CLIENT_IP', ''); 364 } 365 else if ($bCheckProxy && null !== $this->GetServer('HTTP_X_FORWARDED_FOR', null)) 366 { 367 $sIp = $this->GetServer('HTTP_X_FORWARDED_FOR', ''); 368 } 369 else 370 { 371 $sIp = $this->GetServer('REMOTE_ADDR', ''); 372 } 373 374 return $sIp; 375 } 376 377 /** 378 * @param string $sUrl 379 * @param array $aPost = array() 380 * @param string $sCustomUserAgent = 'MailSo Http User Agent (v1)' 381 * @param int $iCode = 0 382 * @param \MailSo\Log\Logger $oLogger = null 383 * @param int $iTimeout = 20 384 * @param string $sProxy = '' 385 * @param string $sProxyAuth = '' 386 * 387 * @return string|bool 388 */ 389 public function SendPostRequest($sUrl, $aPost = array(), $sCustomUserAgent = 'MailSo Http User Agent (v1)', &$iCode = 0, 390 $oLogger = null, $iTimeout = 20, $sProxy = '', $sProxyAuth = '') 391 { 392 $aOptions = array( 393 CURLOPT_URL => $sUrl, 394 CURLOPT_HEADER => false, 395 CURLOPT_FAILONERROR => true, 396 CURLOPT_SSL_VERIFYPEER => false, 397 CURLOPT_RETURNTRANSFER => true, 398 CURLOPT_POST => true, 399 CURLOPT_POSTFIELDS => \http_build_query($aPost, '', '&'), 400 CURLOPT_TIMEOUT => (int) $iTimeout 401 ); 402 403 if (0 < \strlen($sCustomUserAgent)) 404 { 405 $aOptions[CURLOPT_USERAGENT] = $sCustomUserAgent; 406 } 407 408 if (0 < \strlen($sProxy)) 409 { 410 $aOptions[CURLOPT_PROXY] = $sProxy; 411 if (0 < \strlen($sProxyAuth)) 412 { 413 $aOptions[CURLOPT_PROXYUSERPWD] = $sProxyAuth; 414 } 415 } 416 417 $oCurl = \curl_init(); 418 \curl_setopt_array($oCurl, $aOptions); 419 420 if ($oLogger) 421 { 422 $oLogger->Write('cURL: Send post request: '.$sUrl); 423 } 424 425 $mResult = \curl_exec($oCurl); 426 427 $iCode = (int) \curl_getinfo($oCurl, CURLINFO_HTTP_CODE); 428 $sContentType = (string) \curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE); 429 430 if ($oLogger) 431 { 432 $oLogger->Write('cURL: Post request result: (Status: '.$iCode.', ContentType: '.$sContentType.')'); 433 if (false === $mResult || 200 !== $iCode) 434 { 435 $oLogger->Write('cURL: Error: '.\curl_error($oCurl), \MailSo\Log\Enumerations\Type::WARNING); 436 } 437 } 438 439 if (\is_resource($oCurl)) 440 { 441 \curl_close($oCurl); 442 } 443 444 return $mResult; 445 } 446 447 /** 448 * @param string $sUrl 449 * @param array $aOptions 450 * @param \MailSo\Log\Logger $oLogger = null 451 * 452 * @return string 453 */ 454 static public function DetectAndHackFollowLocationUrl($sUrl, &$aOptions, $oLogger = null) 455 { 456 $sSafeMode = \strtolower(\trim(@\ini_get('safe_mode'))); 457 $bSafeMode = 'on' === $sSafeMode || '1' === $sSafeMode; 458 459 $sNewUrl = null; 460 $sUrl = isset($aOptions[CURLOPT_URL]) ? $aOptions[CURLOPT_URL] : $sUrl; 461 462 if (isset($aOptions[CURLOPT_FOLLOWLOCATION]) && $aOptions[CURLOPT_FOLLOWLOCATION] && 0 < \strlen($sUrl) && 463 ($bSafeMode || \ini_get('open_basedir') !== '')) 464 { 465 $aOptions[CURLOPT_FOLLOWLOCATION] = false; 466 467 $iMaxRedirects = isset($aOptions[CURLOPT_MAXREDIRS]) ? $aOptions[CURLOPT_MAXREDIRS] : 5; 468 $iRedirectLimit = $iMaxRedirects; 469 470 if ($iRedirectLimit > 0) 471 { 472 $sNewUrl = $sUrl; 473 474 $oCurl = \curl_init($sUrl); 475 476 $aAddOptions = array( 477 CURLOPT_URL => $sUrl, 478 CURLOPT_HEADER => true, 479 CURLOPT_NOBODY => true, 480 CURLOPT_FAILONERROR => false, 481 CURLOPT_SSL_VERIFYPEER => false, 482 CURLOPT_FOLLOWLOCATION => false, 483 CURLOPT_FORBID_REUSE => false, 484 CURLOPT_RETURNTRANSFER => true, 485 CURLOPT_TIMEOUT => 5 486 ); 487 488 if (isset($aOptions[CURLOPT_HTTPHEADER]) && \is_array($aOptions[CURLOPT_HTTPHEADER]) && 0 < \count($aOptions[CURLOPT_HTTPHEADER])) 489 { 490 $aAddOptions[CURLOPT_HTTPHEADER] = $aOptions[CURLOPT_HTTPHEADER]; 491 } 492 493 \curl_setopt_array($oCurl, $aAddOptions); 494 495 do 496 { 497 \curl_setopt($oCurl, CURLOPT_URL, $sNewUrl); 498 499 $sHeader = \curl_exec($oCurl); 500 if (\curl_errno($oCurl)) 501 { 502 $iCode = 0; 503 } 504 else 505 { 506 $iCode = \curl_getinfo($oCurl, CURLINFO_HTTP_CODE); 507 if ($iCode === 301 || $iCode === 302) 508 { 509 $aMatches = array(); 510 \preg_match('/Location:(.*?)\n/', $sHeader, $aMatches); 511 $sNewUrl = \trim(\array_pop($aMatches)); 512 513 if ($oLogger) 514 { 515 $oLogger->Write('cUrl: Location URL: '.$sNewUrl); 516 } 517 } 518 else 519 { 520 $iCode = 0; 521 } 522 } 523 524 } while ($iCode && --$iRedirectLimit); 525 526 \curl_close($oCurl); 527 if ($iRedirectLimit > 0 && 0 < \strlen($sNewUrl)) 528 { 529 $aOptions[CURLOPT_URL] = $sNewUrl; 530 } 531 } 532 } 533 534 return null === $sNewUrl ? $sUrl : $sNewUrl; 535 } 536 537 /** 538 * @param string $sUrl 539 * @param resource $rFile 540 * @param string $sCustomUserAgent = 'MailSo Http User Agent (v1)' 541 * @param string $sContentType = '' 542 * @param int $iCode = 0 543 * @param \MailSo\Log\Logger $oLogger = null 544 * @param int $iTimeout = 10 545 * @param string $sProxy = '' 546 * @param string $sProxyAuth = '' 547 * @param array $aHttpHeaders = array() 548 * @param bool $bFollowLocation = true 549 * 550 * @return bool 551 */ 552 public function SaveUrlToFile($sUrl, $rFile, $sCustomUserAgent = 'MailSo Http User Agent (v1)', &$sContentType = '', &$iCode = 0, 553 $oLogger = null, $iTimeout = 10, $sProxy = '', $sProxyAuth = '', $aHttpHeaders = array(), $bFollowLocation = true) 554 { 555 if (null === $sCustomUserAgent) 556 { 557 $sCustomUserAgent = 'MailSo Http User Agent (v1)'; 558 } 559 560 if (!is_resource($rFile)) 561 { 562 if ($oLogger) 563 { 564 $oLogger->Write('cURL: input resource invalid.', \MailSo\Log\Enumerations\Type::WARNING); 565 } 566 567 return false; 568 } 569 570 $sUrl = \trim($sUrl); 571 if ('//' === substr($sUrl, 0, 2)) 572 { 573 $sUrl = 'http:'.$sUrl; 574 } 575 576 $aOptions = array( 577 CURLOPT_URL => $sUrl, 578 CURLOPT_HEADER => false, 579 CURLOPT_FAILONERROR => true, 580 CURLOPT_SSL_VERIFYPEER => false, 581 CURLOPT_RETURNTRANSFER => true, 582 CURLOPT_FOLLOWLOCATION => !!$bFollowLocation, 583 CURLOPT_MAXREDIRS => 7, 584 CURLOPT_FILE => $rFile, 585 CURLOPT_TIMEOUT => (int) $iTimeout 586 ); 587 588 if (0 < \strlen($sCustomUserAgent)) 589 { 590 $aOptions[CURLOPT_USERAGENT] = $sCustomUserAgent; 591 } 592 593 if (0 < \strlen($sProxy)) 594 { 595 $aOptions[CURLOPT_PROXY] = $sProxy; 596 if (0 < \strlen($sProxyAuth)) 597 { 598 $aOptions[CURLOPT_PROXYUSERPWD] = $sProxyAuth; 599 } 600 } 601 602 if (\is_array($aHttpHeaders) && 0 < \count($aHttpHeaders)) 603 { 604 $aOptions[CURLOPT_HTTPHEADER] = $aHttpHeaders; 605 } 606 607 if ($oLogger) 608 { 609 $oLogger->Write('cUrl: URL: '.$sUrl); 610// if (isset($aOptions[CURLOPT_HTTPHEADER]) && \is_array($aOptions[CURLOPT_HTTPHEADER]) && 0 < \count($aOptions[CURLOPT_HTTPHEADER])) 611// { 612// $oLogger->Write('cUrl: Headers: '.\print_r($aOptions[CURLOPT_HTTPHEADER], true)); 613// } 614 } 615 616 \MailSo\Base\Http::DetectAndHackFollowLocationUrl($sUrl, $aOptions, $oLogger); 617 618 $oCurl = \curl_init(); 619 \curl_setopt_array($oCurl, $aOptions); 620 621 $bResult = \curl_exec($oCurl); 622 623 $iCode = (int) \curl_getinfo($oCurl, CURLINFO_HTTP_CODE); 624 $sContentType = (string) \curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE); 625 626 if ($oLogger) 627 { 628 $oLogger->Write('cUrl: Request result: '.($bResult ? 'true' : 'false').' (Status: '.$iCode.', ContentType: '.$sContentType.')'); 629 if (!$bResult || 200 !== $iCode) 630 { 631 $oLogger->Write('cUrl: Error: '.\curl_error($oCurl), \MailSo\Log\Enumerations\Type::WARNING); 632 } 633 } 634 635 if (\is_resource($oCurl)) 636 { 637 \curl_close($oCurl); 638 } 639 640 return $bResult; 641 } 642 643 /** 644 * @param string $sUrl 645 * @param string $sCustomUserAgent = 'MailSo Http User Agent (v1)' 646 * @param string $sContentType = '' 647 * @param int $iCode = 0 648 * @param \MailSo\Log\Logger $oLogger = null 649 * @param int $iTimeout = 10 650 * @param string $sProxy = '' 651 * @param string $sProxyAuth = '' 652 * @param array $aHttpHeaders = array() 653 * @param bool $bFollowLocation = true 654 * 655 * @return string|bool 656 */ 657 public function GetUrlAsString($sUrl, $sCustomUserAgent = 'MailSo Http User Agent (v1)', &$sContentType = '', &$iCode = 0, 658 $oLogger = null, $iTimeout = 10, $sProxy = '', $sProxyAuth = '', $aHttpHeaders = array(), $bFollowLocation = true) 659 { 660 $rMemFile = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); 661 if ($this->SaveUrlToFile($sUrl, $rMemFile, $sCustomUserAgent, $sContentType, $iCode, $oLogger, $iTimeout, $sProxy, $sProxyAuth, $aHttpHeaders, $bFollowLocation) && \is_resource($rMemFile)) 662 { 663 \rewind($rMemFile); 664 return \stream_get_contents($rMemFile); 665 } 666 667 return false; 668 } 669 670 /** 671 * @param int $iExpireTime 672 * @param bool $bSetCacheHeader = true 673 * @param string $sEtag = '' 674 * 675 * @return bool 676 */ 677 public function ServerNotModifiedCache($iExpireTime, $bSetCacheHeader = true, $sEtag = '') 678 { 679 $bResult = false; 680 if (0 < $iExpireTime) 681 { 682 $iUtcTimeStamp = \time(); 683 $sIfModifiedSince = $this->GetHeader('If-Modified-Since', ''); 684 if (0 === \strlen($sIfModifiedSince)) 685 { 686 if ($bSetCacheHeader) 687 { 688 @\header('Cache-Control: public', true); 689 @\header('Pragma: public', true); 690 @\header('Last-Modified: '.\gmdate('D, d M Y H:i:s', $iUtcTimeStamp - $iExpireTime).' UTC', true); 691 @\header('Expires: '.\gmdate('D, j M Y H:i:s', $iUtcTimeStamp + $iExpireTime).' UTC', true); 692 693 if (0 < strlen($sEtag)) 694 { 695 \header('Etag: '.$sEtag, true); 696 } 697 } 698 } 699 else 700 { 701 $this->StatusHeader(304); 702 $bResult = true; 703 } 704 } 705 706 return $bResult; 707 } 708 709 /** 710 * @staticvar boolean $bCache 711 */ 712 public function ServerNoCache() 713 { 714 static $bCache = false; 715 if (false === $bCache) 716 { 717 $bCache = true; 718 @\header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); 719 @\header('Last-Modified: '.\gmdate('D, d M Y H:i:s').' GMT'); 720 @\header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); 721 @\header('Cache-Control: post-check=0, pre-check=0', false); 722 @\header('Pragma: no-cache'); 723 } 724 } 725 726 /** 727 * @staticvar boolean $bCache 728 * @param string $sEtag 729 * @param int $iLastModified 730 * @param int $iExpires 731 */ 732 public function ServerUseCache($sEtag, $iLastModified, $iExpires) 733 { 734 static $bCache = false; 735 if (false === $bCache) 736 { 737 $bCache = true; 738 @\header('Cache-Control: private', true); 739 @\header('ETag: '.$sEtag, true); 740 @\header('Last-Modified: '.\gmdate('D, d M Y H:i:s', $iLastModified).' UTC', true); 741 @\header('Expires: '.\gmdate('D, j M Y H:i:s', $iExpires).' UTC', true); 742 } 743 } 744 745 /** 746 * @param int $iStatus 747 * 748 * @return void 749 */ 750 public function StatusHeader($iStatus, $sCustomStatusText = '') 751 { 752 $iStatus = (int) $iStatus; 753 if (99 < $iStatus) 754 { 755 $aStatus = array( 756 200 => 'OK', 757 206 => 'Partial Content', 758 301 => 'Moved Permanently', 759 304 => 'Not Modified', 760 400 => 'Bad Request', 761 401 => 'Unauthorized', 762 403 => 'Forbidden', 763 404 => 'Not Found', 764 405 => 'Method Not Allowed', 765 416 => 'Requested range not satisfiable' 766 ); 767 768 $sCustomStatusText = \trim($sCustomStatusText); 769 $sHeaderHead = \ini_get('cgi.rfc2616_headers') && false !== \strpos(\strtolower(\php_sapi_name()), 'cgi') ? 'Status:' : $this->ServerProtocol(); 770 $sHeaderText = (0 === \strlen($sCustomStatusText) && isset($aStatus[$iStatus]) ? $aStatus[$iStatus] : $sCustomStatusText); 771 772 \header(\trim($sHeaderHead.' '.$iStatus.' '.$sHeaderText), true, $iStatus); 773 } 774 } 775 776 /** 777 * @return string 778 */ 779 public function GetPath() 780 { 781 $sUrl = \ltrim(\substr($this->GetServer('SCRIPT_NAME', ''), 0, \strrpos($this->GetServer('SCRIPT_NAME', ''), '/')), '/'); 782 return '' === $sUrl ? '/' : '/'.$sUrl.'/'; 783 } 784 785 /** 786 * @return string 787 */ 788 public function GetUrl() 789 { 790 return $this->GetServer('REQUEST_URI', ''); 791 } 792 793 /** 794 * @return string 795 */ 796 public function GetFullUrl() 797 { 798 return $this->GetScheme().'://'.$this->GetHost(true, false).$this->GetPath(); 799 } 800} 801