]> git.mxchange.org Git - friendica.git/blob - src/App/BaseURL.php
Move force_ssl behavior
[friendica.git] / src / App / BaseURL.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\App;
23
24 use Friendica\Core\Config\Capability\IManageConfigValues;
25 use Friendica\Core\System;
26 use Friendica\Util\Strings;
27 use Friendica\Network\HTTPException;
28 use GuzzleHttp\Psr7\ServerRequest;
29 use GuzzleHttp\Psr7\Uri;
30 use Psr\Http\Message\UriInterface;
31 use Psr\Log\LoggerInterface;
32
33 /**
34  * A class which checks and contains the basic
35  * environment for the BaseURL (url, urlpath, ssl_policy, hostname, scheme)
36  */
37 class BaseURL extends Uri implements UriInterface
38 {
39         public function __construct(IManageConfigValues $config, LoggerInterface $logger, array $server = [])
40         {
41                 $url = $config->get('system', 'url');
42                 if (empty($url)) {
43                         $logger->critical('Invalid config - Missing system.url');
44                         $url = ServerRequest::getUriFromGlobals()
45                                                                 ->withQuery('')
46                                                                 ->withPath($this->determineURLPath($server));
47
48                         parent::__construct((string)$url);
49                 } else {
50                         parent::__construct($url);
51                 }
52         }
53
54         /**
55          * Figure out if we are running at the top of a domain or in a subdirectory
56          */
57         private function determineURLPath(array $server): string
58         {
59                 /* Relative script path to the web server root
60                  * Not all of those $_SERVER properties can be present, so we do by inverse priority order
61                  */
62                 $relativeScriptPath =
63                         ($server['REDIRECT_URL'] ?? '') ?:
64                                 ($server['REDIRECT_URI'] ?? '') ?:
65                                         ($server['REDIRECT_SCRIPT_URL'] ?? '') ?:
66                                                 ($server['SCRIPT_URL'] ?? '') ?:
67                                                         $server['REQUEST_URI'] ?? '';
68
69                 /* $relativeScriptPath gives /relative/path/to/friendica/module/parameter
70                  * QUERY_STRING gives pagename=module/parameter
71                  *
72                  * To get /relative/path/to/friendica we perform dirname() for as many levels as there are slashes in the QUERY_STRING
73                  */
74                 if (!empty($relativeScriptPath)) {
75                         // Module
76                         if (!empty($server['QUERY_STRING'])) {
77                                 return trim(dirname($relativeScriptPath, substr_count(trim($server['QUERY_STRING'], '/'), '/') + 1), '/');
78                         } else {
79                                 // Root page
80                                 $scriptPathParts = explode('?', $relativeScriptPath, 2);
81                                 return trim($scriptPathParts[0], '/');
82                         }
83                 }
84
85                 return '';
86         }
87
88         /**
89          * Removes the base url from an url. This avoids some mixed content problems.
90          *
91          * @param string $origURL
92          *
93          * @return string The cleaned url
94          */
95         public function remove(string $origURL): string
96         {
97                 // Remove the hostname from the url if it is an internal link
98                 $nurl = Strings::normaliseLink($origURL);
99                 $base = Strings::normaliseLink($this->__toString());
100                 $url  = str_replace($base . '/', '', $nurl);
101
102                 // if it is an external link return the original value
103                 if ($url === $nurl) {
104                         return $origURL;
105                 } else {
106                         return $url;
107                 }
108         }
109
110         /**
111          * Redirects to another module relative to the current Friendica base URL.
112          * If you want to redirect to a external URL, use System::externalRedirectTo()
113          *
114          * @param string $toUrl The destination URL (Default is empty, which is the default page of the Friendica node)
115          * @param bool   $ssl   if true, base URL will try to get called with https:// (works just for relative paths)
116          *
117          * @throws HTTPException\FoundException
118          * @throws HTTPException\MovedPermanentlyException
119          * @throws HTTPException\TemporaryRedirectException
120          *
121          * @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node
122          */
123         public function redirect(string $toUrl = '', bool $ssl = false)
124         {
125                 if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
126                         throw new HTTPException\InternalServerErrorException("$toUrl is not a relative path, please use System::externalRedirectTo");
127                 }
128
129                 $redirectTo = $this->__toString() . '/' . ltrim($toUrl, '/');
130                 System::externalRedirect($redirectTo);
131         }
132 }