aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2020-09-03 14:51:41 +0200
committerArthurHoaro <arthur@hoa.ro>2020-09-12 21:39:01 +0200
commit650a5f09cbeb1c1bef19810c6cc504c06d5b7e87 (patch)
tree6be70f1658128246e57d39c73e1bc3b13e992de1
parente809908f9e593b2cec11f72849caa1dae6394451 (diff)
downloadShaarli-650a5f09cbeb1c1bef19810c6cc504c06d5b7e87.tar.gz
Shaarli-650a5f09cbeb1c1bef19810c6cc504c06d5b7e87.tar.zst
Shaarli-650a5f09cbeb1c1bef19810c6cc504c06d5b7e87.zip
Add manual configuration for root URL
This new setting under 'general.root_url' allows to override automatic discovery of Shaarli instance's URL. Fixes #1339
-rw-r--r--application/feed/FeedBuilder.php6
-rw-r--r--application/http/HttpUtils.php8
-rw-r--r--doc/md/Shaarli-configuration.md71
-rw-r--r--index.php3
-rw-r--r--tests/http/HttpUtils/IndexUrlTest.php36
-rw-r--r--tests/http/HttpUtils/IndexUrlTestWithConstant.php51
6 files changed, 134 insertions, 41 deletions
diff --git a/application/feed/FeedBuilder.php b/application/feed/FeedBuilder.php
index 3653c32f..f6def630 100644
--- a/application/feed/FeedBuilder.php
+++ b/application/feed/FeedBuilder.php
@@ -122,9 +122,9 @@ class FeedBuilder
122 $data['language'] = $this->getTypeLanguage($feedType); 122 $data['language'] = $this->getTypeLanguage($feedType);
123 $data['last_update'] = $this->getLatestDateFormatted($feedType); 123 $data['last_update'] = $this->getLatestDateFormatted($feedType);
124 $data['show_dates'] = !$this->hideDates || $this->isLoggedIn; 124 $data['show_dates'] = !$this->hideDates || $this->isLoggedIn;
125 // Remove leading slash from REQUEST_URI. 125 // Remove leading path from REQUEST_URI (already contained in $pageaddr).
126 $data['self_link'] = escape(server_url($this->serverInfo)) 126 $requestUri = preg_replace('#(.*?/)(feed.*)#', '$2', escape($this->serverInfo['REQUEST_URI']));
127 . escape($this->serverInfo['REQUEST_URI']); 127 $data['self_link'] = $pageaddr . $requestUri;
128 $data['index_url'] = $pageaddr; 128 $data['index_url'] = $pageaddr;
129 $data['usepermalinks'] = $this->usePermalinks === true; 129 $data['usepermalinks'] = $this->usePermalinks === true;
130 $data['links'] = $linkDisplayed; 130 $data['links'] = $linkDisplayed;
diff --git a/application/http/HttpUtils.php b/application/http/HttpUtils.php
index 4fc4e3dc..9f414073 100644
--- a/application/http/HttpUtils.php
+++ b/application/http/HttpUtils.php
@@ -369,7 +369,11 @@ function server_url($server)
369 */ 369 */
370function index_url($server) 370function index_url($server)
371{ 371{
372 $scriptname = $server['SCRIPT_NAME'] ?? ''; 372 if (defined('SHAARLI_ROOT_URL') && null !== SHAARLI_ROOT_URL) {
373 return rtrim(SHAARLI_ROOT_URL, '/') . '/';
374 }
375
376 $scriptname = !empty($server['SCRIPT_NAME']) ? $server['SCRIPT_NAME'] : '/';
373 if (endsWith($scriptname, 'index.php')) { 377 if (endsWith($scriptname, 'index.php')) {
374 $scriptname = substr($scriptname, 0, -9); 378 $scriptname = substr($scriptname, 0, -9);
375 } 379 }
@@ -392,7 +396,7 @@ function page_url($server)
392 $scriptname = substr($scriptname, 0, -9); 396 $scriptname = substr($scriptname, 0, -9);
393 } 397 }
394 398
395 $route = ltrim($server['REQUEST_URI'] ?? '', $scriptname); 399 $route = preg_replace('@^' . $scriptname . '@', '', $server['REQUEST_URI'] ?? '');
396 if (! empty($server['QUERY_STRING'])) { 400 if (! empty($server['QUERY_STRING'])) {
397 return index_url($server) . $route . '?' . $server['QUERY_STRING']; 401 return index_url($server) . $route . '?' . $server['QUERY_STRING'];
398 } 402 }
diff --git a/doc/md/Shaarli-configuration.md b/doc/md/Shaarli-configuration.md
index 14eec7b2..263fb761 100644
--- a/doc/md/Shaarli-configuration.md
+++ b/doc/md/Shaarli-configuration.md
@@ -7,7 +7,7 @@ Once your Shaarli instance is installed, the file `data/config.json.php` is gene
7- its values override those defined in `index.php` 7- its values override those defined in `index.php`
8- it is wrapped in a PHP comment so that its contents are never served by the web server, regardless of configuration 8- it is wrapped in a PHP comment so that its contents are never served by the web server, regardless of configuration
9 9
10**Do not edit configuration options in index.php! Your changes would be lost.** 10**Do not edit configuration options in index.php! Your changes would be lost.**
11 11
12## Tools menu 12## Tools menu
13 13
@@ -135,71 +135,72 @@ Some settings can be configured directly from a web browser by accesing the `Too
135## Settings 135## Settings
136 136
137### Credentials 137### Credentials
138 138
139_These settings should not be edited_ 139_These settings should not be edited_
140 140
141- **login**: Login username. 141- **login**: Login username.
142- **hash**: Generated password hash. 142- **hash**: Generated password hash.
143- **salt**: Password salt. 143- **salt**: Password salt.
144 144
145### General 145### General
146 146
147- **title**: Shaarli's instance title. 147- **title**: Shaarli's instance title.
148- **header_link**: Link to the homepage. 148- **header_link**: Link to the homepage.
149- **links_per_page**: Number of Shaares displayed per page. 149- **links_per_page**: Number of Shaares displayed per page.
150- **timezone**: See [the list of supported timezones](http://php.net/manual/en/timezones.php). 150- **timezone**: See [the list of supported timezones](http://php.net/manual/en/timezones.php).
151- **enabled_plugins**: List of enabled plugins. 151- **enabled_plugins**: List of enabled plugins.
152- **default_note_title**: Default title of a new note. 152- **default_note_title**: Default title of a new note.
153- **retrieve_description** (boolean): If set to true, for every new Shaare Shaarli will try to retrieve the description and keywords from the HTML meta tags. 153- **retrieve_description** (boolean): If set to true, for every new Shaare Shaarli will try to retrieve the description and keywords from the HTML meta tags.
154- **root_url**: Overrides automatic discovery of Shaarli instance's URL (e.g.) `https://sub.domain.tld/shaarli-folder/`.
154 155
155### Security 156### Security
156 157
157- **session_protection_disabled**: Disable session cookie hijacking protection (not recommended). 158- **session_protection_disabled**: Disable session cookie hijacking protection (not recommended).
158 It might be useful if your IP adress often changes. 159 It might be useful if your IP adress often changes.
159- **ban_after**: Failed login attempts before being IP banned. 160- **ban_after**: Failed login attempts before being IP banned.
160- **ban_duration**: IP ban duration in seconds. 161- **ban_duration**: IP ban duration in seconds.
161- **open_shaarli**: Anyone can add a new Shaare while logged out if enabled. 162- **open_shaarli**: Anyone can add a new Shaare while logged out if enabled.
162- **trusted_proxies**: List of trusted IP which won't be banned after failed login attemps. Useful if Shaarli is behind a reverse proxy. 163- **trusted_proxies**: List of trusted IP which won't be banned after failed login attemps. Useful if Shaarli is behind a reverse proxy.
163- **allowed_protocols**: List of allowed protocols in shaare URLs or markdown-rendered descriptions. Useful if you want to store `javascript:` links (bookmarklets) in Shaarli (default: `["ftp", "ftps", "magnet"]`). 164- **allowed_protocols**: List of allowed protocols in shaare URLs or markdown-rendered descriptions. Useful if you want to store `javascript:` links (bookmarklets) in Shaarli (default: `["ftp", "ftps", "magnet"]`).
164 165
165### Resources 166### Resources
166 167
167- **data_dir**: Data directory. 168- **data_dir**: Data directory.
168- **datastore**: Shaarli's Shaares database file path. 169- **datastore**: Shaarli's Shaares database file path.
169- **history**: Shaarli's operation history file path. 170- **history**: Shaarli's operation history file path.
170- **updates**: File path for the ran updates file. 171- **updates**: File path for the ran updates file.
171- **log**: Log file path. 172- **log**: Log file path.
172- **update_check**: Last update check file path. 173- **update_check**: Last update check file path.
173- **raintpl_tpl**: Templates directory. 174- **raintpl_tpl**: Templates directory.
174- **raintpl_tmp**: Template engine cache directory. 175- **raintpl_tmp**: Template engine cache directory.
175- **thumbnails_cache**: Thumbnails cache directory. 176- **thumbnails_cache**: Thumbnails cache directory.
176- **page_cache**: Shaarli's internal cache directory. 177- **page_cache**: Shaarli's internal cache directory.
177- **ban_file**: Banned IP file path. 178- **ban_file**: Banned IP file path.
178 179
179### Translation 180### Translation
180 181
181- **language**: translation language (also see [Translations](Translations)) 182- **language**: translation language (also see [Translations](Translations))
182 - **auto** (default): The translation language is chosen from the browser locale. 183 - **auto** (default): The translation language is chosen from the browser locale.
183 It means that the language can be different for 2 different visitors depending on their locale. 184 It means that the language can be different for 2 different visitors depending on their locale.
184 - **en**: Use the English translation. 185 - **en**: Use the English translation.
185 - **fr**: Use the French translation. 186 - **fr**: Use the French translation.
186- **mode**: 187- **mode**:
187 - **auto** or **php** (default): Use the PHP implementation of gettext (slower) 188 - **auto** or **php** (default): Use the PHP implementation of gettext (slower)
188 - **gettext**: Use PHP builtin gettext extension 189 - **gettext**: Use PHP builtin gettext extension
189 (faster, but requires `php-gettext` to be installed and to reload the web server on update) 190 (faster, but requires `php-gettext` to be installed and to reload the web server on update)
190- **extension**: Translation extensions for custom themes or plugins. 191- **extension**: Translation extensions for custom themes or plugins.
191Must be an associative array: `translation domain => translation path`. 192Must be an associative array: `translation domain => translation path`.
192 193
193### Updates 194### Updates
194 195
195- **check_updates**: Enable or disable update check to the git repository. 196- **check_updates**: Enable or disable update check to the git repository.
196- **check_updates_branch**: Git branch used to check updates (e.g. `stable` or `master`). 197- **check_updates_branch**: Git branch used to check updates (e.g. `stable` or `master`).
197- **check_updates_interval**: Look for new version every N seconds (default: every day). 198- **check_updates_interval**: Look for new version every N seconds (default: every day).
198 199
199### Privacy 200### Privacy
200 201
201- **default_private_links**: Check the private checkbox by default for every new Shaare. 202- **default_private_links**: Check the private checkbox by default for every new Shaare.
202- **hide_public_links**: All Shaares are hidden while logged out. 203- **hide_public_links**: All Shaares are hidden while logged out.
203- **force_login**: if **hide_public_links** and this are set to `true`, all anonymous users are redirected to the login page. 204- **force_login**: if **hide_public_links** and this are set to `true`, all anonymous users are redirected to the login page.
204- **hide_timestamps**: Timestamps are hidden. 205- **hide_timestamps**: Timestamps are hidden.
205- **remember_user_default**: Default state of the login page's *remember me* checkbox 206- **remember_user_default**: Default state of the login page's *remember me* checkbox
@@ -207,14 +208,14 @@ Must be an associative array: `translation domain => translation path`.
207 208
208### Feed 209### Feed
209 210
210- **rss_permalinks**: Enable this to redirect RSS links to Shaarli's permalinks instead of shaared URL. 211- **rss_permalinks**: Enable this to redirect RSS links to Shaarli's permalinks instead of shaared URL.
211- **show_atom**: Display ATOM feed button. 212- **show_atom**: Display ATOM feed button.
212 213
213### Thumbnail 214### Thumbnail
214 215
215- **enable_thumbnails**: Enable or disable thumbnail display. 216- **enable_thumbnails**: Enable or disable thumbnail display.
216- **enable_localcache**: Enable or disable local cache. 217- **enable_localcache**: Enable or disable local cache.
217 218
218## Plugins configuration 219## Plugins configuration
219 220
220See [Plugins](Plugins.md) \ No newline at end of file 221See [Plugins](Plugins.md)
diff --git a/index.php b/index.php
index 869f42de..b10397dd 100644
--- a/index.php
+++ b/index.php
@@ -35,6 +35,9 @@ use Slim\App;
35 35
36$conf = new ConfigManager(); 36$conf = new ConfigManager();
37 37
38// Manually override root URL for complex server configurations
39define('SHAARLI_ROOT_URL', $conf->get('general.root_url', null));
40
38// In dev mode, throw exception on any warning 41// In dev mode, throw exception on any warning
39if ($conf->get('dev.debug', false)) { 42if ($conf->get('dev.debug', false)) {
40 // See all errors (for debugging only) 43 // See all errors (for debugging only)
diff --git a/tests/http/HttpUtils/IndexUrlTest.php b/tests/http/HttpUtils/IndexUrlTest.php
index 73d33cd4..cce45c51 100644
--- a/tests/http/HttpUtils/IndexUrlTest.php
+++ b/tests/http/HttpUtils/IndexUrlTest.php
@@ -5,12 +5,14 @@
5 5
6namespace Shaarli\Http; 6namespace Shaarli\Http;
7 7
8use PHPUnit\Framework\TestCase;
9
8require_once 'application/http/HttpUtils.php'; 10require_once 'application/http/HttpUtils.php';
9 11
10/** 12/**
11 * Unitary tests for index_url() 13 * Unitary tests for index_url()
12 */ 14 */
13class IndexUrlTest extends \PHPUnit\Framework\TestCase 15class IndexUrlTest extends TestCase
14{ 16{
15 /** 17 /**
16 * If on the main page, remove "index.php" from the URL resource 18 * If on the main page, remove "index.php" from the URL resource
@@ -103,4 +105,36 @@ class IndexUrlTest extends \PHPUnit\Framework\TestCase
103 ) 105 )
104 ); 106 );
105 } 107 }
108
109 /**
110 * The route is stored in REQUEST_URI and subfolder
111 */
112 public function testPageUrlWithRouteUnderSubfolder()
113 {
114 $this->assertEquals(
115 'http://host.tld/subfolder/picture-wall',
116 page_url(
117 array(
118 'HTTPS' => 'Off',
119 'SERVER_NAME' => 'host.tld',
120 'SERVER_PORT' => '80',
121 'SCRIPT_NAME' => '/subfolder/index.php',
122 'REQUEST_URI' => '/subfolder/picture-wall',
123 )
124 )
125 );
126
127 $this->assertEquals(
128 'http://host.tld/subfolder/admin/picture-wall',
129 page_url(
130 array(
131 'HTTPS' => 'Off',
132 'SERVER_NAME' => 'host.tld',
133 'SERVER_PORT' => '80',
134 'SCRIPT_NAME' => '/subfolder/admin/index.php',
135 'REQUEST_URI' => '/subfolder/admin/picture-wall',
136 )
137 )
138 );
139 }
106} 140}
diff --git a/tests/http/HttpUtils/IndexUrlTestWithConstant.php b/tests/http/HttpUtils/IndexUrlTestWithConstant.php
new file mode 100644
index 00000000..15ca3d72
--- /dev/null
+++ b/tests/http/HttpUtils/IndexUrlTestWithConstant.php
@@ -0,0 +1,51 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Http;
6
7use PHPUnit\Framework\TestCase;
8
9/**
10 * Test index_url with SHAARLI_ROOT_URL defined to override automatic retrieval.
11 * This should stay in its dedicated class to make sure to not alter other tests of the suite.
12 */
13class IndexUrlTestWithConstant extends TestCase
14{
15 public static function setUpBeforeClass(): void
16 {
17 define('SHAARLI_ROOT_URL', 'http://other-host.tld/subfolder/');
18 }
19
20 /**
21 * The route is stored in REQUEST_URI and subfolder
22 */
23 public function testIndexUrlWithConstantDefined()
24 {
25 $this->assertEquals(
26 'http://other-host.tld/subfolder/',
27 index_url(
28 array(
29 'HTTPS' => 'Off',
30 'SERVER_NAME' => 'host.tld',
31 'SERVER_PORT' => '80',
32 'SCRIPT_NAME' => '/index.php',
33 'REQUEST_URI' => '/picture-wall',
34 )
35 )
36 );
37
38 $this->assertEquals(
39 'http://other-host.tld/subfolder/',
40 index_url(
41 array(
42 'HTTPS' => 'Off',
43 'SERVER_NAME' => 'host.tld',
44 'SERVER_PORT' => '80',
45 'SCRIPT_NAME' => '/admin/index.php',
46 'REQUEST_URI' => '/admin/picture-wall',
47 )
48 )
49 );
50 }
51}