1<?php 2/** 3 * Matomo - free/libre analytics platform 4 * 5 * @link https://matomo.org 6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later 7 * 8 */ 9namespace Piwik; 10 11use Exception; 12use Matomo\Network\IPUtils; 13 14/** 15 * Provides URL related helper methods. 16 * 17 * This class provides simple methods that can be used to parse and modify 18 * the current URL. It is most useful when plugins need to redirect the current 19 * request to a URL and when they need to link to other parts of Piwik in 20 * HTML. 21 * 22 * ### Examples 23 * 24 * **Redirect to a different controller action** 25 * 26 * public function myControllerAction() 27 * { 28 * $url = Url::getCurrentQueryStringWithParametersModified(array( 29 * 'module' => 'DevicesDetection', 30 * 'action' => 'index' 31 * )); 32 * Url::redirectToUrl($url); 33 * } 34 * 35 * **Link to a different controller action in a template** 36 * 37 * public function myControllerAction() 38 * { 39 * $url = Url::getCurrentQueryStringWithParametersModified(array( 40 * 'module' => 'UserCountryMap', 41 * 'action' => 'realtimeMap', 42 * 'changeVisitAlpha' => 0, 43 * 'removeOldVisits' => 0 44 * )); 45 * $view = new View("@MyPlugin/myPopup"); 46 * $view->realtimeMapUrl = $url; 47 * return $view->render(); 48 * } 49 * 50 */ 51class Url 52{ 53 /** 54 * Returns the current URL. 55 * 56 * @return string eg, `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"` 57 * @api 58 */ 59 public static function getCurrentUrl() 60 { 61 return self::getCurrentScheme() . '://' 62 . self::getCurrentHost() 63 . self::getCurrentScriptName(false) 64 . self::getCurrentQueryString(); 65 } 66 67 /** 68 * Returns the current URL without the query string. 69 * 70 * @param bool $checkTrustedHost Whether to do trusted host check. Should ALWAYS be true, 71 * except in {@link Piwik\Plugin\Controller}. 72 * @return string eg, `"http://example.org/dir1/dir2/index.php"` if the current URL is 73 * `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"`. 74 * @api 75 */ 76 public static function getCurrentUrlWithoutQueryString($checkTrustedHost = true) 77 { 78 return self::getCurrentScheme() . '://' 79 . self::getCurrentHost($default = 'unknown', $checkTrustedHost) 80 . self::getCurrentScriptName(false); 81 } 82 83 /** 84 * Returns the current URL without the query string and without the name of the file 85 * being executed. 86 * 87 * @return string eg, `"http://example.org/dir1/dir2/"` if the current URL is 88 * `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"`. 89 * @api 90 */ 91 public static function getCurrentUrlWithoutFileName() 92 { 93 return self::getCurrentScheme() . '://' 94 . self::getCurrentHost() 95 . self::getCurrentScriptPath(); 96 } 97 98 /** 99 * Returns the path to the script being executed. The script file name is not included. 100 * 101 * @return string eg, `"/dir1/dir2/"` if the current URL is 102 * `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"` 103 * @api 104 */ 105 public static function getCurrentScriptPath() 106 { 107 $queryString = self::getCurrentScriptName(); 108 109 //add a fake letter case /test/test2/ returns /test which is not expected 110 $urlDir = dirname($queryString . 'x'); 111 $urlDir = str_replace('\\', '/', $urlDir); 112 // if we are in a subpath we add a trailing slash 113 if (strlen($urlDir) > 1) { 114 $urlDir .= '/'; 115 } 116 return $urlDir; 117 } 118 119 /** 120 * Returns the path to the script being executed. Includes the script file name. 121 * 122 * @param bool $removePathInfo If true (default value) then the PATH_INFO will be stripped. 123 * @return string eg, `"/dir1/dir2/index.php"` if the current URL is 124 * `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"` 125 * @api 126 */ 127 public static function getCurrentScriptName($removePathInfo = true) 128 { 129 $url = ''; 130 131 // insert extra path info if proxy_uri_header is set and enabled 132 if (isset(Config::getInstance()->General['proxy_uri_header']) 133 && Config::getInstance()->General['proxy_uri_header'] == 1 134 && !empty($_SERVER['HTTP_X_FORWARDED_URI']) 135 ) { 136 $url .= $_SERVER['HTTP_X_FORWARDED_URI']; 137 } 138 139 if (!empty($_SERVER['REQUEST_URI'])) { 140 $url .= $_SERVER['REQUEST_URI']; 141 142 // strip http://host (Apache+Rails anomaly) 143 if (preg_match('~^https?://[^/]+($|/.*)~D', $url, $matches)) { 144 $url = $matches[1]; 145 } 146 147 // strip parameters 148 if (($pos = mb_strpos($url, "?")) !== false) { 149 $url = mb_substr($url, 0, $pos); 150 } 151 152 // strip path_info 153 if ($removePathInfo && !empty($_SERVER['PATH_INFO'])) { 154 $url = mb_substr($url, 0, -mb_strlen($_SERVER['PATH_INFO'])); 155 } 156 } 157 158 /** 159 * SCRIPT_NAME is our fallback, though it may not be set correctly 160 * 161 * @see http://php.net/manual/en/reserved.variables.php 162 */ 163 if (empty($url)) { 164 if (isset($_SERVER['SCRIPT_NAME'])) { 165 $url = $_SERVER['SCRIPT_NAME']; 166 } elseif (isset($_SERVER['SCRIPT_FILENAME'])) { 167 $url = $_SERVER['SCRIPT_FILENAME']; 168 } elseif (isset($_SERVER['argv'])) { 169 $url = $_SERVER['argv'][0]; 170 } 171 } 172 173 if (!isset($url[0]) || $url[0] !== '/') { 174 $url = '/' . $url; 175 } 176 177 // A hash part should actually be never send to the server, as browsers automatically remove them from the request 178 // The same happens for tools like cUrl. While Apache won't answer requests that contain them, Nginx would handle them 179 // and the hash part would be included in REQUEST_URI. Therefor we always remove any hash parts here. 180 if (mb_strpos($url, '#')) { 181 $url = mb_substr($url, 0, mb_strpos($url, '#')); 182 } 183 184 return $url; 185 } 186 187 /** 188 * Returns the current URL's protocol. 189 * 190 * @return string `'https'` or `'http'` 191 * @api 192 */ 193 public static function getCurrentScheme() 194 { 195 if (self::isPiwikConfiguredToAssumeSecureConnection()) { 196 return 'https'; 197 } 198 return self::getCurrentSchemeFromRequestHeader(); 199 } 200 201 /** 202 * Validates the **Host** HTTP header (untrusted user input). Used to prevent Host header 203 * attacks. 204 * 205 * @param string|bool $host Contents of Host: header from the HTTP request. If `false`, gets the 206 * value from the request. 207 * @return bool `true` if valid; `false` otherwise. 208 */ 209 public static function isValidHost($host = false) 210 { 211 // only do trusted host check if it's enabled 212 if (isset(Config::getInstance()->General['enable_trusted_host_check']) 213 && Config::getInstance()->General['enable_trusted_host_check'] == 0 214 ) { 215 return true; 216 } 217 218 if ($host === false) { 219 $host = self::getHostFromServerVariable(); 220 if (empty($host)) { 221 // if no current host, assume valid 222 return true; 223 } 224 } 225 226 // if host is in hardcoded allowlist, assume it's valid 227 if (in_array($host, self::getAlwaysTrustedHosts())) { 228 return true; 229 } 230 231 $trustedHosts = self::getTrustedHosts(); 232 233 // Only punctuation we allow is '[', ']', ':', '.', '_' and '-' 234 $hostLength = strlen($host); 235 if ($hostLength !== strcspn($host, '`~!@#$%^&*()+={}\\|;"\'<>,?/ ')) { 236 return false; 237 } 238 239 // if no trusted hosts, just assume it's valid 240 if (empty($trustedHosts)) { 241 self::saveTrustedHostnameInConfig($host); 242 return true; 243 } 244 245 // Escape trusted hosts for preg_match call below 246 foreach ($trustedHosts as &$trustedHost) { 247 $trustedHost = preg_quote($trustedHost); 248 } 249 $trustedHosts = str_replace("/", "\\/", $trustedHosts); 250 251 $untrustedHost = mb_strtolower($host); 252 $untrustedHost = rtrim($untrustedHost, '.'); 253 254 $hostRegex = mb_strtolower('/(^|.)' . implode('$|', $trustedHosts) . '$/'); 255 256 $result = preg_match($hostRegex, $untrustedHost); 257 return 0 !== $result; 258 } 259 260 /** 261 * Records one host, or an array of hosts in the config file, 262 * if user is Super User 263 * 264 * @static 265 * @param $host string|array 266 * @return bool 267 */ 268 public static function saveTrustedHostnameInConfig($host) 269 { 270 return self::saveHostsnameInConfig($host, 'General', 'trusted_hosts'); 271 } 272 273 public static function saveCORSHostnameInConfig($host) 274 { 275 return self::saveHostsnameInConfig($host, 'General', 'cors_domains'); 276 } 277 278 protected static function saveHostsnameInConfig($host, $domain, $key) 279 { 280 if (Piwik::hasUserSuperUserAccess() 281 && file_exists(Config::getLocalConfigPath()) 282 ) { 283 $config = Config::getInstance()->$domain; 284 if (!is_array($host)) { 285 $host = array($host); 286 } 287 $host = array_filter($host); 288 if (empty($host)) { 289 return false; 290 } 291 $config[$key] = $host; 292 Config::getInstance()->$domain = $config; 293 Config::getInstance()->forceSave(); 294 return true; 295 } 296 return false; 297 } 298 299 /** 300 * Returns the current host. 301 * 302 * @param bool $checkIfTrusted Whether to do trusted host check. Should ALWAYS be true, 303 * except in Controller. 304 * @return string|bool eg, `"demo.piwik.org"` or false if no host found. 305 */ 306 public static function getHost($checkIfTrusted = true) 307 { 308 $host = self::getHostFromServerVariable(); 309 310 if (strlen($host) && (!$checkIfTrusted || self::isValidHost($host))) { 311 return $host; 312 } 313 314 // HTTP/1.0 request doesn't include Host: header 315 if (isset($_SERVER['SERVER_ADDR'])) { 316 return $_SERVER['SERVER_ADDR']; 317 } 318 319 return false; 320 } 321 322 protected static function getHostFromServerVariable() 323 { 324 try { 325 // this fails when trying to get the hostname before the config was initialized 326 // e.g. for loading the domain specific configuration file 327 // in such a case we always use HTTP_HOST 328 $preferServerName = Config::getInstance()->General['host_validation_use_server_name']; 329 } catch (\Exception $e) { 330 $preferServerName = false; 331 } 332 333 if ($preferServerName && strlen($host = self::getHostFromServerNameVar())) { 334 return $host; 335 } elseif (isset($_SERVER['HTTP_HOST']) && strlen($host = $_SERVER['HTTP_HOST'])) { 336 return $host; 337 } 338 339 return false; 340 } 341 342 /** 343 * Sets the host. Useful for CLI scripts, eg. core:archive command 344 * 345 * @param $host string 346 */ 347 public static function setHost($host) 348 { 349 $_SERVER['SERVER_NAME'] = $host; 350 $_SERVER['HTTP_HOST'] = $host; 351 unset($_SERVER['SERVER_PORT']); 352 } 353 354 /** 355 * Returns the current host. 356 * 357 * @param string $default Default value to return if host unknown 358 * @param bool $checkTrustedHost Whether to do trusted host check. Should ALWAYS be true, 359 * except in Controller. 360 * @return string eg, `"example.org"` if the current URL is 361 * `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"` 362 * @api 363 */ 364 public static function getCurrentHost($default = 'unknown', $checkTrustedHost = true) 365 { 366 $hostHeaders = array(); 367 368 $config = Config::getInstance()->General; 369 if (isset($config['proxy_host_headers'])) { 370 $hostHeaders = $config['proxy_host_headers']; 371 } 372 373 if (!is_array($hostHeaders)) { 374 $hostHeaders = array(); 375 } 376 377 $host = self::getHost($checkTrustedHost); 378 $default = Common::sanitizeInputValue($host ? $host : $default); 379 380 return IP::getNonProxyIpFromHeader($default, $hostHeaders); 381 } 382 383 /** 384 * Returns the query string of the current URL. 385 * 386 * @return string eg, `"?param1=value1¶m2=value2"` if the current URL is 387 * `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"` 388 * @api 389 */ 390 public static function getCurrentQueryString() 391 { 392 $url = ''; 393 if (isset($_SERVER['QUERY_STRING']) 394 && !empty($_SERVER['QUERY_STRING']) 395 ) { 396 $url .= "?" . $_SERVER['QUERY_STRING']; 397 } 398 return $url; 399 } 400 401 /** 402 * Returns an array mapping query parameter names with query parameter values for 403 * the current URL. 404 * 405 * @return array If current URL is `"http://example.org/dir1/dir2/index.php?param1=value1¶m2=value2"` 406 * this will return: 407 * 408 * array( 409 * 'param1' => string 'value1', 410 * 'param2' => string 'value2' 411 * ) 412 * @api 413 */ 414 public static function getArrayFromCurrentQueryString() 415 { 416 $queryString = self::getCurrentQueryString(); 417 $urlValues = UrlHelper::getArrayFromQueryString($queryString); 418 return $urlValues; 419 } 420 421 /** 422 * Modifies the current query string with the supplied parameters and returns 423 * the result. Parameters in the current URL will be overwritten with values 424 * in `$params` and parameters absent from the current URL but present in `$params` 425 * will be added to the result. 426 * 427 * @param array $params set of parameters to modify/add in the current URL 428 * eg, `array('param3' => 'value3')` 429 * @return string eg, `"?param2=value2¶m3=value3"` 430 * @api 431 */ 432 public static function getCurrentQueryStringWithParametersModified($params) 433 { 434 $urlValues = self::getArrayFromCurrentQueryString(); 435 foreach ($params as $key => $value) { 436 $urlValues[$key] = $value; 437 } 438 $query = self::getQueryStringFromParameters($urlValues); 439 if (strlen($query) > 0) { 440 return '?' . $query; 441 } 442 return ''; 443 } 444 445 /** 446 * Converts an array of parameters name => value mappings to a query 447 * string. Values must already be URL encoded before you call this function. 448 * 449 * @param array $parameters eg. `array('param1' => 10, 'param2' => array(1,2))` 450 * @return string eg. `"param1=10¶m2[]=1¶m2[]=2"` 451 * @api 452 */ 453 public static function getQueryStringFromParameters($parameters) 454 { 455 $query = ''; 456 foreach ($parameters as $name => $value) { 457 if (is_null($value) || $value === false) { 458 continue; 459 } 460 if (is_array($value)) { 461 foreach ($value as $theValue) { 462 $query .= $name . "[]=" . $theValue . "&"; 463 } 464 } else { 465 $query .= $name . "=" . $value . "&"; 466 } 467 } 468 $query = substr($query, 0, -1); 469 return $query; 470 } 471 472 public static function getQueryStringFromUrl($url) 473 { 474 return parse_url($url, PHP_URL_QUERY); 475 } 476 477 /** 478 * Redirects the user to the referrer. If no referrer exists, the user is redirected 479 * to the current URL without query string. 480 * 481 * @api 482 */ 483 public static function redirectToReferrer() 484 { 485 $referrer = self::getReferrer(); 486 if ($referrer !== false) { 487 self::redirectToUrl($referrer); 488 } 489 self::redirectToUrl(self::getCurrentUrlWithoutQueryString()); 490 } 491 492 private static function redirectToUrlNoExit($url) 493 { 494 if (UrlHelper::isLookLikeUrl($url) 495 || strpos($url, 'index.php') === 0 496 ) { 497 Common::sendResponseCode(302); 498 Common::sendHeader("X-Robots-Tag: noindex"); 499 Common::sendHeader("Location: $url"); 500 } else { 501 echo "Invalid URL to redirect to."; 502 } 503 504 if (Common::isPhpCliMode()) { 505 throw new Exception("If you were using a browser, Matomo would redirect you to this URL: $url \n\n"); 506 } 507 } 508 509 /** 510 * Redirects the user to the specified URL. 511 * 512 * @param string $url 513 * @throws Exception 514 * @api 515 */ 516 public static function redirectToUrl($url) 517 { 518 // Close the session manually. 519 // We should not have to call this because it was registered via register_shutdown_function, 520 // but it is not always called fast enough 521 Session::close(); 522 523 self::redirectToUrlNoExit($url); 524 525 exit; 526 } 527 528 /** 529 * If the page is using HTTP, redirect to the same page over HTTPS 530 */ 531 public static function redirectToHttps() 532 { 533 if (ProxyHttp::isHttps()) { 534 return; 535 } 536 $url = self::getCurrentUrl(); 537 $url = str_replace("http://", "https://", $url); 538 self::redirectToUrl($url); 539 } 540 541 /** 542 * Returns the **HTTP_REFERER** `$_SERVER` variable, or `false` if not found. 543 * 544 * @return string|false 545 * @api 546 */ 547 public static function getReferrer() 548 { 549 if (!empty($_SERVER['HTTP_REFERER'])) { 550 return $_SERVER['HTTP_REFERER']; 551 } 552 return false; 553 } 554 555 /** 556 * Returns `true` if the URL points to something on the same host, `false` if otherwise. 557 * 558 * @param string $url 559 * @return bool True if local; false otherwise. 560 * @api 561 */ 562 public static function isLocalUrl($url) 563 { 564 if (empty($url)) { 565 return true; 566 } 567 568 // handle host name mangling 569 $requestUri = isset($_SERVER['SCRIPT_URI']) ? $_SERVER['SCRIPT_URI'] : ''; 570 $parseRequest = @parse_url($requestUri); 571 $hosts = array(self::getHost(), self::getCurrentHost()); 572 if (!empty($parseRequest['host'])) { 573 $hosts[] = $parseRequest['host']; 574 } 575 576 // drop port numbers from hostnames and IP addresses 577 $hosts = array_map(array('self', 'getHostSanitized'), $hosts); 578 579 $disableHostCheck = Config::getInstance()->General['enable_trusted_host_check'] == 0; 580 // compare scheme and host 581 $parsedUrl = @parse_url($url); 582 $host = IPUtils::sanitizeIp(@$parsedUrl['host']); 583 return !empty($host) 584 && ($disableHostCheck || in_array($host, $hosts)) 585 && !empty($parsedUrl['scheme']) 586 && in_array($parsedUrl['scheme'], array('http', 'https')); 587 } 588 589 /** 590 * Checks whether the given host is a local host like `127.0.0.1` or `localhost`. 591 * 592 * @param string $host 593 * @return bool 594 */ 595 public static function isLocalHost($host) 596 { 597 if (empty($host)) { 598 return false; 599 } 600 601 // remove port 602 $hostWithoutPort = explode(':', $host); 603 array_pop($hostWithoutPort); 604 $hostWithoutPort = implode(':', $hostWithoutPort); 605 606 $localHostnames = Url::getLocalHostnames(); 607 return in_array($host, $localHostnames, true) 608 || in_array($hostWithoutPort, $localHostnames, true); 609 } 610 611 public static function getTrustedHostsFromConfig() 612 { 613 $hosts = self::getHostsFromConfig('General', 'trusted_hosts'); 614 615 // Case user wrote in the config, http://example.com/test instead of example.com 616 foreach ($hosts as &$host) { 617 if (UrlHelper::isLookLikeUrl($host)) { 618 $host = parse_url($host, PHP_URL_HOST); 619 } 620 } 621 return $hosts; 622 } 623 624 public static function getTrustedHosts() 625 { 626 return self::getTrustedHostsFromConfig(); 627 } 628 629 public static function getCorsHostsFromConfig() 630 { 631 return self::getHostsFromConfig('General', 'cors_domains'); 632 } 633 634 /** 635 * Returns hostname, without port numbers 636 * 637 * @param $host 638 * @return array 639 */ 640 public static function getHostSanitized($host) 641 { 642 if (!class_exists("Matomo\\Network\\IPUtils")) { 643 throw new Exception("Matomo\\Network\\IPUtils could not be found, maybe you are using Matomo from git and need to update Composer. $ php composer.phar update"); 644 } 645 return IPUtils::sanitizeIp($host); 646 } 647 648 protected static function getHostsFromConfig($domain, $key) 649 { 650 $config = @Config::getInstance()->$domain; 651 652 if (!isset($config[$key])) { 653 return array(); 654 } 655 656 $hosts = $config[$key]; 657 if (!is_array($hosts)) { 658 return array(); 659 } 660 return $hosts; 661 } 662 663 /** 664 * Returns the host part of any valid URL. 665 * 666 * @param string $url Any fully qualified URL 667 * @return string|null The actual host in lower case or null if $url is not a valid fully qualified URL. 668 */ 669 public static function getHostFromUrl($url) 670 { 671 if (!is_string($url)) { 672 return null; 673 } 674 675 $urlHost = parse_url($url, PHP_URL_HOST); 676 677 if (empty($urlHost)) { 678 return null; 679 } 680 681 return mb_strtolower($urlHost); 682 } 683 684 /** 685 * Checks whether any of the given URLs has the given host. If not, we will also check whether any URL uses a 686 * subdomain of the given host. For instance if host is "example.com" and a URL is "http://www.example.com" we 687 * consider this as valid and return true. The always trusted hosts such as "127.0.0.1" are considered valid as well. 688 * 689 * @param $host 690 * @param $urls 691 * @return bool 692 */ 693 public static function isHostInUrls($host, $urls) 694 { 695 if (empty($host)) { 696 return false; 697 } 698 699 $host = mb_strtolower($host); 700 701 if (!empty($urls)) { 702 foreach ($urls as $url) { 703 if (mb_strtolower($url) === $host) { 704 return true; 705 } 706 707 $siteHost = self::getHostFromUrl($url); 708 709 if ($siteHost === $host) { 710 return true; 711 } 712 713 if (Common::stringEndsWith($siteHost, '.' . $host)) { 714 // allow subdomains 715 return true; 716 } 717 } 718 } 719 720 return in_array($host, self::getAlwaysTrustedHosts()); 721 } 722 723 /** 724 * List of hosts that are never checked for validity. 725 * 726 * @return array 727 */ 728 private static function getAlwaysTrustedHosts() 729 { 730 return self::getLocalHostnames(); 731 } 732 733 /** 734 * @return array 735 */ 736 public static function getLocalHostnames() 737 { 738 return array('localhost', '127.0.0.1', '::1', '[::1]', '[::]', '0000::1', '0177.0.0.1', '2130706433', '[0:0:0:0:0:ffff:127.0.0.1]'); 739 } 740 741 /** 742 * @return bool 743 */ 744 public static function isSecureConnectionAssumedByPiwikButNotForcedYet() 745 { 746 $isSecureConnectionLikelyNotUsed = Url::isSecureConnectionLikelyNotUsed(); 747 $hasSessionCookieSecureFlag = ProxyHttp::isHttps(); 748 $isSecureConnectionAssumedByPiwikButNotForcedYet = Url::isPiwikConfiguredToAssumeSecureConnection() && !SettingsPiwik::isHttpsForced(); 749 750 return $isSecureConnectionLikelyNotUsed 751 && $hasSessionCookieSecureFlag 752 && $isSecureConnectionAssumedByPiwikButNotForcedYet; 753 } 754 755 /** 756 * @return string 757 */ 758 protected static function getCurrentSchemeFromRequestHeader() 759 { 760 if (isset($_SERVER['HTTP_X_FORWARDED_SCHEME']) && strtolower($_SERVER['HTTP_X_FORWARDED_SCHEME']) === 'https') { 761 return 'https'; 762 } 763 764 if (isset($_SERVER['HTTP_X_URL_SCHEME']) && strtolower($_SERVER['HTTP_X_URL_SCHEME']) === 'https') { 765 return 'https'; 766 } 767 768 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'http') { 769 return 'http'; 770 } 771 772 if ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === true)) 773 || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') 774 ) { 775 776 return 'https'; 777 } 778 return 'http'; 779 } 780 781 protected static function isSecureConnectionLikelyNotUsed() 782 { 783 return Url::getCurrentSchemeFromRequestHeader() == 'http'; 784 } 785 786 /** 787 * @return bool 788 */ 789 protected static function isPiwikConfiguredToAssumeSecureConnection() 790 { 791 $assume_secure_protocol = @Config::getInstance()->General['assume_secure_protocol']; 792 return (bool) $assume_secure_protocol; 793 } 794 795 public static function getHostFromServerNameVar() 796 { 797 $host = @$_SERVER['SERVER_NAME']; 798 if (!empty($host)) { 799 if (strpos($host, ':') === false 800 && !empty($_SERVER['SERVER_PORT']) 801 && $_SERVER['SERVER_PORT'] != 80 802 && $_SERVER['SERVER_PORT'] != 443 803 ) { 804 $host .= ':' . $_SERVER['SERVER_PORT']; 805 } 806 } 807 return $host; 808 } 809} 810