123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <?php
- /**
- * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
- class OC_Request {
-
- const USER_AGENT_IE = '/MSIE/';
- // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent
- const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#';
- const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#';
-
- const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)(:[0-9]+|)$/';
-
- /**
- * @brief Check overwrite condition
- * @param string $type
- * @returns bool
- */
- private static function isOverwriteCondition($type = '') {
- $regex = '/' . OC_Config::getValue('overwritecondaddr', '') . '/';
- return $regex === '//' or preg_match($regex, $_SERVER['REMOTE_ADDR']) === 1
- or ($type !== 'protocol' and OC_Config::getValue('forcessl', false));
- }
-
- /**
- * @brief Checks whether a domain is considered as trusted from the list
- * of trusted domains. If no trusted domains have been configured, returns
- * true.
- * This is used to prevent Host Header Poisoning.
- * @param string $domain
- * @return bool true if the given domain is trusted or if no trusted domains
- * have been configured
- */
- public static function isTrustedDomain($domain) {
- $trustedList = \OC_Config::getValue('trusted_domains', array());
- if (empty($trustedList)) {
- return true;
- }
- if (preg_match(self::REGEX_LOCALHOST, $domain) === 1) {
- return true;
- }
- return in_array($domain, $trustedList);
- }
-
- /**
- * @brief Returns the unverified server host from the headers without checking
- * whether it is a trusted domain
- * @returns string the server host
- *
- * Returns the server host, even if the website uses one or more
- * reverse proxies
- */
- public static function insecureServerHost() {
- $host = null;
- if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
- if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ",") !== false) {
- $parts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
- $host = trim(current($parts));
- } else {
- $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
- }
- } else {
- if (isset($_SERVER['HTTP_HOST'])) {
- $host = $_SERVER['HTTP_HOST'];
- } else if (isset($_SERVER['SERVER_NAME'])) {
- $host = $_SERVER['SERVER_NAME'];
- }
- }
- return $host;
- }
-
- /**
- * Returns the overwritehost setting from the config if set and
- * if the overwrite condition is met
- * @return string|null overwritehost value or null if not defined or the defined condition
- * isn't met
- */
- public static function getOverwriteHost() {
- if(OC_Config::getValue('overwritehost', '') !== '' and self::isOverwriteCondition()) {
- return OC_Config::getValue('overwritehost');
- }
- return null;
- }
-
- /**
- * @brief Returns the server host from the headers, or the first configured
- * trusted domain if the host isn't in the trusted list
- * @returns string the server host
- *
- * Returns the server host, even if the website uses one or more
- * reverse proxies
- */
- public static function serverHost() {
- if(OC::$CLI) {
- return 'localhost';
- }
-
- // overwritehost is always trusted
- $host = self::getOverwriteHost();
- if ($host !== null) {
- return $host;
- }
-
- // get the host from the headers
- $host = self::insecureServerHost();
-
- // Verify that the host is a trusted domain if the trusted domains
- // are defined
- // If no trusted domain is provided the first trusted domain is returned
- if (self::isTrustedDomain($host)) {
- return $host;
- } else {
- $trustedList = \OC_Config::getValue('trusted_domains', array(''));
- return $trustedList[0];
- }
- }
-
- /**
- * @brief Returns the server protocol
- * @returns string the server protocol
- *
- * Returns the server protocol. It respects reverse proxy servers and load balancers
- */
- public static function serverProtocol() {
- if(OC_Config::getValue('overwriteprotocol', '') !== '' and self::isOverwriteCondition('protocol')) {
- return OC_Config::getValue('overwriteprotocol');
- }
- if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
- $proto = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']);
- // Verify that the protocol is always HTTP or HTTPS
- // default to http if an invalid value is provided
- return $proto === 'https' ? 'https' : 'http';
- }
- if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
- return 'https';
- }
- return 'http';
- }
-
- /**
- * @brief Returns the request uri
- * @returns string the request uri
- *
- * Returns the request uri, even if the website uses one or more
- * reverse proxies
- * @return string
- */
- public static function requestUri() {
- $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
- if (OC_Config::getValue('overwritewebroot', '') !== '' and self::isOverwriteCondition()) {
- $uri = self::scriptName() . substr($uri, strlen($_SERVER['SCRIPT_NAME']));
- }
- return $uri;
- }
-
- /**
- * @brief Returns the script name
- * @return string the script name
- *
- * Returns the script name, even if the website uses one or more
- * reverse proxies
- */
- public static function scriptName() {
- $name = $_SERVER['SCRIPT_NAME'];
- $overwriteWebRoot = OC_Config::getValue('overwritewebroot', '');
- if ($overwriteWebRoot !== '' and self::isOverwriteCondition()) {
- $serverroot = str_replace("\\", '/', substr(__DIR__, 0, -strlen('lib/private/')));
- $suburi = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen($serverroot)));
- $name = '/' . ltrim($overwriteWebRoot . $suburi, '/');
- }
- return $name;
- }
-
- /**
- * @brief get Path info from request
- * @return string Path info or false when not found
- */
- public static function getPathInfo() {
- if (array_key_exists('PATH_INFO', $_SERVER)) {
- $path_info = $_SERVER['PATH_INFO'];
- }else{
- $path_info = self::getRawPathInfo();
- // following is taken from Sabre_DAV_URLUtil::decodePathSegment
- $path_info = rawurldecode($path_info);
- $encoding = mb_detect_encoding($path_info, array('UTF-8', 'ISO-8859-1'));
-
- switch($encoding) {
-
- case 'ISO-8859-1' :
- $path_info = utf8_encode($path_info);
-
- }
- // end copy
- }
- return $path_info;
- }
-
- /**
- * @brief get Path info from request, not urldecoded
- * @throws Exception
- * @return string Path info or false when not found
- */
- public static function getRawPathInfo() {
- $requestUri = $_SERVER['REQUEST_URI'];
- // remove too many leading slashes - can be caused by reverse proxy configuration
- if (strpos($requestUri, '/') === 0) {
- $requestUri = '/' . ltrim($requestUri, '/');
- }
-
- // Remove the query string from REQUEST_URI
- if ($pos = strpos($requestUri, '?')) {
- $requestUri = substr($requestUri, 0, $pos);
- }
-
- $scriptName = $_SERVER['SCRIPT_NAME'];
- $path_info = $requestUri;
-
- // strip off the script name's dir and file name
- list($path, $name) = \Sabre_DAV_URLUtil::splitPath($scriptName);
- if (!empty($path)) {
- if( $path === $path_info || strpos($path_info, $path.'/') === 0) {
- $path_info = substr($path_info, strlen($path));
- } else {
- throw new Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')");
- }
- }
- if (strpos($path_info, '/'.$name) === 0) {
- $path_info = substr($path_info, strlen($name) + 1);
- }
- if (strpos($path_info, $name) === 0) {
- $path_info = substr($path_info, strlen($name));
- }
- if($path_info === '/'){
- return '';
- } else {
- return $path_info;
- }
- }
-
- /**
- * @brief Check if the requester sent along an mtime
- * @return false or an mtime
- */
- static public function hasModificationTime () {
- if (isset($_SERVER['HTTP_X_OC_MTIME'])) {
- return $_SERVER['HTTP_X_OC_MTIME'];
- } else {
- return false;
- }
- }
-
- /**
- * Checks whether the user agent matches a given regex
- * @param string|array $agent agent name or array of agent names
- * @return boolean true if at least one of the given agent matches,
- * false otherwise
- */
- static public function isUserAgent($agent) {
- if (!is_array($agent)) {
- $agent = array($agent);
- }
- foreach ($agent as $regex) {
- if (preg_match($regex, $_SERVER['HTTP_USER_AGENT'])) {
- return true;
- }
- }
- return false;
- }
- }
|